@fontdo/5g-message 1.0.5 → 1.0.7
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 +5 -5
- package/cli.ts +136 -0
- package/index.ts +18 -18
- package/openclaw.plugin.json +2 -2
- package/package.json +11 -5
package/README.md
CHANGED
|
@@ -14,16 +14,16 @@ OpenClaw 通道插件,用于连接 Fontdo 5G 消息平台。
|
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
# 将插件复制到 OpenClaw 扩展目录
|
|
17
|
-
cp -r . ~/.openclaw/extensions/
|
|
17
|
+
cp -r . ~/.openclaw/extensions/5g-message
|
|
18
18
|
|
|
19
19
|
# 或者使用链接方式(开发模式)
|
|
20
|
-
openclaw plugins install -l /path/to/
|
|
20
|
+
openclaw plugins install -l /path/to/5g-message
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### 方法 2: NPM 安装
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
openclaw plugins install @
|
|
26
|
+
openclaw plugins install @fontdo/5g-message
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
## 配置
|
|
@@ -33,7 +33,7 @@ openclaw plugins install @openclaw/fontdo-5g-message
|
|
|
33
33
|
```json
|
|
34
34
|
{
|
|
35
35
|
"channels": {
|
|
36
|
-
"
|
|
36
|
+
"5g-message": {
|
|
37
37
|
"enabled": true,
|
|
38
38
|
"accounts": {
|
|
39
39
|
"default": {
|
|
@@ -66,7 +66,7 @@ openclaw plugins install @openclaw/fontdo-5g-message
|
|
|
66
66
|
```json
|
|
67
67
|
{
|
|
68
68
|
"channels": {
|
|
69
|
-
"
|
|
69
|
+
"5g-message": {
|
|
70
70
|
"defaultAccount": "prod",
|
|
71
71
|
"accounts": {
|
|
72
72
|
"prod": {
|
package/cli.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
|
|
7
|
+
// 配置文件路径
|
|
8
|
+
const CONFIG_DIR = path.join(process.env.HOME || process.env.USERPROFILE || '', '.openclaw');
|
|
9
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'openclaw.json');
|
|
10
|
+
|
|
11
|
+
async function main() {
|
|
12
|
+
console.log(chalk.cyan('📱 Fontdo 5G Message 插件配置向导'));
|
|
13
|
+
console.log(chalk.gray('=================================='));
|
|
14
|
+
console.log('');
|
|
15
|
+
|
|
16
|
+
// 读取现有配置
|
|
17
|
+
let config = {};
|
|
18
|
+
if (await fs.exists(CONFIG_FILE)) {
|
|
19
|
+
try {
|
|
20
|
+
config = await fs.readJSON(CONFIG_FILE);
|
|
21
|
+
console.log(chalk.yellow('检测到现有配置,将在其基础上更新'));
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.log(chalk.red('读取配置文件失败,将创建新配置'));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 初始化 5g-message 通道配置
|
|
28
|
+
config.channels = config.channels || {};
|
|
29
|
+
config.channels['5g-message'] = config.channels['5g-message'] || {};
|
|
30
|
+
|
|
31
|
+
let continueAdding = true;
|
|
32
|
+
|
|
33
|
+
while (continueAdding) {
|
|
34
|
+
console.log('');
|
|
35
|
+
console.log(chalk.blue('🔧 账号配置'));
|
|
36
|
+
console.log(chalk.gray('-----------------'));
|
|
37
|
+
|
|
38
|
+
// 收集账号配置信息
|
|
39
|
+
const accountAnswers = await inquirer.prompt([
|
|
40
|
+
{
|
|
41
|
+
type: 'input',
|
|
42
|
+
name: 'accountId',
|
|
43
|
+
message: '账号 ID (例如: default, test, prod):',
|
|
44
|
+
default: 'default',
|
|
45
|
+
validate: (input) => input ? true : '账号 ID 不能为空'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
type: 'input',
|
|
49
|
+
name: 'host',
|
|
50
|
+
message: 'Fontdo 5G 消息平台地址(不含协议前缀):',
|
|
51
|
+
validate: (input) => input ? true : '服务器地址不能为空'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: 'input',
|
|
55
|
+
name: 'appId',
|
|
56
|
+
message: '应用 ID:',
|
|
57
|
+
validate: (input) => input ? true : '应用 ID 不能为空'
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
type: 'input',
|
|
61
|
+
name: 'appKey',
|
|
62
|
+
message: '应用密钥:',
|
|
63
|
+
validate: (input) => input ? true : '应用密钥不能为空'
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: 'input',
|
|
67
|
+
name: 'botName',
|
|
68
|
+
message: '机器人名称:',
|
|
69
|
+
default: 'Fontdo Bot'
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
type: 'confirm',
|
|
73
|
+
name: 'enabled',
|
|
74
|
+
message: '是否启用该账号:',
|
|
75
|
+
default: true
|
|
76
|
+
}
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
// 初始化 accounts 对象
|
|
80
|
+
config.channels['5g-message'].accounts = config.channels['5g-message'].accounts || {};
|
|
81
|
+
|
|
82
|
+
// 保存账号配置
|
|
83
|
+
config.channels['5g-message'].accounts[accountAnswers.accountId] = {
|
|
84
|
+
host: accountAnswers.host,
|
|
85
|
+
appId: accountAnswers.appId,
|
|
86
|
+
appKey: accountAnswers.appKey,
|
|
87
|
+
botName: accountAnswers.botName,
|
|
88
|
+
enabled: accountAnswers.enabled
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// 询问是否继续添加账号
|
|
92
|
+
const addMore = await inquirer.prompt([
|
|
93
|
+
{
|
|
94
|
+
type: 'confirm',
|
|
95
|
+
name: 'addAnother',
|
|
96
|
+
message: '是否继续添加其他账号?',
|
|
97
|
+
default: false
|
|
98
|
+
}
|
|
99
|
+
]);
|
|
100
|
+
|
|
101
|
+
continueAdding = addMore.addAnother;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 确保配置目录存在
|
|
105
|
+
await fs.ensureDir(CONFIG_DIR);
|
|
106
|
+
|
|
107
|
+
// 写入配置文件
|
|
108
|
+
await fs.writeJSON(CONFIG_FILE, config, { spaces: 2 });
|
|
109
|
+
|
|
110
|
+
console.log('');
|
|
111
|
+
console.log(chalk.green('✅ 配置已保存!'));
|
|
112
|
+
console.log(chalk.gray(`配置文件路径: ${CONFIG_FILE}`));
|
|
113
|
+
console.log('');
|
|
114
|
+
|
|
115
|
+
// 显示当前配置的账号列表
|
|
116
|
+
const accounts = config.channels['5g-message'].accounts || {};
|
|
117
|
+
const accountIds = Object.keys(accounts);
|
|
118
|
+
|
|
119
|
+
if (accountIds.length > 0) {
|
|
120
|
+
console.log(chalk.blue('📋 已配置账号:'));
|
|
121
|
+
accountIds.forEach((id) => {
|
|
122
|
+
const account = accounts[id];
|
|
123
|
+
const status = account.enabled ? chalk.green('启用') : chalk.red('禁用');
|
|
124
|
+
console.log(` - ${id}: ${status} (${account.host})`);
|
|
125
|
+
});
|
|
126
|
+
console.log('');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
console.log(chalk.blue('下一步:重启 OpenClaw 服务以应用配置'));
|
|
130
|
+
console.log(chalk.gray('命令: openclaw restart'));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
main().catch((error) => {
|
|
134
|
+
console.error(chalk.red('配置失败:', error.message));
|
|
135
|
+
process.exit(1);
|
|
136
|
+
});
|
package/index.ts
CHANGED
|
@@ -97,7 +97,7 @@ function resolveCustomIMAccount(
|
|
|
97
97
|
): CustomIMAccount {
|
|
98
98
|
const actualAccountId = accountId ?? DEFAULT_ACCOUNT_ID;
|
|
99
99
|
const channels = cfg.channels as Record<string, Record<string, unknown>> | undefined;
|
|
100
|
-
const customImChannel = channels?.["
|
|
100
|
+
const customImChannel = channels?.["5g-message"] as Record<string, unknown> | undefined;
|
|
101
101
|
const accounts = customImChannel?.accounts as Record<string, Record<string, unknown>> | undefined;
|
|
102
102
|
const account = accounts?.[actualAccountId] as Record<string, unknown> | undefined;
|
|
103
103
|
|
|
@@ -126,7 +126,7 @@ function resolveCustomIMAccount(
|
|
|
126
126
|
|
|
127
127
|
function listCustomIMAccountIds(cfg: Record<string, unknown>): string[] {
|
|
128
128
|
const channels = cfg.channels as Record<string, Record<string, unknown>> | undefined;
|
|
129
|
-
const customImChannel = channels?.["
|
|
129
|
+
const customImChannel = channels?.["5g-message"] as Record<string, unknown> | undefined;
|
|
130
130
|
const accounts = customImChannel?.accounts as Record<string, Record<string, unknown>> | undefined;
|
|
131
131
|
return accounts ? Object.keys(accounts) : [];
|
|
132
132
|
}
|
|
@@ -441,7 +441,7 @@ async function dispatchCustomIMMessage(params: {
|
|
|
441
441
|
try {
|
|
442
442
|
route = core.channel.routing.resolveAgentRoute({
|
|
443
443
|
cfg,
|
|
444
|
-
channel: "
|
|
444
|
+
channel: "5g-message",
|
|
445
445
|
accountId: account.accountId,
|
|
446
446
|
peer: {
|
|
447
447
|
kind: isGroup ? "group" : "direct",
|
|
@@ -455,7 +455,7 @@ async function dispatchCustomIMMessage(params: {
|
|
|
455
455
|
}
|
|
456
456
|
|
|
457
457
|
// Build the message context
|
|
458
|
-
const customImFrom = `
|
|
458
|
+
const customImFrom = `5g-message:${msg.sender}`;
|
|
459
459
|
const customImTo = isGroup ? `chat:${chatId}` : `user:${msg.sender}`;
|
|
460
460
|
|
|
461
461
|
// Format message envelope
|
|
@@ -481,13 +481,13 @@ async function dispatchCustomIMMessage(params: {
|
|
|
481
481
|
GroupSubject: isGroup ? chatId : undefined,
|
|
482
482
|
SenderName: msg.sender,
|
|
483
483
|
SenderId: msg.sender,
|
|
484
|
-
Provider: "
|
|
485
|
-
Surface: "
|
|
484
|
+
Provider: "5g-message" as const,
|
|
485
|
+
Surface: "5g-message" as const,
|
|
486
486
|
MessageSid: msg.messageId,
|
|
487
487
|
Timestamp: msg.timestamp,
|
|
488
488
|
WasMentioned: false,
|
|
489
489
|
CommandAuthorized: true,
|
|
490
|
-
OriginatingChannel: "
|
|
490
|
+
OriginatingChannel: "5g-message" as const,
|
|
491
491
|
OriginatingTo: customImTo,
|
|
492
492
|
});
|
|
493
493
|
|
|
@@ -580,13 +580,13 @@ async function dispatchCustomIMMessage(params: {
|
|
|
580
580
|
// ============================================================================
|
|
581
581
|
|
|
582
582
|
export const fontdo5GMessagePlugin: ChannelPlugin<CustomIMAccount> = {
|
|
583
|
-
id: "
|
|
583
|
+
id: "5g-message",
|
|
584
584
|
|
|
585
585
|
meta: {
|
|
586
|
-
id: "
|
|
586
|
+
id: "5g-message",
|
|
587
587
|
label: "Fontdo 5G Message",
|
|
588
588
|
selectionLabel: "Fontdo 5G Message (WebSocket)",
|
|
589
|
-
docsPath: "/channels/
|
|
589
|
+
docsPath: "/channels/5g-message",
|
|
590
590
|
blurb: "Fontdo 5G 消息平台集成,通过 WebSocket JSON-RPC 2.0 协议",
|
|
591
591
|
aliases: ["fontdo", "5g", "5g-message"],
|
|
592
592
|
},
|
|
@@ -601,7 +601,7 @@ export const fontdo5GMessagePlugin: ChannelPlugin<CustomIMAccount> = {
|
|
|
601
601
|
reply: true,
|
|
602
602
|
},
|
|
603
603
|
|
|
604
|
-
reload: { configPrefixes: ["channels.
|
|
604
|
+
reload: { configPrefixes: ["channels.5g-message"] },
|
|
605
605
|
|
|
606
606
|
configSchema: {
|
|
607
607
|
schema: {
|
|
@@ -664,20 +664,20 @@ export const fontdo5GMessagePlugin: ChannelPlugin<CustomIMAccount> = {
|
|
|
664
664
|
...cfg,
|
|
665
665
|
channels: {
|
|
666
666
|
...cfg.channels,
|
|
667
|
-
"
|
|
668
|
-
...cfg.channels?.["
|
|
667
|
+
"5g-message": {
|
|
668
|
+
...cfg.channels?.["5g-message"],
|
|
669
669
|
enabled: true,
|
|
670
670
|
},
|
|
671
671
|
},
|
|
672
672
|
};
|
|
673
673
|
}
|
|
674
674
|
|
|
675
|
-
const customImCfg = cfg.channels?.["
|
|
675
|
+
const customImCfg = cfg.channels?.["5g-message"] as Record<string, unknown> | undefined;
|
|
676
676
|
return {
|
|
677
677
|
...cfg,
|
|
678
678
|
channels: {
|
|
679
679
|
...cfg.channels,
|
|
680
|
-
"
|
|
680
|
+
"5g-message": {
|
|
681
681
|
...customImCfg,
|
|
682
682
|
accounts: {
|
|
683
683
|
...(customImCfg?.accounts as Record<string, unknown>),
|
|
@@ -718,7 +718,7 @@ export const fontdo5GMessagePlugin: ChannelPlugin<CustomIMAccount> = {
|
|
|
718
718
|
throw new Error(`Custom IM account ${ctx.accountId} not configured`);
|
|
719
719
|
}
|
|
720
720
|
|
|
721
|
-
ctx.log?.info(`starting
|
|
721
|
+
ctx.log?.info(`starting 5g-message[${ctx.accountId}]`);
|
|
722
722
|
|
|
723
723
|
// Set initial status
|
|
724
724
|
ctx.setStatus({ accountId: ctx.accountId, connected: false });
|
|
@@ -779,7 +779,7 @@ export const fontdo5GMessagePlugin: ChannelPlugin<CustomIMAccount> = {
|
|
|
779
779
|
// Wait for either abort signal or connection close
|
|
780
780
|
return new Promise<{ stop: () => void }>((resolve) => {
|
|
781
781
|
const stopHandler = () => {
|
|
782
|
-
ctx.log?.info(`stopping
|
|
782
|
+
ctx.log?.info(`stopping 5g-message[${ctx.accountId}]`);
|
|
783
783
|
ctx.setStatus({ accountId: ctx.accountId, connected: false });
|
|
784
784
|
unregisterConnection(ctx.accountId);
|
|
785
785
|
client.disconnect();
|
|
@@ -857,7 +857,7 @@ export const fontdo5GMessagePlugin: ChannelPlugin<CustomIMAccount> = {
|
|
|
857
857
|
// ============================================================================
|
|
858
858
|
|
|
859
859
|
const plugin = {
|
|
860
|
-
id: "
|
|
860
|
+
id: "5g-message",
|
|
861
861
|
name: "Fontdo 5G Message",
|
|
862
862
|
description: "Fontdo 5G 消息平台集成,通过 WebSocket JSON-RPC 2.0 协议",
|
|
863
863
|
configSchema: emptyPluginConfigSchema(),
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fontdo/5g-message",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "OpenClaw 通道插件,用于连接 Fontdo 5G 消息平台",
|
|
5
5
|
"main": "index.ts",
|
|
6
|
+
"bin": {
|
|
7
|
+
"fontdo-5g-message-onboard": "./cli.ts"
|
|
8
|
+
},
|
|
6
9
|
"scripts": {
|
|
7
10
|
"build": "tsc",
|
|
8
11
|
"test": "vitest"
|
|
9
12
|
},
|
|
10
13
|
"dependencies": {
|
|
11
|
-
"ws": "^8.16.0"
|
|
14
|
+
"ws": "^8.16.0",
|
|
15
|
+
"inquirer": "^8.2.7",
|
|
16
|
+
"fs-extra": "^11.3.3",
|
|
17
|
+
"chalk": "^4.1.2"
|
|
12
18
|
},
|
|
13
19
|
"devDependencies": {
|
|
14
20
|
"@types/node": "^20.11.0",
|
|
@@ -21,11 +27,11 @@
|
|
|
21
27
|
"./index.ts"
|
|
22
28
|
],
|
|
23
29
|
"channel": {
|
|
24
|
-
"id": "
|
|
30
|
+
"id": "5g-message",
|
|
25
31
|
"label": "Fontdo 5G Message",
|
|
26
32
|
"selectionLabel": "Fontdo 5G Message (WebSocket)",
|
|
27
|
-
"docsPath": "/channels/
|
|
28
|
-
"docsLabel": "
|
|
33
|
+
"docsPath": "/channels/5g-message",
|
|
34
|
+
"docsLabel": "5g-message",
|
|
29
35
|
"blurb": "Fontdo 5G 消息平台集成,通过 WebSocket JSON-RPC 2.0 协议",
|
|
30
36
|
"order": 100,
|
|
31
37
|
"aliases": [
|