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

@core-workspace/infoflow-openclaw-plugin

v2026.3.9

Published

OpenClaw Infoflow (如流) channel plugin for Baidu enterprise messaging

Readme

Infoflow OpenClaw Plugin

中文 | English


百度如流 (Infoflow) 企业消息平台 — OpenClaw 频道插件。支持 Webhook 和 WebSocket 两种连接方式,具备图片消息收发、引用回复等能力。

目录


快速开始

5 步完成部署,从零到机器人上线回消息。

准备:在如流企业后台创建应用

  1. 如流企业后台 → 应用管理 → 创建机器人应用

  2. 记录以下 4 个参数:

    | 参数 | 在哪找 | |------|--------| | appKey | 应用基本信息 | | appSecret | 应用基本信息 | | checkToken | 消息推送 → 配置 | | encodingAESKey | 消息推送 → 配置 |

  3. 连接方式二选一:

    • WebSocket(推荐,无需公网):不用额外配置
    • Webhook:在"消息推送"填入 https://你的域名/webhook/infoflow

第一步:安装 OpenClaw

# macOS / Linux
curl -fsSL https://openclaw.dev/install.sh | bash

# 安装完成后登录(按提示操作)
openclaw configure

第二步:克隆插件

git clone ssh://icode.baidu.com:8235/baidu/hi/openclaw_infoflow
cd openclaw_infoflow
npm install

第三步:写配置

打开 ~/.openclaw/openclaw.json,在 channels 下加入如流配置:

{
  "channels": {
    "infoflow": {
      "connectionMode": "websocket",
      "wsGateway": "infoflow-open-gateway.weiyun.baidu.com",
      "apiHost": "https://apiin.im.baidu.com",
      "appKey": "填你的 appKey",
      "appSecret": "填你的 appSecret",
      "checkToken": "填你的 checkToken",
      "encodingAESKey": "填你的 encodingAESKey"
    }
  }
}

更多配置项(访问控制、群聊策略、消息格式等)见配置参考

第四步:部署插件

./scripts/deploy.sh

第五步:验证

  • 私聊:在如流给机器人发一条消息,应有回复
  • 群聊:在白名单群 @机器人,应有回复
  • 查日志
openclaw logs | grep infoflow

常见问题

机器人不回复?

openclaw doctor            # 检查配置
openclaw status            # 查看各渠道状态
openclaw logs | grep -i "infoflow\|error"

改了配置没生效?

./scripts/deploy.sh        # 重新同步并重启

群 ID 怎么查?

openclaw directory groups infoflow

配置

最小配置

在 OpenClaw 配置文件中添加:

{
  channels: {
    infoflow: {
      apiHost: "https://apiin.im.baidu.com",
      checkToken: "your-check-token",
      encodingAESKey: "your-encoding-aes-key",
      appKey: "your-app-key",
      appSecret: "your-app-secret",
    },
  },
}

全量配置

