@alemonjs/qq-bot 0.0.4 → 0.0.5

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.
package/README.md CHANGED
@@ -23,18 +23,49 @@ qq-bot:
23
23
  ```
24
24
 
25
25
  ```sh
26
- qq-group-bot:
26
+ qq-bot:
27
27
  master_key:
28
28
  - ''
29
29
  # 默认 推荐nginx进行代理 http://localhost:17157/webhook
30
+ route: '/webhook'
30
31
  port: 17157
31
32
  # 当配置ws的时候,会连接另一台hook机器人的消息。不会再启动本地端口。
32
33
  # 推荐nginx进行代理 http://localhost:17157/
33
- ws: 'wss://xxxx/ws'
34
+ ws: 'wss://xxxx/websocket'
34
35
  # 频道沙盒
35
36
  sandbox: false
36
37
  ```
37
38
 
39
+ ```conf
40
+ server {
41
+ listen 443 ssl http2;
42
+ server_name bundle.com;
43
+ ssl_certificate /usr/local/nginx/bundle.crt;
44
+ ssl_certificate_key /usr/local/nginx/bundle.key;
45
+
46
+ location /webhook {
47
+ # 指向 webhook 服务的端口
48
+ proxy_pass http://localhost:17157;
49
+ proxy_set_header Host $host;
50
+ proxy_set_header X-Real-IP $remote_addr;
51
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
52
+ proxy_set_header X-Forwarded-Proto $scheme;
53
+ }
54
+
55
+ location /websocket {
56
+ # 指向 WebSocket 服务的端口
57
+ proxy_pass http://localhost:17157;
58
+ proxy_http_version 1.1;
59
+ proxy_set_header Upgrade $http_upgrade;
60
+ proxy_set_header Connection "upgrade";
61
+ proxy_set_header Host $host;
62
+ proxy_set_header X-Real-IP $remote_addr;
63
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
64
+ proxy_set_header X-Forwarded-Proto $scheme;
65
+ }
66
+ }
67
+ ```
68
+
38
69
  ## Community
39
70
 
40
71
  QQ Group 806943302
package/lib/api.js CHANGED
@@ -83,7 +83,6 @@ class QQBotAPI {
83
83
  * 0 文本 1 图文 2 md 3 ark 4 embed
84
84
  */
85
85
  async usersOpenMessages(openid, data, msg_id) {
86
- console.log('msg_id', msg_id);
87
86
  return this.groupService({
88
87
  url: `/v2/users/${openid}/messages`,
89
88
  method: 'post',
package/lib/client.js CHANGED
@@ -1,210 +1,228 @@
1
- import { QQBotAPI } from './api.js'
2
- import bodyParser from 'koa-bodyparser'
3
- import Router from 'koa-router'
4
- import { WebhookAPI } from './webhook.js'
5
- import Koa from 'koa'
6
- import { config } from './config.js'
7
- import { v4 } from 'uuid'
8
- import { WebSocketServer, WebSocket } from 'ws'
1
+ import { QQBotAPI } from './api.js';
2
+ import bodyParser from 'koa-bodyparser';
3
+ import Router from 'koa-router';
4
+ import { WebhookAPI } from './webhook.js';
5
+ import Koa from 'koa';
6
+ import { config } from './config.js';
7
+ import { v4 } from 'uuid';
8
+ import { WebSocketServer, WebSocket } from 'ws';
9
9
 
10
10
  class QQBotClient extends QQBotAPI {
11
- #events = {}
12
- #app = null
13
- #count = 0
14
- #client = []
15
- #ws = null
16
- /**
17
- * 设置配置
18
- * @param opstion
19
- */
20
- constructor(opstion) {
21
- super()
22
- if (opstion.secret) config.set('secret', opstion.secret)
23
- if (opstion.app_id) config.set('app_id', opstion.app_id)
24
- if (opstion.token) config.set('token', opstion.token)
25
- if (opstion.port) config.set('port', opstion.port)
26
- if (opstion.ws) config.set('ws', opstion.ws)
27
- }
28
- /**
29
- * 注册事件处理程序
30
- * @param key 事件名称
31
- * @param val 事件处理函数
32
- */
33
- on(key, val) {
34
- if (!this.#events[key]) {
35
- this.#events[key] = []
11
+ #events = {};
12
+ #app = null;
13
+ #count = 0;
14
+ #client = [];
15
+ #ws = null;
16
+ /**
17
+ * 设置配置
18
+ * @param opstion
19
+ */
20
+ constructor(opstion) {
21
+ super();
22
+ if (opstion.secret)
23
+ config.set('secret', opstion.secret);
24
+ if (opstion.app_id)
25
+ config.set('app_id', opstion.app_id);
26
+ if (opstion.token)
27
+ config.set('token', opstion.token);
28
+ if (opstion.port)
29
+ config.set('port', opstion.port);
30
+ if (opstion.ws)
31
+ config.set('ws', opstion.ws);
36
32
  }
37
- this.#events[key].push(val)
38
- return this
39
- }
40
- /**
41
- * 定时鉴权
42
- * @param cfg
43
- * @returns
44
- */
45
- async #setTimeoutBotConfig() {
46
- const callBack = async () => {
47
- const app_id = config.get('app_id')
48
- if (!app_id) return
49
- const secret = config.get('secret')
50
- if (!secret) return
51
- // 发送请求
52
- const data = await this.getAuthentication(app_id, secret).then(res => res.data)
53
- config.set('access_token', data.access_token)
54
- console.info('refresh', data.expires_in, 's')
55
- setTimeout(callBack, data.expires_in * 1000)
56
- }
57
- await callBack()
58
- }
59
- /**
60
- *
61
- * @param cfg
62
- * @param conversation
63
- */
64
- connect() {
65
- try {
66
- const ws = config.get('ws')
67
- if (!ws) {
68
- this.#setTimeoutBotConfig()
69
- this.#app = new Koa()
70
- this.#app.use(bodyParser())
71
- const router = new Router()
72
- const port = config.get('port')
73
- const secret = config.get('secret')
74
- const cfg = {
75
- secret: secret ?? '',
76
- port: port ? Number(port) : 17157
33
+ /**
34
+ * 注册事件处理程序
35
+ * @param key 事件名称
36
+ * @param val 事件处理函数
37
+ */
38
+ on(key, val) {
39
+ if (!this.#events[key]) {
40
+ this.#events[key] = [];
77
41
  }
78
- const ntqqWebhook = new WebhookAPI({
79
- secret: cfg.secret
80
- })
81
- this.#app.use(async (ctx, next) => {
82
- let rawData = ''
83
- ctx.req.on('data', chunk => (rawData += chunk))
84
- ctx.req.on('end', () => (ctx.request.rawBody = rawData))
85
- await next()
86
- })
87
- // 启动服务
88
- router.post('/webhook', async ctx => {
89
- const sign = ctx.req.headers['x-signature-ed25519']
90
- const timestamp = ctx.req.headers['x-signature-timestamp']
91
- const rawBody = ctx.request.rawBody
92
- const isValid = ntqqWebhook.validSign(timestamp, rawBody, String(sign))
93
- if (!isValid) {
94
- ctx.status = 400
95
- ctx.body = { msg: 'invalid signature' }
96
- return
97
- }
98
- const body = ctx.request.body
99
- if (body.op == 13) {
100
- ctx.status = 200
101
- ctx.body = {
102
- // 返回明文 token
103
- plain_token: body.d.plain_token,
104
- // 生成签名
105
- signature: ntqqWebhook.getSign(body.d.event_ts, body.d.plain_token)
106
- }
107
- } else if (body.op == 0) {
108
- ctx.status = 204
109
- // 根据事件类型,处理事件
110
- for (const event of this.#events[body.t] || []) {
111
- event(body.d)
112
- }
113
- const access_token = config.get('access_token')
114
- // 也可以分法到客户端。 发送失败需要处理 或清理调
115
- for (const client of this.#client) {
116
- try {
117
- if (access_token) body['access_token'] = access_token
118
- client.ws.send(JSON.stringify(body))
119
- } catch (e) {
120
- this.#error(e)
121
- }
122
- }
123
- }
124
- })
125
- this.#app.use(router.routes())
126
- this.#app.use(router.allowedMethods())
127
- // 启动服务
128
- const server = this.#app.listen(cfg.port, () => {
129
- console.log('Server running at http://localhost:' + cfg.port + '/webhook')
130
- })
131
- // 创建 WebSocketServer 并监听同一个端口
132
- const wss = new WebSocketServer({ server: server })
133
- // 处理客户端连接
134
- wss.on('connection', ws => {
135
- const clientId = v4()
136
- ws['clientId'] = clientId
137
- console.log(clientId, 'connection')
138
- this.#client.push({ id: clientId, ws })
139
- // 处理消息事件
140
- ws.on('message', message => {
141
- // 拿到消息
142
- try {
143
- const body = JSON.parse(message.toString())
144
- for (const event of this.#events[body.t] || []) {
145
- event(body.d)
146
- }
147
- } catch (e) {
148
- this.#error(e)
42
+ this.#events[key].push(val);
43
+ return this;
44
+ }
45
+ /**
46
+ * 定时鉴权
47
+ * @param cfg
48
+ * @returns
49
+ */
50
+ async #setTimeoutBotConfig() {
51
+ const callBack = async () => {
52
+ const app_id = config.get('app_id');
53
+ if (!app_id)
54
+ return;
55
+ const secret = config.get('secret');
56
+ if (!secret)
57
+ return;
58
+ // 发送请求
59
+ const data = await this.getAuthentication(app_id, secret).then(res => res.data);
60
+ config.set('access_token', data.access_token);
61
+ console.info('refresh', data.expires_in, 's');
62
+ setTimeout(callBack, data.expires_in * 1000);
63
+ };
64
+ await callBack();
65
+ }
66
+ /**
67
+ *
68
+ * @param cfg
69
+ * @param conversation
70
+ */
71
+ connect() {
72
+ try {
73
+ const ws = config.get('ws');
74
+ if (!ws) {
75
+ this.#setTimeoutBotConfig();
76
+ this.#app = new Koa();
77
+ this.#app.use(bodyParser());
78
+ const router = new Router();
79
+ const port = config.get('port');
80
+ const secret = config.get('secret');
81
+ const route = config.get('route') ?? '/webhook';
82
+ const cfg = {
83
+ secret: secret ?? '',
84
+ port: port ? Number(port) : 17157
85
+ };
86
+ const ntqqWebhook = new WebhookAPI({
87
+ secret: cfg.secret
88
+ });
89
+ this.#app.use(async (ctx, next) => {
90
+ let rawData = '';
91
+ ctx.req.on('data', chunk => (rawData += chunk));
92
+ ctx.req.on('end', () => (ctx.request.rawBody = rawData));
93
+ await next();
94
+ });
95
+ // 启动服务
96
+ router.post(route, async (ctx) => {
97
+ const sign = ctx.req.headers['x-signature-ed25519'];
98
+ const timestamp = ctx.req.headers['x-signature-timestamp'];
99
+ const rawBody = ctx.request.rawBody;
100
+ const isValid = ntqqWebhook.validSign(timestamp, rawBody, String(sign));
101
+ if (!isValid) {
102
+ ctx.status = 400;
103
+ ctx.body = { msg: 'invalid signature' };
104
+ return;
105
+ }
106
+ const body = ctx.request.body;
107
+ if (body.op == 13) {
108
+ ctx.status = 200;
109
+ ctx.body = {
110
+ // 返回明文 token
111
+ plain_token: body.d.plain_token,
112
+ // 生成签名
113
+ signature: ntqqWebhook.getSign(body.d.event_ts, body.d.plain_token)
114
+ };
115
+ }
116
+ else if (body.op == 0) {
117
+ ctx.status = 204;
118
+ // 根据事件类型,处理事件
119
+ for (const event of this.#events[body.t] || []) {
120
+ event(body.d);
121
+ }
122
+ const access_token = config.get('access_token');
123
+ // 也可以分法到客户端。 发送失败需要处理 或清理调
124
+ for (const client of this.#client) {
125
+ try {
126
+ if (access_token)
127
+ body['access_token'] = access_token;
128
+ client.ws.send(JSON.stringify(body));
129
+ }
130
+ catch (e) {
131
+ this.#error(e);
132
+ }
133
+ }
134
+ }
135
+ });
136
+ this.#app.use(router.routes());
137
+ this.#app.use(router.allowedMethods());
138
+ // 启动服务
139
+ const server = this.#app.listen(cfg.port, () => {
140
+ console.log('Server running at http://localhost:' + cfg.port + route);
141
+ });
142
+ // 创建 WebSocketServer 并监听同一个端口
143
+ const wss = new WebSocketServer({ server: server });
144
+ console.log('Server running at wss://localhost:' + cfg.port + '/');
145
+ // 处理客户端连接
146
+ wss.on('connection', ws => {
147
+ const clientId = v4();
148
+ ws['clientId'] = clientId;
149
+ console.log(clientId, 'connection');
150
+ this.#client.push({ id: clientId, ws });
151
+ // 处理消息事件
152
+ ws.on('message', (message) => {
153
+ // 拿到消息
154
+ try {
155
+ const body = JSON.parse(message.toString());
156
+ for (const event of this.#events[body.t] || []) {
157
+ event(body.d);
158
+ }
159
+ }
160
+ catch (e) {
161
+ this.#error(e);
162
+ }
163
+ });
164
+ // 处理关闭事件
165
+ ws.on('close', () => {
166
+ console.log(`${clientId} disconnected`);
167
+ this.#client = this.#client.filter(client => client.id !== clientId);
168
+ });
169
+ });
149
170
  }
150
- })
151
- // 处理关闭事件
152
- ws.on('close', () => {
153
- console.log(`${clientId} disconnected`)
154
- this.#client = this.#client.filter(client => client.id !== clientId)
155
- })
156
- })
157
- }
158
- const reconnect = () => {
159
- if (!ws) return
160
- // 使用了ws服务器
161
- this.#ws = new WebSocket(ws)
162
- this.#ws.on('open', () => {
163
- this.#count = 0
164
- console.log('ws connected')
165
- })
166
- this.#ws.on('message', data => {
167
- try {
168
- // 拿到消息
169
- const body = JSON.parse(data.toString())
170
- const access_token = body['access_token']
171
- if (access_token) config.set('access_token', access_token)
172
- for (const event of this.#events[body.t] || []) {
173
- event(body.d)
171
+ else {
172
+ const reconnect = () => {
173
+ // 使用了ws服务器
174
+ this.#ws = new WebSocket(ws);
175
+ this.#ws.on('open', () => {
176
+ this.#count = 0;
177
+ console.log('ws connected');
178
+ });
179
+ this.#ws.on('message', data => {
180
+ try {
181
+ // 拿到消息
182
+ const body = JSON.parse(data.toString());
183
+ const access_token = body['access_token'];
184
+ if (access_token)
185
+ config.set('access_token', access_token);
186
+ for (const event of this.#events[body.t] || []) {
187
+ event(body.d);
188
+ }
189
+ }
190
+ catch (e) {
191
+ this.#error(e);
192
+ }
193
+ });
194
+ this.#ws.on('close', () => {
195
+ console.log('ws closed');
196
+ // 重连5次,超过5次不再重连
197
+ if (this.#count > 5)
198
+ return;
199
+ // 23s 后重连
200
+ setTimeout(() => {
201
+ reconnect();
202
+ }, 23000);
203
+ });
204
+ this.#ws.on('error', e => {
205
+ this.#error(e);
206
+ });
207
+ };
208
+ reconnect();
174
209
  }
175
- } catch (e) {
176
- this.#error(e)
177
- }
178
- })
179
- this.#ws.on('close', () => {
180
- console.log('ws closed')
181
- // 重连5次,超过5次不再重连
182
- if (this.#count > 5) return
183
- // 23s 后重连
184
- setTimeout(() => {
185
- reconnect()
186
- }, 23000)
187
- })
188
- this.#ws.on('error', e => {
189
- this.#error(e)
190
- })
191
- }
192
- reconnect()
193
- } catch (e) {
194
- this.#error(e)
210
+ }
211
+ catch (e) {
212
+ this.#error(e);
213
+ }
195
214
  }
196
- }
197
- /**
198
- *
199
- * @param error
200
- */
201
- #error(error) {
202
- if (this.#events['ERROR']) {
203
- for (const event of this.#events['ERROR'] || []) {
204
- event(error)
205
- }
215
+ /**
216
+ *
217
+ * @param error
218
+ */
219
+ #error(error) {
220
+ if (this.#events['ERROR']) {
221
+ for (const event of this.#events['ERROR'] || []) {
222
+ event(error);
223
+ }
224
+ }
206
225
  }
207
- }
208
226
  }
209
227
 
210
- export { QQBotClient }
228
+ export { QQBotClient };
package/lib/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import * as alemonjs from 'alemonjs';
1
+ import * as alemonjs from 'alemonjs'
2
2
 
3
- declare const platform = "qq-bot";
4
- declare const _default: () => alemonjs.ClientAPI;
3
+ declare const platform = 'qq-bot'
4
+ declare const _default: () => alemonjs.ClientAPI
5
5
 
6
- export { _default as default, platform };
6
+ export { _default as default, platform }
package/lib/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { defineBot, getConfigValue, useUserHashKey, OnProcessor } from 'alemonjs';
2
2
  import { QQBotClient } from './client.js';
3
+ import { GROUP_AT_MESSAGE_CREATE, C2C_MESSAGE_CREATE, DIRECT_MESSAGE_CREATE, AT_MESSAGE_CREATE, MESSAGE_CREATE } from './send/index.js';
3
4
 
4
5
  const client = new Proxy({}, {
5
6
  get: (_, prop) => {
@@ -16,12 +17,19 @@ var index = defineBot(() => {
16
17
  const client = new QQBotClient({
17
18
  secret: config?.secret,
18
19
  app_id: config?.app_id,
20
+ route: config?.route,
19
21
  token: config?.token,
20
22
  port: config?.port,
21
23
  ws: config?.ws
22
24
  });
23
25
  // 连接
24
26
  client.connect();
27
+ /**
28
+ * group
29
+ *
30
+ * GROUP_AT_MESSAGE_CREATE
31
+ * C2C_MESSAGE_CREATE
32
+ */
25
33
  // 监听消息
26
34
  client.on('GROUP_AT_MESSAGE_CREATE', async (event) => {
27
35
  const master_key = config?.master_key ?? [];
@@ -63,7 +71,7 @@ var index = defineBot(() => {
63
71
  MessageText: event.content?.trim(),
64
72
  OpenId: event.author.member_openid,
65
73
  CreateAt: Date.now(),
66
- tag: 'group',
74
+ tag: 'GROUP_AT_MESSAGE_CREATE',
67
75
  value: null
68
76
  };
69
77
  // 当访问的时候获取
@@ -111,9 +119,9 @@ var index = defineBot(() => {
111
119
  MessageId: event.id,
112
120
  MessageText: event.content?.trim(),
113
121
  CreateAt: Date.now(),
114
- OpenId: '',
122
+ OpenId: event.author.user_openid,
115
123
  //
116
- tag: 'group',
124
+ tag: 'C2C_MESSAGE_CREATE',
117
125
  value: null
118
126
  };
119
127
  // 当访问的时候获取
@@ -125,6 +133,9 @@ var index = defineBot(() => {
125
133
  // 处理消息
126
134
  OnProcessor(e, 'private.message.create');
127
135
  });
136
+ /**
137
+ * guild
138
+ */
128
139
  client.on('DIRECT_MESSAGE_CREATE', async (event) => {
129
140
  // 屏蔽其他机器人的消息
130
141
  if (event?.author?.bot)
@@ -170,7 +181,7 @@ var index = defineBot(() => {
170
181
  OpenId: event.guild_id,
171
182
  CreateAt: Date.now(),
172
183
  //
173
- tag: 'guild',
184
+ tag: 'DIRECT_MESSAGE_CREATE',
174
185
  //
175
186
  value: null
176
187
  };
@@ -228,7 +239,7 @@ var index = defineBot(() => {
228
239
  OpenId: event.guild_id,
229
240
  CreateAt: Date.now(),
230
241
  //
231
- tag: 'guild',
242
+ tag: 'AT_MESSAGE_CREATE',
232
243
  //
233
244
  value: null
234
245
  };
@@ -312,7 +323,7 @@ var index = defineBot(() => {
312
323
  OpenId: event.guild_id,
313
324
  CreateAt: Date.now(),
314
325
  //
315
- tag: 'guild',
326
+ tag: 'MESSAGE_CREATE',
316
327
  value: null
317
328
  };
318
329
  // 当访问的时候获取
@@ -330,118 +341,45 @@ var index = defineBot(() => {
330
341
  return {
331
342
  api: {
332
343
  use: {
333
- send: (event, val) => {
344
+ send: async (event, val) => {
334
345
  if (val.length < 0)
335
- return Promise.all([]);
346
+ ;
336
347
  // 打 tag
337
348
  const tag = event.tag;
338
- if (tag == 'group') {
339
- const content = val
340
- .filter(item => item.type == 'Link' || item.type == 'Mention' || item.type == 'Text')
341
- .map(item => {
342
- if (item.type == 'Link') {
343
- return `[${item.options?.title ?? item.value}](${item.value})`;
344
- }
345
- else if (item.type == 'Mention') {
346
- if (item.value == 'everyone' ||
347
- item.value == 'all' ||
348
- item.value == '' ||
349
- typeof item.value != 'string') {
350
- return ``;
351
- }
352
- if (item.options?.belong == 'user') {
353
- return `<@${item.value}>`;
354
- }
355
- return '';
356
- // return `<qqbot-at-everyone />`
357
- }
358
- else if (item.type == 'Text') {
359
- return item.value;
360
- }
361
- })
362
- .join('');
363
- if (content) {
364
- return Promise.all([content].map(item => client.groupOpenMessages(event.GuildId, {
365
- content: item,
366
- msg_id: event.MessageId,
367
- msg_type: 0,
368
- msg_seq: client.getMessageSeq(event.MessageId)
369
- })));
349
+ try {
350
+ if (tag == 'GROUP_AT_MESSAGE_CREATE') {
351
+ return await GROUP_AT_MESSAGE_CREATE(client, event, val);
370
352
  }
371
- const images = val.filter(item => item.type == 'Image').map(item => item.value);
372
- if (images) {
373
- return Promise.all(images.map(async (msg) => {
374
- const file_info = await client
375
- .postRichMediaByGroup(event.GuildId, {
376
- file_type: 1,
377
- file_data: msg.toString('base64')
378
- })
379
- .then(res => res?.file_info);
380
- if (!file_info)
381
- return Promise.resolve(null);
382
- return client.groupOpenMessages(event.GuildId, {
383
- content: '',
384
- media: {
385
- file_info
386
- },
387
- msg_id: event.MessageId,
388
- msg_type: 7,
389
- msg_seq: client.getMessageSeq(event.MessageId)
390
- });
391
- }));
353
+ if (tag == 'C2C_MESSAGE_CREATE') {
354
+ return await C2C_MESSAGE_CREATE(client, event, val);
392
355
  }
393
- }
394
- else {
395
- const content = val
396
- .filter(item => item.type == 'Link' || item.type == 'Mention' || item.type == 'Text')
397
- .map(item => {
398
- if (item.type == 'Link') {
399
- return `[${item.options?.title ?? item.value}](${item.value})`;
400
- }
401
- else if (item.type == 'Mention') {
402
- if (item.value == 'everyone' ||
403
- item.value == 'all' ||
404
- item.value == '' ||
405
- typeof item.value != 'string') {
406
- return `@everyone`;
407
- }
408
- if (item.options?.belong == 'user') {
409
- return `<@!${item.value}>`;
410
- }
411
- else if (item.options?.belong == 'channel') {
412
- return `<#${item.value}>`;
413
- }
414
- return '';
415
- }
416
- else if (item.type == 'Text') {
417
- return item.value;
418
- }
419
- })
420
- .join('');
421
- if (content) {
422
- return Promise.all([content].map(item => client.channelsMessagesPost(event.ChannelId, {
423
- content: item,
424
- msg_id: event.MessageId
425
- })));
356
+ if (tag == 'DIRECT_MESSAGE_CREATE') {
357
+ return await DIRECT_MESSAGE_CREATE(client, event, val);
358
+ }
359
+ if (tag == 'AT_MESSAGE_CREATE') {
360
+ return await AT_MESSAGE_CREATE(client, event, val);
426
361
  }
427
- const images = val.filter(item => item.type == 'Image').map(item => item.value);
428
- if (images) {
429
- return Promise.all(images.map(item => client.postImage(event.ChannelId, {
430
- msg_id: event.MessageId,
431
- image: item
432
- })));
362
+ if (tag == 'MESSAGE_CREATE') {
363
+ return await AT_MESSAGE_CREATE(client, event, val);
433
364
  }
365
+ if (tag == 'MESSAGE_CREATE') {
366
+ return await MESSAGE_CREATE(client, event, val);
367
+ }
368
+ }
369
+ catch (error) {
370
+ return [error];
434
371
  }
435
- return Promise.all([]);
372
+ return [];
436
373
  },
