@searchfe/openclaw-baiduapp 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,20 +2,16 @@
2
2
 
3
3
  本指南帮助你配置百度App渠道,并接入 OpenClaw。
4
4
 
5
- > **⚠️ 重要提示**:Baidu App 插件专注于**文本私聊场景**,不支持群聊和媒体消息(图片/语音/文件)。
6
-
7
5
  ## 功能概览
8
6
 
9
- | 功能 | 状态 |
10
- | :------------- | :--: |
11
- | 文本消息 | ✅ |
12
- | 主动发送消息 | ✅ |
13
- | 私聊 | ✅ |
14
- | 群聊 | |
15
- | 图片/语音/文件 | ❌ |
16
- | Webhook 回调 | ✅ |
17
- | 多账户 | ✅ |
18
- | 访问控制策略 | ✅ |
7
+ | 功能 | 状态 |
8
+ | :----------- | :--: |
9
+ | 文本消息 | ✅ |
10
+ | 主动发送消息 | ✅ |
11
+ | 私聊 | ✅ |
12
+ | Webhook 回调 | |
13
+
14
+ > 更多消息类型支持敬请期待。
19
15
 
20
16
  ## 前置条件
21
17
 
@@ -23,18 +19,12 @@
23
19
  2. 公网可访问的 HTTPS 服务器(用于接收回调)
24
20
  3. OpenClaw 已安装并运行
25
21
 
26
- ---
27
-
28
22
  ## 步骤一:安装插件
29
23
 
30
- ### 方式一:从 npm 安装
31
-
32
24
  ```bash
33
25
  openclaw plugins install @searchfe/openclaw-baiduapp
34
26
  ```
35
27
 
36
- ---
37
-
38
28
  ## 步骤二:获取百度平台凭证
39
29
 
40
30
  <!-- TODO: 补充百度平台注册具体步骤和截图 -->
@@ -46,15 +36,11 @@ openclaw plugins install @searchfe/openclaw-baiduapp
46
36
  - **Token**:消息校验 Token
47
37
  - **EncodingAESKey**:消息加密密钥(43 位字符)
48
38
 
49
- ---
50
-
51
39
  ## 步骤三:配置 OpenClaw
52
40
 
53
41
  ### 使用命令行配置
54
42
 
55
43
  ```bash
56
- openclaw config set channels.openclaw-baiduapp.enabled true
57
- openclaw config set channels.openclaw-baiduapp.webhookPath /openclaw-baiduapp
58
44
  openclaw config set channels.openclaw-baiduapp.token your-token
59
45
  openclaw config set channels.openclaw-baiduapp.encodingAESKey your-43-char-encoding-aes-key
60
46
  openclaw config set channels.openclaw-baiduapp.appKey your-app-key
@@ -69,8 +55,6 @@ openclaw config set channels.openclaw-baiduapp.appSecret your-app-secret
69
55
  {
70
56
  "channels": {
71
57
  "openclaw-baiduapp": {
72
- "enabled": true,
73
- "webhookPath": "/openclaw-baiduapp",
74
58
  "token": "your-token",
75
59
  "encodingAESKey": "your-43-char-encoding-aes-key",
76
60
  "appKey": "your-app-key",
@@ -90,9 +74,6 @@ openclaw config set channels.openclaw-baiduapp.appSecret your-app-secret
90
74
  | `encodingAESKey` | ✅ | 消息加密密钥(43 位) |
91
75
  | `appKey` | ✅ | 应用 App Key(主动发送必需) |
92
76
  | `appSecret` | ✅ | 应用 App Secret(主动发送必需) |
93
- | `welcomeText` | ❌ | 用户首次进入时的欢迎语 |
94
- | `dmPolicy` | ❌ | 私聊策略(默认 `pairing`) |
95
- | `allowFrom` | ❌ | 私聊白名单用户 ID 列表 |
96
77
 
97
78
  ### 环境变量支持
98
79
 
@@ -105,77 +86,18 @@ openclaw config set channels.openclaw-baiduapp.appSecret your-app-secret
105
86
  | `BAIDU_APP_KEY` | `appKey` |
106
87
  | `BAIDU_APP_SECRET` | `appSecret` |
107
88
 
108
- ---
109
-
110
89
  ## 步骤四:重启 Gateway
111
90
 
112
91
  ```bash
113
92
  openclaw gateway restart