{
  channels: {
    infoflow: {
      // ── 基础连接 ──────────────────────────────────────────
      enabled: true,
      apiHost: "https://apiin.im.baidu.com",          // 如流 API 地址(必填)
      connectionMode: "websocket",                      // "webhook"(默认)或 "websocket"
      wsGateway: "infoflow-open-gateway.weiyun.baidu.com", // WebSocket 网关(websocket 模式专用)
      checkToken: "your-check-token",                   // 消息验签 Token(必填)
      encodingAESKey: "your-encoding-aes-key",          // 消息 AES 加密密钥(必填)
      appKey: "your-app-key",                           // 应用 Key(必填)
      appSecret: "your-app-secret",                     // 应用 Secret(必填)
      appAgentId: 12345,                                // 企业后台应用ID,私聊撤回需要
      robotName: "MyBot",                               // 机器人显示名,用于群内 @ 检测

      // ── 访问控制 ──────────────────────────────────────────
      dmPolicy: "allowlist",        // "open" / "pairing" / "allowlist"
      allowFrom: ["alice", "bob"],  // 私聊白名单(uuapName),dmPolicy="allowlist" 时生效
      groupPolicy: "allowlist",     // "open" / "allowlist" / "disabled"
      groupAllowFrom: ["12345678"], // 群聊白名单(群ID字符串),groupPolicy="allowlist" 时生效

      // ── 群聊回复行为 ───────────────────────────────────────
      replyMode: "mention-and-watch", // "ignore" / "record" / "mention-only" / "mention-and-watch" / "proactive"
      requireMention: false,          // 是否强制要求 @ 机器人才触发
      watchMentions: ["alice"],       // 监控指定人被 @,机器人代为判断是否回答
      watchRegex: "故障|告警",        // 群消息命中正则时触发
      followUp: true,                 // 机器人回复后时间窗口内免 @ 追问
      followUpWindow: 300,            // 跟进时间窗口(秒)

      // ── 消息格式 ──────────────────────────────────────────
      dmMessageFormat: "markdown",    // 私聊格式:"text"(默认)或 "markdown"
      groupMessageFormat: "text",     // 群聊格式:"text"(默认)或 "markdown"(不支持引用回复)
      processingHint: true,           // 响应慢时发送"⏳ 处理中..."提示
      processingHintDelay: 5,         // 发送提示前等待秒数(0 = 立即发送)

      // ── 多账号 ────────────────────────────────────────────
      defaultAccount: "main",
      accounts: {
        main: { appKey: "...", appSecret: "..." },    // 字段与顶层相同,会合并覆盖
      },

      // ── 群级别覆盖 ────────────────────────────────────────
      groups: {
        "12345678": {
          replyMode: "proactive",
          systemPrompt: "你是该群的专属助手,回答要简洁。",
        },
      },
    },
  },
}

连接方式

插件支持两种连接方式,通过 connectionMode 配置切换:

| 模式 | 说明 | 适用场景 | |------|------|---------| | webhook(默认) | 如流服务器主动推送 HTTP 请求到你的服务 | 有公网域名或内网穿透 | | websocket | 插件主动连接如流 WebSocket 长连接 | 无公网域名,本地开发调试 |

Webhook 模式:在如流企业后台配置 Webhook URL:

https://your-domain/webhook/infoflow

WebSocket 模式:无需公网域名,适合本地开发:

{
  channels: {
    infoflow: {
      connectionMode: "websocket",
      // wsGateway: "infoflow-open-gateway.weiyun.baidu.com",  // 可选,默认值
    },
  },
}

WebSocket 模式下 checkTokenencodingAESKey 不用于消息解密(连接本身已认证),但仍建议配置以便随时切回 Webhook。

配置参考

基础连接

| 字段 | 类型 | 必填 | 默认值 | 说明 | |------|------|:----:|--------|------| | apiHost | string | ✅ | — | 如流 API 地址,例如 https://apiin.im.baidu.com | | checkToken | string | ✅ | — | 消息验签 Token,从如流企业后台获取 | | encodingAESKey | string | ✅ | — | 消息 AES 加密密钥,从如流企业后台获取 | | appKey | string | ✅ | — | 应用 Key,从如流企业后台获取 | | appSecret | string | ✅ | — | 应用 Secret,从如流企业后台获取 | | appAgentId | number | — | — | 企业后台"应用ID"(数字),私聊消息撤回需要此字段 | | robotName | string | — | — | 机器人在群里的显示名称,用于检测消息中的 @ 提及 | | connectionMode | string | — | "webhook" | 消息接收方式:"webhook" 如流主动推送;"websocket" 插件主动长连接 | | wsGateway | string | — | "infoflow-open-gateway.weiyun.baidu.com" | WebSocket 网关域名,仅 websocket 模式使用 | | enabled | boolean | — | true | 是否启用该插件 |

访问控制

