{"_id":"@tencent-connect/qqbot-nodejs","_rev":"5-7df965d0faf23efe69c51bfe2349dd85","name":"@tencent-connect/qqbot-nodejs","dist-tags":{"latest":"1.0.4"},"versions":{"1.0.3":{"name":"@tencent-connect/qqbot-nodejs","version":"1.0.3","keywords":["qqbot","qq","tencent","bot","sdk","websocket","openapi"],"license":"MIT","_id":"@tencent-connect/qqbot-nodejs@1.0.3","maintainers":[{"name":"uv-w","email":"9837438@qq.com"},{"name":"vnues","email":"1518190293@qq.com"},{"name":"zuosh","email":"13366589984@163.com"},{"name":"joyqwang","email":"645153050@qq.com"},{"name":"tencentconnectqqbot","email":"tencentconnectqqbot@gmail.com"},{"name":"ryanlee-gemini","email":"ryanlee.gemini@gmail.com"}],"dist":{"shasum":"f985e6abe40bd69d431795b5f98de012cb664f06","tarball":"https://registry.npmjs.org/@tencent-connect/qqbot-nodejs/-/qqbot-nodejs-1.0.3.tgz","fileCount":293,"integrity":"sha512-Rmd3GZYm3cipxSMg0qZVeq/+ziY+XqZaNcjvJJKQsyqd6dS7L1p9ERuxU84zsM+vhwwUp+v640p3hTo0P4Y2SQ==","signatures":[{"sig":"MEUCIQCWyHDbOuKF0JGrIljrFNCzgseLE6y3Dp47LlaEd8kY5wIgFUis/vPkAVhzmHZdqx8LHWYqWM5mJUW5nxK7MB9JXUw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1160698},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./protocol":{"types":"./dist/protocol/index.d.ts","import":"./dist/protocol/index.js"}},"gitHead":"095c7179d09087033ff14740203b6e304d5325b5","scripts":{"lint":"eslint .","test":"vitest run","build":"tsc -p tsconfig.build.json","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit","commitlint":"commitlint","playground":"tsx examples/playground/index.ts","test:watch":"vitest","test:coverage":"vitest run --coverage","example:webhook":"tsx examples/webhook/index.ts","playground:build":"node --import tsx examples/playground/index.ts","semantic-release":"semantic-release","ci:prepare-test-pkg":"node scripts/prepare-test-pkg.js"},"_npmUser":{"name":"tencentconnectqqbot","email":"tencentconnectqqbot@gmail.com"},"_npmVersion":"11.16.0","description":"Tencent QQ Bot Node.js SDK — protocol-level client for the QQ Open Platform (HTTP + WebSocket Gateway, message + media + streaming).","directories":{},"_nodeVersion":"24.18.0","dependencies":{"ws":"^8.21.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.0","eslint":"^10.6.0","vitest":"^4.1.10","globals":"^17.7.0","@types/ws":"^8.18.1","silk-wasm":"^3.7.1","@eslint/js":"^10.0.1","typescript":"^5.9.3","@types/node":"^22.20.1","mpg123-decoder":"^1.0.3","@commitlint/cli":"^20.5.3","semantic-release":"^25.0.5","typescript-eslint":"^8.63.0","@vitest/coverage-v8":"^4.1.10","@semantic-release/git":"^10.0.1","@semantic-release/exec":"^7.1.0","@semantic-release/changelog":"^6.0.3","@commitlint/config-conventional":"^20.5.3"},"peerDependencies":{"silk-wasm":"^3.7.1","mpg123-decoder":"^1.0.3"},"peerDependenciesMeta":{"silk-wasm":{"optional":true},"mpg123-decoder":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/qqbot-nodejs_1.0.3_1783929096498_0.33303800286455765","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@tencent-connect/qqbot-nodejs","version":"1.0.4","description":"Tencent QQ Bot Node.js SDK — protocol-level client for the QQ Open Platform (HTTP + WebSocket Gateway, message + media + streaming).","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./protocol":{"types":"./dist/protocol/index.d.ts","import":"./dist/protocol/index.js"}},"scripts":{"build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit","lint":"eslint .","commitlint":"commitlint","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","semantic-release":"semantic-release","ci:prepare-test-pkg":"node scripts/prepare-test-pkg.js","prepack":"npm run build","playground":"tsx examples/playground/index.ts","playground:build":"node --import tsx examples/playground/index.ts","example:webhook":"tsx examples/webhook/index.ts"},"dependencies":{"ws":"^8.21.0"},"devDependencies":{"@commitlint/cli":"^20.5.3","@commitlint/config-conventional":"^20.5.3","@eslint/js":"^10.0.1","@semantic-release/changelog":"^6.0.3","@semantic-release/exec":"^7.1.0","@semantic-release/git":"^10.0.1","@types/node":"^22.20.1","@types/ws":"^8.18.1","@vitest/coverage-v8":"^4.1.10","eslint":"^10.6.0","globals":"^17.7.0","mpg123-decoder":"^1.0.3","semantic-release":"^25.0.5","silk-wasm":"^3.7.1","tsx":"^4.23.0","typescript":"^5.9.3","typescript-eslint":"^8.63.0","vitest":"^4.1.10"},"peerDependencies":{"mpg123-decoder":"^1.0.3","silk-wasm":"^3.7.1"},"peerDependenciesMeta":{"mpg123-decoder":{"optional":true},"silk-wasm":{"optional":true}},"engines":{"node":">=18"},"keywords":["qqbot","qq","tencent","bot","sdk","websocket","openapi"],"license":"MIT","publishConfig":{"access":"public"},"gitHead":"589597a6cb5a24dce8230ba53bfba5390e13c073","_id":"@tencent-connect/qqbot-nodejs@1.0.4","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-gU5HySLplczZXMUjM7NtiUACY7YfX9YlI/R9PKzCLMgLmHvwsX9L2sitsrYPMentGUr9b8NLfSaSTsndF77NBA==","shasum":"8f239c32f5dc7ec2a8930a088cb363e83ab249a7","tarball":"https://registry.npmjs.org/@tencent-connect/qqbot-nodejs/-/qqbot-nodejs-1.0.4.tgz","fileCount":293,"unpackedSize":1163483,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICxSU8XBApUgA/FgqPCux4yFPYblRphKbU+pkqzZQdZjAiAnZwOM2vAVPOy8Xp3GVVLyyPylkdBIvcRoArOd35bPzA=="}]},"_npmUser":{"name":"tencentconnectqqbot","email":"tencentconnectqqbot@gmail.com"},"directories":{},"maintainers":[{"name":"uv-w","email":"9837438@qq.com"},{"name":"vnues","email":"1518190293@qq.com"},{"name":"zuosh","email":"13366589984@163.com"},{"name":"joyqwang","email":"645153050@qq.com"},{"name":"tencentconnectqqbot","email":"tencentconnectqqbot@gmail.com"},{"name":"ryanlee-gemini","email":"ryanlee.gemini@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/qqbot-nodejs_1.0.4_1784000728784_0.9935049769407405"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-13T07:51:36.272Z","modified":"2026-07-14T03:45:29.148Z","1.0.0":"2026-04-30T09:16:06.639Z","1.0.3":"2026-07-13T07:51:36.724Z","1.0.4":"2026-07-14T03:45:28.976Z"},"license":"MIT","keywords":["qqbot","qq","tencent","bot","sdk","websocket","openapi"],"description":"Tencent QQ Bot Node.js SDK — protocol-level client for the QQ Open Platform (HTTP + WebSocket Gateway, message + media + streaming).","maintainers":[{"name":"uv-w","email":"9837438@qq.com"},{"name":"vnues","email":"1518190293@qq.com"},{"name":"zuosh","email":"13366589984@163.com"},{"name":"joyqwang","email":"645153050@qq.com"},{"name":"tencentconnectqqbot","email":"tencentconnectqqbot@gmail.com"},{"name":"ryanlee-gemini","email":"ryanlee.gemini@gmail.com"}],"readme":"# @tencent-connect/qqbot-nodejs\n\nTencent QQ Open Platform Node.js SDK。提供与 QQ 机器人开放平台对接所需的全部\n协议层能力：HTTP REST、WebSocket / Webhook 双传输、Koa-style 中间件管线、\n消息收发、媒体上传（含大文件分块）、C2C 流式消息（stream_messages）。\n\n## 安装\n\n```bash\npnpm add @tencent-connect/qqbot-nodejs\n# 或\nnpm install @tencent-connect/qqbot-nodejs\n```\n\n## 快速开始\n\n```ts\nimport { QQBot } from \"@tencent-connect/qqbot-nodejs\";\n\nconst bot = new QQBot({\n  appId: process.env.QQBOT_APP_ID!,\n  appSecret: process.env.QQBOT_APP_SECRET!,\n  logger: console,\n});\n\nbot.on(\"message\", async (ctx, msg) => {\n  // ctx — Koa-style MiddlewareContext，携带 middleware 注入的数据\n  await bot.sendText(msg.replyTarget, `Echo: ${msg.content}`);\n});\n\nawait bot.start();\n```\n\n参考 [examples/](./examples/) 下的完整示例：\n\n| 示例 | 说明 |\n|------|------|\n| [playground](./examples/playground/) | 核心能力演示（文本、流式、媒体、命令） |\n| [middleware](./examples/middleware/) | 完整 14 层 Koa-style 中间件管线 |\n| [webhook](./examples/webhook/) | Webhook（HTTP 回调）传输模式 |\n| [send-plain-100](./examples/send-plain-100/) | 普通文本发送对照实验 |\n| [send-streaming-100](./examples/send-streaming-100/) | 流式消息发送对照实验 |\n\n## 主要能力\n\n### 1. 双传输模式（WebSocket / Webhook）\n\n```ts\n// WebSocket（默认）— 长连接 + 心跳 + RESUME\nconst bot = new QQBot({ appId, appSecret });\n\n// Webhook — HTTP 回调，适合 Serverless / 水平扩展\nconst bot = new QQBot({\n  appId, appSecret,\n  transport: \"webhook\",\n  webhook: { port: 8080, path: \"/callback\" },\n});\n```\n\n两种模式下中间件、事件监听、消息发送 API 完全一致。\n\n### 2. Koa-style 中间件\n\nSDK 采用洋葱模型中间件，`bot.on(\"message\")` 作为 chain 最内层 downstream：\n\n```ts\nimport { errorHandler, messageFilter, contentSanitizer, mentionGate } from \"@tencent-connect/qqbot-nodejs\";\n\nbot.use(errorHandler());\nbot.use(messageFilter({ skipSelfEcho: true, dedup: { windowMs: 5000 } }));\nbot.use(contentSanitizer({ stripBotMention: true }));\nbot.use(mentionGate({ requireMentionInGroup: true }));\n\n// 自定义中间件\nbot.use(async (ctx, next) => {\n  const start = Date.now();\n  await next();\n  ctx.log.debug?.(`elapsed: ${Date.now() - start}ms`);\n});\n```\n\n内置中间件：\n\n| 中间件 | 说明 |\n|--------|------|\n| `errorHandler` | 统一错误捕获 + 友好回复 |\n| `messageFilter` | 过滤 bot 回声 + 消息去重 |\n| `rateLimiter` | 三层限流（sender / group / global） |\n| `concurrencyGuard` | 同用户/群串行处理（防 stream 并发冲突） |\n| `accessPolicy` | 黑白名单 |\n| `contentSanitizer` | 去 @marker / face tags / 空白清洗 |\n| `mentionGate` | 群聊 @bot 判定 |\n| `quoteRef` | 消息索引记录 + 引用消息解析 |\n| `historyBuffer` | 群历史缓冲 |\n| `envelopeFormatter` | 组装 LLM prompt 上下文（XML tags） |\n| `typingIndicator` | C2C 自动 typing |\n| `slashCommand` | /cmd 命令框架 |\n\n### 3. 文本消息\n\n```ts\nawait bot.sendText(target, \"hello\");\n```\n\n### 4. 文件 / 图片 / 语音\n\n`sendImage` / `sendVoice` / `sendVideo` / `sendFile` 是 `sendMedia` 的便捷封装。\n当源文件 ≥ 5MB 时自动走分块上传。\n\n```ts\nawait bot.sendImage(target, { localPath: \"/tmp/cat.jpg\" });\n\nawait bot.sendFile(\n  target,\n  { buffer: bigBuffer },\n  {\n    fileName: \"report.pdf\",\n    onProgress: (uploaded, total) => console.log(`${uploaded}/${total}`),\n  },\n);\n```\n\n### 5. C2C 流式消息\n\n```ts\nconst stream = bot.openStream({ target });\nfor (const partial of generator) {\n  await stream.update(partial);\n}\nawait stream.complete();\n```\n\nQQ 开放平台限制：`stream_messages` 仅在 C2C（私聊）开放。\n\n### 6. 事件监听\n\n```ts\nbot.on(\"ready\", () => console.log(\"connected\"));\nbot.on(\"resumed\", () => console.log(\"reconnected\"));\nbot.on(\"error\", (err) => console.error(err));\nbot.on(\"message\", (ctx, msg) => { /* C2C / Group / Guild / DM */ });\nbot.on(\"interaction\", (ctx, event) => { /* button click etc. */ });\n```\n\n### 7. 协议层直接访问\n\n```ts\nimport {\n  ApiClient,\n  TokenManager,\n  GatewayConnection,\n  withRetry,\n} from \"@tencent-connect/qqbot-nodejs/protocol\";\n```\n\n## 模块结构\n\n```\nsrc/\n├── QQBot.ts                ← 高层 facade\n├── streaming.ts            ← C2C 流式消息控制器\n├── index.ts                ← 公开 API\n├── middleware/              ← Koa-style 中间件\n│   ├── types.ts                  中间件类型 + 洋葱执行器\n│   ├── error-handler.ts          统一错误捕获\n│   ├── message-filter.ts         回声过滤 + 去重\n│   ├── rate-limiter.ts           三层限流\n│   ├── concurrency-guard.ts     同用户/群串行处理\n│   ├── access-policy.ts          黑白名单\n│   ├── content-sanitizer.ts      内容清洗\n│   ├── mention-gate.ts           @bot 判定\n│   ├── quote-ref.ts              引用消息解析 + 消息索引\n│   ├── history-buffer.ts         群历史缓冲\n│   ├── envelope-formatter.ts     LLM prompt 组装\n│   ├── typing-indicator.ts       typing 状态\n│   └── slash-command.ts          命令框架\n└── protocol/               ← 协议层\n    ├── api/\n    │   ├── api-client.ts         HTTP 客户端\n    │   ├── token.ts              access_token 管理\n    │   ├── messages.ts           消息发送\n    │   ├── media.ts              小文件上传\n    │   ├── media-chunked.ts      大文件分块上传\n    │   ├── retry.ts              重试引擎\n    │   └── routes.ts             路由模板\n    ├── gateway/\n    │   ├── constants.ts          opcode / intent / close code\n    │   ├── codec.ts              消息解码\n    │   ├── reconnect.ts          重连状态机\n    │   ├── event-dispatcher.ts   事件 → InboundMessage\n    │   └── gateway-connection.ts WebSocket 生命周期\n    ├── transport/\n    │   ├── types.ts              EventTransport 接口\n    │   ├── webhook.ts            Webhook 传输\n    │   ├── webhook-verify.ts     Ed25519 签名验证\n    │   └── webhook-server-node.ts  内置 node:http 适配器\n    ├── utils/\n    │   ├── format.ts             格式化工具\n    │   ├── file-utils.ts         文件工具\n    │   └── upload-cache.ts       file_info TTL 缓存\n    ├── types.ts                  全部公共类型 + 错误\n    └── index.ts                  protocol 子入口\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}