437
374
  mention: async (e) => {
438
375
  const event = e.value;
439
376
  const tag = e.tag;
440
377
  // const event = e.value
441
378
  const Metions = [];
442
- if (tag == 'group') {
379
+ // group
380
+ if (tag == 'GROUP_AT_MESSAGE_CREATE' || 'C2C_MESSAGE_CREATE')
443
381
  return Metions;
444
- }
382
+ // guild
445
383
  if (event.mentions) {
446
384
  const mentions = e.value['mentions'];
447
385
  // 艾特消息处理
@@ -0,0 +1,222 @@
1
+ const GROUP_AT_MESSAGE_CREATE = (client, event, val) => {
2
+ const content = val
3
+ .filter(item => item.type == 'Link' || item.type == 'Mention' || item.type == 'Text')
4
+ .map(item => {
5
+ if (item.type == 'Link') {
6
+ return `[${item.options?.title ?? item.value}](${item.value})`;
7
+ }
8
+ else if (item.type == 'Mention') {
9
+ if (item.value == 'everyone' ||
10
+ item.value == 'all' ||
11
+ item.value == '' ||
12
+ typeof item.value != 'string') {
13
+ return ``;
14
+ }
15
+ if (item.options?.belong == 'user') {
16
+ return `<@${item.value}>`;
17
+ }
18
+ return '';
19
+ }
20
+ else if (item.type == 'Text') {
21
+ return item.value;
22
+ }
23
+ })
24
+ .join('');
25
+ if (content) {
26
+ return Promise.all([content].map(item => client.groupOpenMessages(event.GuildId, {
27
+ content: item,
28
+ msg_id: event.MessageId,
29
+ msg_type: 0,
30
+ msg_seq: client.getMessageSeq(event.MessageId)
31
+ })));
32
+ }
33
+ const images = val.filter(item => item.type == 'Image').map(item => item.value);
34
+ if (images) {
35
+ return Promise.all(images.map(async (msg) => {
36
+ const file_info = await client
37
+ .postRichMediaByGroup(event.GuildId, {
38
+ file_type: 1,
39
+ file_data: msg.toString('base64')
40
+ })
41
+ .then(res => res?.file_info);
42
+ if (!file_info)
43
+ return Promise.resolve(null);
44
+ return client.groupOpenMessages(event.GuildId, {
45
+ content: '',
46
+ media: {
47
+ file_info
48
+ },
49
+ msg_id: event.MessageId,
50
+ msg_type: 7,
51
+ msg_seq: client.getMessageSeq(event.MessageId)
52
+ });
53
+ }));
54
+ }
55
+ return [];
56
+ };
57
+ const C2C_MESSAGE_CREATE = (client, event, val) => {
58
+ const content = val
59
+ .filter(item => item.type == 'Link' || item.type == 'Mention' || item.type == 'Text')
60
+ .map(item => {
61
+ if (item.type == 'Text') {
62
+ return item.value;
63
+ }
64
+ return '';
65
+ })
66
+ .join('');
67
+ if (content) {
68
+ return Promise.all([content].map(item => client.usersOpenMessages(event.OpenId, {
69
+ content: item,
70
+ msg_id: event.MessageId,
71
+ msg_type: 0,
72
+ msg_seq: client.getMessageSeq(event.MessageId)
73
+ })));
74
+ }
75
+ const images = val.filter(item => item.type == 'Image').map(item => item.value);
76
+ if (images) {
77
+ return Promise.all(images.map(async (msg) => {
78
+ const file_info = await client
79
+ .postRichMediaByUsers(event.OpenId, {
80
+ file_type: 1,
81
+ file_data: msg.toString('base64')
82
+ })
83
+ .then(res => res?.file_info);
84
+ if (!file_info)
85
+ return Promise.resolve(null);
86
+ return client.usersOpenMessages(event.OpenId, {
87
+ content: '',
88
+ media: {
89
+ file_info
90
+ },
91
+ msg_id: event.MessageId,
92
+ msg_type: 7,
93
+ msg_seq: client.getMessageSeq(event.MessageId)
94
+ });
95
+ }));
96
+ }
97
+ return [];
98
+ };
99
+ /**
100
+ * 频道私聊
101
+ * @param client
102
+ * @param event
103
+ * @param val
104
+ * @returns
105
+ */
106
+ const DIRECT_MESSAGE_CREATE = (client, event, val) => {
107
+ const content = val
108
+ .filter(item => item.type == 'Link' || item.type == 'Mention' || item.type == 'Text')
109
+ .map(item => {
110
+ if (item.type == 'Text') {
111
+ return item.value;
112
+ }
113
+ return '';
114
+ })
115
+ .join('');
116
+ if (content) {
117
+ return Promise.all([content].map(item => client.dmsMessage(event.OpenId, {
118
+ content: item,
119
+ msg_id: event.MessageId
120
+ })));
121
+ }
122
+ const images = val.filter(item => item.type == 'Image').map(item => item.value);
123
+ if (images) {
124
+ return Promise.all(images.map(item => client.postDirectImage(event.OpenId, {
125
+ msg_id: event.MessageId,
126
+ image: item
127
+ })));
128
+ }
129
+ return [];
130
+ };
131
+ const AT_MESSAGE_CREATE = (client, event, val) => {
132
+ const content = val
133
+ .filter(item => item.type == 'Link' || item.type == 'Mention' || item.type == 'Text')
134
+ .map(item => {
135
+ if (item.type == 'Link') {
136
+ return `[${item.options?.title ?? item.value}](${item.value})`;
137
+ }
138
+ else if (item.type == 'Mention') {
139
+ if (item.value == 'everyone' ||
140
+ item.value == 'all' ||
141
+ item.value == '' ||
142
+ typeof item.value != 'string') {
143
+ return `@everyone`;
144
+ }
145
+ if (item.options?.belong == 'user') {
146
+ return `<@!${item.value}>`;
147
+ }
148
+ else if (item.options?.belong == 'channel') {
149
+ return `<#${item.value}>`;
150
+ }
151
+ return '';
152
+ }
153
+ else if (item.type == 'Text') {
154
+ return item.value;
155
+ }
156
+ })
157
+ .join('');
158
+ if (content) {
159
+ return Promise.all([content].map(item => client.channelsMessagesPost(event.ChannelId, {
160
+ content: item,
161
+ msg_id: event.MessageId
162
+ })));
163
+ }
164
+ const images = val.filter(item => item.type == 'Image').map(item => item.value);
165
+ if (images) {
166
+ return Promise.all(images.map(item => client.postImage(event.ChannelId, {
167
+ msg_id: event.MessageId,
168
+ image: item
169
+ })));
170
+ }
171
+ return [];
172
+ };
173
+ /**
174
+ *
175
+ * @param event
176
+ * @param val
177
+ * @returns
178
+ */
179
+ const MESSAGE_CREATE = (client, event, val) => {
180
+ const content = val
181
+ .filter(item => item.type == 'Link' || item.type == 'Mention' || item.type == 'Text')
182
+ .map(item => {
183
+ if (item.type == 'Link') {
184
+ return `[${item.options?.title ?? item.value}](${item.value})`;
185
+ }
186
+ else if (item.type == 'Mention') {
187
+ if (item.value == 'everyone' ||
188
+ item.value == 'all' ||
189
+ item.value == '' ||
190
+ typeof item.value != 'string') {
191
+ return `@everyone`;
192
+ }
193
+ if (item.options?.belong == 'user') {
194
+ return `<@!${item.value}>`;
195
+ }
196
+ else if (item.options?.belong == 'channel') {
197
+ return `<#${item.value}>`;
198
+ }
199
+ return '';
200
+ }
201
+ else if (item.type == 'Text') {
202
+ return item.value;
203
+ }
204
+ })
205
+ .join('');
206
+ if (content) {
207
+ return Promise.all([content].map(item => client.channelsMessagesPost(event.ChannelId, {
208
+ content: item,
209
+ msg_id: event.MessageId
210
+ })));
211
+ }
212
+ const images = val.filter(item => item.type == 'Image').map(item => item.value);
213
+ if (images) {
214
+ return Promise.all(images.map(item => client.postImage(event.ChannelId, {
215
+ msg_id: event.MessageId,
216
+ image: item
217
+ })));
218
+ }
219
+ return [];
220
+ };
221
+
222
+ export { AT_MESSAGE_CREATE, C2C_MESSAGE_CREATE, DIRECT_MESSAGE_CREATE, GROUP_AT_MESSAGE_CREATE, MESSAGE_CREATE };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alemonjs/qq-bot",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "qq-bot",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",