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

@partme.ai/openclaw-douyin

v2026.7.1

Published

OpenClaw 抖音开放平台渠道与运营工具 — 公域 Agent-First 智能运营

Readme

抖音生活服务插件

@partme.ai/openclaw-douyin 对接抖音生活服务商家应用,提供 Webhook 事件入站和经过官方 client_token 鉴权的运营工具。

能力边界

  • Webhook:校验 X-Douyin-Signature = SHA1(app_secret + rawBody) 和 client_key;事件必须先进入账号隔离的持久 Inbox,原子落盘成功后才返回 200。
  • 回调验证:对签名有效的 verify_webhook 返回 {"challenge": ...} JSON。
  • 事件处理:兼容 object 和 JSON 字符串两种 content;后台派发失败采用有限指数退避,Gateway 重启会恢复未完成事件,耗尽后进入有界 DLQ。
  • 访问控制:自定义 Webhook 在 Transcript 前显式执行 dmPolicy、allowFrom、pairing store 和 OpenClaw 命令授权;签名有效不等于发送者有权触发 Agent。
  • OpenAPI:client_token 使用最多 256 项的 LRU + single-flight 缓存;Token 失效时刷新一次;查询类请求支持有限重试;所有凭据请求禁止自动重定向。
  • 工具:实现官方订单查询、餐饮评价回复接口。
  • 多账号:支持顶层账号及 accounts.<id> 覆盖。

生活服务 Webhook 不是私信协议,不提供对称消息发送 API。因此通用 sendText 会明确失败,不会返回虚假消息 ID。Agent 若要执行业务动作,应调用对应 OpenAPI 工具。

运行架构

抖音生活服务平台
        │ 签名 Webhook                         ▲ 官方 OpenAPI
        ▼                                      │
原始报文验签 / client_key                         │
        │                                      │
        ▼                                      │
账号级持久 Inbox(0600 / 原子写 / 容量限制)      │
        │ 落盘成功后 200                        │
        ▼                                      │
DM 与命令策略 ──▶ Msg-Id 去重 ──▶ OpenClaw Agent
        │失败                                     │
        └──▶ 指数退避 ──▶ DLQ ──▶ 管理员重放      │
                                              │
                                              ▼
                          订单查询 / 评价回复 Tool ──▶ Token 缓存
flowchart LR
    Platform["抖音生活服务平台"]
    Webhook["Webhook 路由<br/>原始报文签名 + client_key"]
    Inbox[("账号级持久 Inbox<br/>原子写 + 容量限制")]
    Ack["持久提交后确认接收"]
    Dispatch["后台 Transcript Dispatch"]
    Policy{"DM / 命令访问策略"}
    Agent["OpenClaw Agent"]
    Retry["有限指数退避"]
    DLQ[("有界 DLQ<br/>管理员重放")]
    Tools["订单查询 / 评价回复工具"]
    Token["client_token single-flight 缓存"]
    Api["官方生活服务 OpenAPI"]

    Platform -->|"事件回调"| Webhook --> Inbox --> Ack
    Inbox --> Dispatch --> Policy --> Dedupe[("按账号持久 Msg-Id 去重")] --> Agent
    Dispatch -->|"失败 / 超时"| Retry --> Dispatch
    Retry -->|"耗尽"| DLQ -->|"显式重放"| Inbox
    Agent --> Tools --> Token --> Api
    Api -->|"业务响应"| Tools

Webhook 入站与 OpenAPI 业务动作是两条不同链路:前者先持久接管、再异步派发,后者按接口幂等属性决定是否允许重试。Inbox 文件位于 OpenClaw state 目录,目录权限 0700、文件权限 0600;消息成功或被策略终止后会从 Inbox 删除。

这里的“派发失败”特指 OpenClaw 消息管道返回 error、timed_out、skipped,或插件在调用管道前后抛出异常。若 OpenClaw 已把一次 Agent Turn(包括内部模型错误处理)归类为 completed,插件没有可靠协议判断它是否应再次执行,Inbox 会按终态删除,避免把可能已经产生副作用的任务盲目重放。

Webhook 确认与去重时序

sequenceDiagram
    autonumber
    participant D as 抖音平台
    participant H as Webhook Handler
    participant I as 持久 Inbox
    participant P as DM/命令策略
    participant Q as 持久去重器
    participant A as OpenClaw Agent

    D->>H: POST rawBody + Msg-Id + Signature
    H->>H: 字节上限、SHA1、client_key、JSON 校验
    alt 校验失败
        H-->>D: 4xx,不进入 Agent
    else 校验通过
        H->>I: 原子写入 Msg-Id + 原始事件
        alt 磁盘/容量失败
            I-->>H: 未接管
            H-->>D: 503,请平台重投
        else 持久提交成功
            H-->>D: 200 success(不等待 Agent)
            I->>P: 后台 dmPolicy + allowFrom + pairing + command auth
        alt 未授权
                P-->>I: blocked,删除 Inbox 条目
        else 已授权
                I->>Q: claim(accountId, Msg-Id)
            alt 已提交或正在处理
                    Q-->>I: duplicate,删除 Inbox 条目
            else 认领成功
                    I->>A: Transcript Dispatch
                alt Agent 完成
                        A-->>I: 完成
                        I->>Q: commit,24 小时防重放
                        I->>I: 删除 Inbox 条目
                else 失败或超时
                        A-->>I: error / timeout
                        I->>Q: release
                        I->>I: 指数退避;耗尽后进入 DLQ
                    end
                end
            end
        end
        end
    end

