@eclaw/openclaw-channel 1.0.7 → 1.0.9

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/config.js CHANGED
@@ -30,5 +30,6 @@ export function resolveAccount(cfg, accountId) {
30
30
  apiBase: (account?.apiBase ?? 'https://eclawbot.com').replace(/\/$/, ''),
31
31
  entityId: account?.entityId ?? 0,
32
32
  botName: account?.botName,
33
+ webhookUrl: account?.webhookUrl,
33
34
  };
34
35
  }
package/dist/gateway.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Gateway lifecycle: start an E-Claw account.
3
3
  *
4
- * 1. Initialize HTTP client with channel API credentials
4
+ * 1. Resolve credentials from ctx.account or disk
5
5
  * 2. Start a local HTTP server to receive webhook callbacks
6
6
  * 3. Register callback URL with E-Claw backend
7
7
  * 4. Auto-bind entity if not already bound
package/dist/gateway.js CHANGED
@@ -1,13 +1,45 @@
1
1
  import { createServer } from 'node:http';
2
2
  import { randomBytes } from 'node:crypto';
3
+ import { readFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { homedir } from 'node:os';
3
6
  import { resolveAccount } from './config.js';
4
7
  import { EClawClient } from './client.js';
5
8
  import { setClient } from './outbound.js';
6
9
  import { createWebhookHandler } from './webhook-handler.js';
10
+ /**
11
+ * Resolve account from ctx.
12
+ *
13
+ * OpenClaw may pass a pre-resolved account object in ctx.account,
14
+ * or an empty config. Fall back to reading openclaw.json from disk.
15
+ */
16
+ function resolveAccountFromCtx(ctx) {
17
+ // Preferred: OpenClaw passes the resolved account in ctx.account
18
+ if (ctx.account?.apiKey) {
19
+ return {
20
+ enabled: ctx.account.enabled ?? true,
21
+ apiKey: ctx.account.apiKey,
22
+ apiSecret: ctx.account.apiSecret,
23
+ apiBase: (ctx.account.apiBase ?? 'https://eclawbot.com').replace(/\/$/, ''),
24
+ entityId: ctx.account.entityId ?? 0,
25
+ botName: ctx.account.botName,
26
+ webhookUrl: ctx.account.webhookUrl,
27
+ };
28
+ }
29
+ // Fallback: read config from disk (OpenClaw passes empty config object)
30
+ const configPath = process.env.OPENCLAW_CONFIG_PATH
31
+ || join(homedir(), '.openclaw', 'openclaw.json');
32
+ let fullConfig = {};
33
+ try {
34
+ fullConfig = JSON.parse(readFileSync(configPath, 'utf8'));
35
+ }
36
+ catch { /* ignore */ }
37
+ return resolveAccount(fullConfig, ctx.accountId ?? ctx.account?.accountId);
38
+ }
7
39
  /**
8
40
  * Gateway lifecycle: start an E-Claw account.
9
41
  *
10
- * 1. Initialize HTTP client with channel API credentials
42
+ * 1. Resolve credentials from ctx.account or disk
11
43
  * 2. Start a local HTTP server to receive webhook callbacks
12
44
  * 3. Register callback URL with E-Claw backend
13
45
  * 4. Auto-bind entity if not already bound
@@ -15,12 +47,8 @@ import { createWebhookHandler } from './webhook-handler.js';
15
47
  */
16
48
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
49
  export async function startAccount(ctx) {
18
- const { accountId, config } = ctx;
19
- console.log(`[E-Claw] startAccount called, accountId=${accountId}, config keys=${Object.keys(config || {}).join(',')}`);
20
- console.log(`[E-Claw] config.channels.eclaw=`, JSON.stringify(config?.channels?.eclaw ?? null));
21
- console.log(`[E-Claw] config.accounts=`, JSON.stringify(config?.accounts ?? null));
22
- const account = resolveAccount(config, accountId);
23
- console.log(`[E-Claw] resolved account: enabled=${account.enabled}, apiKey=${account.apiKey ? 'SET' : 'MISSING'}`);
50
+ const accountId = ctx.accountId ?? ctx.account?.accountId ?? 'default';
51
+ const account = resolveAccountFromCtx(ctx);
24
52
  if (!account.enabled || !account.apiKey) {
25
53
  console.log(`[E-Claw] Account ${accountId} disabled or missing credentials, skipping`);
26
54
  return;
@@ -30,12 +58,15 @@ export async function startAccount(ctx) {
30
58
  setClient(accountId, client);
31
59
  // Generate per-session callback token
32
60
  const callbackToken = randomBytes(32).toString('hex');
33
- // Determine webhook configuration
61
+ // Webhook URL: account config > env var > warn
34
62
  const webhookPort = parseInt(process.env.ECLAW_WEBHOOK_PORT || '0') || 0;
35
- const publicUrl = process.env.ECLAW_WEBHOOK_URL;
63
+ const publicUrl = account.webhookUrl?.replace(/\/$/, '')
64
+ || process.env.ECLAW_WEBHOOK_URL?.replace(/\/$/, '');
36
65
  if (!publicUrl) {
37
- console.warn('[E-Claw] ECLAW_WEBHOOK_URL not set. Set this to your public-facing URL ' +
38
- 'so E-Claw can send messages to this plugin. Example: https://my-openclaw.example.com');
66
+ console.warn('[E-Claw] Webhook URL not configured. ' +
67
+ 'Run "openclaw configure" and enter your OpenClaw public URL, ' +
68
+ 'or set ECLAW_WEBHOOK_URL env var. ' +
69
+ 'Example: https://your-openclaw-domain.com');
39
70
  }
40
71
  // Create webhook handler
41
72
  const handler = createWebhookHandler(callbackToken, accountId);
@@ -84,11 +115,9 @@ export async function startAccount(ctx) {
84
115
  }
85
116
  else {
86
117
  console.log(`[E-Claw] Entity ${account.entityId} already bound`);
87
- // For already-bound entities, we need to get the botSecret
88
- // The bind endpoint returns existing credentials for channel-bound entities
89
118
  const bindData = await client.bindEntity(account.entityId, account.botName);
90
119
  console.log(`[E-Claw] Retrieved credentials for entity ${account.entityId}`);
91
- void bindData; // credentials stored in client
120
+ void bindData;
92
121
  }
93
122
  console.log(`[E-Claw] Account ${accountId} ready!`);
94
123
  }
@@ -47,6 +47,11 @@ export const eclawOnboardingAdapter = {
47
47
  placeholder: 'My Bot',
48
48
  initialValue: resolved.botName ?? '',
49
49
  });
50
+ const webhookUrl = await prompter.text({
51
+ message: 'Webhook URL (your OpenClaw public URL, e.g. https://openclaw.example.com)',
52
+ placeholder: 'https://your-openclaw-domain.com',
53
+ initialValue: resolved.webhookUrl ?? '',
54
+ });
50
55
  const nextCfg = {
51
56
  ...cfg,
52
57
  channels: {
@@ -60,6 +65,7 @@ export const eclawOnboardingAdapter = {
60
65
  apiBase: resolved.apiBase || 'https://eclawbot.com',
61
66
  entityId: Number(entityIdStr),
62
67
  botName: String(botName).trim() || undefined,
68
+ webhookUrl: String(webhookUrl).trim() || undefined,
63
69
  enabled: true,
64
70
  },
65
71
  },
package/dist/types.d.ts CHANGED
@@ -6,6 +6,7 @@ export interface EClawAccountConfig {
6
6
  apiBase: string;
7
7
  entityId: number;
8
8
  botName?: string;
9
+ webhookUrl?: string;
9
10
  }
10
11
  /** Inbound message from E-Claw callback webhook */
11
12
  export interface EClawInboundMessage {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eclaw/openclaw-channel",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
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",