@alemonjs/qq-bot 2.1.32 → 2.1.34

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.
Files changed (131) hide show
  1. package/README.md +1984 -35
  2. package/dist/assets/index.css +1 -1
  3. package/dist/assets/index.js +12 -5
  4. package/dist/index.html +1 -1
  5. package/lib/config.d.ts +44 -19
  6. package/lib/config.js +39 -35
  7. package/lib/desktop.d.ts +4 -1
  8. package/lib/desktop.js +53 -57
  9. package/lib/format.d.ts +26 -5
  10. package/lib/format.js +84 -101
  11. package/lib/hook.d.ts +82 -64
  12. package/lib/hook.js +35 -32
  13. package/lib/index.d.ts +6 -4
  14. package/lib/index.js +13 -16
  15. package/lib/index.webhook.d.ts +4 -1
  16. package/lib/index.webhook.js +12 -14
  17. package/lib/index.websoket.d.ts +6 -3
  18. package/lib/index.websoket.js +131 -41
  19. package/lib/message/AT_MESSAGE_CREATE.d.ts +36 -33
  20. package/lib/message/AT_MESSAGE_CREATE.js +1 -1
  21. package/lib/message/CHANNEL_CREATE.d.ts +17 -14
  22. package/lib/message/CHANNEL_CREATE.js +1 -1
  23. package/lib/message/CHANNEL_DELETE.d.ts +22 -14
  24. package/lib/message/CHANNEL_DELETE.js +1 -1
  25. package/lib/message/CHANNEL_UPDATE.d.ts +22 -14
  26. package/lib/message/CHANNEL_UPDATE.js +1 -1
  27. package/lib/message/DIRECT_MESSAGE_CREATE.d.ts +35 -27
  28. package/lib/message/DIRECT_MESSAGE_CREATE.js +1 -1
  29. package/lib/message/DIRECT_MESSAGE_DELETE.d.ts +23 -15
  30. package/lib/message/DIRECT_MESSAGE_DELETE.js +1 -1
  31. package/lib/message/ERROR.d.ts +4 -1
  32. package/lib/message/ERROR.js +1 -1
  33. package/lib/message/GUILD_CREATE.d.ts +22 -14
  34. package/lib/message/GUILD_CREATE.js +1 -1
  35. package/lib/message/GUILD_DELETE.d.ts +22 -14
  36. package/lib/message/GUILD_DELETE.js +1 -1
  37. package/lib/message/GUILD_MEMBER_ADD.d.ts +21 -13
  38. package/lib/message/GUILD_MEMBER_ADD.js +1 -1
  39. package/lib/message/GUILD_MEMBER_REMOVE.d.ts +21 -13
  40. package/lib/message/GUILD_MEMBER_REMOVE.js +1 -1
  41. package/lib/message/GUILD_MEMBER_UPDATE.d.ts +21 -13
  42. package/lib/message/GUILD_MEMBER_UPDATE.js +1 -1
  43. package/lib/message/GUILD_UPDATE.d.ts +22 -14
  44. package/lib/message/GUILD_UPDATE.js +1 -1
  45. package/lib/message/INTERACTION_CREATE.d.ts +52 -44
  46. package/lib/message/INTERACTION_CREATE.js +1 -1
  47. package/lib/message/MESSAGE_CREATE.d.ts +12 -1
  48. package/lib/message/MESSAGE_CREATE.js +1 -1
  49. package/lib/message/MESSAGE_DELETE.d.ts +12 -1
  50. package/lib/message/MESSAGE_DELETE.js +1 -1
  51. package/lib/message/MESSAGE_REACTION_ADD.d.ts +15 -12
  52. package/lib/message/MESSAGE_REACTION_ADD.js +1 -1
  53. package/lib/message/MESSAGE_REACTION_REMOVE.d.ts +15 -12
  54. package/lib/message/MESSAGE_REACTION_REMOVE.js +1 -1
  55. package/lib/message/PUBLIC_MESSAGE_DELETE.d.ts +20 -13
  56. package/lib/message/PUBLIC_MESSAGE_DELETE.js +1 -1
  57. package/lib/message/READY.d.ts +11 -5
  58. package/lib/message/READY.js +1 -1
  59. package/lib/message/group/C2C_MESSAGE_CREATE.d.ts +18 -15
  60. package/lib/message/group/C2C_MESSAGE_CREATE.js +1 -1
  61. package/lib/message/group/C2C_MSG_RECEIVE.d.ts +13 -3
  62. package/lib/message/group/C2C_MSG_RECEIVE.js +1 -1
  63. package/lib/message/group/C2C_MSG_REJECT.d.ts +9 -3
  64. package/lib/message/group/C2C_MSG_REJECT.js +1 -1
  65. package/lib/message/group/FRIEND_ADD.d.ts +13 -3
  66. package/lib/message/group/FRIEND_ADD.js +1 -1
  67. package/lib/message/group/FRIEND_DEL.d.ts +9 -3
  68. package/lib/message/group/FRIEND_DEL.js +1 -1
  69. package/lib/message/group/GROUP_ADD_ROBOT.d.ts +23 -4
  70. package/lib/message/group/GROUP_ADD_ROBOT.js +1 -1
  71. package/lib/message/group/GROUP_AT_MESSAGE_CREATE.d.ts +38 -32
  72. package/lib/message/group/GROUP_AT_MESSAGE_CREATE.js +1 -1
  73. package/lib/message/group/GROUP_DEL_ROBOT.d.ts +19 -4
  74. package/lib/message/group/GROUP_DEL_ROBOT.js +1 -1
  75. package/lib/message/group/GROUP_JOIN_REQUEST.d.ts +84 -0
  76. package/lib/message/group/GROUP_JOIN_REQUEST.js +1 -0
  77. package/lib/message/group/GROUP_MEMBER_ADD.d.ts +8 -5
  78. package/lib/message/group/GROUP_MEMBER_ADD.js +1 -1
  79. package/lib/message/group/GROUP_MEMBER_REMOVE.d.ts +8 -5
  80. package/lib/message/group/GROUP_MEMBER_REMOVE.js +1 -1
  81. package/lib/message/group/GROUP_MESSAGE_CREATE.d.ts +38 -32
  82. package/lib/message/group/GROUP_MESSAGE_CREATE.js +1 -1
  83. package/lib/message/group/GROUP_MSG_RECEIVE.d.ts +14 -4
  84. package/lib/message/group/GROUP_MSG_RECEIVE.js +1 -1
  85. package/lib/message/group/GROUP_MSG_REJECT.d.ts +10 -4
  86. package/lib/message/group/GROUP_MSG_REJECT.js +1 -1
  87. package/lib/message/group/MESSAGE_AUDIT_PASS.d.ts +12 -6
  88. package/lib/message/group/MESSAGE_AUDIT_PASS.js +1 -1
  89. package/lib/message/group/MESSAGE_AUDIT_REJECT.d.ts +12 -6
  90. package/lib/message/group/MESSAGE_AUDIT_REJECT.js +1 -1
  91. package/lib/register.d.ts +12 -9
  92. package/lib/register.js +1246 -1200
  93. package/lib/sdk/api.d.ts +937 -251
  94. package/lib/sdk/api.js +1481 -758
  95. package/lib/sdk/client.webhook.d.ts +25 -8
  96. package/lib/sdk/client.webhook.js +185 -189
  97. package/lib/sdk/client.websoket.d.ts +31 -9
  98. package/lib/sdk/client.websoket.js +369 -392
  99. package/lib/sdk/config.d.ts +6 -2
  100. package/lib/sdk/config.js +9 -6
  101. package/lib/sdk/instance.d.ts +11 -3
  102. package/lib/sdk/instance.js +73 -83
  103. package/lib/sdk/intents.d.ts +89 -3
  104. package/lib/sdk/intents.js +116 -31
  105. package/lib/sdk/message.d.ts +7 -4
  106. package/lib/sdk/message.group.d.ts +38 -33
  107. package/lib/sdk/message.group.js +1 -1
  108. package/lib/sdk/message.guild.d.ts +40 -37
  109. package/lib/sdk/message.guild.js +1 -1
  110. package/lib/sdk/message.js +1 -1
  111. package/lib/sdk/message.public.d.ts +8 -5
  112. package/lib/sdk/message.public.js +1 -1
  113. package/lib/sdk/qr-auth.d.ts +55 -0
  114. package/lib/sdk/qr-auth.js +169 -0
  115. package/lib/sdk/registry.d.ts +34 -24
  116. package/lib/sdk/registry.js +134 -114
  117. package/lib/sdk/session.d.ts +19 -15
  118. package/lib/sdk/session.js +51 -54
  119. package/lib/sdk/typing.d.ts +416 -68
  120. package/lib/sdk/typing.js +1 -1
  121. package/lib/sdk/webhook.secret.d.ts +33 -13
  122. package/lib/sdk/webhook.secret.js +50 -36
  123. package/lib/sends.d.ts +46 -25
  124. package/lib/sends.js +533 -497
  125. package/lib/types.d.ts +52 -41
  126. package/lib/types.js +1 -1
  127. package/lib/upload.d.ts +50 -0
  128. package/lib/upload.js +89 -0
  129. package/lib/utils.d.ts +9 -1
  130. package/lib/utils.js +10 -5
  131. package/package.json +11 -8
