@alemonjs/qq-bot 0.0.4 → 0.0.6

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',
@@ -104,7 +103,8 @@ class QQBotAPI {
104
103
  // 如果映射表大小超过 100,则删除最早添加的 MessageId
105
104
  if (this.#map.size > 100) {
106
105
  const firstKey = this.#map.keys().next().value;
107
- this.#map.delete(firstKey);
106
+ if (firstKey)
107
+ this.#map.delete(firstKey);
108
108
  }
109
109
  return seq;
110
110
  }
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
+ // 1.3s 后重连
200
+ setTimeout(() => {
201
+ reconnect();
202
+ }, 1300);
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/from.js CHANGED
@@ -21,18 +21,18 @@ async function createPicFrom(image, name = 'image.jpg') {
21
21
  // 是 buffer
22
22
  }
23
23
  else if (Buffer.isBuffer(image)) {
24
- const { ext } = await fileTypeFromBuffer(image);
24
+ const file = await fileTypeFromBuffer(image);
25
25
  if (!name)
26
- name = 'file.' + ext;
26
+ name = 'file.' + file?.ext;
27
27
  picData = new Readable();
28
28
  picData.push(image);
29
29
  picData.push(null);
30
30
  // 是 文件流
31
31
  }
32
32
  else if (isReadable(image)) {
33
- const { ext } = await fileTypeFromStream(image);
33
+ const file = await fileTypeFromStream(image);
34
34
  if (!name)
35
- name = 'file.' + ext;
35
+ name = 'file.' + file?.ext;
36
36
  picData = image;
37
37
  }
