{"_id":"@wechatbot/wechatbot","_rev":"5-05791e0dcce0daaca6af8f71a20aa07b","name":"@wechatbot/wechatbot","dist-tags":{"latest":"2.2.0"},"versions":{"2.0.0":{"name":"@wechatbot/wechatbot","version":"2.0.0","license":"MIT","_id":"@wechatbot/wechatbot@2.0.0","maintainers":[{"name":"agmod","email":"jiwei@agmod.com"},{"name":"jiwei-corespeed","email":"jiwei@corespeed.io"}],"dist":{"shasum":"2d17cd2139dd3b0719f714c436902a572465a03c","tarball":"https://registry.npmjs.org/@wechatbot/wechatbot/-/wechatbot-2.0.0.tgz","fileCount":174,"integrity":"sha512-pJ7A3fz1+fhFoluNJYHQI0FLKF5vYk80hZIVoIovrei9M5oqcL5QqKqFIe7/jbDWl6pkOFgf2HlHCG4eC/o5+w==","signatures":[{"sig":"MEUCIQCakoB4vdEwfeMCcxjk81svU+IZve4M7g4eD3xR18xGaQIgBIPesxDE+hpQ3wOALk4dl7a4f6Th2VysyTZgOVP4n68=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":252210},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":"./dist/index.js","./media":"./dist/media/index.js","./storage":"./dist/storage/index.js","./middleware":"./dist/middleware/index.js"},"gitHead":"e1553d330b14142a400feaa8faf52ec37fcd6115","scripts":{"dev":"tsc --watch","lint":"tsc --noEmit","test":"node --experimental-vm-modules node_modules/.bin/vitest run","build":"tsc","test:watch":"node --experimental-vm-modules node_modules/.bin/vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"agmod","email":"jiwei@agmod.com"},"_npmVersion":"11.11.0","description":"WeChat iLink Bot SDK — modular, extensible, production-grade","directories":{},"_nodeVersion":"25.8.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.5.4","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/wechatbot_2.0.0_1774273522936_0.16269986295388295","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"@wechatbot/wechatbot","version":"2.0.1","license":"MIT","_id":"@wechatbot/wechatbot@2.0.1","maintainers":[{"name":"agmod","email":"jiwei@agmod.com"},{"name":"jiwei-corespeed","email":"jiwei@corespeed.io"}],"homepage":"https://github.com/corespeed-io/wechatbot#readme","bugs":{"url":"https://github.com/corespeed-io/wechatbot/issues"},"dist":{"shasum":"52f22b8e8a1b1f31e51be2cbde14a5e4f0e085a6","tarball":"https://registry.npmjs.org/@wechatbot/wechatbot/-/wechatbot-2.0.1.tgz","fileCount":174,"integrity":"sha512-MH/jCMEgYYTADa7jKASIrby8dtjdMVAbmosgtYgfhX49mi0Si9LIDM0ecJMg/vw0Lctrgp0t6e75y/XBKScJuQ==","signatures":[{"sig":"MEQCICLIJHkVOZOBqXO4SMfRhcMSzwUvM+qyU6i14b88CSExAiBfrKwkl6Hccn8BjnkyNnpBI+/HiuZUriPBk8WNwE0TIQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@wechatbot%2fwechatbot@2.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":252315},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":"./dist/index.js","./media":"./dist/media/index.js","./storage":"./dist/storage/index.js","./middleware":"./dist/middleware/index.js"},"gitHead":"61efdb90d6d66e524e6941649874f3db503296e1","scripts":{"dev":"tsc --watch","lint":"tsc --noEmit","test":"node --experimental-vm-modules node_modules/.bin/vitest run","build":"tsc","test:watch":"node --experimental-vm-modules node_modules/.bin/vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:6c00eec6-f9c9-483d-b465-45ce974aa5fe"}},"repository":{"url":"git+https://github.com/corespeed-io/wechatbot.git","type":"git"},"_npmVersion":"11.12.0","description":"WeChat iLink Bot SDK — modular, extensible, production-grade","directories":{},"_nodeVersion":"22.22.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.5.4","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/wechatbot_2.0.1_1774277128918_0.7716379225572618","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"@wechatbot/wechatbot","version":"2.1.0","license":"MIT","_id":"@wechatbot/wechatbot@2.1.0","maintainers":[{"name":"agmod","email":"jiwei@agmod.com"},{"name":"jiwei-corespeed","email":"jiwei@corespeed.io"}],"homepage":"https://github.com/corespeed-io/wechatbot#readme","bugs":{"url":"https://github.com/corespeed-io/wechatbot/issues"},"dist":{"shasum":"62e5840c971854f3aa6d382a0c4ae29b63080029","tarball":"https://registry.npmjs.org/@wechatbot/wechatbot/-/wechatbot-2.1.0.tgz","fileCount":174,"integrity":"sha512-tO0C3XAVcmQuHyfwYEDdY7Cm1bB3y6hWwem3BImbwuMrReSI/RAHnyOJaBUzKmcfb/qyUTxSaV5uWiPTu/yavw==","signatures":[{"sig":"MEYCIQDDjyeO/vjAWgcXHCCZEecMDzNeWZYkaqr7+zdLNNdbwwIhAKunKDrT3+Rp07XPo+cvYiF5Bjvjsxala5TPTrxBPwKa","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@wechatbot%2fwechatbot@2.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":262097},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":"./dist/index.js","./media":"./dist/media/index.js","./storage":"./dist/storage/index.js","./middleware":"./dist/middleware/index.js"},"gitHead":"396c40e9e10211923f25c0f9700cb246f292f5d1","scripts":{"dev":"tsc --watch","lint":"tsc --noEmit","test":"node --experimental-vm-modules node_modules/.bin/vitest run","build":"tsc","test:watch":"node --experimental-vm-modules node_modules/.bin/vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:6c00eec6-f9c9-483d-b465-45ce974aa5fe"}},"repository":{"url":"git+https://github.com/corespeed-io/wechatbot.git","type":"git"},"_npmVersion":"11.11.0","description":"WeChat iLink Bot SDK — modular, extensible, production-grade","directories":{},"_nodeVersion":"24.14.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.5.4","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/wechatbot_2.1.0_1775524160500_0.5342592120443976","host":"s3://npm-registry-packages-npm-production"}},"2.1.1":{"name":"@wechatbot/wechatbot","version":"2.1.1","license":"MIT","_id":"@wechatbot/wechatbot@2.1.1","maintainers":[{"name":"agmod","email":"jiwei@agmod.com"},{"name":"jiwei-corespeed","email":"jiwei@corespeed.io"}],"homepage":"https://github.com/corespeed-io/wechatbot#readme","bugs":{"url":"https://github.com/corespeed-io/wechatbot/issues"},"dist":{"shasum":"085d87c6755db50c10f16749de2606a48b64b810","tarball":"https://registry.npmjs.org/@wechatbot/wechatbot/-/wechatbot-2.1.1.tgz","fileCount":174,"integrity":"sha512-94H1HrfksPB46HZdnQ2Ifebaz8eg6cy8SCIr1siFa0HsyPT9S+Hf6e3jAFtpC9ky9TF0JIXAv4rlcABmgvZhrA==","signatures":[{"sig":"MEYCIQDvFR/nwtt12PWNFydPjZfmvdI1uvtaILkA3HkDLpbmpgIhALT5+5IRVn8ywuGHWB103r3V4MyV25eT1bICyEs7F9yM","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@wechatbot%2fwechatbot@2.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":262316},"type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":"./dist/index.js","./media":"./dist/media/index.js","./storage":"./dist/storage/index.js","./middleware":"./dist/middleware/index.js"},"gitHead":"c081868c905d24f10e30fc6deef7b23ba1b18389","scripts":{"dev":"tsc --watch","lint":"tsc --noEmit","test":"node --experimental-vm-modules node_modules/.bin/vitest run","build":"tsc","test:watch":"node --experimental-vm-modules node_modules/.bin/vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:6c00eec6-f9c9-483d-b465-45ce974aa5fe"}},"repository":{"url":"git+https://github.com/corespeed-io/wechatbot.git","type":"git"},"_npmVersion":"11.11.0","description":"WeChat iLink Bot SDK — modular, extensible, production-grade","directories":{},"_nodeVersion":"24.14.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.5.4","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/wechatbot_2.1.1_1776439268359_0.833583663685276","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@wechatbot/wechatbot","version":"2.2.0","description":"WeChat iLink Bot SDK — modular, extensible, production-grade","type":"module","exports":{".":"./dist/index.js","./media":"./dist/media/index.js","./middleware":"./dist/middleware/index.js","./storage":"./dist/storage/index.js"},"types":"./dist/index.d.ts","engines":{"node":">=22"},"scripts":{"build":"tsc","dev":"tsc --watch","test":"node --experimental-vm-modules node_modules/.bin/vitest run","test:watch":"node --experimental-vm-modules node_modules/.bin/vitest","lint":"tsc --noEmit","prepublishOnly":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/corespeed-io/wechatbot.git"},"license":"MIT","devDependencies":{"@types/node":"^22.0.0","typescript":"^5.5.4","vitest":"^3.0.0"},"gitHead":"a632b633f5658c7054546ee3209e359f05e3c934","_id":"@wechatbot/wechatbot@2.2.0","bugs":{"url":"https://github.com/corespeed-io/wechatbot/issues"},"homepage":"https://github.com/corespeed-io/wechatbot#readme","_nodeVersion":"24.17.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-M3+RbTrwr5pW2GQC8RwGWh2JTZkSUHJFIjgs6R4UlBb4IaTOoTu6CmEW3G7MEGwU0ScswXCAN/iYfk1w4/UYeg==","shasum":"7a8889893a9478ec2fe54a8f7c92fde3a300aee3","tarball":"https://registry.npmjs.org/@wechatbot/wechatbot/-/wechatbot-2.2.0.tgz","fileCount":178,"unpackedSize":275782,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@wechatbot%2fwechatbot@2.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGkLtoM7aGLCecuOZR4uyZ1joeESbta5xZVZhnwKTNa2AiAphHNr6JNha+JPlGtfylTQWhOjDFXMo00i/6mkzoalVQ=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:6c00eec6-f9c9-483d-b465-45ce974aa5fe"}},"directories":{},"maintainers":[{"name":"agmod","email":"jiwei@agmod.com"},{"name":"jiwei-corespeed","email":"jiwei@corespeed.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/wechatbot_2.2.0_1782947514252_0.23341559513364962"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-23T13:45:22.854Z","modified":"2026-07-01T23:11:54.726Z","2.0.0":"2026-03-23T13:45:23.089Z","2.0.1":"2026-03-23T14:45:29.072Z","2.1.0":"2026-04-07T01:09:20.634Z","2.1.1":"2026-04-17T15:21:08.528Z","2.2.0":"2026-07-01T23:11:54.391Z"},"bugs":{"url":"https://github.com/corespeed-io/wechatbot/issues"},"license":"MIT","homepage":"https://github.com/corespeed-io/wechatbot#readme","repository":{"type":"git","url":"git+https://github.com/corespeed-io/wechatbot.git"},"description":"WeChat iLink Bot SDK — modular, extensible, production-grade","maintainers":[{"name":"agmod","email":"jiwei@agmod.com"},{"name":"jiwei-corespeed","email":"jiwei@corespeed.io"}],"readme":"# @wechatbot/wechatbot — Node.js SDK\n\nWeChat iLink Bot SDK for Node.js — modular, extensible, production-grade.\n\n## Install\n\n```bash\nnpm install @wechatbot/wechatbot\n```\n\nRequires Node.js >= 22 (for native fetch). Zero runtime dependencies.\n\n## Quick Start\n\n```typescript\nimport { WeChatBot } from '@wechatbot/wechatbot'\n\nconst bot = new WeChatBot()\nawait bot.login()\n\nbot.onMessage(async (msg) => {\n  await bot.sendTyping(msg.userId)\n  await bot.reply(msg, `Echo: ${msg.text}`)\n})\n\nawait bot.start()\n```\n\n## Architecture\n\n```\nsrc/\n├── core/           ← WeChatBot client, typed events, error hierarchy\n├── transport/      ← HTTP client with retry & timeout\n├── protocol/       ← Raw iLink API calls + wire types\n├── auth/           ← QR login + credential persistence\n├── messaging/      ← Poller, Sender, Typing, ContextStore\n├── media/          ← AES-128-ECB crypto, CDN upload/download\n├── middleware/      ← Express-style middleware engine + builtins\n├── message/        ← Parser, Builder, friendly types\n├── storage/        ← Pluggable storage (file, memory, custom)\n├── logger/         ← Structured leveled logging\n└── index.ts        ← Public exports\n```\n\n## Configuration\n\n```typescript\nconst bot = new WeChatBot({\n  storage: 'file',            // 'file' | 'memory' | custom Storage\n  storageDir: '~/.wechatbot',\n  logLevel: 'info',           // 'debug' | 'info' | 'warn' | 'error' | 'silent'\n  loginCallbacks: {\n    onQrUrl: (url) => renderQrCode(url),\n    onScanned: () => console.log('Scanned!'),\n  },\n})\n```\n\n## API Reference\n\n### Lifecycle\n\n| Method | Description |\n|---|---|\n| `new WeChatBot(options?)` | Create a bot instance |\n| `bot.login(options?)` | QR login (auto-skips if credentials exist) |\n| `bot.start()` | Start long-poll loop |\n| `bot.run(options?)` | login() + start() in one call |\n| `bot.stop()` | Stop gracefully |\n| `bot.isRunning` | Whether the poll loop is active |\n\n### Receiving\n\n| Method | Description |\n|---|---|\n| `bot.onMessage(handler)` | Register message handler |\n| `bot.download(msg)` | Download any media from a message (image/file/video/voice) |\n\n### Sending — `reply(msg, content)` / `send(userId, content)`\n\nBoth methods accept the same content types:\n\n```typescript\n// Text (string shorthand)\nawait bot.reply(msg, 'Hello!')\n\n// Text (object)\nawait bot.reply(msg, { text: 'Hello!' })\n\n// Image with optional caption\nawait bot.reply(msg, { image: pngBuffer, caption: 'Screenshot' })\n\n// Video with optional caption\nawait bot.reply(msg, { video: mp4Buffer, caption: 'Check this out' })\n\n// File — auto-routes by extension (.png → image, .mp4 → video, else → file)\nawait bot.reply(msg, { file: data, fileName: 'report.pdf' })\nawait bot.reply(msg, { file: data, fileName: 'photo.png' })   // → sent as image\n\n// From URL — auto-download + auto-detect type\nawait bot.reply(msg, { url: 'https://example.com/photo.jpg' })\n\n// Send to a user by ID (same content options)\nawait bot.send(userId, { image: buffer, caption: 'Hi!' })\n```\n\n### Typing\n\n| Method | Description |\n|---|---|\n| `bot.sendTyping(userId)` | Show \"typing...\" indicator |\n| `bot.stopTyping(userId)` | Cancel typing indicator |\n\n### Advanced\n\n| Method | Description |\n|---|---|\n| `bot.sendRaw(payload)` | Send pre-built MessageBuilder payload |\n| `bot.upload(options)` | Upload to CDN without sending |\n| `bot.downloadRaw(media, aeskey?)` | Download from raw CDN reference |\n| `bot.createMessage(userId)` | Fluent MessageBuilder |\n\n### Middleware\n\n```typescript\nbot.use(loggingMiddleware(bot.logger))\nbot.use(rateLimitMiddleware({ maxMessages: 10, windowMs: 60_000 }))\nbot.use(typeFilterMiddleware('text', 'image'))\nbot.use(filterMiddleware(/^\\/\\w+/))\n\n// Custom middleware\nbot.use(async (ctx, next) => {\n  console.log(`From: ${ctx.message.userId}`)\n  await next()\n})\n```\n\n### Events\n\n```typescript\nbot.on('login', (creds) => { })\nbot.on('message', (msg) => { })\nbot.on('session:expired', () => { })\nbot.on('session:restored', (creds) => { })\nbot.on('error', (err) => { })\nbot.on('poll:start', () => { })\nbot.on('poll:stop', () => { })\nbot.on('close', () => { })\n```\n\n### Message Types\n\n```typescript\ninterface IncomingMessage {\n  userId: string\n  text: string\n  type: 'text' | 'image' | 'voice' | 'file' | 'video'\n  timestamp: Date\n  images: ImageContent[]\n  voices: VoiceContent[]\n  files: FileContent[]\n  videos: VideoContent[]\n  quotedMessage?: QuotedMessage\n  raw: WireMessage\n}\n```\n\n### Storage Interface\n\n```typescript\ninterface Storage {\n  get<T>(key: string): Promise<T | undefined>\n  set<T>(key: string, value: T): Promise<void>\n  delete(key: string): Promise<void>\n  has(key: string): Promise<boolean>\n  clear(): Promise<void>\n}\n```\n\n## Development\n\n```bash\nnpm install\nnpm run build    # TypeScript → dist/\nnpm test         # 69 unit tests\nnpm run lint     # Type check\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}