| 字段 | 类型 | 必填 | 默认值 | 说明 | |------|------|:----:|--------|------| | dmPolicy | string | — | "open" | 私聊策略:"open" 任何人可触发;"pairing" 需配对授权;"allowlist" 仅白名单用户 | | allowFrom | string[] | — | [] | 私聊白名单(uuapName / 邮箱前缀),dmPolicy="allowlist" 时生效 | | groupPolicy | string | — | "open" | 群聊策略:"open" 任何群可触发;"allowlist" 仅白名单群;"disabled" 完全禁用群聊 | | groupAllowFrom | string[] | — | [] | 群聊白名单(群 ID 数字字符串),groupPolicy="allowlist" 时生效 | | requireMention | boolean | — | false | 群聊是否强制要求 @ 机器人才触发(与 replyMode 配合使用) |

回复行为

| 字段 | 类型 | 必填 | 默认值 | 说明 | |------|------|:----:|--------|------| | replyMode | string | — | "mention-and-watch" | 群聊回复策略:ignore(丢弃)/ record(仅记录)/ mention-only(仅被@时)/ mention-and-watch(被@或关注人被@时)/ proactive(主动参与) | | followUp | boolean | — | true | 机器人回复后,时间窗口内自动识别追问,无需再次 @ | | followUpWindow | number | — | 300 | 跟进时间窗口(秒) | | watchMentions | string[] | — | [] | 监控指定人员被 @,机器人作为其助手代为判断是否回答,填写 uuapName | | watchRegex | string | — | — | JavaScript 正则表达式,群消息内容命中时触发回复 |

消息格式

| 字段 | 类型 | 必填 | 默认值 | 说明 | |------|------|:----:|--------|------| | dmMessageFormat | string | — | "text" | 私聊发出消息的格式:"text" 纯文本;"markdown" 富文本,支持标题/加粗/列表 | | groupMessageFormat | string | — | "text" | 群聊发出消息的格式:"text" 纯文本;"markdown" 富文本。注意:markdown 格式不支持引用回复 | | processingHint | boolean | — | true | LLM 响应较慢时,提前发送"⏳ 处理中..."提示;出错时发"处理出错,请稍后重试" | | processingHintDelay | number | — | 5 | 发送"⏳ 处理中..."前等待的秒数;LLM 在此时间内响应则不发;设为 0 立即发送 |

多账号与分组

| 字段 | 类型 | 必填 | 说明 | |------|------|:----:|------| | accounts | object | — | 多账号配置,key 为自定义账号 ID,value 字段与顶层配置相同 | | defaultAccount | string | — | 多账号模式下的默认账号 ID | | groups | object | — | 按群覆盖配置,key 为群 ID(数字字符串),字段见下方 |

群级别配置 (groups.<groupId>)

每个群可独立覆盖全局配置,未设置的字段继承顶层配置。

| 字段 | 类型 | 说明 | |------|------|------| | replyMode | string | 覆盖该群的回复策略 | | watchMentions | string[] | 覆盖该群监控的人员列表 | | watchRegex | string | 覆盖该群的正则匹配规则 | | followUp | boolean | 覆盖该群的跟进开关 | | followUpWindow | number | 覆盖该群的跟进时间窗口(秒) | | systemPrompt | string | 该群专属系统提示词,覆盖全局 Agent 的 system prompt |

配置优先级:群级别 > 账号级别 > 顶层默认值


插件架构

核心模块

| 模块 | 文件 | 功能 | |------|------|------| | 插件入口 | index.ts | 注册 Channel、Webhook 路由、Tools、Hooks | | Channel 定义 | src/channel.ts | 插件结构、生命周期、Actions | | 消息接收(Webhook) | src/inbound/webhook-parser.ts | Webhook 解析、解密、去重 | | 消息接收(WebSocket) | src/inbound/ws-receiver.ts | WebSocket 长连接 | | 接入管理 | src/inbound/monitor.ts | Webhook/WebSocket 启动管理 | | 消息处理 | src/inbound/message-handler.ts | replyMode 决策、历史注入、LLM 调用 | | 消息发送 | src/outbound/send.ts | 私聊/群聊发送 API | | 回复分发 | src/outbound/reply-dispatcher.ts | @mentions 解析、分块、引用回复构造 | | 图片处理 | src/outbound/media.ts | 图片下载、压缩、Base64(含 SSRF 防护) | | Actions | src/outbound/actions.ts | Channel Actions(send/delete,供 LLM 通过 Channel 调用) | | Agent Tools | src/tools/index.ts | infoflow_send / infoflow_recall(LLM Function Calling) | | Agent Hooks | src/hooks/index.ts | before_agent_start 钩子(如流平台背景知识注入) | | 多账号 | src/config/accounts.ts | 账号解析、配置合并 | | SDK 适配 | src/sdk/token-adapter.ts | Token 管理,封装 SDK TokenManager | | 消息存储 | src/outbound/message-store.ts | 已发送消息记录(支持撤回) |