38
38
  else {
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) => {
@@ -11,17 +12,26 @@ const client = new Proxy({}, {
11
12
  });
12
13
  const platform = 'qq-bot';
13
14
  var index = defineBot(() => {
14
- const value = getConfigValue();
15
- const config = value['qq-bot'];
15
+ let value = getConfigValue();
16
+ if (!value)
17
+ value = {};
18
+ const config = value[platform];
16
19
  const client = new QQBotClient({
17
20
  secret: config?.secret,
18
21
  app_id: config?.app_id,
22
+ route: config?.route,
19
23
  token: config?.token,
20
24
  port: config?.port,
21
25
  ws: config?.ws
22
26
  });
23
27
  // 连接
24
28
  client.connect();
29
+ /**
30
+ * group
31
+ *
32
+ * GROUP_AT_MESSAGE_CREATE
33
+ * C2C_MESSAGE_CREATE
34
+ */
25
35
  // 监听消息
26
36
  client.on('GROUP_AT_MESSAGE_CREATE', async (event) => {
27
37
  const master_key = config?.master_key ?? [];
@@ -47,6 +57,7 @@ var index = defineBot(() => {
47
57
  });
48
58
  // 定义消
49
59
  const e = {
60
+ name: 'message.create',
50
61
  // 事件类型
51
62
  Platform: platform,
52
63
  // guild
@@ -63,7 +74,7 @@ var index = defineBot(() => {
63
74
  MessageText: event.content?.trim(),
64
75
  OpenId: event.author.member_openid,
65
76
  CreateAt: Date.now(),
66
- tag: 'group',
77
+ tag: 'GROUP_AT_MESSAGE_CREATE',
67
78
  value: null
68
79
  };
69
80
  // 当访问的时候获取
@@ -99,6 +110,7 @@ var index = defineBot(() => {
99
110
  });
100
111
  // 定义消
101
112
  const e = {
113
+ name: 'private.message.create',
102
114
  // 事件类型
103
115
  Platform: platform,
104
116
  // 用户Id
@@ -111,9 +123,9 @@ var index = defineBot(() => {
111
123
  MessageId: event.id,
112
124
  MessageText: event.content?.trim(),
113
125
  CreateAt: Date.now(),
114
- OpenId: '',
126
+ OpenId: event.author.user_openid,
115
127
  //
116
- tag: 'group',
128
+ tag: 'C2C_MESSAGE_CREATE',
117
129
  value: null
118
130
  };
119
131
  // 当访问的时候获取
@@ -125,6 +137,9 @@ var index = defineBot(() => {
125
137
  // 处理消息
126
138
  OnProcessor(e, 'private.message.create');
127
139
  });
140
+ /**
141
+ * guild
142
+ */
128
143
  client.on('DIRECT_MESSAGE_CREATE', async (event) => {
129
144
  // 屏蔽其他机器人的消息
130
145
  if (event?.author?.bot)
@@ -152,11 +167,12 @@ var index = defineBot(() => {
152
167
  });
153
168
  // 定义消
154
169
  const e = {
170
+ name: 'private.message.create',
155
171
  // 事件类型
156
172
  Platform: platform,
157
173
  //
158
- GuildId: event.guild_id,
159
- ChannelId: event.channel_id,
174
+ // GuildId: event.guild_id,
175
+ // ChannelId: event.channel_id,
160
176
  // 用户Id
161
177
  UserId: event?.author?.id ?? '',
162
178
  UserKey,
@@ -170,7 +186,7 @@ var index = defineBot(() => {
170
186
  OpenId: event.guild_id,
171
187
  CreateAt: Date.now(),
172
188
  //
173
- tag: 'guild',
189
+ tag: 'DIRECT_MESSAGE_CREATE',
174
190
  //
175
191
  value: null
176
192
  };
@@ -211,6 +227,7 @@ var index = defineBot(() => {
211
227
  });
212
228
  // 定义消
213
229
  const e = {
230
+ name: 'message.create',
214
231
  // 事件类型
215
232
  Platform: platform,
216
233
  GuildId: event.guild_id,
@@ -228,7 +245,7 @@ var index = defineBot(() => {
228
245
  OpenId: event.guild_id,
229
246
  CreateAt: Date.now(),
230
247
  //
231
- tag: 'guild',
248
+ tag: 'AT_MESSAGE_CREATE',
232
249
  //
233
250
  value: null
234
251
  };
@@ -295,6 +312,7 @@ var index = defineBot(() => {
295
312
  });
296
313
  // 定义消
297
314
  const e = {
315
+ name: 'message.create',
298
316
  // 事件类型
299
317
  Platform: platform,
300
318
  //
@@ -312,7 +330,7 @@ var index = defineBot(() => {
312
330
  OpenId: event.guild_id,
313
331
  CreateAt: Date.now(),
314
332
  //
315
- tag: 'guild',
333
+ tag: 'MESSAGE_CREATE',
316
334
  value: null
317
335
  };
318
336
  // 当访问的时候获取
@@ -330,118 +348,45 @@ var index = defineBot(() => {
330
348
  return {
331
349
  api: {
332
350
  use: {
333
- send: (event, val) => {
351
+ send: async (event, val) => {
334
352
  if (val.length < 0)
335
- return Promise.all([]);
353
+ ;
336
354
  // 打 tag
337
355
  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
- })));
356
+ try {
357
+ if (tag == 'GROUP_AT_MESSAGE_CREATE') {
358
+ return await GROUP_AT_MESSAGE_CREATE(client, event, val);
370
359
  }
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
- }));
360
+ if (tag == 'C2C_MESSAGE_CREATE') {
361
+ return await C2C_MESSAGE_CREATE(client, event, val);
392
362
  }
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
- })));
363
+ if (tag == 'DIRECT_MESSAGE_CREATE') {
364
+ return await DIRECT_MESSAGE_CREATE(client, event, val);
365
+ }
366
+ if (tag == 'AT_MESSAGE_CREATE') {
367
+ return await AT_MESSAGE_CREATE(client, event, val);
426
368
  }
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
- })));
369
+ if (tag == 'MESSAGE_CREATE') {
370
+ return await AT_MESSAGE_CREATE(client, event, val);
433
371
  }
372
+ if (tag == 'MESSAGE_CREATE') {
373
+ return await MESSAGE_CREATE(client, event, val);
374
+ }
375
+ }
376
+ catch (error) {
377
+ return [error];
434
378
  }
435
- return Promise.all([]);
379
+ return [];
436
380
  },
437
381
  mention: async (e) => {
438
382
  const event = e.value;
439
383
  const tag = e.tag;
440
384
  // const event = e.value
441
385
  const Metions = [];
442
- if (tag == 'group') {
386
+ // group
387
+ if (tag == 'GROUP_AT_MESSAGE_CREATE' || 'C2C_MESSAGE_CREATE')
443
388
  return Metions;
444
- }
389
+ // guild
445
390
  if (event.mentions) {
446
391
  const mentions = e.value['mentions'];
447
392
  // 艾特消息处理
@@ -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.6",
4
4
  "description": "qq-bot",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",
@@ -26,7 +26,6 @@
26
26
  "@noble/curves": "^1.7.0"
27
27
  },
28
28
  "devDependencies": {
29
- "alemonjs": "^2.0.0-rc.77",
30
29
  "@rollup/plugin-typescript": "^11.1.6",
31
30
  "lvyjs": "^0.2.13",
32
31
  "rollup": "^4.18.1",