npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@openclaw-china/wechat-mp

v2026.3.22

Published

OpenClaw WeChat Official Account (微信公众号) channel plugin

Downloads

1,446

Readme

@openclaw-china/wechat-mp

wechat-mp 是一个独立的微信公众号(订阅号 / 服务号)渠道插件,用于把公众号消息接入 OpenClaw。

功能特性

入站消息

| 消息类型 | 支持状态 | 说明 | |---------|---------|------| | 文本消息 | ✅ | 完整支持,自动处理超长分割 | | 图片消息 | ✅ | 返回图片 URL 和 MediaId | | 语音消息 | ✅ | 支持 ASR 自动转文字 | | 视频消息 | ✅ | 返回视频 MediaId | | 短视频消息 | ✅ | 返回短视频 MediaId | | 位置消息 | ✅ | 返回经纬度和地址 | | 链接消息 | ✅ | 返回标题、描述和 URL | | 事件消息 | ✅ | subscribe/unsubscribe/scan/click/view |

主动发送

| 发送类型 | 支持状态 | 说明 | |---------|---------|------| | 文本消息 | ✅ | 支持超长自动分割 | | 模板消息 | ✅ | 业务通知消息 | | 图片消息 | ✅ | 自动上传并发送 | | 语音消息 | ✅ | 自动上传并发送 | | 视频消息 | ✅ | 自动上传并发送 |

高级功能

  • 语音转文字 (ASR): 集成腾讯云语音识别,自动将语音转为文字
  • 重试机制: 支持指数退避重试,处理网络波动和限流
  • 时间窗口检查: 48小时交互窗口检测,发送前权限验证
  • Markdown 渲染: 自动转换为公众号友好的纯文本格式

配置示例

基础配置

{
  "channels": {
    "wechat-mp": {
      "enabled": true,
      "webhookPath": "/wechat-mp",
      "appId": "wx1234567890abcdef",
      "appSecret": "your-app-secret",
      "token": "your-callback-token",
      "encodingAESKey": "your-43-char-encoding-aes-key",
      "messageMode": "safe",
      "replyMode": "active",
      "activeDeliveryMode": "split",
      "renderMarkdown": true,
      "welcomeText": "你好,欢迎关注。"
    }
  }
}

完整配置(含 ASR)

{
  "channels": {
    "wechat-mp": {
      "enabled": true,
      "webhookPath": "/wechat-mp",
      "appId": "wx1234567890abcdef",
      "appSecret": "your-app-secret",
      "token": "your-callback-token",
      "encodingAESKey": "your-43-char-encoding-aes-key",
      "messageMode": "safe",
      "replyMode": "active",
      "activeDeliveryMode": "split",
      "renderMarkdown": true,
      "welcomeText": "你好,欢迎关注。",
      "dmPolicy": "open",
      "allowFrom": [],
      "retryConfig": {
        "maxRetries": 3,
        "initialDelay": 1000,
        "maxDelay": 10000,
        "backoffMultiplier": 2
      },
      "asr": {
        "enabled": true,
        "appId": "腾讯云 AppId",
        "secretId": "腾讯云 SecretId",
        "secretKey": "腾讯云 SecretKey",
        "engineType": "16k_zh",
        "timeoutMs": 30000
      }
    }
  }
}

多账号配置

{
  "channels": {
    "wechat-mp": {
      "defaultAccount": "main",
      "accounts": {
        "main": {
          "appId": "wx-main-account",
          "appSecret": "main-secret",
          "token": "main-token"
        },
        "sub": {
          "appId": "wx-sub-account",
          "appSecret": "sub-secret",
          "token": "sub-token"
        }
      }
    }
  }
}

配置字段说明

基础配置

| 字段 | 类型 | 必填 | 说明 | |-----|------|-----|------| | enabled | boolean | 否 | 是否启用,默认 true | | webhookPath | string | 否 | 回调路径,默认 /wechat-mp | | appId | string | 是 | 公众号 AppId | | appSecret | string | 条件 | 主动发送必填 | | token | string | 是 | 回调 Token | | encodingAESKey | string | 条件 | safe/compat 模式必填 | | messageMode | string | 否 | 消息模式:plain / safe / compat | | replyMode | string | 否 | 回复模式:passive / active | | activeDeliveryMode | string | 否 | 主动发送模式:split / merged | | renderMarkdown | boolean | 否 | 是否渲染 Markdown,默认 true | | welcomeText | string | 否 | 关注欢迎语 | | dmPolicy | string | 否 | DM 策略:open / pairing / allowlist / disabled | | allowFrom | string[] | 否 | 允许的用户列表 |