项目结构

infoflow-openclaw/
├── index.ts                          # 插件入口
├── openclaw.plugin.json              # 插件元数据
├── skills/                           # 随插件分发的 skill 包
│   └── infoflow-dev/                 # 如流开发者指南 skill
├── src/
│   ├── channel.ts
│   ├── logging.ts
│   ├── runtime.ts
│   ├── types.ts
│   ├── config/
│   │   └── accounts.ts
│   ├── inbound/
│   │   ├── monitor.ts
│   │   ├── webhook-parser.ts
│   │   ├── ws-receiver.ts
│   │   └── message-handler.ts
│   ├── outbound/
│   │   ├── send.ts
│   │   ├── reply-dispatcher.ts
│   │   ├── media.ts
│   │   ├── actions.ts
│   │   ├── message-store.ts
│   │   └── target-resolver.ts
│   ├── tools/
│   │   └── index.ts
│   ├── hooks/
│   │   └── index.ts
│   └── sdk/
│       └── token-adapter.ts
└── README.md

开发指南

前置要求

  • Node.js >= 18
  • OpenClaw >= 2026.3.2

本地开发

# 修改代码后同步并重启
rsync -av --delete ./ ~/.openclaw/extensions/infoflow/ \
  --exclude node_modules --exclude dist --exclude .git
openclaw gateway restart

# 查看日志
tail -f ~/.openclaw/logs/gateway.log | grep -i infoflow

常用命令

# 查看最近日志(含 DEBUG)
tail -200 ~/.openclaw/logs/gateway.log | grep DEBUG

# 检查 Webhook 是否收到消息
tail -200 ~/.openclaw/logs/gateway.log | grep "webhook"

# 检查消息是否发送成功
tail -200 ~/.openclaw/logs/gateway.log | grep "sendInfoflowMessage"

扩展:Agent Tools

Tools 是 LLM Function Calling 的实现,Agent 可主动调用来执行操作。

内置 Tools

infoflow_send — 主动发消息

| 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | to | string | ✅ | "username" 私聊,"group:GROUP_ID" 群聊 | | message | string | ✅ | 消息正文,支持 Markdown | | atAll | boolean | — | 群消息中 @全体成员 | | mentionUserIds | string | — | 逗号分隔的 uuapName(群消息 @指定成员) | | accountId | string | — | 多账号时指定账号 ID |

infoflow_recall — 撤回消息

| 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | to | string | ✅ | 格式同 infoflow_send | | count | number | — | 撤回最近 N 条(默认 1) | | messageId | string | — | 撤回指定消息 ID(优先于 count) | | accountId | string | — | 多账号时指定账号 ID |

添加自定义 Tool

src/tools/ 下新建文件,在 src/tools/index.tsregisterInfoflowTools 中注册:

import { Type, type Static } from "@sinclair/typebox";
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";

const MyToolSchema = Type.Object({
  query: Type.String({ description: "查询关键词" }),
});

export function registerMyTool(api: OpenClawPluginApi) {
  api.registerTool({
    name: "infoflow_my_tool",
    description: "工具说明...",
    parameters: MyToolSchema,
    async execute(_toolCallId, params) {
      const p = params as Static<typeof MyToolSchema>;
      const result = { data: "..." };
      return {
        content: [{ type: "text" as const, text: JSON.stringify(result) }],
        details: result,
      };
    },
  });
}

