ErisPulse-KookAdapter 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- erispulse_kookadapter-0.1.0/ErisPulse_KookAdapter.egg-info/PKG-INFO +110 -0
- erispulse_kookadapter-0.1.0/ErisPulse_KookAdapter.egg-info/SOURCES.txt +13 -0
- erispulse_kookadapter-0.1.0/ErisPulse_KookAdapter.egg-info/dependency_links.txt +1 -0
- erispulse_kookadapter-0.1.0/ErisPulse_KookAdapter.egg-info/entry_points.txt +2 -0
- erispulse_kookadapter-0.1.0/ErisPulse_KookAdapter.egg-info/requires.txt +3 -0
- erispulse_kookadapter-0.1.0/ErisPulse_KookAdapter.egg-info/top_level.txt +1 -0
- erispulse_kookadapter-0.1.0/Kook/CallApi.py +291 -0
- erispulse_kookadapter-0.1.0/Kook/Converter.py +175 -0
- erispulse_kookadapter-0.1.0/Kook/Core.py +537 -0
- erispulse_kookadapter-0.1.0/Kook/__init__.py +1 -0
- erispulse_kookadapter-0.1.0/LICENSE +202 -0
- erispulse_kookadapter-0.1.0/PKG-INFO +110 -0
- erispulse_kookadapter-0.1.0/README.md +96 -0
- erispulse_kookadapter-0.1.0/pyproject.toml +18 -0
- erispulse_kookadapter-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ErisPulse-KookAdapter
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: ErisPulse Kook Adapter - Kook平台适配器
|
|
5
|
+
Author-email: ShanFish <shanfishdev@qq.com>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Requires-Python: >=3.8
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: ErisPulse
|
|
11
|
+
Requires-Dist: websockets>=10.0
|
|
12
|
+
Requires-Dist: aiohttp>=3.8.0
|
|
13
|
+
Dynamic: license-file
|
|
14
|
+
|
|
15
|
+
# ErisPulse-KookAdapter
|
|
16
|
+
基于开源机器人框架[ErisPulse](https://github.com/ErisPulse/ErisPulse)的Kook(开黑啦)机器人适配器。
|
|
17
|
+
|
|
18
|
+
项目目前已托管至PyPi,使用以下命令以完成安装:
|
|
19
|
+
```bash
|
|
20
|
+
pip install ErisPulse-KookAdapter
|
|
21
|
+
```
|
|
22
|
+
此时执行`ep list`,应该可以看到`ErisPulse-KookAdapter`在已安装的适配器列表中。
|
|
23
|
+
|
|
24
|
+
## 使用
|
|
25
|
+
```python
|
|
26
|
+
from ErisPulse import sdk
|
|
27
|
+
adapter = sdk.adapter.get("Kook")
|
|
28
|
+
```
|
|
29
|
+
然后就可以对adapter变量进行适配器方法操作了。
|
|
30
|
+
|
|
31
|
+
适配器支持链式调用:
|
|
32
|
+
```python
|
|
33
|
+
# @用户
|
|
34
|
+
await kook.Send.To("group", "频道ID").At("用户ID").Text("Hello")
|
|
35
|
+
|
|
36
|
+
# @多个用户
|
|
37
|
+
await kook.Send.To("group", "频道ID").At("用户1").At("用户2").Text("Hello")
|
|
38
|
+
|
|
39
|
+
# @全体
|
|
40
|
+
await kook.Send.To("group", "频道ID").AtAll().Text("公告")
|
|
41
|
+
|
|
42
|
+
# 回复消息
|
|
43
|
+
await kook.Send.To("group", "频道ID").Reply("消息ID").Text("回复内容")
|
|
44
|
+
|
|
45
|
+
# 组合使用
|
|
46
|
+
await kook.Send.To("group", "频道ID").At("用户ID").Reply("消息ID").Text("Hello")
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
另外,支持不同消息`SendDSL`调用:
|
|
50
|
+
```python
|
|
51
|
+
# 文本消息
|
|
52
|
+
await kook.Send.To("group", "频道ID").Text("Hello World")
|
|
53
|
+
|
|
54
|
+
# 图片消息
|
|
55
|
+
await kook.Send.To("group", "频道ID").Image("http://example.com/image.jpg")
|
|
56
|
+
|
|
57
|
+
# 视频消息
|
|
58
|
+
await kook.Send.To("group", "频道ID").Video("http://example.com/video.mp4")
|
|
59
|
+
|
|
60
|
+
# 文件消息
|
|
61
|
+
await kook.Send.To("group", "频道ID").File("http://example.com/file.pdf")
|
|
62
|
+
|
|
63
|
+
# 语音消息
|
|
64
|
+
await kook.Send.To("group", "频道ID").Voice("http://example.com/voice.mp3")
|
|
65
|
+
|
|
66
|
+
# KMarkdown 消息
|
|
67
|
+
await kook.Send.To("group", "频道ID").Markdown("**粗体** *斜体*")
|
|
68
|
+
|
|
69
|
+
# 卡片消息
|
|
70
|
+
await kook.Send.To("group", "频道ID").Card({
|
|
71
|
+
"type": "card",
|
|
72
|
+
"theme": "primary",
|
|
73
|
+
"size": "lg",
|
|
74
|
+
"modules": [
|
|
75
|
+
{"type": "header", "text": {"type": "plain-text", "content": "标题"}},
|
|
76
|
+
{"type": "section", "text": {"type": "kmarkdown", "content": "内容"}}
|
|
77
|
+
]
|
|
78
|
+
})
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 私信消息
|
|
82
|
+
```python
|
|
83
|
+
# 发送私信给指定用户
|
|
84
|
+
await kook.Send.To("user", "用户ID").Text("Hello")
|
|
85
|
+
await kook.Send.To("user", "用户ID").Markdown("**私信内容**")
|
|
86
|
+
await kook.Send.To("user", "用户ID").Card({...})
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 消息编辑与撤回
|
|
90
|
+
```python
|
|
91
|
+
# 发送消息并获取消息ID
|
|
92
|
+
result = await kook.Send.To("group", "频道ID").Markdown("**原始内容**")
|
|
93
|
+
msg_id = result["data"]["msg_id"]
|
|
94
|
+
|
|
95
|
+
# 编辑消息(仅支持 KMarkdown 和 CardMessage)
|
|
96
|
+
await kook.Send.To("group", "频道ID").Edit(msg_id, "**更新后的内容**")
|
|
97
|
+
|
|
98
|
+
# 撤回消息
|
|
99
|
+
await kook.Send.To("group", "频道ID").Recall(msg_id)
|
|
100
|
+
|
|
101
|
+
# 上传本地文件 并获取文件URL
|
|
102
|
+
result = await kook.Send.Upload("C:/path/to/image.jpg")
|
|
103
|
+
file_url = result["data"]["url"]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
## 参考文档
|
|
108
|
+
- [Kook API 文档](https://developer.kookapp.cn/doc)
|
|
109
|
+
- [ErisPulse 文档](https://erisdev.com)
|
|
110
|
+
- [ErisPulse 主库](https://github.com/ErisPulse/ErisPulse)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
ErisPulse_KookAdapter.egg-info/PKG-INFO
|
|
5
|
+
ErisPulse_KookAdapter.egg-info/SOURCES.txt
|
|
6
|
+
ErisPulse_KookAdapter.egg-info/dependency_links.txt
|
|
7
|
+
ErisPulse_KookAdapter.egg-info/entry_points.txt
|
|
8
|
+
ErisPulse_KookAdapter.egg-info/requires.txt
|
|
9
|
+
ErisPulse_KookAdapter.egg-info/top_level.txt
|
|
10
|
+
Kook/CallApi.py
|
|
11
|
+
Kook/Converter.py
|
|
12
|
+
Kook/Core.py
|
|
13
|
+
Kook/__init__.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Kook
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import aiohttp
|
|
2
|
+
import uuid
|
|
3
|
+
|
|
4
|
+
class CallApi:
|
|
5
|
+
def __init__(self, token: str):
|
|
6
|
+
self.token = token
|
|
7
|
+
self.session = aiohttp.ClientSession()
|
|
8
|
+
|
|
9
|
+
async def close(self):
|
|
10
|
+
if self.session.closed:
|
|
11
|
+
return
|
|
12
|
+
await self.session.close()
|
|
13
|
+
|
|
14
|
+
async def start(self):
|
|
15
|
+
if not self.session.closed:
|
|
16
|
+
return
|
|
17
|
+
await self.session.start()
|
|
18
|
+
|
|
19
|
+
async def send_message(
|
|
20
|
+
self,
|
|
21
|
+
target_id: str,
|
|
22
|
+
type: int,
|
|
23
|
+
content: str,
|
|
24
|
+
quote_msg_id: str = None,
|
|
25
|
+
template_id: str = None,
|
|
26
|
+
**kwargs
|
|
27
|
+
) -> dict:
|
|
28
|
+
"""发送频道消息"""
|
|
29
|
+
if not self.token:
|
|
30
|
+
return {
|
|
31
|
+
"code": -1,
|
|
32
|
+
"msg": "token未刷新, 请刷新后重试",
|
|
33
|
+
"data": {}
|
|
34
|
+
}
|
|
35
|
+
nonce = str(uuid.uuid4())
|
|
36
|
+
payload = {
|
|
37
|
+
"nonce": nonce,
|
|
38
|
+
"target_id": target_id,
|
|
39
|
+
"type": type,
|
|
40
|
+
"content": content,
|
|
41
|
+
}
|
|
42
|
+
if quote_msg_id:
|
|
43
|
+
payload["quote"] = quote_msg_id
|
|
44
|
+
if template_id:
|
|
45
|
+
payload["template_id"] = template_id
|
|
46
|
+
|
|
47
|
+
# 添加其他可选参数(如 mention, mention_all 等)
|
|
48
|
+
for key, value in kwargs.items():
|
|
49
|
+
if value is not None:
|
|
50
|
+
payload[key] = value
|
|
51
|
+
|
|
52
|
+
async with self.session.post(
|
|
53
|
+
"https://www.kookapp.cn/api/v3/message/create",
|
|
54
|
+
json=payload,
|
|
55
|
+
headers={
|
|
56
|
+
"Authorization": f"Bot {self.token}",
|
|
57
|
+
"Content-Type": "application/json"
|
|
58
|
+
}
|
|
59
|
+
) as resp:
|
|
60
|
+
data = await resp.json()
|
|
61
|
+
return data
|
|
62
|
+
|
|
63
|
+
async def send_direct_message(
|
|
64
|
+
self,
|
|
65
|
+
target_id: str,
|
|
66
|
+
type: int,
|
|
67
|
+
content: str,
|
|
68
|
+
quote_msg_id: str = None,
|
|
69
|
+
template_id: str = None,
|
|
70
|
+
**kwargs
|
|
71
|
+
) -> dict:
|
|
72
|
+
"""发送私信消息"""
|
|
73
|
+
if not self.token:
|
|
74
|
+
return {
|
|
75
|
+
"code": -1,
|
|
76
|
+
"msg": "token未刷新, 请刷新后重试",
|
|
77
|
+
"data": {}
|
|
78
|
+
}
|
|
79
|
+
nonce = str(uuid.uuid4())
|
|
80
|
+
payload = {
|
|
81
|
+
"nonce": nonce,
|
|
82
|
+
"target_id": target_id,
|
|
83
|
+
"type": type,
|
|
84
|
+
"content": content,
|
|
85
|
+
}
|
|
86
|
+
if quote_msg_id:
|
|
87
|
+
payload["quote"] = quote_msg_id
|
|
88
|
+
if template_id:
|
|
89
|
+
payload["template_id"] = template_id
|
|
90
|
+
|
|
91
|
+
# 添加其他可选参数(如 reply_msg_id 等)
|
|
92
|
+
for key, value in kwargs.items():
|
|
93
|
+
if value is not None:
|
|
94
|
+
payload[key] = value
|
|
95
|
+
|
|
96
|
+
async with self.session.post(
|
|
97
|
+
"https://www.kookapp.cn/api/v3/direct-message/create",
|
|
98
|
+
json=payload,
|
|
99
|
+
headers={
|
|
100
|
+
"Authorization": f"Bot {self.token}",
|
|
101
|
+
"Content-Type": "application/json"
|
|
102
|
+
}
|
|
103
|
+
) as resp:
|
|
104
|
+
data = await resp.json()
|
|
105
|
+
return data
|
|
106
|
+
|
|
107
|
+
async def update_direct_message(
|
|
108
|
+
self,
|
|
109
|
+
msg_id: str,
|
|
110
|
+
content: str,
|
|
111
|
+
quote: str = None,
|
|
112
|
+
template_id: str = None,
|
|
113
|
+
**kwargs
|
|
114
|
+
) -> dict:
|
|
115
|
+
"""更新私信消息(仅支持 KMarkdown type=9 和 CardMessage type=10)"""
|
|
116
|
+
if not self.token:
|
|
117
|
+
return {
|
|
118
|
+
"code": -1,
|
|
119
|
+
"msg": "token未刷新, 请刷新后重试",
|
|
120
|
+
"data": {}
|
|
121
|
+
}
|
|
122
|
+
payload = {
|
|
123
|
+
"msg_id": msg_id,
|
|
124
|
+
"content": content,
|
|
125
|
+
}
|
|
126
|
+
if quote is not None:
|
|
127
|
+
payload["quote"] = quote
|
|
128
|
+
if template_id:
|
|
129
|
+
payload["template_id"] = template_id
|
|
130
|
+
|
|
131
|
+
# 添加其他可选参数
|
|
132
|
+
for key, value in kwargs.items():
|
|
133
|
+
if value is not None:
|
|
134
|
+
payload[key] = value
|
|
135
|
+
|
|
136
|
+
async with self.session.post(
|
|
137
|
+
"https://www.kookapp.cn/api/v3/direct-message/update",
|
|
138
|
+
json=payload,
|
|
139
|
+
headers={
|
|
140
|
+
"Authorization": f"Bot {self.token}",
|
|
141
|
+
"Content-Type": "application/json"
|
|
142
|
+
}
|
|
143
|
+
) as resp:
|
|
144
|
+
data = await resp.json()
|
|
145
|
+
return data
|
|
146
|
+
|
|
147
|
+
async def delete_direct_message(
|
|
148
|
+
self,
|
|
149
|
+
msg_id: str,
|
|
150
|
+
**kwargs
|
|
151
|
+
) -> dict:
|
|
152
|
+
"""删除私信消息"""
|
|
153
|
+
if not self.token:
|
|
154
|
+
return {
|
|
155
|
+
"code": -1,
|
|
156
|
+
"msg": "token未刷新, 请刷新后重试",
|
|
157
|
+
"data": {}
|
|
158
|
+
}
|
|
159
|
+
payload = {
|
|
160
|
+
"msg_id": msg_id,
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# 添加其他可选参数
|
|
164
|
+
for key, value in kwargs.items():
|
|
165
|
+
if value is not None:
|
|
166
|
+
payload[key] = value
|
|
167
|
+
|
|
168
|
+
async with self.session.post(
|
|
169
|
+
"https://www.kookapp.cn/api/v3/direct-message/delete",
|
|
170
|
+
json=payload,
|
|
171
|
+
headers={
|
|
172
|
+
"Authorization": f"Bot {self.token}",
|
|
173
|
+
"Content-Type": "application/json"
|
|
174
|
+
}
|
|
175
|
+
) as resp:
|
|
176
|
+
data = await resp.json()
|
|
177
|
+
return data
|
|
178
|
+
|
|
179
|
+
async def update_channel_message(
|
|
180
|
+
self,
|
|
181
|
+
msg_id: str,
|
|
182
|
+
content: str,
|
|
183
|
+
quote: str = None,
|
|
184
|
+
temp_target_id: str = None,
|
|
185
|
+
template_id: str = None,
|
|
186
|
+
**kwargs
|
|
187
|
+
) -> dict:
|
|
188
|
+
"""更新频道消息(仅支持 KMarkdown type=9 和 CardMessage type=10)"""
|
|
189
|
+
if not self.token:
|
|
190
|
+
return {
|
|
191
|
+
"code": -1,
|
|
192
|
+
"msg": "token未刷新, 请刷新后重试",
|
|
193
|
+
"data": {}
|
|
194
|
+
}
|
|
195
|
+
payload = {
|
|
196
|
+
"msg_id": msg_id,
|
|
197
|
+
"content": content,
|
|
198
|
+
}
|
|
199
|
+
if quote is not None:
|
|
200
|
+
payload["quote"] = quote
|
|
201
|
+
if temp_target_id:
|
|
202
|
+
payload["temp_target_id"] = temp_target_id
|
|
203
|
+
if template_id:
|
|
204
|
+
payload["template_id"] = template_id
|
|
205
|
+
|
|
206
|
+
# 添加其他可选参数
|
|
207
|
+
for key, value in kwargs.items():
|
|
208
|
+
if value is not None:
|
|
209
|
+
payload[key] = value
|
|
210
|
+
|
|
211
|
+
async with self.session.post(
|
|
212
|
+
"https://www.kookapp.cn/api/v3/message/update",
|
|
213
|
+
json=payload,
|
|
214
|
+
headers={
|
|
215
|
+
"Authorization": f"Bot {self.token}",
|
|
216
|
+
"Content-Type": "application/json"
|
|
217
|
+
}
|
|
218
|
+
) as resp:
|
|
219
|
+
data = await resp.json()
|
|
220
|
+
return data
|
|
221
|
+
|
|
222
|
+
async def delete_channel_message(
|
|
223
|
+
self,
|
|
224
|
+
msg_id: str,
|
|
225
|
+
**kwargs
|
|
226
|
+
) -> dict:
|
|
227
|
+
"""删除频道消息"""
|
|
228
|
+
if not self.token:
|
|
229
|
+
return {
|
|
230
|
+
"code": -1,
|
|
231
|
+
"msg": "token未刷新, 请刷新后重试",
|
|
232
|
+
"data": {}
|
|
233
|
+
}
|
|
234
|
+
payload = {
|
|
235
|
+
"msg_id": msg_id,
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
# 添加其他可选参数
|
|
239
|
+
for key, value in kwargs.items():
|
|
240
|
+
if value is not None:
|
|
241
|
+
payload[key] = value
|
|
242
|
+
|
|
243
|
+
async with self.session.post(
|
|
244
|
+
"https://www.kookapp.cn/api/v3/message/delete",
|
|
245
|
+
json=payload,
|
|
246
|
+
headers={
|
|
247
|
+
"Authorization": f"Bot {self.token}",
|
|
248
|
+
"Content-Type": "application/json"
|
|
249
|
+
}
|
|
250
|
+
) as resp:
|
|
251
|
+
data = await resp.json()
|
|
252
|
+
return data
|
|
253
|
+
|
|
254
|
+
async def upload_file(self, file_path: str) -> dict:
|
|
255
|
+
if not self.token:
|
|
256
|
+
return {
|
|
257
|
+
"code": -1,
|
|
258
|
+
"msg": "token未刷新, 请刷新后重试",
|
|
259
|
+
"data": {}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async with self.session.post(
|
|
263
|
+
"https://www.kookapp.cn/api/v3/asset/create",
|
|
264
|
+
headers={
|
|
265
|
+
"Authorization": f"Bot {self.token}",
|
|
266
|
+
"Content-Type": "multipart/form-data"
|
|
267
|
+
},
|
|
268
|
+
data={
|
|
269
|
+
"file": open(file_path, "rb")
|
|
270
|
+
}
|
|
271
|
+
) as resp:
|
|
272
|
+
data = await resp.json()
|
|
273
|
+
return data
|
|
274
|
+
|
|
275
|
+
async def get_ws_gateway(self, need_compress: bool = True) -> str:
|
|
276
|
+
if not self.token:
|
|
277
|
+
return ""
|
|
278
|
+
async with self.session.post(
|
|
279
|
+
"https://www.kookapp.cn/api/v3/gateway/index",
|
|
280
|
+
headers={
|
|
281
|
+
"Authorization": f"Bot {self.token}",
|
|
282
|
+
"Content-Type": "application/json"
|
|
283
|
+
},
|
|
284
|
+
json={
|
|
285
|
+
"need_compress": 1 if need_compress else 0
|
|
286
|
+
}
|
|
287
|
+
) as resp:
|
|
288
|
+
data = await resp.json()
|
|
289
|
+
if data.get("code") == 0:
|
|
290
|
+
return data.get("data", {}).get("url", "")
|
|
291
|
+
return ""
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Kook Event -> OneBot V12
|
|
3
|
+
标准协议转换器
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import uuid
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class KookAdapterConverter:
|
|
12
|
+
def convert(self, data):
|
|
13
|
+
d = data.get("d", {})
|
|
14
|
+
extra = d.get("extra", {})
|
|
15
|
+
author = extra.get("author", {})
|
|
16
|
+
kook_type = d.get("type", 0)
|
|
17
|
+
channel_type = d.get("channel_type", "")
|
|
18
|
+
|
|
19
|
+
onebot_data = {
|
|
20
|
+
"id": str(uuid.uuid4()).replace("-", ""),
|
|
21
|
+
"time": time.time(),
|
|
22
|
+
"type": self._get_message_type(data),
|
|
23
|
+
"detail_type": self._get_detail_type(data),
|
|
24
|
+
"platform": "Kook",
|
|
25
|
+
"self": {
|
|
26
|
+
"platform": "Kook",
|
|
27
|
+
"user_id": ""
|
|
28
|
+
},
|
|
29
|
+
"Kook_raw": data,
|
|
30
|
+
"Kook_raw_type": kook_type,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if onebot_data["type"] == "message":
|
|
34
|
+
onebot_data.update({
|
|
35
|
+
"message_id": d.get("msg_id", ""),
|
|
36
|
+
"user_id": author.get("id", ""),
|
|
37
|
+
"message": self._convert_message_content(data),
|
|
38
|
+
"alt_message": d.get("content", ""),
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
if channel_type == "PERSON":
|
|
42
|
+
onebot_data["detail_type"] = "private"
|
|
43
|
+
elif channel_type == "GROUP":
|
|
44
|
+
onebot_data["group_id"] = d.get("target_id", "")
|
|
45
|
+
|
|
46
|
+
mentions = extra.get("mention", [])
|
|
47
|
+
if mentions:
|
|
48
|
+
onebot_data["mentions"] = mentions
|
|
49
|
+
|
|
50
|
+
elif onebot_data["type"] == "notice":
|
|
51
|
+
onebot_data["user_id"] = author.get("id", "")
|
|
52
|
+
onebot_data["guild_id"] = extra.get("guild_id", "")
|
|
53
|
+
onebot_data.update(self._convert_notice_data(data))
|
|
54
|
+
|
|
55
|
+
return onebot_data
|
|
56
|
+
|
|
57
|
+
def _get_message_type(self, data):
|
|
58
|
+
kook_type = data.get("d", {}).get("type", 0)
|
|
59
|
+
return {
|
|
60
|
+
255: "notice"
|
|
61
|
+
}.get(kook_type, "message")
|
|
62
|
+
|
|
63
|
+
def _get_detail_type(self, data):
|
|
64
|
+
d = data.get("d", {})
|
|
65
|
+
kook_type = d.get("type", 0)
|
|
66
|
+
if kook_type == 255:
|
|
67
|
+
return data.get("d", {}).get("extra", {}).get("type", "")
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
1: "text",
|
|
71
|
+
2: "image",
|
|
72
|
+
3: "video",
|
|
73
|
+
4: "file",
|
|
74
|
+
8: "record",
|
|
75
|
+
9: "kmarkdown",
|
|
76
|
+
10: "json",
|
|
77
|
+
}.get(kook_type, "unknown")
|
|
78
|
+
|
|
79
|
+
def _convert_message_content(self, data):
|
|
80
|
+
d = data.get("d", {})
|
|
81
|
+
extra = d.get("extra", {})
|
|
82
|
+
kook_type = d.get("type", 0)
|
|
83
|
+
content = d.get("content", "")
|
|
84
|
+
|
|
85
|
+
message_segments = []
|
|
86
|
+
|
|
87
|
+
if kook_type == 1:
|
|
88
|
+
message_segments.append({"type": "text", "data": {"text": content}})
|
|
89
|
+
elif kook_type == 2:
|
|
90
|
+
attachments = extra.get("attachments", {})
|
|
91
|
+
url = attachments.get("url", content)
|
|
92
|
+
message_segments.append({"type": "image", "data": {"file": url, "url": url}})
|
|
93
|
+
elif kook_type == 3:
|
|
94
|
+
attachments = extra.get("attachments", {})
|
|
95
|
+
url = attachments.get("url", content)
|
|
96
|
+
message_segments.append({"type": "video", "data": {"file": url, "url": url}})
|
|
97
|
+
elif kook_type == 4:
|
|
98
|
+
attachments = extra.get("attachments", {})
|
|
99
|
+
url = attachments.get("url", content)
|
|
100
|
+
message_segments.append({"type": "file", "data": {"file": url, "url": url}})
|
|
101
|
+
elif kook_type == 8:
|
|
102
|
+
attachments = extra.get("attachments", {})
|
|
103
|
+
url = attachments.get("url", content)
|
|
104
|
+
message_segments.append({"type": "record", "data": {"file": url, "url": url}})
|
|
105
|
+
elif kook_type == 9:
|
|
106
|
+
kmarkdown = extra.get("kmarkdown", {})
|
|
107
|
+
raw_content = kmarkdown.get("raw_content", content)
|
|
108
|
+
message_segments.append({"type": "text", "data": {"text": raw_content}})
|
|
109
|
+
elif kook_type == 10:
|
|
110
|
+
message_segments.append({"type": "json", "data": {"data": content}})
|
|
111
|
+
else:
|
|
112
|
+
message_segments.append({"type": "text", "data": {"text": content}})
|
|
113
|
+
|
|
114
|
+
mention = extra.get("mention", [])
|
|
115
|
+
if mention:
|
|
116
|
+
for user_id in mention:
|
|
117
|
+
message_segments.insert(0, {"type": "mention", "data": {"user_id": user_id}})
|
|
118
|
+
|
|
119
|
+
if extra.get("mention_all", False):
|
|
120
|
+
message_segments.insert(0, {"type": "mention_all", "data": {}})
|
|
121
|
+
|
|
122
|
+
return message_segments
|
|
123
|
+
|
|
124
|
+
def _convert_notice_data(self, data):
|
|
125
|
+
d = data.get("d", {})
|
|
126
|
+
extra = d.get("extra", {})
|
|
127
|
+
event_type = extra.get("type", "")
|
|
128
|
+
body = extra.get("body", {})
|
|
129
|
+
|
|
130
|
+
notice_data = {}
|
|
131
|
+
|
|
132
|
+
# 映射 Kook 事件类型到标准 notice_type
|
|
133
|
+
if event_type == "added_reaction":
|
|
134
|
+
notice_data["notice_type"] = "reaction_added"
|
|
135
|
+
notice_data["sub_type"] = "added_reaction"
|
|
136
|
+
notice_data["channel_id"] = body.get("channel_id", "")
|
|
137
|
+
notice_data["message_id"] = body.get("msg_id", "")
|
|
138
|
+
notice_data["user_id"] = body.get("user_id", "")
|
|
139
|
+
notice_data["emoji"] = body.get("emoji", {})
|
|
140
|
+
elif event_type == "deleted_reaction":
|
|
141
|
+
notice_data["notice_type"] = "reaction_removed"
|
|
142
|
+
notice_data["sub_type"] = "deleted_reaction"
|
|
143
|
+
notice_data["channel_id"] = body.get("channel_id", "")
|
|
144
|
+
notice_data["message_id"] = body.get("msg_id", "")
|
|
145
|
+
notice_data["user_id"] = body.get("user_id", "")
|
|
146
|
+
notice_data["emoji"] = body.get("emoji", {})
|
|
147
|
+
elif event_type == "private_added_reaction":
|
|
148
|
+
notice_data["notice_type"] = "reaction_added"
|
|
149
|
+
notice_data["sub_type"] = "private_added_reaction"
|
|
150
|
+
notice_data["message_id"] = body.get("msg_id", "")
|
|
151
|
+
notice_data["user_id"] = body.get("user_id", "")
|
|
152
|
+
notice_data["emoji"] = body.get("emoji", {})
|
|
153
|
+
elif event_type == "private_deleted_reaction":
|
|
154
|
+
notice_data["notice_type"] = "reaction_removed"
|
|
155
|
+
notice_data["sub_type"] = "private_deleted_reaction"
|
|
156
|
+
notice_data["message_id"] = body.get("msg_id", "")
|
|
157
|
+
notice_data["user_id"] = body.get("user_id", "")
|
|
158
|
+
notice_data["emoji"] = body.get("emoji", {})
|
|
159
|
+
elif event_type == "updated_private_message":
|
|
160
|
+
notice_data["notice_type"] = "message_updated"
|
|
161
|
+
notice_data["sub_type"] = "updated_private_message"
|
|
162
|
+
notice_data["message_id"] = body.get("msg_id", "")
|
|
163
|
+
notice_data["user_id"] = body.get("author_id", "")
|
|
164
|
+
notice_data["content"] = body.get("content", "")
|
|
165
|
+
elif event_type == "deleted_private_message":
|
|
166
|
+
notice_data["notice_type"] = "message_deleted"
|
|
167
|
+
notice_data["sub_type"] = "deleted_private_message"
|
|
168
|
+
notice_data["message_id"] = body.get("msg_id", "")
|
|
169
|
+
notice_data["user_id"] = body.get("author_id", "")
|
|
170
|
+
else:
|
|
171
|
+
notice_data["notice_type"] = "system"
|
|
172
|
+
notice_data["sub_type"] = event_type if event_type else "system"
|
|
173
|
+
notice_data["raw_event"] = extra
|
|
174
|
+
|
|
175
|
+
return notice_data
|