114
93
  ```
115
94
 
116
- ---
117
-
118
95
  ## 步骤五:验证配置
119
96
 
120
97
  1. 在百度平台配置 Webhook 回调地址,指向你的 OpenClaw Gateway
121
98
  2. 平台验证通过后,发送一条测试消息
122
99
  3. 查看 OpenClaw 日志确认消息接收和回复
123
100
 
124
- ---
125
-
126
- ## 高级配置
127
-
128
- ### 访问控制
129
-
130
- ```json
131
- {
132
- "channels": {
133
- "openclaw-baiduapp": {
134
- "enabled": true,
135
- "dmPolicy": "open",
136
- "allowFrom": []
137
- }
138
- }
139
- }
140
- ```
141
-
142
- | 字段 | 说明 |
143
- | :---------- | :--------------------------------------------------------------------------------------- |
144
- | `dmPolicy` | 私聊策略:`open`(任何人)/ `pairing`(配对)/ `allowlist`(白名单)/ `disabled`(禁用) |
145
- | `allowFrom` | 私聊白名单用户 ID 列表(当 `dmPolicy` 为 `allowlist` 时生效) |
146
-
147
- ### 多账户配置
148
-
149
- ```json
150
- {
151
- "channels": {
152
- "openclaw-baiduapp": {
153
- "enabled": true,
154
- "accounts": {
155
- "bot1": {
156
- "webhookPath": "/openclaw-baiduapp-1",
157
- "token": "token-1",
158
- "encodingAESKey": "key-1",
159
- "appKey": "app-key-1",
160
- "appSecret": "secret-1"
161
- },
162
- "bot2": {
163
- "webhookPath": "/openclaw-baiduapp-2",
164
- "token": "token-2",
165
- "encodingAESKey": "key-2",
166
- "appKey": "app-key-2",
167
- "appSecret": "secret-2"
168
- }
169
- }
170
- }
171
- }
172
- }
173
- ```
174
-
175
- > 提示:多账号共用同一路径/Token 时,系统会使用第一个匹配的账号。建议每个账号使用独立的 `webhookPath`。
176
-
177
- ---
178
-
179
101
  ## 常见问题
180
102
 
181
103
  ### Q: 保存配置时提示验证失败?
@@ -190,21 +112,6 @@ openclaw gateway restart
190
112
  1. 检查 `appKey`、`appSecret` 是否正确
191
113
  2. 查看 OpenClaw 日志获取详细错误信息
192
114
 
193
- ### Q: 如何使用 target 发送消息?
194
-
195
- ```bash
196
- # 使用 user: 前缀
197
- send user:userId123 你好
198
-
199
- # 使用 openclaw-baiduapp: 完整前缀
200
- send openclaw-baiduapp:user:userId123 你好
201
-
202
- # 指定账户
203
- send user:userId123@bot1 你好
204
- ```
205
-
206
- ---
207
-
208
115
  ## 开发验证
209
116
 
210
117
  ```bash
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@ interface BaiduAppAccountConfig {
10
10
  appSecret?: string;
11
11
  apiBase?: string;
12
12
  welcomeText?: string;
13
+ touser?: string;
13
14
  }
14
15
  type BaiduAppConfig = BaiduAppAccountConfig & {
15
16
  accounts?: Record<string, BaiduAppAccountConfig>;
@@ -26,6 +27,7 @@ interface ResolvedBaiduAppAccount {
26
27
  appSecret?: string;
27
28
  apiBase: string;
28
29
  canSendActive: boolean;
30
+ touser?: string;
29
31
  config: BaiduAppAccountConfig;
30
32
  }
31
33
  interface BaiduAppInboundBase {
@@ -128,6 +130,10 @@ declare const baiduAppPlugin: {
128
130
  welcomeText: {
129
131
  type: string;
130
132
  };
133
+ touser: {
134
+ type: string;
135
+ description: string;
136
+ };
131
137
  defaultAccount: {
132
138
  type: string;
133
139
  };
@@ -164,6 +170,10 @@ declare const baiduAppPlugin: {
164
170
  welcomeText: {
165
171
  type: string;
166
172
  };
173
+ touser: {
174
+ type: string;
175
+ description: string;
176
+ };
167
177
  };
168
178
  };
169
179
  };
@@ -369,6 +379,7 @@ interface SendMessageOptions$1 {
369
379
  msgid?: string;
370
380
  streamId?: string;
371
381
  chunkKey?: number;
382
+ touser?: string;
372
383
  }
373
384
  declare function sendBaiduAppMessage(account: ResolvedBaiduAppAccount, message: string, options?: SendMessageOptions$1): Promise<SendMessageResult>;
374
385
 
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import crypto from 'crypto';
2
+ import { createRequire } from 'module';
2
3
 
3
4
  var __defProp = Object.defineProperty;
4
5
  var __export = (target, all) => {
@@ -4058,7 +4059,8 @@ var BaiduAppAccountSchema = external_exports.object({
4058
4059
  appKey: external_exports.string().optional(),
4059
4060
  appSecret: external_exports.string().optional(),
4060
4061
  apiBase: external_exports.string().optional(),
4061
- welcomeText: external_exports.string().optional()
4062
+ welcomeText: external_exports.string().optional(),
4063
+ touser: external_exports.string().optional()
4062
4064
  });
4063
4065
  BaiduAppAccountSchema.extend({
4064
4066
  defaultAccount: external_exports.string().optional(),
@@ -4078,6 +4080,7 @@ var BaiduAppConfigJsonSchema = {
4078
4080
  appSecret: { type: "string" },
4079
4081
  apiBase: { type: "string" },
4080
4082
  welcomeText: { type: "string" },
4083
+ touser: { type: "string", description: "Default target user ID for outbound messages" },
4081
4084
  defaultAccount: { type: "string" },
4082
4085
  accounts: {
4083
4086
  type: "object",
@@ -4093,7 +4096,8 @@ var BaiduAppConfigJsonSchema = {
4093
4096
  appKey: { type: "string" },
4094
4097
  appSecret: { type: "string" },
4095
4098
  apiBase: { type: "string" },
4096
- welcomeText: { type: "string" }
4099
+ welcomeText: { type: "string" },
4100
+ touser: { type: "string", description: "Default target user ID for outbound messages" }
4097
4101
  }
4098
4102
  }
4099
4103
  }
@@ -4156,6 +4160,7 @@ function resolveBaiduAppAccount(params) {
4156
4160
  const canSendActive = Boolean(appKey && token && encodingAESKey);
4157
4161
  const rawApiBase = merged.apiBase?.trim() || (isDefaultAccount ? process.env.BAIDU_API_BASE?.trim() : void 0) || void 0;
4158
4162
  const apiBase = (rawApiBase || DEFAULT_API_BASE).replace(/\/+$/, "");
4163
+ const touser = merged.touser?.trim() || (isDefaultAccount ? process.env.BAIDU_APP_TOUSER?.trim() : void 0) || void 0;
4159
4164
  return {
4160
4165
  accountId,
4161
4166
  name: merged.name?.trim() || void 0,
@@ -4167,6 +4172,7 @@ function resolveBaiduAppAccount(params) {
4167
4172
  appSecret,
4168
4173
  apiBase,
4169
4174
  canSendActive,
4175
+ touser,
4170
4176
  config: merged
4171
4177
  };
4172
4178
  }
@@ -4263,6 +4269,9 @@ function encryptBaiduAppPlaintext(params) {
4263
4269
  const encrypted = Buffer.concat([cipher.update(padded), cipher.final()]);
4264
4270
  return encrypted.toString("base64");
4265
4271
  }
4272
+ var require2 = createRequire(import.meta.url);
4273
+ var pkg = require2("../package.json");
4274
+ var PLUGIN_VERSION = pkg.version;
4266
4275
 
4267
4276
  // src/api.ts
4268
4277
  var logger = createLogger("openclaw-baiduapp");
@@ -4277,8 +4286,16 @@ async function sendBaiduAppMessage(account, message, options) {
4277
4286
  }
4278
4287
  const payload = {
4279
4288
  msgtype: "text",
4280
- text: { content: message }
4289
+ text: { content: message },
4290
+ version: PLUGIN_VERSION,
4291
+ ...options?.msgid != null ? { msgid: options.msgid } : {},
4292
+ ...options?.streamId != null ? { streamId: options.streamId } : {},
4293
+ ...options?.chunkKey != null ? { chunkKey: options.chunkKey } : {}
4281
4294
  };
4295
+ const touser = options?.touser?.trim() || account.touser;
4296
+ if (touser) {
4297
+ payload.touser = touser;
4298
+ }
4282
4299
  const plaintext = JSON.stringify(payload);
4283
4300
  const encrypt = encryptBaiduAppPlaintext({
4284
4301
  encodingAESKey: account.encodingAESKey ?? "",
@@ -4294,12 +4311,7 @@ async function sendBaiduAppMessage(account, message, options) {
4294
4311
  });
4295
4312
  const sendMessageUrl = `${account.apiBase}/chat/openclaw/callback`;
4296
4313
  const url = `${sendMessageUrl}?timestamp=${encodeURIComponent(timestamp)}&ak=${encodeURIComponent(account.appKey ?? "")}&nonce=${encodeURIComponent(nonce)}&msg_signature=${encodeURIComponent(msgSignature)}`;
4297
- const body = JSON.stringify({
4298
- encrypt,
4299
- ...options?.msgid != null ? { msgid: options.msgid } : {},
4300
- ...options?.streamId != null ? { streamId: options.streamId } : {},
4301
- ...options?.chunkKey != null ? { chunkKey: options.chunkKey } : {}
4302
- });
4314
+ const body = JSON.stringify({ encrypt });
4303
4315
  logger.info(`POST ${url}`);
4304
4316
  logger.debug(`request body: ${body}`);
4305
4317
  const resp = await fetch(url, {
@@ -4383,7 +4395,7 @@ async function dispatchBaiduAppMessage(params) {
4383
4395
  const envelopeOptions = channel.reply?.resolveEnvelopeFormatOptions ? channel.reply.resolveEnvelopeFormatOptions(safeCfg) : void 0;
4384
4396
  const body = channel.reply?.formatAgentEnvelope ? channel.reply.formatAgentEnvelope({
4385
4397
  channel: "Baidu App",
4386
- from: "",
4398
+ from: "openclaw-baiduapp:user",
4387
4399
  previousTimestamp,
4388
4400
  envelope: envelopeOptions,
4389
4401
  body: rawBody
@@ -4595,7 +4607,8 @@ function isXmlFormat(raw) {
4595
4607
  return trimmed.startsWith("<") && trimmed.endsWith(">");
4596
4608
  }
4597
4609
  function buildEncryptedJsonReply(params) {
4598
- const plaintext = JSON.stringify(params.plaintextJson ?? {});
4610
+ const base = params.plaintextJson != null && typeof params.plaintextJson === "object" ? params.plaintextJson : {};
4611
+ const plaintext = JSON.stringify({ ...base, version: PLUGIN_VERSION });
4599
4612
  const encrypt = encryptBaiduAppPlaintext({
4600
4613
  encodingAESKey: params.account.encodingAESKey ?? "",
4601
4614
  plaintext
@@ -4915,7 +4928,7 @@ async function handleBaiduAppWebhookRequest(req, res) {
4915
4928
  const welcome = target.account.config.welcomeText?.trim();
4916
4929
  if (welcome && target.account.canSendActive) {
4917
4930
  logger2.info("sending welcome message");
4918
- sendBaiduAppMessage(target.account, welcome).catch((err) => {
4931
+ sendBaiduAppMessage(target.account, welcome, { touser: target.account.touser }).catch((err) => {
4919
4932
  logger2.error(`failed to send welcome message: ${String(err)}`);
4920
4933
  });
4921
4934
  }
@@ -5019,7 +5032,8 @@ async function handleBaiduAppWebhookRequest(req, res) {
5019
5032
  await sendBaiduAppMessage(target.account, chunks[i], {
5020
5033
  msgid,
5021
5034
  streamId,
5022
- chunkKey: i
5035
+ chunkKey: i,
5036
+ touser: target.account.touser
5023
5037
  });
5024
5038
  logger2.debug(`active send chunk ${i + 1}/${chunks.length} sent: streamId=${streamId}`);
5025
5039
  }
@@ -5242,7 +5256,9 @@ var baiduAppPlugin = {
5242
5256
  };
5243
5257
  }
5244
5258
  try {
5245
- const result = await sendBaiduAppMessage(account, params.text);
5259
+ const result = await sendBaiduAppMessage(account, params.text, {
5260
+ touser: params.to || account.touser
5261
+ });
5246
5262
  return {
5247
5263
  channel: "openclaw-baiduapp",
5248
5264
  ok: result.ok,
@@ -5278,7 +5294,9 @@ var baiduAppPlugin = {
5278
5294
  };
5279
5295
  }
5280
5296
  try {
5281
- const result = await sendBaiduAppMessage(account, content);
5297
+ const result = await sendBaiduAppMessage(account, content, {
5298
+ touser: params.to || account.touser
5299
+ });
5282
5300
  return {
5283
5301
  channel: "openclaw-baiduapp",
5284
5302
  ok: result.ok,
@@ -5367,7 +5385,7 @@ async function sendMessage(account, options) {
5367
5385
  };
5368
5386
  }
5369
5387
  try {
5370
- const textResult = await sendBaiduAppMessage(account, options.text);
5388
+ const textResult = await sendBaiduAppMessage(account, options.text, { touser: account.touser });
5371
5389
  return {
5372
5390
  ok: textResult.ok,
5373
5391
  msgid: textResult.msgid,