package/dist/index.html CHANGED
@@ -1,4 +1,4 @@
1
- <!doctype html>
1
+ <!DOCTYPE html>
2
2
  <html lang="en" id="__gui">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
package/lib/config.d.ts CHANGED
@@ -1,20 +1,45 @@
1
- import { Options as sdkOptions } from './sdk/typing';
2
- export declare const platform = "qq-bot";
3
- export declare const platformFullName = "@alemonjs/qq-bot";
4
- export type Options = {
5
- master_key?: string[];
6
- master_id?: string[];
7
- markdownToText?: boolean;
8
- hideUnsupported?: boolean | number;
9
- bots?: Record<string, Omit<sdkOptions, 'app_id'> & {
10
- app_id?: string;
11
- }>;
12
- default_bot?: string;
13
- } & sdkOptions;
14
- export declare const getQQBotConfig: () => Options;
15
- export declare const getQQBotBots: () => {
16
- bots: Map<string, sdkOptions>;
17
- defaultBot?: string;
1
+ import { Options as Options$1 } from "./sdk/typing.js";
2
+ //#region src/config.d.ts
3
+ declare const platform = "qq-bot";
4
+ declare const platformFullName = "@alemonjs/qq-bot";
5
+ type Options = {
6
+ /**
7
+ * 主人-用户KEY
8
+ */
9
+ master_key?: string[];
10
+ /**
11
+ * 主人-用户ID
12
+ */
13
+ master_id?: string[];
14
+ /**
15
+ * 将 Markdown 降级为纯文本发送
16
+ * 部分机器人不支持 Markdown 消息类型,开启后 Markdown 和按钮将转为可读纯文本
17
+ * @default false
18
+ */
19
+ markdownToText?: boolean;
20
+ /**
21
+ * 隐藏不支持的消息类型
22
+ * - true 或 1:一级隐藏,不可读占位符([视频]、[音频]等)被置空,可读内容保留
23
+ * - 2:二级隐藏,按钮仅显示指令数据,链接仅显示 URL
24
+ * - 3:三级隐藏,按钮和链接的 data 也不保留,完全隐藏
25
+ * - 4:四级隐藏,不进行任何转换,直接丢弃
26
+ * @default false
27
+ */
28
+ hideUnsupported?: boolean | number;
29
+ /** Multi-bot mode. Keys are BotId/AppId; each child overrides common options. */
30
+ bots?: Record<string, Omit<Options$1, 'app_id'> & {
31
+ app_id?: string;
32
+ }>;
33
+ /** Required for proactive actions without BotId when more than one bot is configured. */
34
+ default_bot?: string;
35
+ } & Options$1;
36
+ declare const getQQBotConfig: () => Options;
37
+ /** Converts legacy single-bot configuration into the same representation as multi-bot mode. */
38
+ declare const getQQBotBots: () => {
39
+ bots: Map<string, Options$1>;
40
+ defaultBot?: string;
18
41
  };
19
- export declare const getIdentity: (UserId: string) => readonly [boolean, string];
20
- export declare const getMaster: (UserId: string) => readonly [boolean, string];
42
+ declare const getIdentity: (UserId: string) => readonly [boolean, string];
43
+ declare const getMaster: (UserId: string) => readonly [boolean, string];
44
+ //#endregion
45
+ export { Options, getIdentity, getMaster, getQQBotBots, getQQBotConfig, platform, platformFullName };
package/lib/config.js CHANGED
@@ -1,45 +1,49 @@
1
- import { getConfigValue, isMaster, createUserHashKey } from 'alemonjs';
1
+ import { createUserHashKey, getConfigValue, isMaster } from "alemonjs";
2
2
 
3
- const platform = 'qq-bot';
4
- const platformFullName = '@alemonjs/qq-bot';
3
+ //#region src/config.ts
4
+ const platform = "qq-bot";
5
+ const platformFullName = "@alemonjs/qq-bot";
5
6
  const getQQBotConfig = () => {
6
- const value = getConfigValue() || {};
7
- const commonValue = value[platform] || {};
8
- const bagValue = value[platformFullName] || {};
9
- return { ...commonValue, ...bagValue };
7
+ const value = getConfigValue() || {};
8
+ const commonValue = value["qq-bot"] || {};
9
+ const bagValue = value["@alemonjs/qq-bot"] || {};
10
+ return {
11
+ ...commonValue,
12
+ ...bagValue
13
+ };
10
14
  };
15
+ /** Converts legacy single-bot configuration into the same representation as multi-bot mode. */
11
16
  const getQQBotBots = () => {
12
- const config = getQQBotConfig();
13
- const { bots: configuredBots, default_bot, master_id: _masterId, master_key: _masterKey, markdownToText: _markdown, hideUnsupported: _hide, ...common } = config;
14
- const bots = new Map();
15
- if (configuredBots && Object.keys(configuredBots).length) {
16
- for (const [botId, value] of Object.entries(configuredBots)) {
17
- if (value.app_id && value.app_id !== botId)
18
- throw new Error(`qq-bot bots.${botId}.app_id must match its map key`);
19
- if (!value.secret)
20
- throw new Error(`qq-bot bots.${botId}.secret is required`);
21
- bots.set(botId, { ...common, ...value, app_id: botId, secret: value.secret });
22
- }
23
- }
24
- else if (config.app_id && config.secret) {
25
- bots.set(config.app_id, common);
26
- }
27
- if (bots.size > 1 && !default_bot)
28
- throw new Error('qq-bot.default_bot is required when multiple bots are configured');
29
- if (default_bot && !bots.has(default_bot))
30
- throw new Error(`qq-bot.default_bot ${default_bot} is not configured`);
31
- return { bots, defaultBot: default_bot || (bots.size === 1 ? bots.keys().next().value : undefined) };
17
+ const config = getQQBotConfig();
18
+ const { bots: configuredBots, default_bot, master_id: _masterId, master_key: _masterKey, markdownToText: _markdown, hideUnsupported: _hide, ...common } = config;
19
+ const bots = /* @__PURE__ */ new Map();
20
+ if (configuredBots && Object.keys(configuredBots).length) for (const [botId, value] of Object.entries(configuredBots)) {
21
+ if (value.app_id && value.app_id !== botId) throw new Error(`qq-bot bots.${botId}.app_id must match its map key`);
22
+ if (!value.secret) throw new Error(`qq-bot bots.${botId}.secret is required`);
23
+ bots.set(botId, {
24
+ ...common,
25
+ ...value,
26
+ app_id: botId,
27
+ secret: value.secret
28
+ });
29
+ }
30
+ else if (config.app_id && config.secret) bots.set(config.app_id, common);
31
+ if (bots.size > 1 && !default_bot) throw new Error("qq-bot.default_bot is required when multiple bots are configured");
32
+ if (default_bot && !bots.has(default_bot)) throw new Error(`qq-bot.default_bot ${default_bot} is not configured`);
33
+ return {
34
+ bots,
35
+ defaultBot: default_bot || (bots.size === 1 ? bots.keys().next().value : void 0)
36
+ };
32
37
  };
33
38
  const getIdentity = (UserId) => {
34
- const isMasterUser = UserId ? isMaster(UserId, platform) : false;
35
- const UserKey = createUserHashKey({
36
- Platform: platform,
37
- UserId
38
- });
39
- return [isMasterUser, UserKey];
39
+ return [UserId ? isMaster(UserId, platform) : false, createUserHashKey({
40
+ Platform: platform,
41
+ UserId
42
+ })];
40
43
  };
41
44
  const getMaster = (UserId) => {
42
- return getIdentity(UserId);
45
+ return getIdentity(UserId);
43
46
  };
44
47
 
45
- export { getIdentity, getMaster, getQQBotBots, getQQBotConfig, platform, platformFullName };
48
+ //#endregion
49
+ export { getIdentity, getMaster, getQQBotBots, getQQBotConfig, platform, platformFullName };
package/lib/desktop.d.ts CHANGED
@@ -1 +1,4 @@
1
- export declare const activate: (context: any) => void;
1
+ //#region src/desktop.d.ts
2
+ declare const activate: (context: any) => void;
3
+ //#endregion
4
+ export { activate };
package/lib/desktop.js CHANGED
@@ -1,60 +1,56 @@
1
- import { readFileSync } from 'fs';
2
- import { dirname, join } from 'path';
3
- import { fileURLToPath } from 'url';
4
- import { getConfig, getConfigValue } from 'alemonjs';
5
- import { getQQBotRegistry } from './index.websoket.js';
1
+ import { getQQBotRegistry } from "./index.websoket.js";
2
+ import { getConfig, getConfigValue } from "alemonjs";
3
+ import { readFileSync } from "fs";
4
+ import { dirname, join } from "path";
5
+ import { fileURLToPath } from "url";
6
6
 
7
- const __dirname$1 = dirname(fileURLToPath(import.meta.url));
8
- const activate = context => {
9
- const webView = context.createSidebarWebView(context);
10
- context.onCommand('open.qq-bot', () => {
11
- const dir = join(__dirname$1, '../', 'dist', 'index.html');
12
- const scriptReg = /<script.*?src="(.+?)".*?>/;
13
- const styleReg = /<link.*?rel="stylesheet".*?href="(.+?)".*?>/;
14
- const iconReg = /<link.*?rel="icon".*?href="(.+?)".*?>/g;
15
- const styleUri = context.createExtensionDir(join(__dirname$1, '../', 'dist', 'assets', 'index.css'));
16
- const scriptUri = context.createExtensionDir(join(__dirname$1, '../', 'dist', 'assets', 'index.js'));
17
- const html = readFileSync(dir, 'utf-8')
18
- .replace(iconReg, '')
19
- .replace(scriptReg, `<script type="module" crossorigin src="${scriptUri}"></script>`)
20
- .replace(styleReg, `<link rel="stylesheet" crossorigin href="${styleUri}">`);
21
- webView.loadWebView(html);
22
- });
23
- webView.onMessage(data => {
24
- try {
25
- if (data.type === 'qq-bot.form.save') {
26
- const { bots_json: _botsJson, ...db } = data.data;
27
- const config = getConfig();
28
- const value = config.value ?? {};
29
- value['qq-bot'] = {
30
- ...db,
31
- master_key: db.master_key?.split(',') ?? null,
32
- master_id: db.master_id?.split(',') ?? null
33
- };
34
- config.saveValue(value);
35
- context.notification('QQ Bot 配置保存成功~');
36
- }
37
- else if (data.type === 'qq-bot.init') {
38
- let config = getConfigValue();
39
- if (!config) {
40
- config = {};
41
- }
42
- webView.postMessage({
43
- type: 'qq-bot.init',
44
- data: config['qq-bot'] ?? {}
45
- });
46
- }
47
- else if (data.type === 'qq-bot.status') {
48
- webView.postMessage({
49
- type: 'qq-bot.status',
50
- data: getQQBotRegistry()?.getConnectionStatus() ?? { Platform: 'qq-bot', state: 'stopped', bots: [] }
51
- });
52
- }
53
- }
54
- catch (e) {
55
- console.error(e);
56
- }
57
- });
7
+ //#region src/desktop.ts
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ const activate = (context) => {
10
+ const webView = context.createSidebarWebView(context);
11
+ context.onCommand("open.qq-bot", () => {
12
+ const dir = join(__dirname, "../", "dist", "index.html");
13
+ const scriptReg = /<script.*?src="(.+?)".*?>/;
14
+ const styleReg = /<link.*?rel="stylesheet".*?href="(.+?)".*?>/;
15
+ const iconReg = /<link.*?rel="icon".*?href="(.+?)".*?>/g;
16
+ const styleUri = context.createExtensionDir(join(__dirname, "../", "dist", "assets", "index.css"));
17
+ const scriptUri = context.createExtensionDir(join(__dirname, "../", "dist", "assets", "index.js"));
18
+ const html = readFileSync(dir, "utf-8").replace(iconReg, "").replace(scriptReg, `<script type="module" crossorigin src="${scriptUri}"><\/script>`).replace(styleReg, `<link rel="stylesheet" crossorigin href="${styleUri}">`);
19
+ webView.loadWebView(html);
20
+ });
21
+ webView.onMessage((data) => {
22
+ try {
23
+ if (data.type === "qq-bot.form.save") {
24
+ const { bots_json: _botsJson, ...db } = data.data;
25
+ const config = getConfig();
26
+ const value = config.value ?? {};
27
+ value["qq-bot"] = {
28
+ ...db,
29
+ master_key: db.master_key?.split(",") ?? null,
30
+ master_id: db.master_id?.split(",") ?? null
31
+ };
32
+ config.saveValue(value);
33
+ context.notification("QQ Bot 配置保存成功~");
34
+ } else if (data.type === "qq-bot.init") {
35
+ let config = getConfigValue();
36
+ if (!config) config = {};
37
+ webView.postMessage({
38
+ type: "qq-bot.init",
39
+ data: config["qq-bot"] ?? {}
40
+ });
41
+ } else if (data.type === "qq-bot.status") webView.postMessage({
42
+ type: "qq-bot.status",
43
+ data: getQQBotRegistry()?.getConnectionStatus() ?? {
44
+ Platform: "qq-bot",
45
+ state: "stopped",
46
+ bots: []
47
+ }
48
+ });
49
+ } catch (e) {
50
+ console.error(e);
51
+ }
52
+ });
58
53
  };
59
54
 
60
- export { activate };
55
+ //#endregion
56
+ export { activate };
package/lib/format.d.ts CHANGED
@@ -1,5 +1,26 @@
1
- import type { DataEnums, DataMarkDown } from 'alemonjs';
2
- export declare const markdownToText: (items: DataMarkDown["value"], hideUnsupported?: boolean | number) => string;
3
- export declare const buttonsToText: (rows: any[]) => string;
4
- export declare const markdownRawToText: (raw: string, hideUnsupported?: boolean | number) => string;
5
- export declare const dataEnumToText: (item: DataEnums, hideUnsupported?: boolean | number) => string;
1
+ import { DataEnums, DataMarkDown } from "alemonjs";
2
+ //#region src/format.d.ts
3
+ /**
4
+ * 将结构化 Markdown 子元素数组转为可读纯文本
5
+ */
6
+ declare const markdownToText: (items: DataMarkDown['value'], hideUnsupported?: boolean | number) => string;
7
+ /**
8
+ * 将按钮组转为可读纯文本
9
+ */
10
+ declare const buttonsToText: (rows: any[]) => string;
11
+ /**
12
+ * 将原始 Markdown 字符串转为可读纯文本
13
+ * QQ Bot 不支持原始 Markdown 直接渲染,需要降级
14
+ */
15
+ declare const markdownRawToText: (raw: string, hideUnsupported?: boolean | number) => string;
16
+ /**
17
+ * 将 DataEnums 数组中不被原生处理的类型降级为文本
18
+ *
19
+ * qq-bot 原生支持: Text, Mention, Link, Image, ImageFile, ImageURL,
20
+ * Markdown, BT.group
21
+ * qq-bot 内部扩展: ButtonTemplate, Ark.list, Ark.Card, Ark.BigCard
22
+ * 其余类型降级为文本
23
+ */
24
+ declare const dataEnumToText: (item: DataEnums, hideUnsupported?: boolean | number) => string;
25
+ //#endregion
26
+ export { buttonsToText, dataEnumToText, markdownRawToText, markdownToText };
package/lib/format.js CHANGED
@@ -1,110 +1,93 @@
1
+ //#region src/format.ts
2
+ /**
3
+ * 将结构化 Markdown 子元素数组转为可读纯文本
4
+ */
1
5
  const markdownToText = (items, hideUnsupported) => {
2
- if (Number(hideUnsupported) >= 4) {
3
- return '';
4
- }
5
- return items
6
- .map(item => {
7
- switch (item.type) {
8
- case 'MD.text':
9
- return item.value;
10
- case 'MD.title':
11
- return hideUnsupported ? `${item.value}\n` : `【${item.value}】\n`;
12
- case 'MD.subtitle':
13
- return hideUnsupported ? `${item.value}\n` : `〖${item.value}〗\n`;
14
- case 'MD.bold':
15
- case 'MD.italic':
16
- case 'MD.italicStar':
17
- case 'MD.strikethrough':
18
- return item.value;
19
- case 'MD.link': {
20
- const v = item.value;
21
- if (Number(hideUnsupported) >= 3) {
22
- return '';
23
- }
24
- return Number(hideUnsupported) >= 2 ? v.url : `${v.text}( ${v.url} )`;
25
- }
26
- case 'MD.image':
27
- return hideUnsupported ? '' : '[图片]';
28
- case 'MD.list':
29
- return (item.value
30
- .map(li => {
31
- if (typeof li.value === 'object') {
32
- return `${li.value.index}. ${li.value.text ?? ''}`;
33
- }
34
- return `· ${li.value}`;
35
- })
36
- .join('\n') + '\n');
37
- case 'MD.blockquote':
38
- return `> ${item.value}\n`;
39
- case 'MD.divider':
40
- return hideUnsupported ? '' : '————————\n';
41
- case 'MD.newline':
42
- return '\n';
43
- case 'MD.code':
44
- return item.value;
45
- case 'MD.mention':
46
- if (item.value === 'everyone') {
47
- return '@全体成员';
48
- }
49
- return `@${item.value ?? ''}`;
50
- case 'MD.content':
51
- return item.value;
52
- case 'MD.button':
53
- if (Number(hideUnsupported) >= 3) {
54
- return '';
55
- }
56
- if (Number(hideUnsupported) >= 2) {
57
- return item.options?.data || String(item.value);
58
- }
59
- return hideUnsupported ? String(item.value) : `[${item.value}]`;
60
- default:
61
- return String(item?.value ?? '');
62
- }
63
- })
64
- .join('');
6
+ if (Number(hideUnsupported) >= 4) return "";
7
+ return items.map((item) => {
8
+ switch (item.type) {
9
+ case "MD.text": return item.value;
10
+ case "MD.title": return hideUnsupported ? `${item.value}\n` : `【${item.value}】\n`;
11
+ case "MD.subtitle": return hideUnsupported ? `${item.value}\n` : `〖${item.value}〗\n`;
12
+ case "MD.bold":
13
+ case "MD.italic":
14
+ case "MD.italicStar":
15
+ case "MD.strikethrough": return item.value;
16
+ case "MD.link": {
17
+ const v = item.value;
18
+ if (Number(hideUnsupported) >= 3) return "";
19
+ return Number(hideUnsupported) >= 2 ? v.url : `${v.text}( ${v.url} )`;
20
+ }
21
+ case "MD.image": return hideUnsupported ? "" : "[图片]";
22
+ case "MD.list": return item.value.map((li) => {
23
+ if (typeof li.value === "object") return `${li.value.index}. ${li.value.text ?? ""}`;
24
+ return `· ${li.value}`;
25
+ }).join("\n") + "\n";
26
+ case "MD.blockquote": return `> ${item.value}\n`;
27
+ case "MD.divider": return hideUnsupported ? "" : "————————\n";
28
+ case "MD.newline": return "\n";
29
+ case "MD.code": return item.value;
30
+ case "MD.mention":
31
+ if (item.value === "everyone") return "@全体成员";
32
+ return `@${item.value ?? ""}`;
33
+ case "MD.content": return item.value;
34
+ case "MD.button":
35
+ if (Number(hideUnsupported) >= 3) return "";
36
+ if (Number(hideUnsupported) >= 2) return item.options?.data || String(item.value);
37
+ return hideUnsupported ? String(item.value) : `[${item.value}]`;
38
+ default: return String(item?.value ?? "");
39
+ }
40
+ }).join("");
65
41
  };
42
+ /**
43
+ * 将按钮组转为可读纯文本
44
+ */
66
45
  const buttonsToText = (rows) => {
67
- return rows.map((row) => row.value.map((btn) => `[${btn.value}]`).join(' ')).join('\n');
46
+ return rows.map((row) => row.value.map((btn) => `[${btn.value}]`).join(" ")).join("\n");
68
47
  };
48
+ /**
49
+ * 将原始 Markdown 字符串转为可读纯文本
50
+ * QQ Bot 不支持原始 Markdown 直接渲染,需要降级
51
+ */
69
52
  const markdownRawToText = (raw, hideUnsupported) => {
70
- if (Number(hideUnsupported) >= 4) {
71
- return '';
72
- }
73
- let text = raw;
74
- text = text.replace(/!\[([^\]]*)\]\([^)]*\)/g, hideUnsupported ? '' : '[图片]');
75
- text = text.replace(/\[([^\]]*)\]\(([^)]*)\)/g, Number(hideUnsupported) >= 2 ? '$2' : '$1');
76
- text = text.replace(/^#{1,6}\s+/gm, '');
77
- text = text.replace(/(\*{3}|_{3})([^*_]+)\1/g, '$2');
78
- text = text.replace(/(\*{2}|_{2})([^*_]+)\1/g, '$2');
79
- text = text.replace(/(?<!\*)\*(?!\*)([^*]+)(?<!\*)\*(?!\*)/g, '$1');
80
- text = text.replace(/(?<!_)_(?!_)([^_]+)(?<!_)_(?!_)/g, '$1');
81
- text = text.replace(/~~([^~]+)~~/g, '$1');
82
- text = text.replace(/`([^`]+)`/g, '$1');
83
- text = text.replace(/```[\s\S]*?```/g, match => {
84
- return match.replace(/```\w*\n?/g, '').trim();
85
- });
86
- text = text.replace(/^>\s+/gm, '');
87
- text = text.replace(/^[-*_]{3,}\s*$/gm, hideUnsupported ? '' : '————————');
88
- text = text.replace(/^[\s]*[-*+]\s+/gm, '· ');
89
- text = text.replace(/^[\s]*(\d+)\.\s+/gm, '$1. ');
90
- return text;
53
+ if (Number(hideUnsupported) >= 4) return "";
54
+ let text = raw;
55
+ text = text.replace(/!\[([^\]]*)\]\([^)]*\)/g, hideUnsupported ? "" : "[图片]");
56
+ text = text.replace(/\[([^\]]*)\]\(([^)]*)\)/g, Number(hideUnsupported) >= 2 ? "$2" : "$1");
57
+ text = text.replace(/^#{1,6}\s+/gm, "");
58
+ text = text.replace(/(\*{3}|_{3})([^*_]+)\1/g, "$2");
59
+ text = text.replace(/(\*{2}|_{2})([^*_]+)\1/g, "$2");
60
+ text = text.replace(/(?<!\*)\*(?!\*)([^*]+)(?<!\*)\*(?!\*)/g, "$1");
61
+ text = text.replace(/(?<!_)_(?!_)([^_]+)(?<!_)_(?!_)/g, "$1");
62
+ text = text.replace(/~~([^~]+)~~/g, "$1");
63
+ text = text.replace(/`([^`]+)`/g, "$1");
64
+ text = text.replace(/```[\s\S]*?```/g, (match) => {
65
+ return match.replace(/```\w*\n?/g, "").trim();
66
+ });
67
+ text = text.replace(/^>\s+/gm, "");
68
+ text = text.replace(/^[-*_]{3,}\s*$/gm, hideUnsupported ? "" : "————————");
69
+ text = text.replace(/^[\s]*[-*+]\s+/gm, "· ");
70
+ text = text.replace(/^[\s]*(\d+)\.\s+/gm, "$1. ");
71
+ return text;
91
72
  };