OpenAPI 重试边界

flowchart TD
    CALL["Tool 发起 OpenAPI"] --> TOKEN["single-flight client_token"] --> API["抖音生活服务 API"]
    API --> RESULT{"响应结果"}
    RESULT -->|"成功"| RETURN["返回 data / extra"]
    RESULT -->|"token 无效或过期"| REFRESH["仅清当前账号缓存"] --> API
    RESULT -->|"查询请求 + 429/5xx/瞬时业务码"| RETRY["有限指数退避,最多 3 次"] --> API
    RESULT -->|"写请求结果不确定或参数/权限错误"| FAIL["直接失败,不盲目重放"]

配置

{
  "channels": {
    "douyin": {
      "enabled": true,
      "app_key": "your_client_key",
      "app_secret": "your_client_secret",
      "account_id": "your_life_account_id",
      "poi_id": "your_poi_id",
      "webhook_path": "/channels/douyin/webhook",
      "callback_url": "https://example.com/channels/douyin/webhook",
      "request_timeout_ms": 10000,
      "webhookDelivery": {
        "maxPending": 1000,
        "maxAttempts": 5,
        "initialDelayMs": 1000,
        "maxDelayMs": 60000,
        "maxDeadLetters": 100,
        "maxStateBytes": 33554432
      },
      "dmPolicy": "open"
    }
  }
}

dmPolicy 的语义:

  • open:允许所有已通过平台验签的发送者;若消息是 OpenClaw 命令,仍计算命令授权。
  • allowlist:仅允许 allowFrom 或已批准 pairing store 中的发送者。
  • pairing:未知发送者只创建 OpenClaw pairing 请求,本次事件不进入 Agent。生活服务 Webhook 没有通用被动回复能力,插件不会把配对码泄露到 HTTP 响应或日志;管理员通过 OpenClaw pairing 命令查看并批准。
  • disabled:所有入站事件在 Agent 前被拒绝,但仍对已验签平台请求快速 ACK,防止无意义重投。

Inbox 运维

GET  /douyin/status
        │ 查看各账号 pending / DLQ / 最老积压 / 最近错误
        ▼
确认故障已经修复
        │
        ▼
POST /douyin/replay-dead-letters?account=default&limit=100
        │
        ▼
DLQ ──原子迁回──▶ Pending Inbox ──▶ 后台重新派发

两个端点都要求 OpenClaw Gateway 管理员认证,不返回消息正文、用户 ID 或凭据。maxStateBytes 同时约束 pending 与 DLQ 的完整持久文件,避免大报文乘以积压数量耗尽磁盘;容量或持久化失败时 Webhook 返回 503。

account_id 是抖音来客商户根账户 ID;poi_id 是评价回复等接口需要的门店 ID。旧字段 shop_id 仅作为 account_id 的兼容回退,新配置不应继续使用。

多账号示例:

{
  "channels": {
    "douyin": {
      "accounts": {
        "shop-a": {
          "enabled": true,
          "app_key": "client_key_a",
          "app_secret": "client_secret_a",
          "account_id": "account_a",
          "poi_id": "poi_a",
          "webhook_path": "/channels/douyin/webhook-shop-a"
        }
      }
    }
  }
}

命名账号未显式配置 webhook_path 时,会从顶层路径派生独立地址,例如 shop-a 对应 /channels/douyin/webhook/shop-a。不同账号不能共用同一回调路径;重复路由会直接启动失败,不会静默覆盖其他账号。

OpenAPI 工具

douyin_query_orders

调用 GET https://open.douyin.com/goodlife/v1/trade/order/query/。

主要参数:account、account_id、page_num、page_size、cursor、order_id、ext_order_id、open_id、order_status、创单/修改时间范围。

要求应用具备 life.capacity.order.query 权限。page_size 为 1–100,普通分页窗口不能超过 10000 条,超出后应使用 cursor。

douyin_reply_review

调用 POST https://open.douyin.com/goodlife/v1/akte/comment/reply/。

参数:account、account_id、poi_id、rate_id、text。要求应用具备 life.capacity.catering.comment 和评价回复权限。

Webhook 配置

抖音生活服务 Webhook 只接受 HTTPS 回调。将平台回调地址设置为:

https://<公开域名>/channels/douyin/webhook

生产环境需保证反向代理完整保留原始请求体、Msg-Id 和 X-Douyin-Signature,不能重新序列化 JSON 后再转发。

验证

pnpm --dir extensions/douyin typecheck
pnpm --dir extensions/douyin test
pnpm --dir extensions/douyin build
OPENCLAW_E2E_HOST_GATEWAY=1 pnpm test:e2e -- --plugins douyin --skip-browser

独立 E2E 会打包安装插件到 OpenClaw 2026.7.1,验证挑战应答、非法签名拒绝、真实 Agent Turn、同进程重复投递和 Gateway 重启后的持久防重;不会调用真实抖音账号。正式上线前仍需使用已获权限的生活服务应用验证回调、订单查询和评价回复。

官方参考: