Skip to content

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

8 stars

Watchers

1 watching

Forks

Repository files navigation

@tencent-connect/qqbot-nodejs

English (this file) · 简体中文

npm version CI License: MIT Node.js Version

Tencent QQ Open Platform Node.js SDK. Provides every protocol-layer capability needed to integrate with the QQ Bot Open Platform: HTTP REST, dual WebSocket / Webhook transport, a Koa-style middleware pipeline, messaging, media upload (including chunked upload for large files), and C2C streaming messages (stream_messages).

Requirements

  • Node.js >= 20 (uses global fetch / AbortController)
  • Pure ESM ("type": "module"); CJS consumers should use dynamic import()

Install

pnpm add @tencent-connect/qqbot-nodejs
# or
npm install @tencent-connect/qqbot-nodejs

Quick Start

import { QQBot } from "@tencent-connect/qqbot-nodejs";

const bot = new QQBot({
  appId: process.env.QQBOT_APP_ID!,
  appSecret: process.env.QQBOT_APP_SECRET!,
  logger: console,
});

bot.on("message", async (ctx, msg) => {
  // ctx — Koa-style MiddlewareContext carrying data injected by middleware
  await bot.sendText(msg.replyTarget, `Echo: ${msg.content}`);
});

await bot.start();

See the complete examples under examples/:

Example Description
playground Core capabilities demo (text, streaming, media, commands)
middleware Full 13-layer Koa-style middleware pipeline
webhook Webhook (HTTP callback) transport
send-plain-100 Plain-text send baseline
send-streaming-100 Streaming-message send baseline

Examples read QQBOT_APP_ID / QQBOT_APP_SECRET from process.env only for demo convenience. The SDK itself never reads environment variables — credentials are always injected via new QQBot({ appId, appSecret }).

Features

1. Dual transport (WebSocket / Webhook)

// WebSocket (default) — long-lived connection + heartbeat + RESUME
const bot = new QQBot({ appId, appSecret });

// Webhook — HTTP callback, suited to Serverless / horizontal scaling
const bot = new QQBot({
  appId, appSecret,
  transport: "webhook",
  webhook: { port: 8080, path: "/callback" },
});

Middleware, event listeners and send APIs are identical in both modes.

2. Koa-style middleware

The SDK uses an onion-model middleware chain; bot.on("message") is the innermost downstream:

import { errorHandler, messageFilter, contentSanitizer, mentionGate } from "@tencent-connect/qqbot-nodejs";

bot.use(errorHandler());
bot.use(messageFilter({ skipSelfEcho: true, dedup: { windowMs: 5000 } }));
bot.use(contentSanitizer({ stripBotMention: true }));
bot.use(mentionGate({ requireMentionInGroup: true }));

// Custom middleware
bot.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  ctx.log.debug?.(`elapsed: ${Date.now() - start}ms`);
});

Built-in middleware:

Middleware Purpose
errorHandler Unified error capture + friendly reply
messageFilter Bot echo filtering + message dedup
rateLimiter Three-tier rate limiting (sender / group / global)
concurrencyGuard Serial processing per user / group (avoids stream races)
accessPolicy Allow / block lists
contentSanitizer Strip @markers / face tags / whitespace
mentionGate Group @bot gating
quoteRef Message index recording + quoted-message resolution
historyBuffer Group history buffer
envelopeFormatter Assemble LLM prompt context (XML tags)
typingIndicator Automatic C2C typing
slashCommand /cmd command framework

3. Text messages

await bot.sendText(target, "hello");

4. Files / images / voice

sendImage / sendVoice / sendVideo / sendFile are convenience wrappers over sendMedia. Sources ≥ 5 MB switch to chunked upload automatically.

await bot.sendImage(target, { localPath: "/tmp/cat.jpg" });

await bot.sendFile(
  target,
  { buffer: bigBuffer },
  {
    fileName: "report.pdf",
    onProgress: (uploaded, total) => console.log(`${uploaded}/${total}`),
  },
);

5. C2C streaming messages

const stream = bot.openStream({ target });
for (const partial of generator) {
  await stream.update(partial);
}
await stream.complete();

QQ Open Platform constraint: stream_messages is available for C2C (private chat) only.

6. Events