扩展:Agent Hooks

Hooks 通过 api.on() 注册生命周期钩子,在 Agent 启动时向 system prompt 注入背景知识。

内置 Hook

infoflow-intro — 如流平台背景知识

每次 Agent 启动时自动注入,告知 LLM 如流平台的会话类型、消息格式、Bot 能力和访问控制。注入内容被缓存到 system prompt 尾部(prompt caching),不产生额外每轮 token 消耗。

添加自定义 Hook

src/hooks/index.tsregisterInfoflowHooks 中添加:

api.on("before_agent_start", (_event, ctx) => {
  return {
    appendSystemContext: `
## 业务规则
- 工单 SLA:P0 30 分钟,P1 2 小时
    `.trim(),
  };
});

Hook 返回值字段:

| 字段 | 说明 | |------|------| | appendSystemContext | 追加到 system prompt 尾部(推荐,利用 prompt caching) | | prependSystemContext | 插入到 system prompt 头部 | | systemPrompt | 完全覆盖 system prompt(慎用) | | modelOverride | 覆盖模型 |


扩展:Agent Skills

Skills 是随插件分发的知识包,安装插件时自动安装到用户的 OpenClaw 实例,为 Agent 提供领域专属知识。

内置 Skill

infoflow-dev — 如流开发者指南

包含如流消息 API 参考、鉴权机制、插件配置说明等开发文档。当用户在 Agent 会话中询问如流相关开发问题时自动触发。

Skill 文件位于 skills/infoflow-dev/,随 openclaw plugins install 一并安装。

添加自定义 Skill

skills/ 下新建目录,包含 SKILL.md(必须)和可选的 scripts/references/assets/ 目录:

skills/
└── my-skill/
    ├── SKILL.md          # Skill 元数据(frontmatter)+ 使用说明
    └── references/
        └── guide.md      # 按需加载的参考文档

SKILL.md 格式:

---
name: my-skill
description: Skill 描述,说明何时触发(这是触发机制,写清楚触发场景)
---

# 使用说明
...

openclaw.plugin.jsonskills 字段声明 Skill 目录路径:

{
  "skills": ["./skills/my-skill"]
}

FAQ

1. 如何获取如流配置参数?

在如流企业后台:

  1. 进入"应用管理" → 选择你的机器人应用
  2. 获取 appKeyappSecretappAgentId
  3. 配置 Webhook,获取 checkTokenencodingAESKey

2. 机器人不回复消息?

  1. 检查 replyMode 是否允许该群触发
  2. 检查日志是否收到 Webhook 请求:
    tail -200 ~/.openclaw/logs/gateway.log | grep "webhook"
  3. 检查 robotName 是否与如流后台一致(影响 @ 检测)
  4. 检查 groupPolicy 是否允许该群

