@cored-im/openclaw-plugin 0.1.7 → 0.1.11

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.
@@ -61,15 +61,12 @@ describe("resolveAccountConfig", () => {
61
61
  const account = resolveAccountConfig(cfg);
62
62
  expect(account).toEqual({
63
63
  accountId: "default",
64
- enabled: true,
65
64
  appId: "app_1",
66
65
  appSecret: "secret_1",
67
66
  backendUrl: "https://your-backend-url.com",
67
+ enabled: true,
68
68
  enableEncryption: true,
69
69
  requestTimeout: 30_000,
70
- requireMention: true,
71
- botUserId: undefined,
72
- inboundWhitelist: [],
73
70
  });
74
71
  });
75
72
 
@@ -82,7 +79,7 @@ describe("resolveAccountConfig", () => {
82
79
  appId: "app_bot1",
83
80
  appSecret: "secret_bot1",
84
81
  backendUrl: "http://localhost:11000",
85
- requireMention: false,
82
+ enableEncryption: false,
86
83
  },
87
84
  },
88
85
  },
@@ -91,8 +88,7 @@ describe("resolveAccountConfig", () => {
91
88
  const account = resolveAccountConfig(cfg, "bot1");
92
89
  expect(account.accountId).toBe("bot1");
93
90
  expect(account.appId).toBe("app_bot1");
94
- expect(account.requireMention).toBe(false);
95
- expect(account.enableEncryption).toBe(true); // default
91
+ expect(account.enableEncryption).toBe(false);
96
92
  });
97
93
 