重试配置 (retryConfig)

| 字段 | 类型 | 默认值 | 说明 | |-----|------|-------|------| | maxRetries | number | 3 | 最大重试次数 | | initialDelay | number | 1000 | 初始延迟(毫秒) | | maxDelay | number | 10000 | 最大延迟(毫秒) | | backoffMultiplier | number | 2 | 退避乘数 |

ASR 配置 (asr)

| 字段 | 类型 | 必填 | 说明 | |-----|------|-----|------| | enabled | boolean | 否 | 是否启用 ASR | | appId | string | 是 | 腾讯云 AppId | | secretId | string | 是 | 腾讯云 SecretId | | secretKey | string | 是 | 腾讯云 SecretKey | | engineType | string | 否 | 引擎类型,默认 16k_zh | | timeoutMs | number | 否 | 超时时间,默认 30000 |

API 使用示例

发送文本

import { wechatMpOutbound } from "@openclaw-china/wechat-mp";

// 发送文本
await wechatMpOutbound.sendText({
  cfg,
  to: "user:openid123",
  text: "Hello, World!"
});

发送模板消息

await wechatMpOutbound.sendTemplate({
  cfg,
  to: "user:openid123",
  templateId: "template_id_here",
  data: {
    first: { value: "您好,您有新的通知" },
    keyword1: { value: "订单号:123456" },
    keyword2: { value: "已发货" },
    remark: { value: "点击查看详情" }
  },
  url: "https://example.com/order/123456"
});

发送媒体消息

import { readFileSync } from "fs";

// 发送图片
await wechatMpOutbound.sendMedia({
  cfg,
  to: "user:openid123",
  mediaType: "image",
  buffer: readFileSync("./image.jpg"),
  filename: "image.jpg"
});

// 发送语音
await wechatMpOutbound.sendMedia({
  cfg,
  to: "user:openid123",
  mediaType: "voice",
  buffer: readFileSync("./voice.amr"),
  filename: "voice.amr"
});

// 发送视频
await wechatMpOutbound.sendMedia({
  cfg,
  to: "user:openid123",
  mediaType: "video",
  buffer: readFileSync("./video.mp4"),
  filename: "video.mp4"
});

检查发送能力

// 检查用户是否在 48 小时交互窗口内
const capability = await wechatMpOutbound.checkCapability({
  cfg,
  to: "user:openid123"
});

if (!capability.canSend) {
  console.log(`无法发送:${capability.reason}`);
}

// 检查时间窗口
const inWindow = wechatMpOutbound.checkTimeWindow({
  config: { mode: "business" } // 工作时间 9:00-18:00
});

记录用户交互

// 在处理入站消息时调用,用于 48 小时窗口跟踪
await wechatMpOutbound.recordInteraction({
  cfg,
  openId: "openid123"
});

联调要点

  1. 回调配置:公众号后台服务器地址指向网关回调地址
  2. 消息模式
    • plain:明文模式,最小链路验证
    • safe:加密模式,需要 encodingAESKey
    • compat:兼容模式,同时支持明文和加密
  3. 主动发送:必须配置 appSecret
  4. 回复模式
    • passive:5 秒内 HTTP 回包
    • active:使用客服消息 API 主动发送
  5. 消息长度:2048 字节限制,超长自动分割
  6. 语音识别
    • 方法一:公众号后台开启"语音识别"功能
    • 方法二:配置 asr 使用腾讯云 ASR

开发测试

# 构建
pnpm -F @openclaw-china/wechat-mp build

# 测试
pnpm -F @openclaw-china/wechat-mp test

# 类型检查
pnpm -F @openclaw-china/wechat-mp typecheck

文档入口

  • 开发计划:doc/guides/wechat-mp/doc/开发计划.md
  • 配置指南:doc/guides/wechat-mp/configuration.md
  • 微信官方文档:doc/guides/wechat-mp/doc/mp接口文档/