@alemonjs/qq-bot 2.1.34 → 2.1.36

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
@@ -116,7 +116,7 @@ export default async () => {
116
116
 
117
117
  ### 流程
118
118
 
119
- 1. 启动适配器(默认 WebSocket 模式),终端输出授权二维码与链接,并在**运行目录**保存二维码图片(`qqbot-login-qr.png`,二维码刷新时自动覆盖);
119
+ 1. 启动适配器(默认 WebSocket 模式),通过 CBP 输出授权二维码与链接;二维码图片由 CBP/UI 统一处理;
120
120
  2. 使用**手机 QQ**(开放平台上该机器人的管理者账号)扫描二维码(终端直接扫,或打开保存的图片扫),并在页面中确认授权;
121
121
  3. 适配器自动轮询授权结果,平台下发的凭证在本地解密(AES-256-GCM,密钥不落盘);
122
122
  4. `app_id` 与 `secret` 自动写入 `alemon.config.yaml` 的 `qq-bot` 节(保留文件中已有的注释与原格式),随后立即连接,无需重启。
@@ -131,13 +131,13 @@ export default async () => {
131
131
 
132
132
  ### 说明
133
133
 
134
- | 事项 | 说明 |
135
- | -------- | ------------------------------------------------------------------------------------------------ |
136
- | 触发条件 | 配置中未填写 `app_id`/`secret`,且未配置 `bots`(WebSocket 模式) |
137
- | 二维码 | 终端出码 + 图片保存到运行目录(`qqbot-login-qr.png`),过期自动刷新(最多 3 次),总超时 10 分钟 |
138
- | 凭证安全 | AppSecret 全程密文传输、本地解密,密钥仅存内存不落盘 |
139
- | 失败处理 | 超时 / 刷新次数用尽 / 授权取消时跳过连接并输出日志,可重启重试或手动配置 |
140
- | Webhook | Webhook 模式(配置 `route`/`port`/`ws`)不触发扫码流程,需自行填写完整配置 |
134
+ | 事项 | 说明 |
135
+ | -------- | -------------------------------------------------------------------------- |
136
+ | 触发条件 | 配置中未填写 `app_id`/`secret`,且未配置 `bots`(WebSocket 模式) |
137
+ | 二维码 | CBP 统一输出,过期自动刷新(最多 3 次),总超时 10 分钟 |
138
+ | 凭证安全 | AppSecret 全程密文传输、本地解密,密钥仅存内存不落盘 |
139
+ | 失败处理 | 超时 / 刷新次数用尽 / 授权取消时跳过连接并输出日志,可重启重试或手动配置 |
140
+ | Webhook | Webhook 模式(配置 `route`/`port`/`ws`)不触发扫码流程,需自行填写完整配置 |
141
141
 
142
142
  ---
143
143
 
package/lib/format.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { DataEnums, DataMarkDown } from "alemonjs";
2
2
  //#region src/format.d.ts
3
+ /** 群聊、私聊和频道共用有序正文;提及等原生文本由发送上下文提供。 */
4
+ declare const formatQQContent: (items: DataEnums[], renderNative: (item: DataEnums) => string, plain?: boolean, hideUnsupported?: boolean | number) => string;
3
5
  /**
4
6
  * 将结构化 Markdown 子元素数组转为可读纯文本
5
7
  */
@@ -22,5 +24,6 @@ declare const markdownRawToText: (raw: string, hideUnsupported?: boolean | numbe
22
24
  * 其余类型降级为文本
23
25
  */
24
26
  declare const dataEnumToText: (item: DataEnums, hideUnsupported?: boolean | number) => string;
27
+ declare const createMarkdownText: (data: DataMarkDown['value']) => string;
25
28
  //#endregion
26
- export { buttonsToText, dataEnumToText, markdownRawToText, markdownToText };
29
+ export { buttonsToText, createMarkdownText, dataEnumToText, formatQQContent, markdownRawToText, markdownToText };
package/lib/format.js CHANGED
@@ -1,10 +1,32 @@
1
+ import { joinMarkdownParts, renderMarkdownBlockquote } from "alemonjs/markdown";
2
+
1
3
  //#region src/format.ts
4
+ /** 群聊、私聊和频道共用有序正文;提及等原生文本由发送上下文提供。 */
5
+ const formatQQContent = (items, renderNative, plain = false, hideUnsupported) => {
6
+ return items.map((item) => {
7
+ if (item.type === "Markdown") return plain ? markdownToText(item.value, hideUnsupported) : createMarkdownText(item.value);
8
+ if (item.type === "MarkdownOriginal") {
9
+ const text = plain ? markdownRawToText(item.value, hideUnsupported) : item.value;
10
+ return text ? `\n\n${text}\n\n` : "";
11
+ }
12
+ if (item.type === "BT.group") {
13
+ if (!plain || Number(hideUnsupported) >= 4) return "";
14
+ const text = item.value.map((row) => row.value.map((button) => {
15
+ if (Number(hideUnsupported) >= 3) return "";
16
+ if (Number(hideUnsupported) >= 2) return button.options?.data || button.value;
17
+ return hideUnsupported ? button.value : `[${button.value}]`;
18
+ }).filter(Boolean).join(" ")).filter(Boolean).join("\n");
19
+ return text ? `\n\n${text}\n\n` : "";
20
+ }
21
+ return renderNative(item);
22
+ }).join("");
23
+ };
2
24
  /**
3
25
  * 将结构化 Markdown 子元素数组转为可读纯文本
4
26
  */
5
27
  const markdownToText = (items, hideUnsupported) => {
6
28
  if (Number(hideUnsupported) >= 4) return "";
7
- return items.map((item) => {
29
+ return joinMarkdownParts(items, items.map((item) => {
8
30
  switch (item.type) {
9
31
  case "MD.text": return item.value;
10
32
  case "MD.title": return hideUnsupported ? `${item.value}\n` : `【${item.value}】\n`;
@@ -16,6 +38,7 @@ const markdownToText = (items, hideUnsupported) => {
16
38
  case "MD.link": {
17
39
  const v = item.value;
18
40
  if (Number(hideUnsupported) >= 3) return "";
41
+ if (!v.url) return v.text;
19
42
  return Number(hideUnsupported) >= 2 ? v.url : `${v.text}( ${v.url} )`;
20
43
  }
21
44
  case "MD.image": return hideUnsupported ? "" : "[图片]";
@@ -23,7 +46,7 @@ const markdownToText = (items, hideUnsupported) => {
23
46
  if (typeof li.value === "object") return `${li.value.index}. ${li.value.text ?? ""}`;
24
47
  return `· ${li.value}`;
25
48
  }).join("\n") + "\n";
26
- case "MD.blockquote": return `> ${item.value}\n`;
49
+ case "MD.blockquote": return renderMarkdownBlockquote(item.value, (children) => markdownToText(children, hideUnsupported));
27
50
  case "MD.divider": return hideUnsupported ? "" : "————————\n";
28
51
  case "MD.newline": return "\n";
29
52
  case "MD.code": return item.value;
@@ -37,7 +60,7 @@ const markdownToText = (items, hideUnsupported) => {
37
60
  return hideUnsupported ? String(item.value) : `[${item.value}]`;
38
61
  default: return String(item?.value ?? "");
39
62
  }
40
- }).join("");
63
+ }));
41
64
  };
42
65
  /**
43
66
  * 将按钮组转为可读纯文本
@@ -88,6 +111,47 @@ const dataEnumToText = (item, hideUnsupported) => {
88
111
  default: return "";
89
112
  }
90
113
  };
114
+ const mdFormatters = {
115
+ "MD.title": (value) => `# ${value} `,
116
+ "MD.subtitle": (value) => `## ${value} `,
117
+ "MD.text": (value) => `${value} `,
118
+ "MD.bold": (value) => `**${value}** `,
119
+ "MD.divider": () => "\n***\n",
120
+ "MD.italic": (value) => `__${value}__ `,
121
+ "MD.italicStar": (value) => `*${value}* `,
122
+ "MD.strikethrough": (value) => `~~${value}~~ `,
123
+ "MD.blockquote": (value) => renderMarkdownBlockquote(value, createMarkdownText),
124
+ "MD.newline": () => "\n",
125
+ "MD.link": (value) => {
126
+ if (!value?.text && !value?.url) return "";
127
+ if (!value?.text || !value?.url) return `<${value?.url ?? value?.text}> `;
128
+ return `[🔗${value?.text}](${value?.url}) `;
129
+ },
130
+ "MD.image": (value, options) => `\n![text #${options?.width || 208}px #${options?.height || 320}px](${value})\n`,
131
+ "MD.mention": (value, options) => {
132
+ const { belong } = options || {};
133
+ if (belong === "channel") return "";
134
+ if (value === "everyone") return "<qqbot-at-everyone />";
135
+ if (belong === "user") return `<qqbot-at-user id="${value}" />`;
136
+ return `<qqbot-at-user id="${value}" />`;
137
+ },
138
+ "MD.content": (value) => `${value}`,
139
+ "MD.button": (title, options) => {
140
+ const { data, autoEnter } = options || {};
141
+ if (autoEnter) return `<qqbot-cmd-enter text="${data}" show="${title}" />`;
142
+ return `<qqbot-cmd-input text="${data}" show="${title}" />`;
143
+ }
144
+ };
145
+ const createMarkdownText = (data) => {
146
+ return joinMarkdownParts(data, data.map((mdItem) => {
147
+ if (mdFormatters[mdItem.type]) return mdFormatters[mdItem.type](mdItem?.value, mdItem?.options);
148
+ if (mdItem.type === "MD.list" && typeof mdItem.value !== "string") return `${mdItem.value.map((listItem) => {
149
+ return typeof listItem.value === "object" ? `\n${listItem.value.index}. ${listItem.value.text}` : `\n- ${listItem.value}`;
150
+ }).join("")}\n`;
151
+ if (mdItem.type === "MD.code") return `\n\`\`\`${mdItem?.options?.language || ""}\n${mdItem.value}\n\`\`\`\n`;
152
+ return String(mdItem["value"] || "");
153
+ }));
154
+ };
91
155
 
92
156
  //#endregion
93
- export { buttonsToText, dataEnumToText, markdownRawToText, markdownToText };
157
+ export { buttonsToText, createMarkdownText, dataEnumToText, formatQQContent, markdownRawToText, markdownToText };
@@ -31,7 +31,7 @@ const bootstrap = async () => {
31
31
  activeRegistry = registry;
32
32
  if (!hasConfiguredCredentials()) {
33
33
  logger.info("[qq-bot] 未检测到 app_id/secret 配置,进入扫码登录流程");
34
- const result = await qrLogin({ onQRCode: (qrBuffer, url, _qrImagePath, loginId, refresh) => {
34
+ const result = await qrLogin({ onQRCode: (qrBuffer, url, loginId, refresh) => {
35
35
  loginStatus = {
36
36
  state: "awaiting_qrcode",
37
37
  type: "qrcode",
@@ -35,14 +35,14 @@ type QRLoginOptions = {
35
35
  pollInterval?: number;
36
36
  /** 注入门户请求(测试用) */
37
37
  request?: PortalRequest;
38
- /** 二维码生成回调(默认同时终端出码并保存图片到运行目录) */
39
- onQRCode?: (qrBuffer: Buffer, url: string, qrImagePath: string | undefined, loginId: string, refresh: number) => void | Promise<void>;
38
+ /** 二维码生成回调;图片由回调方或 CBP 统一处理,不在适配器运行目录落盘 */
39
+ onQRCode?: (qrBuffer: Buffer, url: string, loginId: string, refresh: number) => void | Promise<void>;
40
40
  /** 状态变化回调 */
41
41
  onStatus?: (message: string) => void | Promise<void>;
42
42
  };
43
43
  /**
44
44
  * 扫码登录流程:
45
- * 创建绑定任务 → 终端出码并保存二维码图片到运行目录 → 轮询授权结果 → 解密 AppSecret。
45
+ * 创建绑定任务 → 生成二维码并通过回调交给 CBP/UI → 轮询授权结果 → 解密 AppSecret。
46
46
  * 成功返回 { appId, clientSecret, userOpenid };超时/失败/刷新次数用尽返回 null
47
47
  */
48
48
  declare const qrLogin: (options?: QRLoginOptions) => Promise<QRLoginResult | null>;
@@ -2,7 +2,7 @@ import { getConfig, logger } from "alemonjs";
2
2
  import axios from "axios";
3
3
  import { createDecipheriv, randomBytes } from "node:crypto";
4
4
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
- import { dirname, join } from "node:path";
5
+ import { dirname } from "node:path";
6
6
  import QRCode from "qrcode";
7
7
  import YAML from "yaml";
8
8
 
@@ -51,7 +51,7 @@ const buildConnectUrl = (taskId) => {
51
51
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
52
52
  /**
53
53
  * 扫码登录流程:
54
- * 创建绑定任务 → 终端出码并保存二维码图片到运行目录 → 轮询授权结果 → 解密 AppSecret。
54
+ * 创建绑定任务 → 生成二维码并通过回调交给 CBP/UI → 轮询授权结果 → 解密 AppSecret。
55
55
  * 成功返回 { appId, clientSecret, userOpenid };超时/失败/刷新次数用尽返回 null
56
56
  */
57
57
  const qrLogin = async (options = {}) => {
@@ -70,7 +70,6 @@ const qrLogin = async (options = {}) => {
70
70
  return null;
71
71
  }
72
72
  const url = buildConnectUrl(taskId);
73
- let qrImagePath = null;
74
73
  let qrBuffer = null;
75
74
  try {
76
75
  qrBuffer = await QRCode.toBuffer(url, {
@@ -78,12 +77,10 @@ const qrLogin = async (options = {}) => {
78
77
  width: 320,
79
78
  margin: 2
80
79
  });
81
- qrImagePath = join(process.cwd(), "qqbot-login-qr.png");
82
- writeFileSync(qrImagePath, qrBuffer);
83
80
  } catch (err) {
84
- logger.warn(`[qq-bot] 二维码图片保存失败:${err?.message ?? err}`);
81
+ logger.warn(`[qq-bot] 二维码生成失败:${err?.message ?? err}`);
85
82
  }
86
- if (qrBuffer && onQRCode) await onQRCode(qrBuffer, url, qrImagePath ?? void 0, taskId, refresh);
83
+ if (qrBuffer && onQRCode) await onQRCode(qrBuffer, url, taskId, refresh);
87
84
  await onStatus?.("请使用手机 QQ 扫描二维码并确认授权");
88
85
  logger.warn("[qq-bot] 注意:扫码授权完成后平台将重置机器人密钥,旧密钥会立即失效;若该机器人已在其他实例中运行,请更新其配置");
89
86
  while (Date.now() < deadline) {
package/lib/sends.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { getQQBotConfig } from "./config.js";
2
- import { buttonsToText, dataEnumToText, markdownToText } from "./format.js";
2
+ import { createMarkdownText, dataEnumToText, formatQQContent } from "./format.js";
3
3
  import { ResultCode, createResult, logger } from "alemonjs";
4
4
  import { readFileSync } from "fs";
5
5
  import axios from "axios";
@@ -172,47 +172,6 @@ const createArkListData = (value) => {
172
172
  ]
173
173
  };
174
174
  };
175
- const mdFormatters = {
176
- "MD.title": (value) => `# ${value} `,
177
- "MD.subtitle": (value) => `## ${value} `,
178
- "MD.text": (value) => `${value} `,
179
- "MD.bold": (value) => `**${value}** `,
180
- "MD.divider": () => "\n***\n",
181
- "MD.italic": (value) => `__${value}__ `,
182
- "MD.italicStar": (value) => `*${value}* `,
183
- "MD.strikethrough": (value) => `~~${value}~~ `,
184
- "MD.blockquote": (value) => `\n> ${value} `,
185
- "MD.newline": () => "\n",
186
- "MD.link": (value) => {
187
- if (!value?.text && !value?.url) return "";
188
- if (!value?.text || !value?.url) return `<${value?.url ?? value?.text}> `;
189
- return `[🔗${value?.text}](${value?.url}) `;
190
- },
191
- "MD.image": (value, options) => `\n![text #${options?.width || 208}px #${options?.height || 320}px](${value})\n`,
192
- "MD.mention": (value, options) => {
193
- const { belong } = options || {};
194
- if (belong === "channel") return "";
195
- if (belong === "user") return `<qqbot-at-user id="${value}" />`;
196
- if (value === "everyone") return "<qqbot-at-everyone />";
197
- return `<qqbot-at-user id="${value}" />`;
198
- },
199
- "MD.content": (value) => `${value}`,
200
- "MD.button": (title, options) => {
201
- const { data, autoEnter } = options || {};
202
- if (autoEnter) return `<qqbot-cmd-enter text="${data}" show="${title}" />`;
203
- return `<qqbot-cmd-input text="${data}" show="${title}" />`;
204
- }
205
- };
206
- const createMarkdownText = (data) => {
207
- return data.map((mdItem) => {
208
- if (mdFormatters[mdItem.type]) return mdFormatters[mdItem.type](mdItem?.value, mdItem?.options);
209
- if (mdItem.type === "MD.list" && typeof mdItem.value !== "string") return `${mdItem.value.map((listItem) => {
210
- return typeof listItem.value === "object" ? `\n${listItem.value.index}. ${listItem.value.text}` : `\n- ${listItem.value}`;
211
- }).join("")}\n`;
212
- if (mdItem.type === "MD.code") return `\n\`\`\`${mdItem?.options?.language || ""}\n${mdItem.value}\n\`\`\`\n`;
213
- return String(mdItem["value"] || "");
214
- }).join("");
215
- };
216
175
  const formatMention = (item, mode) => {
217
176
  if (mode === "guild-direct") return "";
218
177
  const value = item.value;
@@ -373,16 +332,7 @@ const resolveMediaUrl = async (media, uploadMedia) => {
373
332
  }
374
333
  };
375
334
  /** 移除富媒体占位符(dataEnumToText 降级产生的 [视频]/[音频]/[附件]) */
376
- const stripMediaPlaceholders = (text) => text.replace(/\[附件[^\]]*\]/g, "").replace(/\[音频\]/g, "").replace(/\[视频\]/g, "").replace(/\n{2,}/g, "\n").trim();
377
- /** 当 markdownToText 选项开启时,将 Markdown 和按钮降级为纯文本并追加到 content */
378
- const flattenMdToText = (content, val) => {
379
- const mdItems = val.filter((item) => item.type === "Markdown");
380
- const btnItems = val.filter((item) => item.type === "BT.group");
381
- const parts = [content];
382
- for (const item of mdItems) if (item.type === "Markdown" && typeof item.value !== "string") parts.push(markdownToText(item.value));
383
- for (const item of btnItems) if (item.type === "BT.group" && typeof item.value !== "string") parts.push(buttonsToText(item.value));
384
- return parts.filter(Boolean).join("\n").replace(/^[^\S\n\r]+|[^\S\n\r]+$/g, "");
385
- };
335
+ const stripMediaPlaceholders = (text) => text.replace(/\[附件[^\]]*\]/g, "").replace(/\[音频\]/g, "").replace(/\[视频\]/g, "").trim();
386
336
  /** Open API 通用发送逻辑(群组 / C2C) */
387
337
  const sendOpenApiMessage = async (content, val, baseParams, uploadMedia, sendMessage, label, options) => {
388
338
  const config = getQQBotConfig();
@@ -392,7 +342,7 @@ const sendOpenApiMessage = async (content, val, baseParams, uploadMedia, sendMes
392
342
  const fileInfo = await resolveMediaUrl(media, uploadMedia);
393
343
  if (!fileInfo) return [createResult(ResultCode.Fail, "媒体上传失败", null)];
394
344
  const res = await sendMessage({
395
- content: stripMediaPlaceholders(flattenMdToText(content, val)),
345
+ content: stripMediaPlaceholders(formatQQContent(val, (item) => extractContent([item], "group"), true, config.hideUnsupported)),
396
346
  media: { file_info: fileInfo },
397
347
  msg_type: 7,
398
348
  ...baseParams
@@ -404,7 +354,7 @@ const sendOpenApiMessage = async (content, val, baseParams, uploadMedia, sendMes
404
354
  return [];
405
355
  }
406
356
  if (mdToText) {
407
- const textContent = flattenMdToText(content, val);
357
+ const textContent = formatQQContent(val, (item) => extractContent([item], "group"), true, config.hideUnsupported);
408
358
  if (textContent) {
409
359
  const res = await sendMessage({
410
360
  content: textContent,
@@ -417,7 +367,7 @@ const sendOpenApiMessage = async (content, val, baseParams, uploadMedia, sendMes
417
367
  }
418
368
  const mdParams = buildMdAndButtonsParams(val);
419
369
  if (mdParams) {
420
- if (mdParams.markdown?.content && content) mdParams.markdown.content = content + "\n" + mdParams.markdown.content;
370
+ if (mdParams.markdown?.content) mdParams.markdown.content = formatQQContent(val, (item) => extractContent([item], "group"));
421
371
  const res = await sendMessage({
422
372
  content,
423
373
  msg_type: 2,
@@ -463,14 +413,14 @@ const resolveImageBuffer = async (images) => {
463
413
  return null;
464
414
  };
465
415
  /** Guild API 通用发送逻辑(频道公聊 / 频道私聊) */
466
- const sendGuildMessage = async (content, val, baseParams, sendMessage, label) => {
416
+ const sendGuildMessage = async (content, val, baseParams, sendMessage, label, mode) => {
467
417
  const config = getQQBotConfig();
468
418
  const mdToText = config.markdownToText === true;
469
419
  const images = filterImages(val);
470
420
  if (images.length > 0) {
471
421
  const imageBuffer = await resolveImageBuffer(images);
472
422
  const res = await sendMessage({
473
- content: flattenMdToText(content, val),
423
+ content: formatQQContent(val, (item) => extractContent([item], mode), true, config.hideUnsupported),
474
424
  ...baseParams
475
425
  }, imageBuffer);
476
426
  return [createResult(ResultCode.Ok, label, { id: res?.id })];
@@ -480,7 +430,7 @@ const sendGuildMessage = async (content, val, baseParams, sendMessage, label) =>
480
430
  return [];
481
431
  }
482
432
  if (mdToText) {
483
- const textContent = flattenMdToText(content, val);
433
+ const textContent = formatQQContent(val, (item) => extractContent([item], mode), true, config.hideUnsupported);
484
434
  if (textContent) {
485
435
  const res = await sendMessage({
486
436
  content: textContent,
@@ -492,7 +442,7 @@ const sendGuildMessage = async (content, val, baseParams, sendMessage, label) =>
492
442
  }
493
443
  const mdParams = buildMdAndButtonsParams(val);
494
444
  if (mdParams) {
495
- if (mdParams.markdown?.content && content) mdParams.markdown.content = content + "\n" + mdParams.markdown.content;
445
+ if (mdParams.markdown?.content) mdParams.markdown.content = formatQQContent(val, (item) => extractContent([item], mode));
496
446
  const res = await sendMessage({
497
447
  content: "",
498
448
  ...mdParams,
@@ -549,7 +499,7 @@ const DIRECT_MESSAGE_CREATE = async (client, event, val) => {
549
499
  const baseParams = buildBaseParams(event._tag, event.MessageId, "INTERACTION_CREATE_GUILD");
550
500
  const content = extractContent(val, "guild-direct");
551
501
  try {
552
- return await sendGuildMessage(content, val, baseParams, (data, buf) => client.dmsMessages(event.UserId, data, buf), "client.dmsMessage");
502
+ return await sendGuildMessage(content, val, baseParams, (data, buf) => client.dmsMessages(event.UserId, data, buf), "client.dmsMessage", "guild-direct");
553
503
  } catch (err) {
554
504
  return [createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)];
555
505
  }
@@ -561,7 +511,7 @@ const MESSAGE_CREATE = async (client, event, val) => {
561
511
  const baseParams = buildBaseParams(event._tag, event.MessageId, "INTERACTION_CREATE_GUILD");
562
512
  const content = extractContent(val, "guild-public");
563
513
  try {
564
- return await sendGuildMessage(content, val, baseParams, (data, buf) => client.channelsMessages(event.ChannelId, data, buf), "client.channelsMessagesPost");
514
+ return await sendGuildMessage(content, val, baseParams, (data, buf) => client.channelsMessages(event.ChannelId, data, buf), "client.channelsMessagesPost", "guild-public");
565
515
  } catch (err) {
566
516
  return [createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)];
567
517
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alemonjs/qq-bot",
3
- "version": "2.1.34",
3
+ "version": "2.1.36",
4
4
  "description": "QQ官方平台",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",
@@ -30,7 +30,7 @@
30
30
  "yaml": "^2.5.1"
31
31
  },
32
32
  "peerDependencies": {
33
- "alemonjs": "^2.1.0-alpha.15"
33
+ "alemonjs": "^2.1.108"
34
34
  },
35
35
  "types": "lib",
36
36
  "exports": {
@@ -97,5 +97,5 @@
97
97
  "type": "git",
98
98
  "url": "https://github.com/lemonade-lab/alemonjs.git"
99
99
  },
100
- "gitHead": "8e6c0d91889ff7926fc7bc58ac8dc664c8f721ea"
100
+ "gitHead": "a4d4fded0874b070e356e6a83b06bd3e474f9133"
101
101
  }