@eclaw/openclaw-channel 1.0.14 → 1.0.15

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/client.d.ts CHANGED
@@ -12,13 +12,15 @@ export declare class EClawClient {
12
12
  constructor(config: EClawAccountConfig);
13
13
  /** Register callback URL with E-Claw backend */
14
14
  registerCallback(callbackUrl: string, callbackToken: string): Promise<RegisterResponse>;
15
- /** Bind an entity via channel API (bypasses 6-digit code) */
16
- bindEntity(entityId: number, name?: string): Promise<BindResponse>;
15
+ /** Bind an entity via channel API (bypasses 6-digit code).
16
+ * If entityId is omitted, the backend auto-selects the first free slot.
17
+ */
18
+ bindEntity(entityId?: number, name?: string): Promise<BindResponse>;
17
19
  /** Send bot message to user */
18
20
  sendMessage(message: string, state?: string, mediaType?: string, mediaUrl?: string): Promise<MessageResponse>;
19
21
  /** Unregister callback on shutdown */
20
22
  unregisterCallback(): Promise<void>;
21
23
  get currentDeviceId(): string | null;
22
24
  get currentBotSecret(): string | null;
23
- get currentEntityId(): number;
25
+ get currentEntityId(): number | undefined;
24
26
  }
package/dist/client.js CHANGED
@@ -11,7 +11,7 @@ export class EClawClient {
11
11
  constructor(config) {
12
12
  this.apiBase = config.apiBase;
13
13
  this.apiKey = config.apiKey;
14
- this.entityId = config.entityId;
14
+ this.entityId = config.entityId; // undefined until assigned by bindEntity
15
15
  }
16
16
  /** Register callback URL with E-Claw backend */
17
17
  async registerCallback(callbackUrl, callbackToken) {
@@ -31,24 +31,37 @@ export class EClawClient {
31
31
  this.deviceId = data.deviceId;
32
32
  return data;
33
33
  }
34
- /** Bind an entity via channel API (bypasses 6-digit code) */
34
+ /** Bind an entity via channel API (bypasses 6-digit code).
35
+ * If entityId is omitted, the backend auto-selects the first free slot.
36
+ */
35
37
  async bindEntity(entityId, name) {
38
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
+ const body = { channel_api_key: this.apiKey };
40
+ if (entityId !== undefined)
41
+ body.entityId = entityId;
42
+ if (name)
43
+ body.name = name;
36
44
  const res = await fetch(`${this.apiBase}/api/channel/bind`, {
37
45
  method: 'POST',
38
46
  headers: { 'Content-Type': 'application/json' },
39
- body: JSON.stringify({
40
- channel_api_key: this.apiKey,
41
- entityId,
42
- name: name || undefined,
43
- }),
47
+ body: JSON.stringify(body),
44
48
  });
49
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
50
  const data = await res.json();
46
51
  if (!data.success) {
52
+ // Build a detailed error message when all slots are full
53
+ if (res.status === 409 && data.entities) {
54
+ const list = data.entities
55
+ .map((e) => ` slot ${e.entityId} (${e.character})${e.name ? ` "${e.name}"` : ''}`)
56
+ .join('\n');
57
+ throw new Error(`${data.message}\nCurrent entities:\n${list}\n` +
58
+ 'Add entityId to your channel config to target a specific slot after unbinding it.');
59
+ }
47
60
  throw new Error(data.message || `Bind failed (HTTP ${res.status})`);
48
61
  }
49
62
  this.botSecret = data.botSecret;
50
63
  this.deviceId = data.deviceId;
51
- this.entityId = entityId;
64
+ this.entityId = data.entityId; // Use server-assigned slot
52
65
  return data;
53
66
  }
54
67
  /** Send bot message to user */
package/dist/config.js CHANGED
@@ -28,7 +28,7 @@ export function resolveAccount(cfg, accountId) {
28
28
  apiKey: account?.apiKey ?? '',
29
29
  apiSecret: account?.apiSecret,
30
30
  apiBase: (account?.apiBase ?? 'https://eclawbot.com').replace(/\/$/, ''),
31
- entityId: account?.entityId ?? 0,
31
+ entityId: account?.entityId, // undefined = auto-assign
32
32
  botName: account?.botName,
33
33
  webhookUrl: account?.webhookUrl,
34
34
  };
package/dist/types.d.ts CHANGED
@@ -4,7 +4,7 @@ export interface EClawAccountConfig {
4
4
  apiKey: string;
5
5
  apiSecret?: string;
6
6
  apiBase: string;
7
- entityId: number;
7
+ entityId?: number;
8
8
  botName?: string;
9
9
  webhookUrl?: string;
10
10
  }
@@ -50,6 +50,13 @@ export interface BindResponse {
50
50
  publicCode: string;
51
51
  bindingType: string;
52
52
  }
53
+ /** Error response when all entity slots are full */
54
+ export interface SlotsFullError {
55
+ success: false;
56
+ message: string;
57
+ entities: EClawEntityInfo[];
58
+ hint: string;
59
+ }
53
60
  /** Response from POST /api/channel/message */
54
61
  export interface MessageResponse {
55
62
  success: boolean;
@@ -16,7 +16,7 @@
16
16
  "apiKey": { "type": "string", "description": "Channel API Key (eck_...)" },
17
17
  "apiSecret": { "type": "string", "description": "Channel API Secret (ecs_...)" },
18
18
  "apiBase": { "type": "string", "default": "https://eclawbot.com" },
19
- "entityId": { "type": "number", "default": 0, "minimum": 0, "maximum": 7 },
19
+ "entityId": { "type": "number", "minimum": 0, "maximum": 7, "description": "Optional: entity slot to use (0-7). If omitted, auto-assigned to first free slot." },
20
20
  "botName": { "type": "string", "maxLength": 20 }
21
21
  },
22
22
  "required": ["apiKey", "apiSecret"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eclaw/openclaw-channel",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "E-Claw channel plugin for OpenClaw — AI chat platform for live wallpaper entities",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",