98
94
  it("falls back to env vars when config values are missing", () => {
@@ -136,14 +132,12 @@ describe("resolveAccountConfig", () => {
136
132
  describe("validateAccountConfig", () => {
137
133
  const validConfig = {
138
134
  accountId: "default",
139
- enabled: true,
140
135
  appId: "app_1",
141
136
  appSecret: "secret_1",
142
137
  backendUrl: "https://api.cored.im",
138
+ enabled: true,
143
139
  enableEncryption: true,
144
140
  requestTimeout: 30_000,
145
- requireMention: true,
146
- inboundWhitelist: [],
147
141
  };
148
142
 
149
143
  it("returns no errors for valid config", () => {
package/src/config.ts CHANGED
@@ -6,8 +6,6 @@ import type { CoredChannelConfig, CoredAccountConfig } from "./types.js";
6
6
  const DEFAULTS = {
7
7
  enableEncryption: true,
8
8
  requestTimeout: 30_000,
9
- requireMention: true,
10
- inboundWhitelist: [] as string[],
11
9
  } as const;
12
10
 
13
11
  const ENV_PREFIX = "CORED_";
@@ -35,10 +33,6 @@ function readEnvConfig(): Partial<CoredAccountConfig> {
35
33
  env[`${ENV_PREFIX}ENABLE_ENCRYPTION`] !== "false";
36
34
  if (env[`${ENV_PREFIX}REQUEST_TIMEOUT`])
37
35
  result.requestTimeout = Number(env[`${ENV_PREFIX}REQUEST_TIMEOUT`]);
38
- if (env[`${ENV_PREFIX}REQUIRE_MENTION`] !== undefined)
39
- result.requireMention = env[`${ENV_PREFIX}REQUIRE_MENTION`] !== "false";
40
- if (env[`${ENV_PREFIX}BOT_USER_ID`])
41
- result.botUserId = env[`${ENV_PREFIX}BOT_USER_ID`];
42
36
 
43
37
  return result;
44
38
  }
@@ -69,18 +63,14 @@ export function resolveAccountConfig(
69
63
 
70
64
  return {
71
65
  accountId: id,
72
- enabled: raw?.enabled ?? true,
73
66
  appId: raw?.appId ?? envConfig.appId ?? "",
74
67
  appSecret: raw?.appSecret ?? envConfig.appSecret ?? "",
75
68
  backendUrl: raw?.backendUrl ?? envConfig.backendUrl ?? "",
69
+ enabled: raw?.enabled ?? true,
76
70
  enableEncryption:
77
71
  raw?.enableEncryption ?? envConfig.enableEncryption ?? DEFAULTS.enableEncryption,
78
72
  requestTimeout:
79
73
  raw?.requestTimeout ?? envConfig.requestTimeout ?? DEFAULTS.requestTimeout,
80
- requireMention:
81
- raw?.requireMention ?? envConfig.requireMention ?? DEFAULTS.requireMention,
82
- botUserId: raw?.botUserId ?? envConfig.botUserId,
83
- inboundWhitelist: raw?.inboundWhitelist ?? [...DEFAULTS.inboundWhitelist],
84
74
  };
85
75
  }
86
76
 
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) 2026 Cored Limited
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { defineChannelPluginEntry, type PluginApi } from "openclaw/plugin-sdk/core";
4
+ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
5
5
  import { coredPlugin } from "./channel.js";
6
6
  import { listEnabledAccountConfigs, validateAccountConfig } from "./config.js";
7
7
  import {
@@ -9,64 +9,58 @@ import {
9
9
  destroyAllClients,
10
10
  clientCount,
11
11
  } from "./core/cored-client.js";
12
- import { processInboundMessage, type ExtendedPluginApi } from "./messaging/inbound.js";
12
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
13
+ import { processInboundMessage } from "./messaging/inbound.js";
13
14
  import { makeDeliver, setTyping, clearTyping, readMessage } from "./messaging/outbound.js";
14
15
  import type { CoredAccountConfig, CoredMessageEvent } from "./types.js";
15
16
 
16
- // Extended PluginApi with config type for service registration
17
- interface ServicePluginApi extends ExtendedPluginApi {
18
- config: { channels?: Record<string, unknown> };
19
- }
20
-
21
17
  export default defineChannelPluginEntry({
22
18
  id: "cored",
23
19
  name: "Cored",
24
20
  description: "Connect OpenClaw with Cored",
25
21
  plugin: coredPlugin,
26
22
  registerFull(api) {
27
- const typedApi = api as ServicePluginApi;
28
-
29
- typedApi.registerService({
23
+ api.registerService({
30
24
  id: "cored-sdk",
31
25
  start: async () => {
32
26
  if (clientCount() > 0) return;
33
27
 
34
- const accounts = listEnabledAccountConfigs(typedApi.config);
28
+ const accounts = listEnabledAccountConfigs(api.config);
35
29
  if (accounts.length === 0) {
36
- typedApi.logger?.warn?.("[cored] no enabled account config found — service idle");
30
+ api.logger?.warn?.("[cored] no enabled account config found — service idle");
37
31
  return;
38
32
  }
39
33
 
40
34
  for (const account of accounts) {
41
35
  const errors = validateAccountConfig(account);
42
36
  if (errors.length > 0) {
43
- typedApi.logger?.warn?.(
37
+ api.logger?.warn?.(
44
38
  `[cored] skipping account=${account.accountId}: ${errors.map((e) => e.message).join("; ")}`,
45
39
  );
46
40
  continue;
47
41
  }
48
42
 
49
43
  try {
50
- await startAccount(typedApi, account);
51
- typedApi.logger?.info?.(
44
+ await startAccount(api, account);
45
+ api.logger?.info?.(
52
46
  `[cored] account=${account.accountId} connected (appId=${account.appId})`,
53
47
  );
54
48
  } catch (err) {
55
- typedApi.logger?.error?.(
49
+ api.logger?.error?.(
56
50
  `[cored] account=${account.accountId} failed to start: ${err instanceof Error ? err.message : String(err)}`,
57
51
  );
58
52
  }
59
53
  }
60
54
 
61
- typedApi.logger?.info?.(`[cored] service started with ${clientCount()} account(s)`);
55
+ api.logger?.info?.(`[cored] service started with ${clientCount()} account(s)`);
62
56
  },
63
57
  stop: async () => {
64
58
  await destroyAllClients();
65
- typedApi.logger?.info?.("[cored] service stopped — all clients disconnected");
59
+ api.logger?.info?.("[cored] service stopped — all clients disconnected");
66
60
  },
67
61
  });
68
62
 
69
- typedApi.logger?.info?.("[cored] plugin registered");
63
+ api.logger?.info?.("[cored] plugin registered");
70
64
  },
71
65
  });
72
66
 
@@ -74,7 +68,7 @@ export default defineChannelPluginEntry({
74
68
  * Start a single account — create client, subscribe to inbound events.
75
69
  */
76
70
  async function startAccount(
77
- api: ServicePluginApi,
71
+ api: OpenClawPluginApi,
78
72
  account: CoredAccountConfig,
79
73
  ): Promise<void> {
80
74
  const deliver = makeDeliver(account.accountId, (msg) => api.logger?.warn?.(msg));
@@ -97,7 +91,7 @@ async function startAccount(
97
91
  * Handle a single inbound message with typing indicator lifecycle.
98
92
  */
99
93
  async function handleInbound(
100
- api: ServicePluginApi,
94
+ api: OpenClawPluginApi,
101
95
  account: CoredAccountConfig,
102
96
  event: CoredMessageEvent,
103
97
  deliver: (chatId: string, text: string) => Promise<void>,
@@ -5,7 +5,6 @@ import { describe, it, expect, beforeEach, vi } from "vitest";
5
5
  import {
6
6
  parseMessageEvent,
7
7
  checkMessageGate,
8
- isBotMentioned,
9
8
  isDuplicate,
10
9
  _resetDedup,
11
10
  buildContext,
@@ -14,8 +13,8 @@ import {
14
13
  import type {
15
14
  CoredAccountConfig,
16
15
  CoredMessageEvent,
17
- PluginApi,
18
16
  } from "../types.js";
17
+ import type { InboundPluginApi } from "./inbound.js";
19
18
 
20
19
  // ---------------------------------------------------------------------------
21
20
  // Helpers
@@ -26,15 +25,12 @@ function makeAccount(
26
25
  ): CoredAccountConfig {
27
26
  return {
28
27
  accountId: "test-account",
29
- enabled: true,
30
28
  appId: "app_test",
31
29
  appSecret: "secret",
32
30
  backendUrl: "https://your-backend-url.com",
31
+ enabled: true,
33
32
  enableEncryption: true,
34
33
  requestTimeout: 30_000,
35
- requireMention: true,
36
- botUserId: "bot_user_001",
37
- inboundWhitelist: [],
38
34
  ...overrides,
39
35
  };
40
36
  }
@@ -56,7 +52,7 @@ function makeEvent(
56
52
  };
57
53
  }
58
54
 
59
- function makeMockApi(): PluginApi {
55
+ function makeMockApi(): InboundPluginApi {
60
56
  return {
61
57
  registerChannel: vi.fn(),
62
58
  registerService: vi.fn(),
@@ -197,112 +193,11 @@ describe("parseMessageEvent", () => {
197
193
  describe("checkMessageGate", () => {
198
194
  it("passes a normal direct message", () => {
199
195
  const msg = parseMessageEvent(makeEvent())!;
200
- const account = makeAccount({ requireMention: false });
201
- const result = checkMessageGate(msg, account);
202
- expect(result.pass).toBe(true);
203
- });
204
-
205
- it("blocks self-messages", () => {
206
- const event = makeEvent({
207
- sender: { userId: "bot_user_001" },
208
- });
209
- const msg = parseMessageEvent(event)!;
210
196
  const account = makeAccount();
211
197
  const result = checkMessageGate(msg, account);
212
- expect(result.pass).toBe(false);
213
- expect(result.reason).toBe("self-message");
214
- });
215
-
216
- it("blocks sender not in whitelist when whitelist is set", () => {
217
- const msg = parseMessageEvent(makeEvent())!;
218
- const account = makeAccount({
219
- inboundWhitelist: ["allowed_user"],
220
- });
221
- const result = checkMessageGate(msg, account);
222
- expect(result.pass).toBe(false);
223
- expect(result.reason).toBe("sender-not-in-whitelist");
224
- });
225
-
226
- it("passes sender in whitelist", () => {
227
- const msg = parseMessageEvent(makeEvent())!;
228
- const account = makeAccount({
229
- inboundWhitelist: ["user_sender_001"],
230
- requireMention: false,
231
- });
232
- const result = checkMessageGate(msg, account);
233
198
  expect(result.pass).toBe(true);
234
199
  });
235
200
 
236
- it("blocks group message without mention when requireMention is true", () => {
237
- const event = makeEvent({ chatType: "group" });
238
- const msg = parseMessageEvent(event)!;
239
- const account = makeAccount({ requireMention: true });
240
- const result = checkMessageGate(msg, account);
241
- expect(result.pass).toBe(false);
242
- expect(result.reason).toBe("group-no-mention");
243
- });
244
-
245
- it("passes group message with mention", () => {
246
- const event = makeEvent({
247
- chatType: "group",
248
- mentionUserList: [{ userId: "bot_user_001" }],
249
- });
250
- const msg = parseMessageEvent(event)!;
251
- const account = makeAccount({ requireMention: true });
252
- const result = checkMessageGate(msg, account);
253
- expect(result.pass).toBe(true);
254
- });
255
-
256
- it("passes group message when requireMention is false", () => {
257
- const event = makeEvent({ chatType: "group" });
258
- const msg = parseMessageEvent(event)!;
259
- const account = makeAccount({ requireMention: false });
260
- const result = checkMessageGate(msg, account);
261
- expect(result.pass).toBe(true);
262
- });
263
-
264
- it("skips self-message check when botUserId is not set", () => {
265
- const event = makeEvent({
266
- sender: { userId: "any_user" },
267
- });
268
- const msg = parseMessageEvent(event)!;
269
- const account = makeAccount({ botUserId: undefined });
270
- const result = checkMessageGate(msg, account);
271
- expect(result.pass).toBe(true);
272
- });
273
- });
274
-
275
- // ---------------------------------------------------------------------------
276
- // isBotMentioned
277
- // ---------------------------------------------------------------------------
278
-
279
- describe("isBotMentioned", () => {
280
- it("returns true when bot is in mentionUserIds", () => {
281
- const event = makeEvent({
282
- mentionUserList: [{ userId: "bot_user_001" }],
283
- });
284
- const msg = parseMessageEvent(event)!;
285
- const account = makeAccount();
286
- expect(isBotMentioned(msg, account)).toBe(true);
287
- });
288
-
289
- it("returns false when bot is not mentioned", () => {
290
- const event = makeEvent({
291
- mentionUserList: [{ userId: "other_user" }],
292
- });
293
- const msg = parseMessageEvent(event)!;
294
- const account = makeAccount();
295
- expect(isBotMentioned(msg, account)).toBe(false);
296
- });
297
-
298
- it("returns false when botUserId is not set", () => {
299
- const event = makeEvent({
300
- mentionUserList: [{ userId: "bot_user_001" }],
301
- });
302
- const msg = parseMessageEvent(event)!;
303
- const account = makeAccount({ botUserId: undefined });
304
- expect(isBotMentioned(msg, account)).toBe(false);
305
- });
306
201
  });
307
202
 
308
203
  // ---------------------------------------------------------------------------
@@ -348,7 +243,7 @@ describe("buildContext", () => {
348
243
  expect(ctx.AccountId).toBe("test-account");
349
244
  expect(ctx.Body).toBe("hello world");
350
245
  expect(ctx.From).toBe("cored:user:user_sender_001");
351
- expect(ctx.To).toBe("cored:bot:bot_user_001");
246
+ expect(ctx.To).toBe("cored:bot:app_test");
352
247
  expect(ctx.SessionKey).toBe("cored:user:user_sender_001");
353
248
  expect(ctx.CommandAuthorized).toBe(true);
354
249
  expect(ctx._cored.isGroup).toBe(false);
@@ -367,12 +262,6 @@ describe("buildContext", () => {
367
262
  expect(ctx._cored.chatId).toBe("chat_group_1");
368
263
  });
369
264
 
370
- it("falls back to appId when botUserId is not set", () => {
371
- const msg = parseMessageEvent(makeEvent())!;
372
- const account = makeAccount({ botUserId: undefined });
373
- const ctx = buildContext(msg, account);
374
- expect(ctx.To).toBe("cored:bot:app_test");
375
- });
376
265
  });
377
266
 
378
267
  // ---------------------------------------------------------------------------
@@ -386,7 +275,7 @@ describe("processInboundMessage", () => {
386
275
 
387
276
  it("dispatches a valid direct message", async () => {
388
277
  const api = makeMockApi();
389
- const account = makeAccount({ requireMention: false });
278
+ const account = makeAccount();
390
279
  const event = makeEvent();
391
280
  const deliver = vi.fn().mockResolvedValue(undefined);
392
281
 
@@ -397,21 +286,9 @@ describe("processInboundMessage", () => {
397
286
  expect(api.runtime.channel.session.recordInboundSession).toHaveBeenCalledOnce();
398
287
  });
399
288
 
400
- it("filters self-messages", async () => {
401
- const api = makeMockApi();
402
- const account = makeAccount();
403
- const event = makeEvent({ sender: { userId: "bot_user_001" } });
404
- const deliver = vi.fn();
405
-
406
- const result = await processInboundMessage(api, account, event, { deliver });
407
-
408
- expect(result).toBe(false);
409
- expect(api.runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher).not.toHaveBeenCalled();
410
- });
411
-
412
289
  it("filters duplicate messages", async () => {
413
290
  const api = makeMockApi();
414
- const account = makeAccount({ requireMention: false });
291
+ const account = makeAccount();
415
292
  const msgId = "msg_dedup_test";
416
293
  const event = makeEvent({ messageId: msgId });
417
294
  const deliver = vi.fn();
@@ -423,31 +300,6 @@ describe("processInboundMessage", () => {
423
300
  expect(second).toBe(false);
424
301
  });
425
302
 
426
- it("filters group messages without mention when required", async () => {
427
- const api = makeMockApi();
428
- const account = makeAccount({ requireMention: true });
429
- const event = makeEvent({ chatType: "group" });
430
- const deliver = vi.fn();
431
-
432
- const result = await processInboundMessage(api, account, event, { deliver });
433
-
434
- expect(result).toBe(false);
435
- });
436
-
437
- it("dispatches group message with mention", async () => {
438
- const api = makeMockApi();
439
- const account = makeAccount({ requireMention: true });
440
- const event = makeEvent({
441
- chatType: "group",
442
- mentionUserList: [{ userId: "bot_user_001" }],
443
- });
444
- const deliver = vi.fn().mockResolvedValue(undefined);
445
-
446
- const result = await processInboundMessage(api, account, event, { deliver });
447
-
448
- expect(result).toBe(true);
449
- });
450
-
451
303
  it("returns false for unparseable event", async () => {
452
304
  const api = makeMockApi();
453
305
  const account = makeAccount();
@@ -463,7 +315,7 @@ describe("processInboundMessage", () => {
463
315
  const api = makeMockApi();
464
316
  // Remove dispatch function
465
317
  (api.runtime.channel.reply as Record<string, unknown>).dispatchReplyWithBufferedBlockDispatcher = undefined;
466
- const account = makeAccount({ requireMention: false });
318
+ const account = makeAccount();
467
319
  const event = makeEvent();
468
320
  const deliver = vi.fn();
469
321
 
@@ -482,7 +334,7 @@ describe("processInboundMessage", () => {
482
334
  });
483
335
  api.runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher = mockDispatch;
484
336
 
485
- const account = makeAccount({ requireMention: false });
337
+ const account = makeAccount();
486
338
  const event = makeEvent({ chatId: "chat_deliver_test" });
487
339
  const deliver = vi.fn().mockResolvedValue(undefined);
488
340
 
@@ -500,7 +352,7 @@ describe("processInboundMessage", () => {
500
352
  });
501
353
  api.runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher = mockDispatch;
502
354
 
503
- const account = makeAccount({ requireMention: false });
355
+ const account = makeAccount();
504
356
  const event = makeEvent();
505
357
  const deliver = vi.fn();
506
358
 
@@ -511,7 +363,7 @@ describe("processInboundMessage", () => {
511
363
 
512
364
  it("records session with updateLastRoute for DM", async () => {
513
365
  const api = makeMockApi();
514
- const account = makeAccount({ requireMention: false });
366
+ const account = makeAccount();
515
367
  const event = makeEvent({ chatId: "chat_dm_001" });
516
368
  const deliver = vi.fn().mockResolvedValue(undefined);
517
369
 
@@ -528,7 +380,7 @@ describe("processInboundMessage", () => {
528
380
 
529
381
  it("does not set updateLastRoute for group messages", async () => {
530
382
  const api = makeMockApi();
531
- const account = makeAccount({ requireMention: false });
383
+ const account = makeAccount();
532
384
  const event = makeEvent({ chatType: "group" });
533
385
  const deliver = vi.fn().mockResolvedValue(undefined);
534
386
 
@@ -547,7 +399,7 @@ describe("processInboundMessage", () => {
547
399
  });
548
400
  api.runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher = mockDispatch;
549
401
 
550
- const account = makeAccount({ requireMention: false });
402
+ const account = makeAccount();
551
403
  const event = makeEvent();
552
404
  const deliver = vi.fn();
553
405
 
@@ -14,22 +14,25 @@ import type {
14
14
  CoredAccountConfig,
15
15
  CoredMessage,
16
16
  CoredMessageEvent,
17
- PluginApi,
18
17
  } from "../types.js";
19
18
 
20
- // Extended PluginApi with runtime surfaces used by this module
21
- export interface ExtendedPluginApi extends PluginApi {
19
+ // Plugin API surface used by this module.
20
+ // At runtime the full OpenClawPluginApi is provided by the gateway;
21
+ // we only declare the subset we access so the module stays decoupled
22
+ // and testable without importing the full SDK.
23
+ export interface InboundPluginApi {
24
+ config: Record<string, unknown>;
22
25
  runtime?: {
23
26
  channel?: {
24
27
  reply?: {
25
- dispatchReplyWithBufferedBlockDispatcher?: (opts: unknown) => Promise<void>;
28
+ dispatchReplyWithBufferedBlockDispatcher?: (...args: any[]) => any;
26
29
  };
27
30
  session?: {
28
- recordInboundSession?: (opts: unknown) => Promise<void>;
29
- resolveStorePath?: (store: unknown, opts: unknown) => string;
31
+ recordInboundSession?: (...args: any[]) => any;
32
+ resolveStorePath?: (...args: any[]) => string;
30
33
  };
31
34
  routing?: {
32
- resolveAgentRoute?: (opts: unknown) => unknown;
35
+ resolveAgentRoute?: (...args: any[]) => unknown;
33
36
  };
34
37
  };
35
38
  };
@@ -148,41 +151,9 @@ export function checkMessageGate(
148
151
  msg: ParsedInboundMessage,
149
152
  account: CoredAccountConfig,
150
153
  ): GateResult {
151
- // 1. Self-message filter: ignore messages from the bot itself
152
- if (account.botUserId && msg.senderId === account.botUserId) {
153
- return { pass: false, reason: "self-message" };
154
- }
155
-
156
- // 2. Whitelist filter: if whitelist is non-empty, only allow listed senders
157
- if (account.inboundWhitelist.length > 0) {
158
- if (!account.inboundWhitelist.includes(msg.senderId)) {
159
- return { pass: false, reason: "sender-not-in-whitelist" };
160
- }
161
- }
162
-
163
- // 3. Group mention filter: in group chats, require @mention if configured
164
- if (
165
- msg.chatType === "group" &&
166
- account.requireMention &&
167
- !isBotMentioned(msg, account)
168
- ) {
169
- return { pass: false, reason: "group-no-mention" };
170
- }
171
-
172
154
  return { pass: true };
173
155
  }
174
156
 
175
- /**
176
- * Check if the bot was @mentioned in a message.
177
- */
178
- export function isBotMentioned(
179
- msg: ParsedInboundMessage,
180
- account: CoredAccountConfig,
181
- ): boolean {
182
- if (!account.botUserId) return false;
183
- return msg.mentionUserIds.includes(account.botUserId);
184
- }
185
-
186
157
  // ---------------------------------------------------------------------------
187
158
  // Dedup — skip already-processed message IDs
188
159
  // ---------------------------------------------------------------------------
@@ -276,7 +247,7 @@ export function buildContext(
276
247
  return {
277
248
  Body: msg.body,
278
249
  From: isGroup ? `cored:chat:${msg.chatId}` : `cored:user:${msg.senderId}`,
279
- To: `cored:bot:${account.botUserId ?? account.appId}`,
250
+ To: `cored:bot:${account.appId}`,
280
251
  SessionKey: sessionKey,
281
252
  AccountId: account.accountId,
282
253
  ChatType: isGroup ? "group" : "direct",
@@ -314,7 +285,7 @@ export interface InboundDispatchOptions {
314
285
  * Returns `true` if the message was dispatched, `false` if filtered.
315
286
  */
316
287
  export async function processInboundMessage(
317
- api: ExtendedPluginApi,
288
+ api: InboundPluginApi,
318
289
  account: CoredAccountConfig,
319
290
  event: CoredMessageEvent,
320
291
  opts: InboundDispatchOptions,
@@ -2,6 +2,6 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
5
- import { coredPlugin } from "./channel.js";
5
+ import { base } from "./channel.js";
6
6
 
7
- export default defineSetupPluginEntry(coredPlugin);
7
+ export default defineSetupPluginEntry(base);
package/src/types.ts CHANGED
@@ -5,39 +5,30 @@
5
5
 
6
6
  export interface CoredAccountConfig {
7
7
  accountId: string;
8
- enabled: boolean;
9
8
  appId: string;
10
9
  appSecret: string;
11
10
  backendUrl: string;
11
+ enabled: boolean;
12
12
  enableEncryption: boolean;
13
13
  requestTimeout: number;
14
- requireMention: boolean;
15
- botUserId?: string;
16
- inboundWhitelist: string[];
17
14
  }
18
15
 
19
16
  export interface CoredRawAccountConfig {
20
17
  appId?: string;
21
18
  appSecret?: string;
22
19
  backendUrl?: string;
20
+ enabled?: boolean;
23
21
  enableEncryption?: boolean;
24
22
  requestTimeout?: number;
25
- requireMention?: boolean;
26
- enabled?: boolean;
27
- botUserId?: string;
28
- inboundWhitelist?: string[];
29
23
  }
30
24
 
31
25
  export interface CoredChannelConfig {
32
26
  appId?: string;
33
27
  appSecret?: string;
34
28
  backendUrl?: string;
29
+ enabled?: boolean;
35
30
  enableEncryption?: boolean;
36
31
  requestTimeout?: number;
37
- requireMention?: boolean;
38
- enabled?: boolean;
39
- botUserId?: string;
40
- inboundWhitelist?: string[];
41
32
  accounts?: Record<string, CoredRawAccountConfig>;
42
33
  }
43
34
 
@@ -79,7 +70,3 @@ export type ConnectionState =
79
70
  | "connected"
80
71
  | "disconnecting";
81
72
 
82
- // --- OpenClaw Plugin API (re-export from SDK) ---
83
-
84
- // Re-export PluginApi from SDK for convenience
85
- export type { PluginApi } from "openclaw/plugin-sdk/core";