@nextclaw/channel-extension-qq 0.1.2 → 0.1.4

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/dist/main.js CHANGED
@@ -8,3 +8,5 @@ await startBusChannelExtension({
8
8
  });
9
9
  //#endregion
10
10
  export {};
11
+
12
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","names":[],"sources":["../src/main.ts"],"sourcesContent":["import { startBusChannelExtension, warnNcpEventError } from \"@nextclaw/extension-sdk\";\nimport { QQChannel, type QQChannelConfig } from \"./services/qq-channel.service.js\";\n\nawait startBusChannelExtension<QQChannelConfig>({\n channelId: \"qq\",\n createChannel: ({ config, bus }) => new QQChannel(config, bus),\n onChannelStartError: warnNcpEventError(\"qq\"),\n});\n"],"mappings":";;;AAGA,MAAM,yBAA0C;CAC9C,WAAW;CACX,gBAAgB,EAAE,QAAQ,UAAU,IAAI,UAAU,QAAQ,IAAI;CAC9D,qBAAqB,kBAAkB,KAAK;CAC7C,CAAC"}
@@ -39,17 +39,15 @@ var QQChannel = class {
39
39
  if (!this.bot) return;
40
40
  const qqMeta = msg.metadata?.qq ?? {};
41
41
  const messageType = qqMeta.messageType ?? "private";
42
- const metadataMessageId = msg.metadata?.message_id ?? null;
43
- const sourceId = msg.replyTo ?? metadataMessageId ?? void 0;
44
- const source = sourceId ? { id: sourceId } : void 0;
45
- const rawContent = msg.content ?? "";
46
- const payload = rawContent;
42
+ const replyTo = msg.replyTo ?? msg.metadata?.message_id;
43
+ const source = replyTo ? { id: replyTo } : void 0;
44
+ const rawContent = msg.content;
47
45
  try {
48
46
  await this.sendByMessageType({
49
47
  messageType,
50
48
  qqMeta,
51
49
  msg,
52
- payload,
50
+ payload: rawContent,
53
51
  source
54
52
  });
55
53
  } catch (error) {
@@ -87,7 +85,6 @@ var QQChannel = class {
87
85
  chatId: route.chatId,
88
86
  content: this.decorateSpeakerPrefix({
89
87
  content,
90
- messageType: route.messageType,
91
88
  senderId: identity.senderId,
92
89
  senderName
93
90
  }),
@@ -119,22 +116,17 @@ var QQChannel = class {
119
116
  resolveIncomingRoute = (event, rawEvent, senderId, senderName) => {
120
117
  let chatId = senderId;
121
118
  let messageType = "private";
122
- const qqMeta = {};
119
+ const qqMeta = { userId: senderId };
120
+ if (senderName) qqMeta.userName = senderName;
123
121
  if (event.message_type === "group") {
124
122
  messageType = "group";
125
123
  const groupId = event.group_id || rawEvent.group_openid || "";
126
124
  chatId = groupId;
127
125
  qqMeta.groupId = groupId;
128
- qqMeta.userId = senderId;
129
- if (senderName) qqMeta.userName = senderName;
130
- } else {
131
- qqMeta.userId = senderId;
132
- if (senderName) qqMeta.userName = senderName;
133
126
  }
134
127
  qqMeta.messageType = messageType;
135
128
  return {
136
129
  chatId,
137
- messageType,
138
130
  metadata: qqMeta
139
131
  };
140
132
  };
@@ -350,3 +342,5 @@ var QQChannel = class {
350
342
  };
351
343
  //#endregion
352
344
  export { QQChannel };
345
+
346
+ //# sourceMappingURL=qq-channel.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qq-channel.service.js","names":[],"sources":["../../src/services/qq-channel.service.ts"],"sourcesContent":["import type { BusChannelMessageBus, BusChannelRuntime } from \"@nextclaw/extension-sdk\";\nimport {\n Bot,\n ReceiverMode,\n SessionEvents,\n type GroupMessageEvent,\n type PrivateMessageEvent\n} from \"qq-official-bot\";\n\nexport type QQChannelConfig = { appId?: string; secret?: string; allowFrom?: string[] };\n\ntype QQMessageEvent = PrivateMessageEvent | GroupMessageEvent;\ntype QQMessageType = \"private\" | \"group\";\ntype QQRawUser = Partial<Record<\n \"id\" | \"user_id\" | \"user_openid\" | \"member_openid\" | \"username\" | \"user_name\" | \"nickname\" | \"nick\" | \"card\",\n string\n>>;\ntype QQRawEvent = { author?: QQRawUser; sender?: QQRawUser; group_openid?: string };\ntype QQIncomingIdentity = { messageId: string; rawEvent: QQRawEvent; senderId: string };\ntype QQIncomingRoute = { chatId: string; metadata: Record<string, unknown> };\n\nexport class QQChannel {\n name = \"qq\";\n protected running = false;\n private bot: Bot | null = null;\n private processedIds: string[] = [];\n private processedSet: Set<string> = new Set();\n private senderNameCache: Map<string, string> = new Map();\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private connectTask: Promise<void> | null = null;\n private reconnectAttempt = 0;\n private readonly reconnectBaseMs = 1000;\n private readonly reconnectMaxMs = 60000;\n protected readonly connectTimeoutMs: number = 90000;\n\n constructor(private readonly config: QQChannelConfig, private readonly bus: BusChannelMessageBus) {}\n\n start = async (): Promise<void> => {\n if (!this.config.appId || !this.config.secret) {\n this.running = false;\n throw new Error(\"QQ appId/appSecret not configured\");\n }\n\n this.running = true;\n this.reconnectAttempt = 0;\n this.clearReconnectTimer();\n this.tryConnect(\"startup\");\n await this.connectTask;\n };\n\n stop = async (): Promise<void> => {\n this.running = false;\n this.clearReconnectTimer();\n this.reconnectAttempt = 0;\n await this.teardownBot();\n if (this.connectTask) {\n await this.connectTask;\n }\n };\n\n send: BusChannelRuntime[\"send\"] = async (msg) => {\n if (!this.bot) {\n return;\n }\n\n const qqMeta = (msg.metadata?.qq as Record<string, unknown> | undefined) ?? {};\n const messageType = (qqMeta.messageType as QQMessageType | undefined) ?? \"private\";\n const replyTo = msg.replyTo ?? (msg.metadata?.message_id as string | undefined);\n const source = replyTo ? { id: replyTo } : undefined;\n const rawContent = msg.content;\n\n try {\n await this.sendByMessageType({ messageType, qqMeta, msg, payload: rawContent, source });\n } catch (error) {\n if (!this.isDisallowedUrlParamError(error)) {\n throw error;\n }\n const safeText = this.toQqSafeText(rawContent, error);\n await this.sendByMessageType({ messageType, qqMeta, msg, payload: safeText, source });\n }\n };\n\n private sendByMessageType = async (params: {\n messageType: QQMessageType;\n qqMeta: Record<string, unknown>;\n msg: Parameters<BusChannelRuntime[\"send\"]>[0];\n payload: unknown;\n source: { id: string } | undefined;\n }): Promise<void> => {\n const { messageType, qqMeta, msg, payload, source } = params;\n if (messageType === \"group\") {\n const groupId = (qqMeta.groupId as string | undefined) ?? msg.chatId;\n await this.sendWithTokenRetry(() => this.bot?.sendGroupMessage(groupId, payload, source));\n return;\n }\n\n const userId = (qqMeta.userId as string | undefined) ?? msg.chatId;\n await this.sendWithTokenRetry(() => this.bot?.sendPrivateMessage(userId, payload, source));\n };\n\n private handleIncoming = async (event: QQMessageEvent): Promise<void> => {\n const identity = this.resolveIncomingIdentity(event);\n if (!identity) {\n return;\n }\n const content = event.raw_message?.trim() || \"[empty message]\";\n const senderName = this.resolveIncomingSenderName(identity.senderId, identity.rawEvent, content);\n const route = this.resolveIncomingRoute(event, identity.rawEvent, identity.senderId, senderName);\n if (!route.chatId || !this.isAllowed(identity.senderId)) {\n return;\n }\n await this.bus.publishInbound({\n channel: this.name,\n senderId: identity.senderId,\n chatId: route.chatId,\n content: this.decorateSpeakerPrefix({\n content,\n senderId: identity.senderId,\n senderName\n }),\n metadata: {\n message_id: identity.messageId,\n qq: route.metadata\n }\n });\n };\n\n private resolveIncomingIdentity = (event: QQMessageEvent): QQIncomingIdentity | null => {\n const messageId = event.message_id || event.id || \"\";\n if (messageId && this.isDuplicate(messageId)) {\n return null;\n }\n const rawEvent = event as unknown as QQRawEvent;\n if (this.isSelfEvent(event)) {\n return null;\n }\n const senderId = this.resolveSenderId(event, rawEvent);\n return senderId ? { messageId, rawEvent, senderId } : null;\n };\n\n private resolveIncomingSenderName = (senderId: string, rawEvent: QQRawEvent, content: string): string | null => {\n const eventSenderName = this.resolveSenderName(rawEvent);\n if (eventSenderName) {\n this.senderNameCache.set(senderId, eventSenderName);\n }\n const declaredName = this.extractDeclaredName(content);\n if (declaredName) {\n this.senderNameCache.set(senderId, declaredName);\n }\n return declaredName ?? eventSenderName ?? this.senderNameCache.get(senderId) ?? null;\n };\n\n private resolveIncomingRoute = (\n event: QQMessageEvent,\n rawEvent: QQRawEvent,\n senderId: string,\n senderName: string | null,\n ): QQIncomingRoute => {\n let chatId = senderId;\n let messageType: QQMessageType = \"private\";\n const qqMeta: Record<string, unknown> = { userId: senderId };\n if (senderName) {\n qqMeta.userName = senderName;\n }\n\n if (event.message_type === \"group\") {\n messageType = \"group\";\n const groupId = event.group_id || rawEvent.group_openid || \"\";\n chatId = groupId;\n qqMeta.groupId = groupId;\n }\n\n qqMeta.messageType = messageType;\n return { chatId, metadata: qqMeta };\n };\n\n private isAllowed = (senderId: string): boolean => {\n const allowList = this.config.allowFrom ?? [];\n if (!allowList.length || allowList.includes(senderId)) {\n return true;\n }\n return senderId.includes(\"|\") && senderId.split(\"|\").some((part) => allowList.includes(part));\n };\n\n private isSelfEvent = (event: QQMessageEvent): boolean => {\n const userId = typeof event.user_id === \"string\" ? event.user_id : \"\";\n const selfId = typeof event.self_id === \"string\" ? event.self_id : \"\";\n return Boolean(userId && selfId && userId === selfId);\n };\n\n private resolveSenderId = (event: QQMessageEvent, rawEvent: QQRawEvent): string => {\n return this.readFirstString([\n event.user_id,\n rawEvent.sender?.member_openid,\n rawEvent.sender?.user_openid,\n rawEvent.sender?.user_id,\n rawEvent.author?.member_openid,\n rawEvent.author?.user_openid,\n rawEvent.author?.id\n ]) ?? \"\";\n };\n\n private resolveSenderName = (rawEvent: QQRawEvent): string | null => {\n return this.readFirstString([\n rawEvent.sender?.card,\n rawEvent.sender?.nickname,\n rawEvent.sender?.nick,\n rawEvent.sender?.username,\n rawEvent.sender?.user_name,\n rawEvent.author?.username\n ]);\n };\n\n private readFirstString = (values: unknown[]): string | null => {\n for (const value of values) {\n if (typeof value !== \"string\") {\n continue;\n }\n const normalized = value.trim();\n if (normalized) {\n return normalized;\n }\n }\n return null;\n };\n\n private decorateSpeakerPrefix = (params: {\n content: string;\n senderId: string;\n senderName: string | null;\n }): string => {\n const { content, senderId, senderName } = params;\n // Always inject sender identity so both group and private QQ sessions can resolve user identity.\n const userId = this.sanitizeSpeakerToken(senderId);\n if (!userId) {\n return content;\n }\n const name = this.sanitizeSpeakerToken(senderName ?? \"\");\n const speakerFields = [`user_id=${userId}`];\n if (name) {\n speakerFields.push(`name=${name}`);\n }\n return `[speaker:${speakerFields.join(\";\")}] ${content}`;\n };\n\n private sanitizeSpeakerToken = (value: string): string => {\n return value.replace(/[\\r\\n;\\]]/g, \" \").trim();\n };\n\n private extractDeclaredName = (content: string): string | null => {\n const trimmed = content.trim();\n const patterns = [\n /^我的昵称是\\s*([^\\s,。!?!?,]{1,24})$/u,\n /^我叫\\s*([^\\s,。!?!?,]{1,24})$/u,\n /^叫我\\s*([^\\s,。!?!?,]{1,24})$/u\n ];\n for (const pattern of patterns) {\n const match = trimmed.match(pattern);\n if (!match) {\n continue;\n }\n const candidate = this.sanitizeSpeakerToken(match[1] ?? \"\");\n if (candidate) {\n return candidate;\n }\n }\n return null;\n };\n\n private isDuplicate = (messageId: string): boolean => {\n if (this.processedSet.has(messageId)) {\n return true;\n }\n this.processedSet.add(messageId);\n this.processedIds.push(messageId);\n if (this.processedIds.length > 1000) {\n const removed = this.processedIds.splice(0, 500);\n for (const id of removed) {\n this.processedSet.delete(id);\n }\n }\n return false;\n };\n\n private sendWithTokenRetry = async (send: () => Promise<unknown> | undefined): Promise<void> => {\n try {\n await send();\n } catch (error) {\n if (!this.isTokenExpiredError(error) || !this.bot) {\n throw error;\n }\n await this.bot.sessionManager.getAccessToken();\n await send();\n }\n };\n\n private isTokenExpiredError = (error: unknown): boolean => {\n const message = error instanceof Error ? error.message : String(error);\n return message.includes(\"code(11244)\") || message.toLowerCase().includes(\"token not exist or expire\");\n };\n\n private isDisallowedUrlParamError = (error: unknown): boolean => {\n const message = error instanceof Error ? error.message : String(error);\n return message.includes(\"code(40034028)\") || message.includes(\"请求参数不允许包含url\");\n };\n\n private toQqSafeText = (content: string, error: unknown): string => {\n let safe = content\n .replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, \"$1\")\n .replace(/https?:\\/\\/\\S+/gi, \"[link]\")\n .replace(/www\\.\\S+/gi, \"[link]\")\n .replace(/\\b[a-z0-9._/-]+\\.md\\b/gi, \"[file]\");\n\n const blocked = this.extractBlockedUrlToken(error);\n if (blocked) {\n safe = safe.replaceAll(blocked, \"[link]\");\n }\n return safe;\n };\n\n private extractBlockedUrlToken = (error: unknown): string | null => {\n const message = error instanceof Error ? error.message : String(error);\n const match = message.match(/包含url\\s+([^\\s]+)/);\n if (!match) {\n return null;\n }\n const token = match[1].trim();\n return token.length > 0 ? token : null;\n };\n\n private tryConnect = (trigger: string): void => {\n if (!this.running || this.bot || this.connectTask) {\n return;\n }\n this.connectTask = this.connect(trigger).finally(() => {\n this.connectTask = null;\n });\n };\n\n private connect = async (trigger: string): Promise<void> => {\n let candidate: Bot | null = null;\n try {\n candidate = this.createBot();\n await this.startBotWithTimeout(candidate);\n if (!this.running) {\n await this.safeStopBot(candidate);\n return;\n }\n this.bot = candidate;\n this.reconnectAttempt = 0;\n // eslint-disable-next-line no-console\n console.log(\"QQ bot connected\");\n } catch (error) {\n if (candidate) {\n await this.safeStopBot(candidate);\n }\n if (!this.running) {\n return;\n }\n this.reconnectAttempt += 1;\n const delayMs = this.getBackoffDelayMs(this.reconnectAttempt);\n // eslint-disable-next-line no-console\n console.error(\n `[qq] start failed (${trigger}, attempt ${this.reconnectAttempt}), retry in ${delayMs}ms: ${this.formatError(error)}`\n );\n this.scheduleReconnect(delayMs, `${trigger}-retry`);\n }\n };\n\n protected createBot = (): Bot => {\n const bot = new Bot({\n appid: this.config.appId!,\n secret: this.config.secret!,\n mode: ReceiverMode.WEBSOCKET,\n intents: [\"C2C_MESSAGE_CREATE\", \"GROUP_AT_MESSAGE_CREATE\"],\n removeAt: true,\n logLevel: \"info\"\n });\n\n bot.on(\"message.private\", async (event) => {\n await this.handleIncoming(event);\n });\n\n bot.on(\"message.group\", async (event) => {\n await this.handleIncoming(event);\n });\n\n bot.sessionManager.on(SessionEvents.DEAD, () => {\n void this.handleSessionDead(bot);\n });\n\n return bot;\n };\n\n private handleSessionDead = async (bot: Bot): Promise<void> => {\n if (!this.running || this.bot !== bot) {\n return;\n }\n this.bot = null;\n await this.safeStopBot(bot);\n this.reconnectAttempt += 1;\n const delayMs = this.getBackoffDelayMs(this.reconnectAttempt);\n // eslint-disable-next-line no-console\n console.error(`[qq] session dead, reconnect in ${delayMs}ms`);\n this.scheduleReconnect(delayMs, \"session-dead\");\n };\n\n private scheduleReconnect = (delayMs: number, trigger: string): void => {\n if (!this.running) {\n return;\n }\n this.clearReconnectTimer();\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.tryConnect(trigger);\n }, delayMs);\n };\n\n private clearReconnectTimer = (): void => {\n if (!this.reconnectTimer) {\n return;\n }\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n };\n\n private teardownBot = async (): Promise<void> => {\n if (!this.bot) {\n return;\n }\n const bot = this.bot;\n this.bot = null;\n await this.safeStopBot(bot);\n };\n\n private safeStopBot = async (bot: Bot): Promise<void> => {\n bot.removeAllListeners(\"message.private\");\n bot.removeAllListeners(\"message.group\");\n bot.sessionManager.removeAllListeners(SessionEvents.DEAD);\n try {\n await bot.stop();\n } catch {\n // ignore cleanup errors\n }\n };\n\n private startBotWithTimeout = async (bot: Bot): Promise<void> => {\n let timer: ReturnType<typeof setTimeout> | null = null;\n try {\n await Promise.race([\n bot.start(),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(`QQ bot start timed out after ${this.connectTimeoutMs}ms`)), this.connectTimeoutMs);\n })\n ]);\n } finally {\n if (timer) {\n clearTimeout(timer);\n }\n }\n };\n\n get isRunning(): boolean {\n return this.bot !== null;\n }\n\n private getBackoffDelayMs = (attempt: number): number => {\n const jitter = Math.floor(Math.random() * 500);\n const exp = Math.min(this.reconnectMaxMs, this.reconnectBaseMs * 2 ** Math.max(0, attempt - 1));\n return Math.min(this.reconnectMaxMs, exp + jitter);\n };\n\n private formatError = (error: unknown): string => {\n if (error instanceof Error) {\n return error.stack ?? error.message;\n }\n return String(error);\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/channel-extension-qq",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "private": false,
5
5
  "description": "NextClaw QQ channel extension process.",
6
6
  "type": "module",
@@ -18,7 +18,7 @@
18
18
  ],
19
19
  "dependencies": {
20
20
  "qq-official-bot": "1.0.12",
21
- "@nextclaw/extension-sdk": "0.1.8"
21
+ "@nextclaw/extension-sdk": "0.1.10"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/node": "^20.17.6",
@@ -26,7 +26,7 @@
26
26
  "typescript": "^5.6.3"
27
27
  },
28
28
  "scripts": {
29
- "build": "tsdown src/index.ts src/main.ts --dts --clean --target es2022 --no-fixedExtension --unbundle",
29
+ "build": "tsdown src/index.ts src/main.ts --dts.sourcemap --clean --target es2022 --no-fixedExtension --unbundle",
30
30
  "lint": "eslint src --max-warnings=0",
31
31
  "test": "node --import tsx --test src/tests/*.test.ts",
32
32
  "tsc": "tsc -p tsconfig.json"