@eclaw/openclaw-channel 1.0.0 → 1.0.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/README.md +58 -58
- package/dist/channel.d.ts +19 -0
- package/dist/channel.js +2 -0
- package/dist/onboarding.d.ts +19 -0
- package/dist/onboarding.js +77 -0
- package/openclaw.plugin.json +27 -27
- package/package.json +60 -60
package/README.md
CHANGED
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
# @eclaw/openclaw-channel
|
|
2
|
-
|
|
3
|
-
OpenClaw channel plugin for [E-Claw](https://eclawbot.com) — an AI chat platform for live wallpaper entities on Android.
|
|
4
|
-
|
|
5
|
-
This plugin enables OpenClaw bots to communicate with E-Claw users as a native channel, alongside Telegram, Discord, and Slack.
|
|
6
|
-
|
|
7
|
-
## Installation
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install @eclaw/openclaw-channel
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Configuration
|
|
14
|
-
|
|
15
|
-
Add to your OpenClaw `config.yaml`:
|
|
16
|
-
|
|
17
|
-
```yaml
|
|
18
|
-
plugins:
|
|
19
|
-
- "@eclaw/openclaw-channel"
|
|
20
|
-
|
|
21
|
-
channels:
|
|
22
|
-
eclaw:
|
|
23
|
-
accounts:
|
|
24
|
-
default:
|
|
25
|
-
apiKey: "eck_..." # From E-Claw Portal → Settings → Channel API
|
|
26
|
-
apiSecret: "ecs_..." # From E-Claw Portal → Settings → Channel API
|
|
27
|
-
apiBase: "https://eclawbot.com"
|
|
28
|
-
entityId: 0 # Which entity slot to use (0-3)
|
|
29
|
-
botName: "My Bot"
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Getting API Credentials
|
|
33
|
-
|
|
34
|
-
1. Log in to [E-Claw Portal](https://eclawbot.com/portal)
|
|
35
|
-
2. Go to **Settings → Channel API**
|
|
36
|
-
3. Copy your `API Key` and `API Secret`
|
|
37
|
-
|
|
38
|
-
## How It Works
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
User (Android) ──speaks──▶ E-Claw Backend ──webhook──▶ OpenClaw Agent
|
|
42
|
-
OpenClaw Agent ──replies──▶ POST /api/channel/message ──▶ User (Android)
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
- **Inbound**: E-Claw POSTs structured JSON to a webhook URL registered by this plugin
|
|
46
|
-
- **Outbound**: Plugin calls `POST /api/channel/message` with the bot reply
|
|
47
|
-
- **Auth**: `eck_`/`ecs_` channel credentials for API auth, per-entity `botSecret` for message auth
|
|
48
|
-
|
|
49
|
-
## Environment Variables
|
|
50
|
-
|
|
51
|
-
| Variable | Required | Description |
|
|
52
|
-
|----------|----------|-------------|
|
|
53
|
-
| `ECLAW_WEBHOOK_URL` | Production | Public URL for receiving inbound messages |
|
|
54
|
-
| `ECLAW_WEBHOOK_PORT` | Optional | Webhook server port (default: random) |
|
|
55
|
-
|
|
56
|
-
## License
|
|
57
|
-
|
|
58
|
-
MIT
|
|
1
|
+
# @eclaw/openclaw-channel
|
|
2
|
+
|
|
3
|
+
OpenClaw channel plugin for [E-Claw](https://eclawbot.com) — an AI chat platform for live wallpaper entities on Android.
|
|
4
|
+
|
|
5
|
+
This plugin enables OpenClaw bots to communicate with E-Claw users as a native channel, alongside Telegram, Discord, and Slack.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @eclaw/openclaw-channel
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Configuration
|
|
14
|
+
|
|
15
|
+
Add to your OpenClaw `config.yaml`:
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
plugins:
|
|
19
|
+
- "@eclaw/openclaw-channel"
|
|
20
|
+
|
|
21
|
+
channels:
|
|
22
|
+
eclaw:
|
|
23
|
+
accounts:
|
|
24
|
+
default:
|
|
25
|
+
apiKey: "eck_..." # From E-Claw Portal → Settings → Channel API
|
|
26
|
+
apiSecret: "ecs_..." # From E-Claw Portal → Settings → Channel API
|
|
27
|
+
apiBase: "https://eclawbot.com"
|
|
28
|
+
entityId: 0 # Which entity slot to use (0-3)
|
|
29
|
+
botName: "My Bot"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Getting API Credentials
|
|
33
|
+
|
|
34
|
+
1. Log in to [E-Claw Portal](https://eclawbot.com/portal)
|
|
35
|
+
2. Go to **Settings → Channel API**
|
|
36
|
+
3. Copy your `API Key` and `API Secret`
|
|
37
|
+
|
|
38
|
+
## How It Works
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
User (Android) ──speaks──▶ E-Claw Backend ──webhook──▶ OpenClaw Agent
|
|
42
|
+
OpenClaw Agent ──replies──▶ POST /api/channel/message ──▶ User (Android)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- **Inbound**: E-Claw POSTs structured JSON to a webhook URL registered by this plugin
|
|
46
|
+
- **Outbound**: Plugin calls `POST /api/channel/message` with the bot reply
|
|
47
|
+
- **Auth**: `eck_`/`ecs_` channel credentials for API auth, per-entity `botSecret` for message auth
|
|
48
|
+
|
|
49
|
+
## Environment Variables
|
|
50
|
+
|
|
51
|
+
| Variable | Required | Description |
|
|
52
|
+
|----------|----------|-------------|
|
|
53
|
+
| `ECLAW_WEBHOOK_URL` | Production | Public URL for receiving inbound messages |
|
|
54
|
+
| `ECLAW_WEBHOOK_PORT` | Optional | Webhook server port (default: random) |
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
|
|
58
|
+
MIT
|
package/dist/channel.d.ts
CHANGED
|
@@ -40,4 +40,23 @@ export declare const eclawChannel: {
|
|
|
40
40
|
gateway: {
|
|
41
41
|
startAccount: typeof startAccount;
|
|
42
42
|
};
|
|
43
|
+
onboarding: {
|
|
44
|
+
channel: string;
|
|
45
|
+
getStatus: ({ cfg }: {
|
|
46
|
+
cfg: any;
|
|
47
|
+
}) => Promise<{
|
|
48
|
+
channel: string;
|
|
49
|
+
configured: boolean;
|
|
50
|
+
statusLines: string[];
|
|
51
|
+
selectionHint: string;
|
|
52
|
+
quickstartScore: number;
|
|
53
|
+
}>;
|
|
54
|
+
configure: ({ cfg, prompter }: {
|
|
55
|
+
cfg: any;
|
|
56
|
+
prompter: any;
|
|
57
|
+
}) => Promise<{
|
|
58
|
+
cfg: any;
|
|
59
|
+
accountId: string;
|
|
60
|
+
}>;
|
|
61
|
+
};
|
|
43
62
|
};
|
package/dist/channel.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { listAccountIds, resolveAccount } from './config.js';
|
|
2
2
|
import { sendText, sendMedia } from './outbound.js';
|
|
3
3
|
import { startAccount } from './gateway.js';
|
|
4
|
+
import { eclawOnboardingAdapter } from './onboarding.js';
|
|
4
5
|
/**
|
|
5
6
|
* E-Claw ChannelPlugin definition.
|
|
6
7
|
*
|
|
@@ -40,4 +41,5 @@ export const eclawChannel = {
|
|
|
40
41
|
gateway: {
|
|
41
42
|
startAccount,
|
|
42
43
|
},
|
|
44
|
+
onboarding: eclawOnboardingAdapter,
|
|
43
45
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const eclawOnboardingAdapter: {
|
|
2
|
+
channel: string;
|
|
3
|
+
getStatus: ({ cfg }: {
|
|
4
|
+
cfg: any;
|
|
5
|
+
}) => Promise<{
|
|
6
|
+
channel: string;
|
|
7
|
+
configured: boolean;
|
|
8
|
+
statusLines: string[];
|
|
9
|
+
selectionHint: string;
|
|
10
|
+
quickstartScore: number;
|
|
11
|
+
}>;
|
|
12
|
+
configure: ({ cfg, prompter }: {
|
|
13
|
+
cfg: any;
|
|
14
|
+
prompter: any;
|
|
15
|
+
}) => Promise<{
|
|
16
|
+
cfg: any;
|
|
17
|
+
accountId: string;
|
|
18
|
+
}>;
|
|
19
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { listAccountIds, resolveAccount } from './config.js';
|
|
2
|
+
const DEFAULT_ACCOUNT_ID = 'main';
|
|
3
|
+
export const eclawOnboardingAdapter = {
|
|
4
|
+
channel: 'eclaw',
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
+
getStatus: async ({ cfg }) => {
|
|
7
|
+
const ids = listAccountIds(cfg);
|
|
8
|
+
const configured = ids.some((id) => {
|
|
9
|
+
const acc = resolveAccount(cfg, id);
|
|
10
|
+
return Boolean(acc.apiKey && acc.apiSecret);
|
|
11
|
+
});
|
|
12
|
+
return {
|
|
13
|
+
channel: 'eclaw',
|
|
14
|
+
configured,
|
|
15
|
+
statusLines: [`E-Claw: ${configured ? 'configured ✓' : 'not configured'}`],
|
|
16
|
+
selectionHint: configured ? 'configured' : 'E-Claw (AI Live Wallpaper Chat)',
|
|
17
|
+
quickstartScore: configured ? 1 : 3,
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
configure: async ({ cfg, prompter }) => {
|
|
22
|
+
const accountId = DEFAULT_ACCOUNT_ID;
|
|
23
|
+
const resolved = resolveAccount(cfg, accountId);
|
|
24
|
+
await prompter.note([
|
|
25
|
+
'前往 https://eclawbot.com 登入',
|
|
26
|
+
'進入 Portal → 設定 → Channel API',
|
|
27
|
+
'建立 API Key 和 API Secret,填入下方',
|
|
28
|
+
].join('\n'), 'E-Claw 設定說明');
|
|
29
|
+
const apiKey = await prompter.text({
|
|
30
|
+
message: 'Channel API Key',
|
|
31
|
+
placeholder: 'eck_...',
|
|
32
|
+
initialValue: resolved.apiKey || '',
|
|
33
|
+
validate: (v) => (String(v ?? '').trim() ? undefined : '必填'),
|
|
34
|
+
});
|
|
35
|
+
const apiSecret = await prompter.text({
|
|
36
|
+
message: 'Channel API Secret',
|
|
37
|
+
placeholder: 'ecs_...',
|
|
38
|
+
initialValue: resolved.apiSecret || '',
|
|
39
|
+
validate: (v) => (String(v ?? '').trim() ? undefined : '必填'),
|
|
40
|
+
});
|
|
41
|
+
const entityIdStr = await prompter.text({
|
|
42
|
+
message: 'Entity ID (0–3)',
|
|
43
|
+
placeholder: '0',
|
|
44
|
+
initialValue: String(resolved.entityId ?? 0),
|
|
45
|
+
validate: (v) => {
|
|
46
|
+
const n = Number(v);
|
|
47
|
+
return Number.isInteger(n) && n >= 0 && n <= 3 ? undefined : '請輸入 0–3';
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
const botName = await prompter.text({
|
|
51
|
+
message: 'Bot 顯示名稱(選填)',
|
|
52
|
+
placeholder: 'My Bot',
|
|
53
|
+
initialValue: resolved.botName ?? '',
|
|
54
|
+
});
|
|
55
|
+
const nextCfg = {
|
|
56
|
+
...cfg,
|
|
57
|
+
channels: {
|
|
58
|
+
...(cfg.channels ?? {}),
|
|
59
|
+
eclaw: {
|
|
60
|
+
...(cfg.channels?.eclaw ?? {}),
|
|
61
|
+
accounts: {
|
|
62
|
+
...(cfg.channels?.eclaw?.accounts ?? {}), // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
63
|
+
[accountId]: {
|
|
64
|
+
apiKey: String(apiKey).trim(),
|
|
65
|
+
apiSecret: String(apiSecret).trim(),
|
|
66
|
+
apiBase: resolved.apiBase || 'https://eclawbot.com',
|
|
67
|
+
entityId: Number(entityIdStr),
|
|
68
|
+
botName: String(botName).trim() || undefined,
|
|
69
|
+
enabled: true,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
return { cfg: nextCfg, accountId };
|
|
76
|
+
},
|
|
77
|
+
};
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "eclaw",
|
|
3
|
-
"name": "E-Claw",
|
|
4
|
-
"version": "1.0.0",
|
|
5
|
-
"description": "E-Claw AI chat platform channel for OpenClaw",
|
|
6
|
-
"channels": ["eclaw"],
|
|
7
|
-
"configSchema": {
|
|
8
|
-
"type": "object",
|
|
9
|
-
"properties": {
|
|
10
|
-
"accounts": {
|
|
11
|
-
"type": "object",
|
|
12
|
-
"additionalProperties": {
|
|
13
|
-
"type": "object",
|
|
14
|
-
"properties": {
|
|
15
|
-
"enabled": { "type": "boolean", "default": true },
|
|
16
|
-
"apiKey": { "type": "string", "description": "Channel API Key (eck_...)" },
|
|
17
|
-
"apiSecret": { "type": "string", "description": "Channel API Secret (ecs_...)" },
|
|
18
|
-
"apiBase": { "type": "string", "default": "https://eclawbot.com" },
|
|
19
|
-
"entityId": { "type": "number", "default": 0, "minimum": 0, "maximum": 7 },
|
|
20
|
-
"botName": { "type": "string", "maxLength": 20 }
|
|
21
|
-
},
|
|
22
|
-
"required": ["apiKey", "apiSecret"]
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"id": "eclaw",
|
|
3
|
+
"name": "E-Claw",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "E-Claw AI chat platform channel for OpenClaw",
|
|
6
|
+
"channels": ["eclaw"],
|
|
7
|
+
"configSchema": {
|
|
8
|
+
"type": "object",
|
|
9
|
+
"properties": {
|
|
10
|
+
"accounts": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"additionalProperties": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"properties": {
|
|
15
|
+
"enabled": { "type": "boolean", "default": true },
|
|
16
|
+
"apiKey": { "type": "string", "description": "Channel API Key (eck_...)" },
|
|
17
|
+
"apiSecret": { "type": "string", "description": "Channel API Secret (ecs_...)" },
|
|
18
|
+
"apiBase": { "type": "string", "default": "https://eclawbot.com" },
|
|
19
|
+
"entityId": { "type": "number", "default": 0, "minimum": 0, "maximum": 7 },
|
|
20
|
+
"botName": { "type": "string", "maxLength": 20 }
|
|
21
|
+
},
|
|
22
|
+
"required": ["apiKey", "apiSecret"]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
package/package.json
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@eclaw/openclaw-channel",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "E-Claw channel plugin for OpenClaw — AI chat platform for live wallpaper entities",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./dist/index.js",
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"import": "./dist/index.js",
|
|
11
|
-
"types": "./dist/index.d.ts"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"files": [
|
|
15
|
-
"dist/",
|
|
16
|
-
"openclaw.plugin.json",
|
|
17
|
-
"README.md"
|
|
18
|
-
],
|
|
19
|
-
"scripts": {
|
|
20
|
-
"build": "tsc",
|
|
21
|
-
"dev": "tsc --watch",
|
|
22
|
-
"test": "vitest run",
|
|
23
|
-
"lint": "tsc --noEmit",
|
|
24
|
-
"prepublishOnly": "npm run build"
|
|
25
|
-
},
|
|
26
|
-
"openclaw": {
|
|
27
|
-
"extensions": [
|
|
28
|
-
"./dist/index.js"
|
|
29
|
-
],
|
|
30
|
-
"channel": {
|
|
31
|
-
"id": "eclaw",
|
|
32
|
-
"label": "E-Claw",
|
|
33
|
-
"selectionLabel": "E-Claw (AI Live Wallpaper Chat)",
|
|
34
|
-
"docsPath": "https://github.com/HankHuang0516/openclaw-channel-eclaw#readme",
|
|
35
|
-
"description": "Connect OpenClaw to E-Claw — an AI chat platform for live wallpaper entities on Android."
|
|
36
|
-
},
|
|
37
|
-
"install": {
|
|
38
|
-
"npmSpec": "@eclaw/openclaw-channel"
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
"keywords": [
|
|
42
|
-
"openclaw",
|
|
43
|
-
"openclaw-channel",
|
|
44
|
-
"channel",
|
|
45
|
-
"eclaw",
|
|
46
|
-
"ai-agent",
|
|
47
|
-
"live-wallpaper"
|
|
48
|
-
],
|
|
49
|
-
"author": "HankHuang",
|
|
50
|
-
"license": "MIT",
|
|
51
|
-
"repository": {
|
|
52
|
-
"type": "git",
|
|
53
|
-
"url": "
|
|
54
|
-
},
|
|
55
|
-
"devDependencies": {
|
|
56
|
-
"typescript": "^5.4",
|
|
57
|
-
"vitest": "^2.0",
|
|
58
|
-
"@types/node": "^20"
|
|
59
|
-
}
|
|
60
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@eclaw/openclaw-channel",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "E-Claw channel plugin for OpenClaw — AI chat platform for live wallpaper entities",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/",
|
|
16
|
+
"openclaw.plugin.json",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"dev": "tsc --watch",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"lint": "tsc --noEmit",
|
|
24
|
+
"prepublishOnly": "npm run build"
|
|
25
|
+
},
|
|
26
|
+
"openclaw": {
|
|
27
|
+
"extensions": [
|
|
28
|
+
"./dist/index.js"
|
|
29
|
+
],
|
|
30
|
+
"channel": {
|
|
31
|
+
"id": "eclaw",
|
|
32
|
+
"label": "E-Claw",
|
|
33
|
+
"selectionLabel": "E-Claw (AI Live Wallpaper Chat)",
|
|
34
|
+
"docsPath": "https://github.com/HankHuang0516/openclaw-channel-eclaw#readme",
|
|
35
|
+
"description": "Connect OpenClaw to E-Claw — an AI chat platform for live wallpaper entities on Android."
|
|
36
|
+
},
|
|
37
|
+
"install": {
|
|
38
|
+
"npmSpec": "@eclaw/openclaw-channel"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"openclaw",
|
|
43
|
+
"openclaw-channel",
|
|
44
|
+
"channel",
|
|
45
|
+
"eclaw",
|
|
46
|
+
"ai-agent",
|
|
47
|
+
"live-wallpaper"
|
|
48
|
+
],
|
|
49
|
+
"author": "HankHuang",
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "https://github.com/HankHuang0516/openclaw-channel-eclaw"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"typescript": "^5.4",
|
|
57
|
+
"vitest": "^2.0",
|
|
58
|
+
"@types/node": "^20"
|
|
59
|
+
}
|
|
60
|
+
}
|