3. 消息撤回失败?

  • 时间限制:如流 API 通常限制 2 分钟内可撤回
  • 缺少参数:群聊需要 messageid + msgseqid;私聊需要 msgkey + appAgentId
  • 未记录:消息未被记录到 sent-message-store(查看 ~/.openclaw/plugins/infoflow/sent-messages/default.json

4. WebSocket 模式和 Webhook 模式有什么区别?

| | Webhook | WebSocket | |--|---------|-----------| | 需要公网域名 | ✅ | ❌ | | 消息解密(checkToken/AES) | ✅ 需要 | ❌ 不需要 | | 适合场景 | 生产环境 | 本地开发调试 |


License

MIT


Infoflow OpenClaw Plugin (English)

Baidu Infoflow enterprise messaging platform — OpenClaw channel plugin. Supports both Webhook and WebSocket connection modes, with image message handling and quote reply support.

Table of Contents


Quick Start

5 steps from zero to a running bot.

Prerequisites: Create an app in Infoflow enterprise console

  1. Infoflow enterprise console → App Management → Create bot app

  2. Note the following 4 parameters:

    | Parameter | Where to find | |-----------|---------------| | appKey | App basic info | | appSecret | App basic info | | checkToken | Message push → Config | | encodingAESKey | Message push → Config |

  3. Choose a connection mode:

    • WebSocket (recommended, no public domain needed): no extra setup
    • Webhook: set https://your-domain/webhook/infoflow in "Message push"

Step 1: Install OpenClaw

# macOS / Linux
curl -fsSL https://openclaw.dev/install.sh | bash

openclaw configure

Step 2: Clone the plugin

git clone ssh://icode.baidu.com:8235/baidu/hi/openclaw_infoflow
cd openclaw_infoflow
npm install

Step 3: Write config

Open ~/.openclaw/openclaw.json and add the infoflow channel config:

{
  "channels": {
    "infoflow": {
      "connectionMode": "websocket",
      "wsGateway": "infoflow-open-gateway.weiyun.baidu.com",
      "apiHost": "https://apiin.im.baidu.com",
      "appKey": "your-app-key",
      "appSecret": "your-app-secret",
      "checkToken": "your-check-token",
      "encodingAESKey": "your-encoding-aes-key"
    }
  }
}

For more options (access control, group policies, message format, etc.) see Configuration Reference.

Step 4: Deploy

./scripts/deploy.sh

Step 5: Verify

  • DM: Send the bot a direct message — it should reply
  • Group: @mention the bot in a whitelisted group — it should reply
  • Logs: openclaw logs | grep infoflow

Configuration

Minimal Configuration

{
  channels: {
    infoflow: {
      apiHost: "https://apiin.im.baidu.com",
      checkToken: "your-check-token",
      encodingAESKey: "your-encoding-aes-key",
      appKey: "your-app-key",
      appSecret: "your-app-secret",
    },
  },
}

Full Configuration

{
  channels: {
    infoflow: {
      // ── Connection ────────────────────────────────────────
      enabled: true,
      apiHost: "https://apiin.im.baidu.com",           // required
      connectionMode: "websocket",                       // "webhook" (default) or "websocket"
      wsGateway: "infoflow-open-gateway.weiyun.baidu.com", // websocket mode only
      checkToken: "your-check-token",                    // required
      encodingAESKey: "your-encoding-aes-key",           // required
      appKey: "your-app-key",                            // required
      appSecret: "your-app-secret",                      // required
      appAgentId: 12345,                                 // required for DM recall
      robotName: "MyBot",                                // for @mention detection in groups

      // ── Access Control ────────────────────────────────────
      dmPolicy: "allowlist",        // "open" / "pairing" / "allowlist"
      allowFrom: ["alice", "bob"],  // DM whitelist (uuapName), used when dmPolicy="allowlist"
      groupPolicy: "allowlist",     // "open" / "allowlist" / "disabled"
      groupAllowFrom: ["12345678"], // Group whitelist (group ID string), used when groupPolicy="allowlist"

      // ── Reply Behavior ────────────────────────────────────
      replyMode: "mention-and-watch", // "ignore" / "record" / "mention-only" / "mention-and-watch" / "proactive"
      requireMention: false,
      watchMentions: ["alice"],       // act as assistant when these users are @mentioned
      watchRegex: "incident|alert",   // trigger on regex match in group messages
      followUp: true,                 // allow follow-up questions without re-mentioning
      followUpWindow: 300,            // follow-up window in seconds

      // ── Message Format ────────────────────────────────────
      dmMessageFormat: "markdown",    // "text" (default) or "markdown" for DMs
      groupMessageFormat: "text",     // "text" (default) or "markdown" for groups (no quote reply)
      processingHint: true,
      processingHintDelay: 5,

      // ── Multi-account ─────────────────────────────────────
      defaultAccount: "main",
      accounts: {
        main: { appKey: "...", appSecret: "..." },
      },

      // ── Per-group Overrides ───────────────────────────────
      groups: {
        "12345678": {
          replyMode: "proactive",
          systemPrompt: "You are the dedicated assistant for this group.",
        },
      },
    },
  },
}

Connection Modes

| Mode | Description | Use Case | |------|-------------|----------| | webhook (default) | Infoflow server pushes HTTP requests to your service | Public domain or tunnel | | websocket | Plugin connects to Infoflow WebSocket gateway | No public domain, local dev |

Webhook mode — configure Webhook URL in Infoflow enterprise console:

https://your-domain/webhook/infoflow

WebSocket mode — no public domain needed:

{
  channels: {
    infoflow: {
      connectionMode: "websocket",
      // wsGateway: "infoflow-open-gateway.weiyun.baidu.com",  // optional
    },
  },
}

Configuration Reference

Connection

| Field | Type | Required | Default | Description | |-------|------|:--------:|---------|-------------| | apiHost | string | ✅ | — | Infoflow API host, e.g. https://apiin.im.baidu.com | | checkToken | string | ✅ | — | Message verification token from Infoflow enterprise console | | encodingAESKey | string | ✅ | — | AES encryption key from Infoflow enterprise console | | appKey | string | ✅ | — | App Key from Infoflow enterprise console | | appSecret | string | ✅ | — | App Secret from Infoflow enterprise console | | appAgentId | number | — | — | App Agent ID (numeric); required for private message recall | | robotName | string | — | — | Bot display name in groups, used for @mention detection | | connectionMode | string | — | "webhook" | "webhook" (Infoflow pushes to your server) or "websocket" (plugin connects to Infoflow) | | wsGateway | string | — | "infoflow-open-gateway.weiyun.baidu.com" | WebSocket gateway hostname, only used in websocket mode | | enabled | boolean | — | true | Whether to enable the plugin |

Access Control

| Field | Type | Required | Default | Description | |-------|------|:--------:|---------|-------------| | dmPolicy | string | — | "open" | DM policy: "open" (anyone); "pairing" (requires pairing); "allowlist" (whitelist only) | | allowFrom | string[] | — | [] | DM whitelist (uuapName / email prefix), effective when dmPolicy="allowlist" | | groupPolicy | string | — | "open" | Group policy: "open" (any group); "allowlist" (whitelist only); "disabled" (no group messages) | | groupAllowFrom | string[] | — | [] | Group whitelist (numeric group ID strings), effective when groupPolicy="allowlist" | | requireMention | boolean | — | false | Require explicit @ in group messages to trigger |

Reply Behavior

| Field | Type | Required | Default | Description | |-------|------|:--------:|---------|-------------| | replyMode | string | — | "mention-and-watch" | ignore (discard) / record (save only) / mention-only (when @mentioned) / mention-and-watch (default) / proactive (always active) | | followUp | boolean | — | true | Auto-detect follow-up questions after bot replies (no @ needed) | | followUpWindow | number | — | 300 | Follow-up window in seconds | | watchMentions | string[] | — | [] | Watch these users; bot acts as assistant when they are @mentioned | | watchRegex | string | — | — | JavaScript regex; trigger reply when group message content matches |

Message Format

| Field | Type | Required | Default | Description | |-------|------|:--------:|---------|-------------| | dmMessageFormat | string | — | "text" | Format for private (DM) messages: "text" (plain) or "markdown" (rich text) | | groupMessageFormat | string | — | "text" | Format for group messages: "text" (plain) or "markdown" (rich text). Note: markdown does not support quote replies | | processingHint | boolean | — | true | Send "⏳ processing..." hint when LLM is slow; send error message on failure | | processingHintDelay | number | — | 5 | Seconds to wait before sending the hint; set to 0 to send immediately |

Multi-account & Groups

| Field | Type | Required | Description | |-------|------|:--------:|-------------| | accounts | object | — | Multi-account config; key = account ID, value has same fields as top-level | | defaultAccount | string | — | Default account ID | | groups | object | — | Per-group overrides; key = group ID (numeric string) |

Per-group fields: replyMode, watchMentions, watchRegex, followUp, followUpWindow, systemPrompt

Priority: per-group > account-level > top-level defaults


Architecture

| Module | File | Description | |--------|------|-------------| | Entry | index.ts | Register channel, webhook route, tools, hooks | | Channel | src/channel.ts | Plugin structure, lifecycle, actions | | Webhook | src/inbound/webhook-parser.ts | Parse, decrypt, deduplicate | | WebSocket | src/inbound/ws-receiver.ts | Long-lived connection | | Monitor | src/inbound/monitor.ts | Manage Webhook/WebSocket startup | | Handler | src/inbound/message-handler.ts | replyMode logic, history injection, LLM call | | Send | src/outbound/send.ts | DM / group message sending | | Dispatcher | src/outbound/reply-dispatcher.ts | @mentions, chunking, quote reply | | Media | src/outbound/media.ts | Image download, compress, Base64 (SSRF protection) | | Actions | src/outbound/actions.ts | Channel actions (send/delete for LLM) | | Tools | src/tools/index.ts | infoflow_send / infoflow_recall | | Hooks | src/hooks/index.ts | before_agent_start hook | | Accounts | src/config/accounts.ts | Multi-account resolution | | Token | src/sdk/token-adapter.ts | Token management | | Store | src/outbound/message-store.ts | Sent message store (for recall) |


Development Guide

# Sync and restart after code changes
rsync -av --delete ./ ~/.openclaw/extensions/infoflow/ \
  --exclude node_modules --exclude dist --exclude .git
openclaw gateway restart

# View logs
tail -f ~/.openclaw/logs/gateway.log | grep -i infoflow

Extending: Agent Tools

Tools implement LLM Function Calling — the agent calls them to take actions.

infoflow_send — Send a message

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | to | string | ✅ | "username" for DM, "group:GROUP_ID" for group | | message | string | ✅ | Message body (Markdown supported) | | atAll | boolean | — | @all in group | | mentionUserIds | string | — | Comma-separated uuapNames to @mention | | accountId | string | — | Account ID for multi-account setups |

infoflow_recall — Recall messages

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | to | string | ✅ | Same format as infoflow_send | | count | number | — | Recall last N messages (default: 1) | | messageId | string | — | Recall by message ID (overrides count) | | accountId | string | — | Account ID for multi-account setups |

To add a custom tool, register it inside registerInfoflowTools in src/tools/index.ts.


Extending: Agent Hooks

Hooks inject domain knowledge into the agent system prompt via api.on("before_agent_start", ...).

The built-in infoflow-intro hook injects Infoflow platform context (session types, message formats, bot capabilities, access control) into every agent run. The content is appended to the system prompt and benefits from prompt caching.

To add a custom hook, call api.on(...) inside registerInfoflowHooks in src/hooks/index.ts.

Hook return fields: appendSystemContext, prependSystemContext, systemPrompt, modelOverride


Extending: Agent Skills

Skills are knowledge packages bundled with the plugin and auto-installed alongside it. They provide domain-specific context to the Agent.

Built-in Skill

infoflow-dev — Infoflow Developer Guide

Contains Infoflow message API reference, authentication, and plugin configuration docs. Automatically triggers when users ask Infoflow-related development questions.

Located in skills/infoflow-dev/, installed via openclaw plugins install.

Adding a Custom Skill

Create a directory under skills/ with a SKILL.md and optional resource folders:

skills/
└── my-skill/
    ├── SKILL.md
    └── references/
        └── guide.md

Declare the skill path in openclaw.plugin.json:

{
  "skills": ["./skills/my-skill"]
}

FAQ (EN)

Bot not replying?

  1. Check replyMode — confirm the group is allowed to trigger
  2. Check logs for incoming webhook requests
  3. Verify robotName matches the bot's display name (affects @ detection)
  4. Check groupPolicy allows the group

Message recall failing?

  • Time limit: Infoflow API typically allows recall within 2 minutes
  • Missing params: Group recall needs messageid + msgseqid; DM recall needs msgkey + appAgentId
  • Not recorded: Message may not have been saved to the sent-message store

Webhook vs WebSocket?

| | Webhook | WebSocket | |--|---------|-----------| | Requires public domain | ✅ | ❌ | | Message decryption | ✅ needed | ❌ not needed | | Best for | Production | Local development |


License

MIT