73
+ /**
74
+ * 将 DataEnums 数组中不被原生处理的类型降级为文本
75
+ *
76
+ * qq-bot 原生支持: Text, Mention, Link, Image, ImageFile, ImageURL,
77
+ * Markdown, BT.group
78
+ * qq-bot 内部扩展: ButtonTemplate, Ark.list, Ark.Card, Ark.BigCard
79
+ * 其余类型降级为文本
80
+ */
92
81
  const dataEnumToText = (item, hideUnsupported) => {
93
- if (Number(hideUnsupported) >= 4) {
94
- return '';
95
- }
96
- switch (item.type) {
97
- case 'MarkdownOriginal':
98
- return markdownRawToText(String(item.value), hideUnsupported);
99
- case 'Attachment':
100
- return hideUnsupported ? '' : `[附件${item.options?.filename ? ': ' + item.options.filename : ''}]`;
101
- case 'Audio':
102
- return hideUnsupported ? '' : '[音频]';
103
- case 'Video':
104
- return hideUnsupported ? '' : '[视频]';
105
- default:
106
- return '';
107
- }
82
+ if (Number(hideUnsupported) >= 4) return "";
83
+ switch (item.type) {
84
+ case "MarkdownOriginal": return markdownRawToText(String(item.value), hideUnsupported);
85
+ case "Attachment": return hideUnsupported ? "" : `[附件${item.options?.filename ? ": " + item.options.filename : ""}]`;
86
+ case "Audio": return hideUnsupported ? "" : "[音频]";
87
+ case "Video": return hideUnsupported ? "" : "[视频]";
88
+ default: return "";
89
+ }
108
90
  };
109
91
 
110
- export { buttonsToText, dataEnumToText, markdownRawToText, markdownToText };
92
+ //#endregion
93
+ export { buttonsToText, dataEnumToText, markdownRawToText, markdownToText };