bot.on("ready", () => console.log("connected"));
bot.on("resumed", () => console.log("reconnected"));
bot.on("disconnected", ({ code, willReconnect }) => console.log("closed", code, willReconnect));
bot.on("error", (err) => console.error(err)); // recoverable failures; never ends start()
bot.on("message", (ctx, msg) => { /* C2C / Group / Guild / DM */ });
bot.on("interaction", (ctx, event) => { /* button click etc. */ });

7. Lifecycle

WebSocket mode reconnects forever by default. start() resolves on stop() / abort, and rejects — after releasing the connection and token refresher — only when it cannot recover:

Rejection Cause Handling
GatewayError GATEWAY_FATAL_CLOSE 4914 offline / sandbox-only, 4915 banned Needs operator action; don't restart
GatewayError GATEWAY_RETRY_EXHAUSTED Only with a finite reconnect.maxAttempts Restart with backoff
Error Startup token fetch failed (default tokenPrefetch: "sync") Check credentials / network
import { GatewayErrorCode, QQBot } from "@tencent-connect/qqbot-nodejs";

// Set a limit only when an outer supervisor owns process-level restarts
const bot = new QQBot({ appId, appSecret, reconnect: { maxAttempts: 10 } });
try {
  await bot.start(signal);
} catch (err) {
  if ((err as { code?: string }).code === GatewayErrorCode.FATAL_CLOSE) markBlocked(err);
  else scheduleRestart(err);
}

bot.stop(); bot.start(); restarts in place. See USAGE.md §7 for close-code handling.

8. Protocol-level access

import {
  ApiClient,
  TokenManager,
  GatewayConnection,
  withRetry,
} from "@tencent-connect/qqbot-nodejs/protocol";

Documentation

  • USAGE.md — complete usage guide (currently in Chinese; contributions to translate are very welcome).

Optional dependencies

These peerDependencies are declared as optional. Install them only if you need the feature:

Package Enables
silk-wasm Sending voice messages (SILK encoding)
mpg123-decoder Decoding MP3 audio to PCM before encoding

Contributing

Bug reports, feature proposals and pull requests are welcome. Please read:

Module structure

src/
├── QQBot.ts                ← High-level facade
├── streaming.ts            ← C2C streaming-message controller
├── index.ts                ← Public API
├── middleware/              ← Koa-style middleware
│   ├── types.ts                  Middleware types + onion runner
│   ├── error-handler.ts          Unified error capture
│   ├── message-filter.ts         Echo filtering + dedup
│   ├── rate-limiter.ts           Three-tier rate limiting
│   ├── concurrency-guard.ts     Serial processing per user / group
│   ├── access-policy.ts          Allow / block lists
│   ├── content-sanitizer.ts      Content sanitizing
│   ├── mention-gate.ts           @bot gating
│   ├── quote-ref.ts              Quote resolution + message index
│   ├── history-buffer.ts         Group history buffer
│   ├── envelope-formatter.ts     LLM prompt assembly
│   ├── typing-indicator.ts       Typing state
│   └── slash-command.ts          Command framework
└── protocol/               ← Protocol layer
    ├── api/
    │   ├── api-client.ts         HTTP client
    │   ├── token.ts              access_token management
    │   ├── messages.ts           Message sending
    │   ├── media.ts              Small-file upload
    │   ├── media-chunked.ts      Chunked large-file upload
    │   ├── retry.ts              Retry engine
    │   └── routes.ts             Route templates
    ├── gateway/
    │   ├── constants.ts          opcode / intent / close code
    │   ├── codec.ts              Message decoding
    │   ├── reconnect.ts          Reconnect state machine + reconnect policy
    │   ├── errors.ts             GatewayError (terminal start() errors)
    │   ├── event-dispatcher.ts   Event → InboundMessage
    │   └── gateway-connection.ts WebSocket lifecycle
    ├── transport/
    │   ├── types.ts              EventTransport interface
    │   ├── webhook.ts            Webhook transport
    │   ├── webhook-verify.ts     Ed25519 signature verification
    │   └── webhook-server-node.ts  Built-in node:http adapter
    ├── utils/
    │   ├── format.ts             Formatting helpers
    │   ├── file-utils.ts         File helpers
    │   └── upload-cache.ts       file_info TTL cache
    ├── types.ts                  All public types + errors
    └── index.ts                  protocol sub-entry

Contributors

Thanks to everyone who has contributed to this project!

Contributors

Contributor avatars are rendered by contrib.rocks.

License

MIT © Tencent

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

8 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages