@searchfe/openclaw-baiduapp 0.1.8 → 0.1.9-beta.1

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/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
+ import { spawnSync } from 'child_process';
2
+ import readline from 'readline';
1
3
  import path2 from 'path';
2
4
  import { fileURLToPath } from 'url';
3
- import crypto3 from 'crypto';
5
+ import crypto2 from 'crypto';
4
6
  import { createRequire } from 'module';
5
7
  import { lookup } from 'dns/promises';
6
8
  import fs2 from 'fs/promises';
@@ -9,11 +11,120 @@ import fs from 'fs';
9
11
  import { tmpdir } from 'os';
10
12
 
11
13
  var __defProp = Object.defineProperty;
14
+ var __getOwnPropNames = Object.getOwnPropertyNames;
15
+ var __esm = (fn, res) => function __init() {
16
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
17
+ };
12
18
  var __export = (target, all) => {
13
19
  for (var name in all)
14
20
  __defProp(target, name, { get: all[name], enumerable: true });
15
21
  };
16
22
 
23
+ // src/auth/login.ts
24
+ var login_exports = {};
25
+ __export(login_exports, {
26
+ loginBaiduApp: () => loginBaiduApp
27
+ });
28
+ function createTerminalPrompter() {
29
+ const rl = readline.createInterface({
30
+ input: process.stdin,
31
+ output: process.stdout
32
+ });
33
+ const question = (message) => new Promise((resolve) => {
34
+ rl.question(message, (answer) => resolve(answer));
35
+ });
36
+ return {
37
+ select: async (message, choices) => {
38
+ while (true) {
39
+ process.stdout.write(`${message}
40
+ `);
41
+ for (const [index, choice] of choices.entries()) {
42
+ process.stdout.write(`${index + 1}. ${choice}
43
+ `);
44
+ }
45
+ const answer = (await question("\u8BF7\u9009\u62E9\u5E8F\u53F7: ")).trim();
46
+ const choiceIndex = Number(answer);
47
+ if (Number.isInteger(choiceIndex) && choiceIndex >= 1 && choiceIndex <= choices.length) {
48
+ return choices[choiceIndex - 1];
49
+ }
50
+ process.stdout.write(`\u8BF7\u8F93\u5165 1-${choices.length} \u4E4B\u95F4\u7684\u5E8F\u53F7\u3002
51
+ `);
52
+ }
53
+ },
54
+ text: async (message, opts) => {
55
+ while (true) {
56
+ const answer = (await question(`${message}: `)).trim();
57
+ if (!opts?.required || answer) {
58
+ return answer;
59
+ }
60
+ process.stdout.write("\u8BE5\u9879\u4E3A\u5FC5\u586B\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165\u3002\n");
61
+ }
62
+ },
63
+ close: () => {
64
+ rl.close();
65
+ }
66
+ };
67
+ }
68
+ function redactValue(value, opts) {
69
+ if (!value) {
70
+ return "(empty)";
71
+ }
72
+ const keepStart = opts?.keepStart ?? 2;
73
+ const keepEnd = opts?.keepEnd ?? 2;
74
+ if (value.length <= keepStart + keepEnd) {
75
+ return "*".repeat(value.length);
76
+ }
77
+ return `${value.slice(0, keepStart)}***${value.slice(-keepEnd)}`;
78
+ }
79
+ function setConfigValue(key, value) {
80
+ const args = ["config", "set", key, String(value)];
81
+ const result = spawnSync("openclaw", args, {
82
+ stdio: ["ignore", "pipe", "pipe"],
83
+ encoding: "utf8",
84
+ timeout: 15e3
85
+ });
86
+ if (result.status !== 0) {
87
+ const stderr = (result.stderr ?? "").trim();
88
+ throw new Error(`openclaw config set failed: ${stderr || `exit code ${result.status}`}`);
89
+ }
90
+ }
91
+ async function loginBaiduApp(params) {
92
+ void params.cfg;
93
+ void params.verbose;
94
+ const agentId = params.accountId?.trim() || "main";
95
+ const prompter = createTerminalPrompter();
96
+ try {
97
+ const mode = await prompter.select("\u8BF7\u9009\u62E9\u767E\u5EA6 App \u914D\u7F6E\u65B9\u5F0F", [
98
+ "\u624B\u52A8\u586B\u5199",
99
+ "\u626B\u7801\u914D\u7F6E\uFF08\u5373\u5C06\u652F\u6301\uFF09"
100
+ ]);
101
+ if (mode === "\u626B\u7801\u914D\u7F6E\uFF08\u5373\u5C06\u652F\u6301\uFF09") {
102
+ params.runtime.log("\u23F3 \u626B\u7801\u914D\u7F6E\u529F\u80FD\u6B63\u5728\u5F00\u53D1\u4E2D\uFF0C\u656C\u8BF7\u671F\u5F85...");
103
+ params.runtime.log("\u8BF7\u5148\u4F7F\u7528\u624B\u52A8\u586B\u5199\u65B9\u5F0F\u5B8C\u6210\u914D\u7F6E\u3002");
104
+ return;
105
+ }
106
+ const appKey = await prompter.text("App Key", { required: true });
107
+ const appSecret = await prompter.text("App Secret", { required: true });
108
+ const accountKeyPrefix = `channels.openclaw-baiduapp.accounts.${agentId}`;
109
+ setConfigValue(`${accountKeyPrefix}.appKey`, appKey);
110
+ setConfigValue(`${accountKeyPrefix}.appSecret`, appSecret);
111
+ setConfigValue(`${accountKeyPrefix}.enabled`, true);
112
+ params.runtime.log(`\u2705 openclaw-baiduapp \u5DF2\u5B8C\u6210\u914D\u7F6E\uFF08account: ${agentId}\uFF09`);
113
+ params.runtime.log(`- appKey: ${redactValue(appKey, { keepStart: 3, keepEnd: 3 })}`);
114
+ params.runtime.log(`- appSecret: ${redactValue(appSecret, { keepStart: 3, keepEnd: 3 })}`);
115
+ } catch (error) {
116
+ const message = error instanceof Error ? error.message : String(error);
117
+ params.runtime.error(`openclaw-baiduapp \u767B\u5F55\u914D\u7F6E\u5931\u8D25\uFF1A${message}`);
118
+ throw error;
119
+ } finally {
120
+ prompter.close();
121
+ }
122
+ }
123
+ var init_login = __esm({
124
+ "src/auth/login.ts"() {
125
+ }
126
+ });
127
+
17
128
  // node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
18
129
  var external_exports = {};
19
130
  __export(external_exports, {
@@ -4056,14 +4167,13 @@ var NEVER = INVALID;
4056
4167
 
4057
4168
  // src/config.ts
4058
4169
  var DEFAULT_ACCOUNT_ID = "default";
4170
+ var DEFAULT_AGENT_ID = "main";
4059
4171
  var DEFAULT_API_BASE = "https://claw.baidu.com";
4060
4172
  var BaiduAppAccountSchema = external_exports.object({
4061
4173
  name: external_exports.string().optional(),
4062
4174
  enabled: external_exports.boolean().optional(),
4063
4175
  pollingEnabled: external_exports.boolean().optional(),
4064
4176
  webhookPath: external_exports.string().optional(),
4065
- token: external_exports.string().optional(),
4066
- encodingAESKey: external_exports.string().optional(),
4067
4177
  appKey: external_exports.string().optional(),
4068
4178
  appSecret: external_exports.string().optional(),
4069
4179
  apiBase: external_exports.string().optional(),
@@ -4082,8 +4192,6 @@ var BaiduAppConfigJsonSchema = {
4082
4192
  enabled: { type: "boolean" },
4083
4193
  pollingEnabled: { type: "boolean" },
4084
4194
  webhookPath: { type: "string" },
4085
- token: { type: "string" },
4086
- encodingAESKey: { type: "string" },
4087
4195
  appKey: { type: "string" },
4088
4196
  appSecret: { type: "string" },
4089
4197
  apiBase: { type: "string" },
@@ -4099,8 +4207,6 @@ var BaiduAppConfigJsonSchema = {
4099
4207
  enabled: { type: "boolean" },
4100
4208
  pollingEnabled: { type: "boolean" },
4101
4209
  webhookPath: { type: "string" },
4102
- token: { type: "string" },
4103
- encodingAESKey: { type: "string" },
4104
4210
  appKey: { type: "string" },
4105
4211
  appSecret: { type: "string" },
4106
4212
  apiBase: { type: "string" },
@@ -4115,6 +4221,10 @@ function normalizeAccountId(raw) {
4115
4221
  const trimmed = String(raw ?? "").trim();
4116
4222
  return trimmed || DEFAULT_ACCOUNT_ID;
4117
4223
  }
4224
+ function extractAgentId(msg) {
4225
+ const raw = msg.agentid ?? "";
4226
+ return raw.trim() || DEFAULT_AGENT_ID;
4227
+ }
4118
4228
  function listConfiguredAccountIds(cfg) {
4119
4229
  const accounts = cfg.channels?.["openclaw-baiduapp"]?.accounts;
4120
4230
  if (!accounts || typeof accounts !== "object") {
@@ -4162,12 +4272,10 @@ function resolveBaiduAppAccount(params) {
4162
4272
  const merged = mergeBaiduAppAccountConfig(params.cfg, accountId);
4163
4273
  const enabled = baseEnabled && merged.enabled !== false;
4164
4274
  const isDefaultAccount = accountId === DEFAULT_ACCOUNT_ID;
4165
- const token = merged.token?.trim() || (isDefaultAccount ? process.env.BAIDU_APP_TOKEN?.trim() : void 0) || void 0;
4166
- const encodingAESKey = merged.encodingAESKey?.trim() || (isDefaultAccount ? process.env.BAIDU_APP_ENCODING_AES_KEY?.trim() : void 0) || void 0;
4167
4275
  const appKey = merged.appKey?.trim() || (isDefaultAccount ? process.env.BAIDU_APP_KEY?.trim() : void 0) || void 0;
4168
4276
  const appSecret = merged.appSecret?.trim() || (isDefaultAccount ? process.env.BAIDU_APP_SECRET?.trim() : void 0) || void 0;
4169
- const configured = Boolean(token && encodingAESKey);
4170
- const canSendActive = Boolean(appKey && appSecret && token && encodingAESKey);
4277
+ const configured = Boolean(appKey && appSecret);
4278
+ const canSendActive = Boolean(appKey && appSecret);
4171
4279
  const rawApiBase = merged.apiBase?.trim() || (isDefaultAccount ? process.env.BAIDU_API_BASE?.trim() : void 0) || void 0;
4172
4280
  const apiBase = (rawApiBase || DEFAULT_API_BASE).replace(/\/+$/, "");
4173
4281
  return {
@@ -4175,8 +4283,6 @@ function resolveBaiduAppAccount(params) {
4175
4283
  name: merged.name?.trim() || void 0,
4176
4284
  enabled,
4177
4285
  configured,
4178
- token,
4179
- encodingAESKey,
4180
4286
  appKey,
4181
4287
  appSecret,
4182
4288
  apiBase,
@@ -4184,6 +4290,37 @@ function resolveBaiduAppAccount(params) {
4184
4290
  config: merged
4185
4291
  };
4186
4292
  }
4293
+ function resolveAgentField(agentCfg, mainCfg, baseAccount, field) {
4294
+ return agentCfg?.[field]?.trim() || mainCfg?.[field]?.trim() || baseAccount[field];
4295
+ }
4296
+ function resolveAgentAccount(params) {
4297
+ const { baseAccount, cfg, agentId } = params;
4298
+ if (agentId === baseAccount.accountId) {
4299
+ return baseAccount;
4300
+ }
4301
+ const accounts = cfg.channels?.["openclaw-baiduapp"]?.accounts;
4302
+ const agentCfg = accounts?.[agentId] && typeof accounts[agentId] === "object" ? accounts[agentId] : void 0;
4303
+ const mainCfg = agentId !== DEFAULT_AGENT_ID && accounts?.[DEFAULT_AGENT_ID] && typeof accounts[DEFAULT_AGENT_ID] === "object" ? accounts[DEFAULT_AGENT_ID] : void 0;
4304
+ const appKey = resolveAgentField(agentCfg, mainCfg, baseAccount, "appKey");
4305
+ const appSecret = resolveAgentField(agentCfg, mainCfg, baseAccount, "appSecret");
4306
+ const apiBase = baseAccount.apiBase;
4307
+ const name = resolveAgentField(agentCfg, mainCfg, baseAccount, "name");
4308
+ const configured = Boolean(appKey && appSecret);
4309
+ const canSendActive = Boolean(appKey && appSecret);
4310
+ const agentEnabled = agentCfg?.enabled !== false;
4311
+ return {
4312
+ ...baseAccount,
4313
+ accountId: agentId,
4314
+ name: name || baseAccount.name,
4315
+ enabled: agentEnabled && baseAccount.enabled,
4316
+ configured,
4317
+ appKey,
4318
+ appSecret,
4319
+ apiBase,
4320
+ canSendActive,
4321
+ config: { ...baseAccount.config, ...mainCfg ?? {}, ...agentCfg ?? {} }
4322
+ };
4323
+ }
4187
4324
 
4188
4325
  // src/shared/logger.ts
4189
4326
  function createLogger(prefix, opts) {
@@ -4196,86 +4333,27 @@ function createLogger(prefix, opts) {
4196
4333
  error: (msg) => errorFn(`[${prefix}] [ERROR] ${msg}`)
4197
4334
  };
4198
4335
  }
4199
- function decodeEncodingAESKey(encodingAESKey) {
4200
- const trimmed = encodingAESKey.trim();
4201
- if (!trimmed) {
4202
- throw new Error("encodingAESKey missing");
4203
- }
4204
- const withPadding = trimmed.endsWith("=") ? trimmed : `${trimmed}=`;
4205
- const key = Buffer.from(withPadding, "base64");
4206
- if (key.length !== 32) {
4207
- throw new Error(`invalid encodingAESKey (expected 32 bytes after base64 decode, got ${key.length})`);
4208
- }
4209
- return key;
4210
- }
4211
- var PKCS7_BLOCK_SIZE = 32;
4212
- function pkcs7Pad(buf, blockSize) {
4213
- const mod = buf.length % blockSize;
4214
- const pad = mod === 0 ? blockSize : blockSize - mod;
4215
- return Buffer.concat([buf, Buffer.alloc(pad, pad)]);
4216
- }
4217
- function pkcs7Unpad(buf, blockSize) {
4218
- if (buf.length === 0) {
4219
- throw new Error("invalid pkcs7 payload");
4220
- }
4221
- const pad = buf[buf.length - 1];
4222
- if (!pad || pad < 1 || pad > blockSize || pad > buf.length) {
4223
- throw new Error("invalid pkcs7 padding");
4224
- }
4225
- for (let i = 1; i <= pad; i += 1) {
4226
- if (buf[buf.length - i] !== pad) {
4227
- throw new Error("invalid pkcs7 padding");
4228
- }
4229
- }
4230
- return buf.subarray(0, buf.length - pad);
4231
- }
4232
4336
  function sha1Hex(input) {
4233
- return crypto3.createHash("sha1").update(input).digest("hex");
4337
+ return crypto2.createHash("sha1").update(input).digest("hex");
4234
4338
  }
4235
- function computeBaiduAppMsgSignature(params) {
4236
- const parts = [params.token, params.timestamp, params.nonce, params.encrypt].map((value) => String(value ?? "")).sort();
4237
- return sha1Hex(parts.join(""));
4339
+ function computeAKSKBearerToken(params) {
4340
+ return sha1Hex(params.ak + params.sk + params.timestamp + params.nonce);
4238
4341
  }
4239
- function verifyBaiduAppSignature(params) {
4240
- const expected = computeBaiduAppMsgSignature({
4241
- token: params.token,
4342
+ function verifyAKSKBearerToken(params) {
4343
+ const expected = computeAKSKBearerToken({
4344
+ ak: params.ak,
4345
+ sk: params.sk,
4242
4346
  timestamp: params.timestamp,
4243
- nonce: params.nonce,
4244
- encrypt: params.encrypt
4347
+ nonce: params.nonce
4245
4348
  });
4246
- return expected === params.signature;
4349
+ return expected === params.token;
4247
4350
  }
4248
- function decryptBaiduAppEncrypted(params) {
4249
- const aesKey = decodeEncodingAESKey(params.encodingAESKey);
4250
- const iv = aesKey.subarray(0, 16);
4251
- const decipher = crypto3.createDecipheriv("aes-256-cbc", aesKey, iv);
4252
- decipher.setAutoPadding(false);
4253
- const decryptedPadded = Buffer.concat([decipher.update(Buffer.from(params.encrypt, "base64")), decipher.final()]);
4254
- const decrypted = pkcs7Unpad(decryptedPadded, PKCS7_BLOCK_SIZE);
4255
- if (decrypted.length < 20) {
4256
- throw new Error(`invalid decrypted payload (expected at least 20 bytes, got ${decrypted.length})`);
4257
- }
4258
- const msgLen = decrypted.readUInt32BE(16);
4259
- const msgStart = 20;
4260
- const msgEnd = msgStart + msgLen;
4261
- if (msgEnd > decrypted.length) {
4262
- throw new Error(`invalid decrypted msg length (msgEnd=${msgEnd}, payloadLength=${decrypted.length})`);
4263
- }
4264
- return decrypted.subarray(msgStart, msgEnd).toString("utf8");
4351
+ function generateNonce() {
4352
+ return crypto2.randomBytes(8).toString("hex");
4265
4353
  }
4266
- function encryptBaiduAppPlaintext(params) {
4267
- const aesKey = decodeEncodingAESKey(params.encodingAESKey);
4268
- const iv = aesKey.subarray(0, 16);
4269
- const random16 = crypto3.randomBytes(16);
4270
- const msg = Buffer.from(params.plaintext ?? "", "utf8");
4271
- const msgLen = Buffer.alloc(4);
4272
- msgLen.writeUInt32BE(msg.length, 0);
4273
- const raw = Buffer.concat([random16, msgLen, msg]);
4274
- const padded = pkcs7Pad(raw, PKCS7_BLOCK_SIZE);
4275
- const cipher = crypto3.createCipheriv("aes-256-cbc", aesKey, iv);
4276
- cipher.setAutoPadding(false);
4277
- const encrypted = Buffer.concat([cipher.update(padded), cipher.final()]);
4278
- return encrypted.toString("base64");
4354
+ function buildAuthorizationHeader(params) {
4355
+ const token = computeAKSKBearerToken(params);
4356
+ return `Bearer ${token}`;
4279
4357
  }
4280
4358
  var require2 = createRequire(import.meta.url);
4281
4359
  var pkg = require2("../package.json");
@@ -4283,48 +4361,54 @@ var PLUGIN_VERSION = pkg.version;
4283
4361
 
4284
4362
  // src/api.ts
4285
4363
  var logger = createLogger("openclaw-baiduapp");
4364
+ var DEFAULT_sessionId = "agent:main:main";
4286
4365
  async function sendBaiduAppMessage(account, message, options) {
4287
4366
  if (!account.canSendActive) {
4288
- logger.error("Account not configured for active sending (missing appKey, token, or encodingAESKey)");
4367
+ logger.error("Account not configured for active sending (missing appKey or appSecret)");
4289
4368
  return {
4290
4369
  ok: false,
4291
4370
  errcode: -1,
4292
- errmsg: "Account not configured for active sending (missing appKey, token, or encodingAESKey)"
4371
+ errmsg: "Account not configured for active sending (missing appKey or appSecret)"
4293
4372
  };
4294
4373
  }
4295
4374
  const normalizedPayload = typeof message === "string" ? {
4296
- msgtype: "text",
4297
- text: { content: message }
4375
+ list: [{
4376
+ type: "text",
4377
+ data: {
4378
+ text: { content: message }
4379
+ }
4380
+ }]
4298
4381
  } : message;
4299
- const payload = {
4300
- ...normalizedPayload,
4382
+ const sessionId = options?.sessionId ?? DEFAULT_sessionId;
4383
+ const callbackBody = {
4384
+ sessionId,
4385
+ list: normalizedPayload.list,
4301
4386
  version: PLUGIN_VERSION,
4302
- ...options?.msgid != null ? { msgid: options.msgid } : {},
4303
- ...options?.streamId != null ? { streamId: options.streamId } : {},
4304
- ...options?.chunkKey != null ? { chunkKey: options.chunkKey } : {}
4387
+ isActive: options?.isActive || false,
4388
+ ...options?.agentid ? { agentid: options.agentid } : {},
4389
+ ...options?.chunkKey != null ? { chunkKey: options.chunkKey } : {},
4390
+ ...options?.replyToMsgId ? { replyToMsgId: options.replyToMsgId } : {}
4305
4391
  };
4306
- const plaintext = JSON.stringify(payload);
4307
- const encrypt = encryptBaiduAppPlaintext({
4308
- encodingAESKey: account.encodingAESKey ?? "",
4309
- plaintext
4310
- });
4311
4392
  const timestamp = String(Math.floor(Date.now() / 1e3));
4312
- const nonce = crypto3.randomBytes(8).toString("hex");
4313
- const msgSignature = computeBaiduAppMsgSignature({
4314
- token: account.token ?? "",
4393
+ const nonce = generateNonce();
4394
+ const authorization = buildAuthorizationHeader({
4395
+ ak: account.appKey ?? "",
4396
+ sk: account.appSecret ?? "",
4315
4397
  timestamp,
4316
- nonce,
4317
- encrypt
4398
+ nonce
4318
4399
  });
4319
- const sendMessageUrl = `${account.apiBase}/chat/openclaw/callback`;
4320
- const url = `${sendMessageUrl}?timestamp=${encodeURIComponent(timestamp)}&ak=${encodeURIComponent(account.appKey ?? "")}&nonce=${encodeURIComponent(nonce)}&msg_signature=${encodeURIComponent(msgSignature)}`;
4321
- const body = JSON.stringify({ encrypt });
4400
+ const sendMessageUrl = `${account.apiBase}/channel/msg/callback`;
4401
+ const url = `${sendMessageUrl}?timestamp=${encodeURIComponent(timestamp)}&ak=${encodeURIComponent(account.appKey ?? "")}&nonce=${encodeURIComponent(nonce)}`;
4402
+ const body = JSON.stringify(callbackBody);
4322
4403
  logger.info(`POST ${url}`);
4323
4404
  logger.debug(`request body: ${body}`);
4324
4405
  const resp = await fetch(url, {
4325
4406
  method: "POST",
4326
4407
  body,
4327
- headers: { "Content-Type": "application/json" }
4408
+ headers: {
4409
+ "Authorization": authorization,
4410
+ "Content-Type": "application/json"
4411
+ }
4328
4412
  });
4329
4413
  const text = await resp.text();
4330
4414
  if (!text) {
@@ -4365,21 +4449,21 @@ function buildMediaPayload(mediaList, opts) {
4365
4449
 
4366
4450
  // src/bot.ts
4367
4451
  function extractBaiduAppTextContent(msg) {
4368
- const msgtype = String(msg.msgtype ?? msg.MsgType ?? "").toLowerCase();
4452
+ const msgtype = String(msg.msgtype ?? "").toLowerCase();
4369
4453
  if (msgtype === "text") {
4370
- const content = msg.text?.content ?? msg.Content;
4454
+ const content = msg.text?.content;
4371
4455
  return typeof content === "string" ? content : "";
4372
4456
  }
4373
4457
  if (msgtype === "event") {
4374
4458
  const eventtype = String(
4375
- msg.event?.eventtype ?? msg.Event ?? ""
4459
+ msg.event?.eventtype ?? ""
4376
4460
  ).trim();
4377
4461
  return eventtype ? `[event] ${eventtype}` : "[event]";
4378
4462
  }
4379
4463
  return msgtype ? `[${msgtype}]` : "";
4380
4464
  }
4381
4465
  function canDispatchBaiduAppInboundMessage(msg) {
4382
- const msgtype = String(msg.msgtype ?? msg.MsgType ?? "").toLowerCase();
4466
+ const msgtype = String(msg.msgtype ?? "").toLowerCase();
4383
4467
  if (msgtype === "text") {
4384
4468
  if (extractBaiduAppTextContent(msg)) {
4385
4469
  return true;
@@ -4449,7 +4533,7 @@ async function dispatchBaiduAppMessage(params) {
4449
4533
  cfg: safeCfg,
4450
4534
  channel: "openclaw-baiduapp",
4451
4535
  accountId: account.accountId,
4452
- peer: { kind: "dm", id: "default" }
4536
+ peer: { kind: "dm", id: account.accountId || DEFAULT_AGENT_ID }
4453
4537
  });
4454
4538
  logger3.info(`SessionKey: ${route.sessionKey}`);
4455
4539
  logger3.info(
@@ -4479,7 +4563,7 @@ async function dispatchBaiduAppMessage(params) {
4479
4563
  envelope: envelopeOptions,
4480
4564
  body: rawBody
4481
4565
  }) : rawBody;
4482
- const msgid = msg.msgid ?? msg.MsgId ?? void 0;
4566
+ const msgid = msg.msgid ?? void 0;
4483
4567
  const ctxPayload = channel.reply?.finalizeInboundContext ? channel.reply.finalizeInboundContext({
4484
4568
  Body: body,
4485
4569
  RawBody: rawBody,
@@ -4685,7 +4769,7 @@ var require3 = createRequire(import.meta.url);
4685
4769
  var BaiduCloudSdk = require3("@baiducloud/sdk");
4686
4770
  var DefaultBosClient = BaiduCloudSdk.BosClient;
4687
4771
  var MAX_DOWNLOAD_REDIRECTS = 5;
4688
- var EMPTY_QUERY_MD5 = crypto3.createHash("md5").update("").digest("hex");
4772
+ var EMPTY_QUERY_MD5 = crypto2.createHash("md5").update("").digest("hex");
4689
4773
  var SKS_BASE_TOKEN_POSITIONS = [12, 37, 5, 23, 48, 15, 62, 33];
4690
4774
  async function fetchSksCredentials(account, deps = {}) {
4691
4775
  if (!account.appKey?.trim()) {
@@ -4699,7 +4783,7 @@ async function fetchSksCredentials(account, deps = {}) {
4699
4783
  const pageLid = deps.createPageLid?.() ?? generateSksPageLid();
4700
4784
  const timestamp = String((deps.now?.() ?? /* @__PURE__ */ new Date()).getTime());
4701
4785
  const token = createSksRequestToken({ pageLid, timestamp });
4702
- const url = `${apiBase}/file/sts?ak=${encodeURIComponent(account.appKey)}&sk=${encodeURIComponent(account.appSecret)}&tk=${encodeURIComponent(token)}`;
4786
+ const url = `${apiBase}/channel/file/sts?ak=${encodeURIComponent(account.appKey)}&sk=${encodeURIComponent(account.appSecret)}&tk=${encodeURIComponent(token)}`;
4703
4787
  const response = await fetchImpl(url, { method: "POST" });
4704
4788
  if (!response.ok) {
4705
4789
  throw new Error(`SKS request failed with HTTP ${response.status}`);
@@ -4888,10 +4972,10 @@ function parseSksResponse(payload) {
4888
4972
  };
4889
4973
  }
4890
4974
  function generateSksPageLid() {
4891
- return crypto3.randomBytes(16).toString("hex");
4975
+ return crypto2.randomBytes(16).toString("hex");
4892
4976
  }
4893
4977
  function createSksBaseToken(pageLid) {
4894
- const pageLidHash = crypto3.createHash("sha256").update(pageLid).digest("hex");
4978
+ const pageLidHash = crypto2.createHash("sha256").update(pageLid).digest("hex");
4895
4979
  const characters = SKS_BASE_TOKEN_POSITIONS.map((position) => {
4896
4980
  const character = pageLidHash[position];
4897
4981
  if (!character) {
@@ -4950,7 +5034,7 @@ function assertSafeUntrustedFileName(fileName) {
4950
5034
  }
4951
5035
  function buildBosObjectKey(params) {
4952
5036
  const timestamp = formatUtcDate(params.now?.() ?? /* @__PURE__ */ new Date());
4953
- const uniqueId = crypto3.randomUUID();
5037
+ const uniqueId = crypto2.randomUUID();
4954
5038
  return `${params.prefixPath}/${timestamp}/${uniqueId}-${params.fileName}`;
4955
5039
  }
4956
5040
  function formatUtcDate(date) {
@@ -5083,7 +5167,7 @@ function resolveDownloadFileName(params) {
5083
5167
  }
5084
5168
  function buildTempFilePath(params) {
5085
5169
  const timestamp = (params.now?.() ?? /* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
5086
- return path2.join(params.tempDir, `${timestamp}-${crypto3.randomUUID()}-${params.fileName}`);
5170
+ return path2.join(params.tempDir, `${timestamp}-${crypto2.randomUUID()}-${params.fileName}`);
5087
5171
  }
5088
5172
  async function ensurePluginTempDir(resolveTmpDir) {
5089
5173
  const baseTmpDir = resolveTmpDir?.() ?? resolvePreferredOpenClawTmpDir();
@@ -5144,12 +5228,12 @@ function normalizeWebhookPath(raw) {
5144
5228
  function jsonOk(res, body) {
5145
5229
  res.statusCode = 200;
5146
5230
  res.setHeader("Content-Type", "application/json; charset=utf-8");
5147
- res.end(JSON.stringify({ status: 0, data: body }));
5231
+ res.end(JSON.stringify({ code: 0, msg: "success", data: body }));
5148
5232
  }
5149
5233
  function jsonError(res, message, statusCode = 200) {
5150
5234
  res.statusCode = statusCode;
5151
5235
  res.setHeader("Content-Type", "application/json; charset=utf-8");
5152
- res.end(JSON.stringify({ status: -1, message }));
5236
+ res.end(JSON.stringify({ code: -1, msg: message, data: {} }));
5153
5237
  }
5154
5238
  async function readRawBody(req, maxBytes) {
5155
5239
  const chunks = [];
@@ -5181,47 +5265,6 @@ async function readRawBody(req, maxBytes) {
5181
5265
  });
5182
5266
  });
5183
5267
  }
5184
- function parseXmlBody(xml) {
5185
- const result = {};
5186
- const cdataRegex = /<(\w+)><!\[CDATA\[([\s\S]*?)\]\]><\/\1>/g;
5187
- let match;
5188
- while ((match = cdataRegex.exec(xml)) !== null) {
5189
- const [, key = "", value = ""] = match;
5190
- result[key] = value;
5191
- }
5192
- const simpleRegex = /<(\w+)>([^<]*)<\/\1>/g;
5193
- while ((match = simpleRegex.exec(xml)) !== null) {
5194
- const [, key = "", value = ""] = match;
5195
- if (!result[key]) {
5196
- result[key] = value;
5197
- }
5198
- }
5199
- return result;
5200
- }
5201
- function isXmlFormat(raw) {
5202
- const trimmed = raw.trim();
5203
- return trimmed.startsWith("<") && trimmed.endsWith(">");
5204
- }
5205
- function buildEncryptedJsonReply(params) {
5206
- const base = params.plaintextJson != null && typeof params.plaintextJson === "object" ? params.plaintextJson : {};
5207
- const plaintext = JSON.stringify({ ...base, version: PLUGIN_VERSION });
5208
- const encrypt = encryptBaiduAppPlaintext({
5209
- encodingAESKey: params.account.encodingAESKey ?? "",
5210
- plaintext
5211
- });
5212
- const msgsignature = computeBaiduAppMsgSignature({
5213
- token: params.account.token ?? "",
5214
- timestamp: params.timestamp,
5215
- nonce: params.nonce,
5216
- encrypt
5217
- });
5218
- return {
5219
- encrypt,
5220
- msgsignature,
5221
- timestamp: params.timestamp,
5222
- nonce: params.nonce
5223
- };
5224
- }
5225
5268
  function resolveQueryParams(req) {
5226
5269
  const url = new URL(req.url ?? "/", "http://localhost");
5227
5270
  return url.searchParams;
@@ -5230,8 +5273,16 @@ function resolvePath(req) {
5230
5273
  const url = new URL(req.url ?? "/", "http://localhost");
5231
5274
  return normalizeWebhookPath(url.pathname || "/");
5232
5275
  }
5233
- function resolveSignatureParam(params) {
5234
- return params.get("msg_signature") ?? params.get("msgsignature") ?? params.get("signature") ?? "";
5276
+ function resolveBearerToken(req) {
5277
+ const authorization = req.headers.authorization ?? req.headers.Authorization;
5278
+ if (Array.isArray(authorization)) {
5279
+ return "";
5280
+ }
5281
+ const value = typeof authorization === "string" ? authorization.trim() : "";
5282
+ if (!value.toLowerCase().startsWith("bearer ")) {
5283
+ return "";
5284
+ }
5285
+ return value.slice(7).trim();
5235
5286
  }
5236
5287
  function buildLogger(target) {
5237
5288
  return createLogger("openclaw-baiduapp", {
@@ -5299,50 +5350,49 @@ async function downloadInboundFiles(params) {
5299
5350
  }
5300
5351
  };
5301
5352
  }
5302
- function parseBaiduAppPlainMessage(raw) {
5303
- const trimmed = raw.trim();
5304
- if (trimmed.startsWith("<") && trimmed.endsWith(">")) {
5305
- const xmlData = parseXmlBody(trimmed);
5306
- return {
5307
- msgtype: xmlData.MsgType,
5308
- MsgType: xmlData.MsgType,
5309
- msgid: xmlData.MsgId,
5310
- MsgId: xmlData.MsgId,
5311
- content: xmlData.Content,
5312
- Content: xmlData.Content,
5313
- from: xmlData.FromUserName ? { appkey: xmlData.FromUserName } : void 0,
5314
- ToUserName: xmlData.ToUserName,
5315
- CreateTime: xmlData.CreateTime ? Number(xmlData.CreateTime) : void 0,
5316
- BotID: xmlData.BotID ? Number(xmlData.BotID) : void 0,
5317
- Event: xmlData.Event
5318
- };
5319
- }
5353
+ function parseV2MsgToInbound(inner, outer) {
5354
+ const list = Array.isArray(inner.list) ? inner.list : [];
5355
+ const textItem = list.find(
5356
+ (item) => item && typeof item === "object" && item.type === "text"
5357
+ );
5358
+ const fileItems = list.filter(
5359
+ (item) => item && typeof item === "object" && item.type === "file"
5360
+ );
5361
+ const textContent = textItem?.data?.text?.content ?? "";
5362
+ const files = fileItems.map((f) => ({ url: f.data.file_id, fileType: "file" }));
5363
+ return {
5364
+ msgtype: "text",
5365
+ msgid: typeof outer.msgid === "string" ? outer.msgid : void 0,
5366
+ agentid: typeof outer.agentid === "string" ? outer.agentid : void 0,
5367
+ text: textContent ? { content: textContent } : void 0,
5368
+ ...files.length > 0 ? { files } : {}
5369
+ };
5370
+ }
5371
+ function parseBaiduAppCandidates(params) {
5372
+ const results = [];
5373
+ let outer = {};
5320
5374
  try {
5321
- const parsed = JSON.parse(trimmed);
5322
- if (!parsed || typeof parsed !== "object") {
5323
- return {};
5375
+ const parsed = JSON.parse(params.raw);
5376
+ if (parsed && typeof parsed === "object") {
5377
+ outer = parsed;
5324
5378
  }
5325
- return parsed;
5326
5379
  } catch {
5327
- return {};
5380
+ outer = {};
5328
5381
  }
5329
- }
5330
- function decryptBaiduAppCandidates(params) {
5331
- const results = [];
5332
- for (const candidate of params.candidates) {
5333
- if (!candidate.account.encodingAESKey) {
5334
- continue;
5335
- }
5382
+ let inner = {};
5383
+ if (typeof outer.msg === "string") {
5336
5384
  try {
5337
- const plaintext = decryptBaiduAppEncrypted({
5338
- encodingAESKey: candidate.account.encodingAESKey,
5339
- encrypt: params.encrypt
5340
- });
5341
- const msg = parseBaiduAppPlainMessage(plaintext);
5342
- results.push({ target: candidate, plaintext, msg });
5385
+ const parsedInner = JSON.parse(outer.msg);
5386
+ if (parsedInner && typeof parsedInner === "object") {
5387
+ inner = parsedInner;
5388
+ }
5343
5389
  } catch {
5390
+ inner = {};
5344
5391
  }
5345
5392
  }
5393
+ for (const candidate of params.candidates) {
5394
+ results.push({ target: candidate, msg: parseV2MsgToInbound(inner, outer) });
5395
+ }
5346
5396
  return results;
5347
5397
  }
5348
5398
  function selectDecryptedTarget(params) {
@@ -5359,8 +5409,9 @@ async function processBaiduAppInboundMessage(params) {
5359
5409
  const { target, msg } = params;
5360
5410
  const logger3 = buildLogger(target);
5361
5411
  target.statusSink?.({ lastInboundAt: Date.now() });
5362
- const msgtype = String(msg.msgtype ?? msg.MsgType ?? "").toLowerCase();
5363
- const msgid = msg.msgid ?? msg.MsgId ? String(msg.msgid ?? msg.MsgId) : void 0;
5412
+ const msgtype = String(msg.msgtype ?? "").toLowerCase();
5413
+ const msgid = msg.msgid ? String(msg.msgid) : void 0;
5414
+ const agentId = extractAgentId(msg);
5364
5415
  logger3.info(`inbound: type=${msgtype || "unknown"} msgid=${msgid ?? "none"} account=${target.account.accountId}`);
5365
5416
  if (!canDispatchBaiduAppInboundMessage(msg)) {
5366
5417
  logger3.warn(`inbound message skipped: type=${msgtype || "unknown"} reason=no-dispatchable-content`);
@@ -5368,6 +5419,11 @@ async function processBaiduAppInboundMessage(params) {
5368
5419
  }
5369
5420
  const inboundFileResult = msgtype === "text" ? await downloadInboundFiles({ msg, logger: logger3, runtime: target.runtime }) : { localFiles: [], diagnostic: {} };
5370
5421
  const inboundMediaFiles = inboundFileResult.localFiles;
5422
+ const agentAccount = resolveAgentAccount({
5423
+ baseAccount: target.account,
5424
+ cfg: target.config,
5425
+ agentId
5426
+ });
5371
5427
  const core = tryGetBaiduAppRuntime();
5372
5428
  if (core) {
5373
5429
  logger3.info(`agent dispatch started: canSendActive=${target.account.canSendActive}`);
@@ -5380,8 +5436,9 @@ async function processBaiduAppInboundMessage(params) {
5380
5436
  );
5381
5437
  target.statusSink?.({ lastOutboundAt: Date.now() });
5382
5438
  if (target.account.canSendActive) {
5383
- sendBaiduAppMessage(target.account, text, {
5384
- msgid,
5439
+ sendBaiduAppMessage(agentAccount, text, {
5440
+ replyToMsgId: msgid,
5441
+ agentid: agentId,
5385
5442
  chunkKey: currentChunkKey
5386
5443
  }).then((result) => {
5387
5444
  if (!result.ok) {
@@ -5404,7 +5461,7 @@ async function processBaiduAppInboundMessage(params) {
5404
5461
  };
5405
5462
  dispatchBaiduAppMessage({
5406
5463
  cfg: target.config,
5407
- account: target.account,
5464
+ account: agentAccount,
5408
5465
  msg,
5409
5466
  core,
5410
5467
  hooks,
@@ -5446,53 +5503,43 @@ async function handleBaiduAppWebhookRequest(req, res) {
5446
5503
  const query = resolveQueryParams(req);
5447
5504
  const timestamp = query.get("timestamp") ?? "";
5448
5505
  const nonce = query.get("nonce") ?? "";
5449
- const signature = resolveSignatureParam(query);
5506
+ const ak = query.get("ak") ?? "";
5507
+ const token = resolveBearerToken(req);
5450
5508
  const primary = targets[0];
5451
5509
  const logger3 = buildLogger(primary);
5452
5510
  if (req.method === "GET") {
5453
5511
  const echostr = query.get("echostr") ?? "";
5454
- if (!timestamp || !nonce || !signature || !echostr) {
5512
+ if (!ak || !timestamp || !nonce || !token || !echostr) {
5455
5513
  jsonError(res, "missing query params", 400);
5456
5514
  return true;
5457
5515
  }
5458
- const signatureMatched2 = targets.filter((candidate) => {
5459
- if (!candidate.account.token) {
5516
+ const tokenMatched2 = targets.filter((candidate) => {
5517
+ if (!candidate.account.appKey || !candidate.account.appSecret) {
5518
+ return false;
5519
+ }
5520
+ if (candidate.account.appKey !== ak) {
5460
5521
  return false;
5461
5522
  }
5462
- return verifyBaiduAppSignature({
5463
- token: candidate.account.token,
5523
+ return verifyAKSKBearerToken({
5524
+ ak: candidate.account.appKey,
5525
+ sk: candidate.account.appSecret,
5464
5526
  timestamp,
5465
5527
  nonce,
5466
- encrypt: echostr,
5467
- signature
5528
+ token
5468
5529
  });
5469
5530
  });
5470
- if (signatureMatched2.length === 0) {
5471
- jsonError(res, "unauthorized");
5472
- return true;
5473
- }
5474
- const decryptable2 = signatureMatched2.filter((candidate) => Boolean(candidate.account.encodingAESKey));
5475
- if (decryptable2.length === 0) {
5531
+ if (tokenMatched2.length === 0) {
5476
5532
  jsonError(res, "unauthorized");
5477
5533
  return true;
5478
5534
  }
5479
- const decryptedCandidates2 = decryptBaiduAppCandidates({
5480
- candidates: decryptable2,
5481
- encrypt: echostr
5482
- });
5483
- if (decryptedCandidates2.length === 0) {
5484
- jsonError(res, "decrypt failed");
5485
- return true;
5486
- }
5487
- const selected2 = selectDecryptedTarget({ candidates: decryptedCandidates2, logger: logger3 });
5488
- jsonOk(res, selected2.plaintext);
5535
+ jsonOk(res, echostr);
5489
5536
  return true;
5490
5537
  }
5491
5538
  if (req.method !== "POST") {
5492
5539
  jsonError(res, "Method Not Allowed", 405);
5493
5540
  return true;
5494
5541
  }
5495
- if (!timestamp || !nonce || !signature) {
5542
+ if (!ak || !timestamp || !nonce || !token) {
5496
5543
  jsonError(res, "missing query params");
5497
5544
  return true;
5498
5545
  }
@@ -5502,90 +5549,56 @@ async function handleBaiduAppWebhookRequest(req, res) {
5502
5549
  return true;
5503
5550
  }
5504
5551
  const rawBody = body.raw;
5505
- let encrypt = "";
5506
- let msgSignature = signature;
5507
- let msgTimestamp = timestamp;
5508
- let msgNonce = nonce;
5509
- if (isXmlFormat(rawBody)) {
5510
- const xmlData = parseXmlBody(rawBody);
5511
- encrypt = xmlData.Encrypt ?? "";
5512
- msgSignature = xmlData.MsgSignature ?? signature;
5513
- msgTimestamp = xmlData.TimeStamp ?? timestamp;
5514
- msgNonce = xmlData.Nonce ?? nonce;
5515
- logger3.info(`inbound xml parsed: hasEncrypt=${Boolean(encrypt)}, msg_signature=${msgSignature ? "yes" : "no"}`);
5516
- } else {
5517
- try {
5518
- const record = JSON.parse(rawBody);
5519
- encrypt = String(record.encrypt ?? record.Encrypt ?? "");
5520
- logger3.info(`inbound json parsed: hasEncrypt=${Boolean(encrypt)}`);
5521
- } catch {
5522
- logger3.warn(`inbound payload parse failed: not valid xml or json`);
5523
- jsonError(res, "invalid payload format");
5524
- return true;
5525
- }
5526
- }
5527
- if (!encrypt) {
5528
- jsonError(res, "missing encrypt");
5552
+ try {
5553
+ JSON.parse(rawBody);
5554
+ logger3.info("inbound json parsed");
5555
+ } catch {
5556
+ logger3.warn("inbound payload parse failed: not valid json");
5557
+ jsonError(res, "invalid payload format");
5529
5558
  return true;
5530
5559
  }
5531
- const signatureMatched = targets.filter((candidate) => {
5532
- if (!candidate.account.token) {
5560
+ const tokenMatched = targets.filter((candidate) => {
5561
+ if (!candidate.account.appKey || !candidate.account.appSecret) {
5562
+ return false;
5563
+ }
5564
+ if (candidate.account.appKey !== ak) {
5533
5565
  return false;
5534
5566
  }
5535
- return verifyBaiduAppSignature({
5536
- token: candidate.account.token,
5537
- timestamp: msgTimestamp,
5538
- nonce: msgNonce,
5539
- encrypt,
5540
- signature: msgSignature
5567
+ return verifyAKSKBearerToken({
5568
+ ak: candidate.account.appKey,
5569
+ sk: candidate.account.appSecret,
5570
+ timestamp,
5571
+ nonce,
5572
+ token
5541
5573
  });
5542
5574
  });
5543
- if (signatureMatched.length === 0) {
5544
- logger3.warn(`signature verification failed: checked ${targets.length} account(s), none matched`);
5575
+ if (tokenMatched.length === 0) {
5576
+ logger3.warn(`bearer token verification failed: checked ${targets.length} account(s), none matched`);
5545
5577
  jsonError(res, "unauthorized");
5546
5578
  return true;
5547
5579
  }
5548
- logger3.debug(`signature verified: ${signatureMatched.length} account(s) matched`);
5549
- const decryptable = signatureMatched.filter((candidate) => Boolean(candidate.account.encodingAESKey));
5550
- if (decryptable.length === 0) {
5551
- logger3.warn(`no account has encodingAESKey configured`);
5552
- jsonError(res, "openclaw-baiduapp not configured");
5553
- return true;
5554
- }
5555
- const decryptedCandidates = decryptBaiduAppCandidates({
5556
- candidates: decryptable,
5557
- encrypt
5580
+ logger3.debug(`bearer token verified: ${tokenMatched.length} account(s) matched`);
5581
+ const decryptedCandidates = parseBaiduAppCandidates({
5582
+ candidates: tokenMatched,
5583
+ raw: rawBody
5558
5584
  });
5559
- if (decryptedCandidates.length === 0) {
5560
- logger3.warn(`decrypt failed for all ${decryptable.length} candidate account(s)`);
5561
- jsonError(res, "decrypt failed");
5562
- return true;
5563
- }
5564
5585
  const selected = selectDecryptedTarget({ candidates: decryptedCandidates, logger: logger3 });
5565
5586
  const target = selected.target;
5566
- if (!target.account.configured || !target.account.token || !target.account.encodingAESKey) {
5587
+ if (!target.account.configured || !target.account.appKey || !target.account.appSecret) {
5567
5588
  logger3.warn(`selected account ${target.account.accountId} not fully configured`);
5568
5589
  jsonError(res, "openclaw-baiduapp not configured");
5569
5590
  return true;
5570
5591
  }
5571
- const reply = await processBaiduAppInboundMessage({
5592
+ await processBaiduAppInboundMessage({
5572
5593
  target,
5573
5594
  msg: selected.msg
5574
5595
  });
5575
- jsonOk(
5576
- res,
5577
- buildEncryptedJsonReply({
5578
- account: target.account,
5579
- plaintextJson: reply,
5580
- nonce: msgNonce,
5581
- timestamp: msgTimestamp
5582
- })
5583
- );
5596
+ jsonOk(res, {});
5584
5597
  return true;
5585
5598
  }
5586
5599
 
5587
5600
  // src/poller.ts
5588
- var DEFAULT_POLL_INTERVAL_MS = 1e3;
5601
+ var DEFAULT_POLL_INTERVAL_MS = 3e3;
5589
5602
  var DEFAULT_POLL_REQUEST_TIMEOUT_MS = 1e4;
5590
5603
  var accountPollers = /* @__PURE__ */ new Map();
5591
5604
  function buildPollingTextInboundMessage(content) {
@@ -5596,21 +5609,36 @@ function buildPollingTextInboundMessage(content) {
5596
5609
  }
5597
5610
  };
5598
5611
  }
5612
+ function parseTextAndFilesFromList(list) {
5613
+ const textItem = list.find((entry) => entry.type === "text");
5614
+ const fileItems = list.filter((entry) => entry.type === "file");
5615
+ const content = textItem?.type === "text" ? textItem.data.text.content : void 0;
5616
+ const files = fileItems.map((file) => {
5617
+ const fileId = file.data.file_id;
5618
+ return typeof fileId === "string" && fileId.trim() ? { url: fileId, fileType: "file" } : null;
5619
+ }).filter((file) => file != null);
5620
+ return { content, files };
5621
+ }
5599
5622
  async function dispatchPendingPollingMessages(data, target) {
5623
+ console.log(data);
5600
5624
  if (!target || data.length === 0) {
5601
5625
  return;
5602
5626
  }
5603
5627
  for (const item of data) {
5604
- if (String(item.msgtype).toLowerCase() !== "text") {
5605
- continue;
5606
- }
5607
- const content = item.data?.content;
5608
- if (typeof content !== "string" || content.length === 0) {
5628
+ const list = Array.isArray(item.list) ? item.list : [];
5629
+ const { content, files } = parseTextAndFilesFromList(list);
5630
+ console.log({ content, files });
5631
+ if (typeof content !== "string" && files.length === 0) {
5609
5632
  continue;
5610
5633
  }
5611
5634
  await processBaiduAppInboundMessage({
5612
5635
  target,
5613
- msg: buildPollingTextInboundMessage(content)
5636
+ msg: {
5637
+ ...buildPollingTextInboundMessage(typeof content === "string" ? content : ""),
5638
+ msgid: typeof item.msgId === "string" ? item.msgId : void 0,
5639
+ agentid: typeof item.agentId === "string" ? item.agentId : void 0,
5640
+ ...files.length > 0 ? { files } : {}
5641
+ }
5614
5642
  });
5615
5643
  }
5616
5644
  }
@@ -5665,12 +5693,29 @@ function createAbortSignalController(params) {
5665
5693
  };
5666
5694
  }
5667
5695
  async function pollBaiduAppChatlistOnce(account, loggerOptions, requestOptions) {
5668
- const endpoint = `${account.apiBase}/chat/demo/chatlist`;
5696
+ const endpoint = `${account.apiBase}/channel/msg/poll`;
5697
+ const logger3 = createLogger("openclaw-baiduapp:poller", loggerOptions);
5698
+ const timestamp = String(Math.floor(Date.now() / 1e3));
5699
+ const nonce = generateNonce();
5700
+ const authorization = buildAuthorizationHeader({
5701
+ ak: account.appKey ?? "",
5702
+ sk: account.appSecret ?? "",
5703
+ timestamp,
5704
+ nonce
5705
+ });
5669
5706
  const query = new URLSearchParams({
5670
5707
  ak: account.appKey ?? "",
5671
- sk: account.appSecret ?? ""
5708
+ timestamp,
5709
+ nonce
5672
5710
  });
5673
5711
  const url = `${endpoint}?${query.toString()}`;
5712
+ const payload = {
5713
+ sessionId: "agent:main:main",
5714
+ num: 5,
5715
+ version: PLUGIN_VERSION
5716
+ };
5717
+ const body = JSON.stringify(payload);
5718
+ console.log("start poll");
5674
5719
  const requestSignal = createAbortSignalController({
5675
5720
  signal: requestOptions?.signal,
5676
5721
  timeoutMs: requestOptions?.timeoutMs
@@ -5678,8 +5723,13 @@ async function pollBaiduAppChatlistOnce(account, loggerOptions, requestOptions)
5678
5723
  let response;
5679
5724
  try {
5680
5725
  response = await (requestOptions?.fetchImpl ?? fetch)(url, {
5681
- method: "GET",
5682
- signal: requestSignal.signal
5726
+ method: "POST",
5727
+ body,
5728
+ signal: requestSignal.signal,
5729
+ headers: {
5730
+ "Authorization": authorization,
5731
+ "Content-Type": "application/json"
5732
+ }
5683
5733
  });
5684
5734
  } catch (error) {
5685
5735
  requestSignal.cleanup();
@@ -5732,10 +5782,13 @@ async function pollBaiduAppChatlistOnce(account, loggerOptions, requestOptions)
5732
5782
  }
5733
5783
  });
5734
5784
  }
5735
- const data = Array.isArray(parsed.data) ? parsed.data : [];
5785
+ if (parsed.code !== 0) {
5786
+ logger3.debug(`Baidu poll returned non-zero code=${String(parsed.code)}, message=${parsed.message}`);
5787
+ }
5788
+ const msgList = Array.isArray(parsed.data?.msgList) ? parsed.data.msgList : [];
5736
5789
  return buildPollResult({
5737
5790
  ok: true,
5738
- data
5791
+ data: msgList
5739
5792
  });
5740
5793
  }
5741
5794
  function scheduleNextPoll(account, state) {
@@ -5858,9 +5911,20 @@ function inferBaiduOutboundFileType(params) {
5858
5911
  function buildOutboundMediaPayload(params) {
5859
5912
  const caption = params.caption?.trim();
5860
5913
  return {
5861
- msgtype: "text",
5862
- ...caption ? { text: { content: caption } } : {},
5863
- files: [{ url: params.uploadedUrl, fileType: params.fileType }]
5914
+ list: [
5915
+ ...caption ? [{
5916
+ type: "text",
5917
+ data: {
5918
+ text: { content: caption }
5919
+ }
5920
+ }] : [],
5921
+ {
5922
+ type: "file",
5923
+ data: {
5924
+ file_id: params.uploadedUrl
5925
+ }
5926
+ }
5927
+ ]
5864
5928
  };
5865
5929
  }
5866
5930
  function resolveDirectOutboundFiles(files) {
@@ -6097,7 +6161,10 @@ var baiduAppPlugin = {
6097
6161
  };
6098
6162
  }
6099
6163
  try {
6100
- const result = await sendBaiduAppMessage(account, params.text);
6164
+ const result = await sendBaiduAppMessage(account, params.text, {
6165
+ agentid: account.accountId,
6166
+ isActive: true
6167
+ });
6101
6168
  return {
6102
6169
  channel: "openclaw-baiduapp",
6103
6170
  ok: result.ok,
@@ -6142,7 +6209,8 @@ var baiduAppPlugin = {
6142
6209
  caption: params.text,
6143
6210
  uploadedUrl: remoteUrl,
6144
6211
  fileType: inferBaiduOutboundFileType({ mediaPath: remoteUrl })
6145
- })
6212
+ }),
6213
+ { agentid: account.accountId, isActive: true }
6146
6214
  );
6147
6215
  return {
6148
6216
  channel: "openclaw-baiduapp",
@@ -6184,7 +6252,8 @@ var baiduAppPlugin = {
6184
6252
  fileType: inferBaiduOutboundFileType({
6185
6253
  mediaPath: uploaded.fileName || localMediaPath
6186
6254
  })
6187
- })
6255
+ }),
6256
+ { agentid: account.accountId, isActive: true }
6188
6257
  );
6189
6258
  return {
6190
6259
  channel: "openclaw-baiduapp",
@@ -6206,6 +6275,18 @@ var baiduAppPlugin = {
6206
6275
  }
6207
6276
  }
6208
6277
  },
6278
+ auth: {
6279
+ login: async (params) => {
6280
+ void params.channelInput;
6281
+ const { loginBaiduApp: loginBaiduApp2 } = await Promise.resolve().then(() => (init_login(), login_exports));
6282
+ await loginBaiduApp2({
6283
+ cfg: params.cfg,
6284
+ accountId: params.accountId,
6285
+ runtime: params.runtime,
6286
+ verbose: params.verbose
6287
+ });
6288
+ }
6289
+ },
6209
6290
  gateway: {
6210
6291
  startAccount: async (ctx) => {
6211
6292
  ctx.setStatus?.({ accountId: ctx.accountId });
@@ -6243,21 +6324,19 @@ var baiduAppPlugin = {
6243
6324
  existing();
6244
6325
  }
6245
6326
  unregisterHooks.set(ctx.accountId, unregister);
6246
- if (account.config.pollingEnabled === true) {
6247
- startAccountPolling({
6327
+ startAccountPolling({
6328
+ account,
6329
+ dispatchTarget: {
6248
6330
  account,
6249
- dispatchTarget: {
6250
- account,
6251
- config: ctx.cfg ?? {},
6252
- runtime: runtime2,
6253
- statusSink: (patch) => ctx.setStatus?.({ accountId: ctx.accountId, ...patch })
6254
- },
6255
- onError: (error) => {
6256
- const message = error instanceof Error ? error.message : String(error);
6257
- ctx.log?.error(`[openclaw-baiduapp] polling failed for account ${ctx.accountId}: ${message}`);
6258
- }
6259
- });
6260
- }
6331
+ config: ctx.cfg ?? {},
6332
+ runtime: runtime2,
6333
+ statusSink: (patch) => ctx.setStatus?.({ accountId: ctx.accountId, ...patch })
6334
+ },
6335
+ onError: (error) => {
6336
+ const message = error instanceof Error ? error.message : String(error);
6337
+ ctx.log?.error(`[openclaw-baiduapp] polling failed for account ${ctx.accountId}: ${message}`);
6338
+ }
6339
+ });
6261
6340
  ctx.log?.info(
6262
6341
  `[openclaw-baiduapp] webhook registered at ${path4} for account ${ctx.accountId} (canSendActive=${account.canSendActive})`
6263
6342
  );
@@ -6309,7 +6388,7 @@ async function sendMessage(account, options) {
6309
6388
  };
6310
6389
  }
6311
6390
  try {
6312
- const textResult = await sendBaiduAppMessage(account, options.text);
6391
+ const textResult = await sendBaiduAppMessage(account, options.text, { isActive: true });
6313
6392
  return {
6314
6393
  ok: textResult.ok,
6315
6394
  msgid: textResult.msgid,