qidao-openclaw-plugin 1.1.3 → 1.2.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/package.json +1 -1
- package/src/index.js +60 -140
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 栖岛聊天 OpenClaw Channel 插件
|
|
3
|
-
* 严格按照官方文档实现: https://docs.openclaw.ai/tools/plugin
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
5
|
import { QidaoChannel } from './qidao-channel.js';
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
const accountConnections = new Map();
|
|
7
|
+
let connection = null;
|
|
10
8
|
|
|
11
|
-
// Channel 定义
|
|
12
9
|
const qidaoChannel = {
|
|
13
10
|
id: 'qidao',
|
|
14
11
|
|
|
@@ -16,7 +13,7 @@ const qidaoChannel = {
|
|
|
16
13
|
id: 'qidao',
|
|
17
14
|
label: '栖岛聊天',
|
|
18
15
|
selectionLabel: '栖岛聊天 (Qidao Chat)',
|
|
19
|
-
blurb: '
|
|
16
|
+
blurb: '连接到栖岛聊天服务',
|
|
20
17
|
},
|
|
21
18
|
|
|
22
19
|
capabilities: {
|
|
@@ -24,177 +21,100 @@ const qidaoChannel = {
|
|
|
24
21
|
},
|
|
25
22
|
|
|
26
23
|
config: {
|
|
27
|
-
listAccountIds: (
|
|
28
|
-
const accounts = cfg.channels?.qidao?.accounts ?? {};
|
|
29
|
-
return Object.keys(accounts);
|
|
30
|
-
},
|
|
24
|
+
listAccountIds: () => ['default'],
|
|
31
25
|
|
|
32
|
-
resolveAccount: (cfg
|
|
33
|
-
const
|
|
34
|
-
const account = accounts[accountId ?? 'default'];
|
|
35
|
-
|
|
36
|
-
if (!account) {
|
|
37
|
-
return { accountId };
|
|
38
|
-
}
|
|
26
|
+
resolveAccount: (cfg) => {
|
|
27
|
+
const qidaoConfig = cfg.channels?.qidao ?? {};
|
|
39
28
|
|
|
40
29
|
return {
|
|
41
|
-
accountId:
|
|
42
|
-
enabled:
|
|
43
|
-
chatId:
|
|
44
|
-
userId:
|
|
45
|
-
serverUrl:
|
|
46
|
-
};
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
// 添加 setup 配置向导
|
|
51
|
-
setup: {
|
|
52
|
-
configure: async ({ cfg, prompter }) => {
|
|
53
|
-
const accounts = cfg.channels?.qidao?.accounts ?? {};
|
|
54
|
-
const defaultAccount = accounts.default ?? {};
|
|
55
|
-
|
|
56
|
-
const chatId = await prompter.text({
|
|
57
|
-
message: '请输入栖岛 Chat ID:',
|
|
58
|
-
default: defaultAccount.chatId?.toString(),
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
const userId = await prompter.text({
|
|
62
|
-
message: '请输入栖岛 User ID (可选):',
|
|
63
|
-
default: defaultAccount.userId?.toString() || '',
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const serverUrl = await prompter.text({
|
|
67
|
-
message: '请输入服务器地址:',
|
|
68
|
-
default: defaultAccount.serverUrl || 'wss://oc.qidao.chat/ws',
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
const newCfg = {
|
|
72
|
-
...cfg,
|
|
73
|
-
channels: {
|
|
74
|
-
...cfg.channels,
|
|
75
|
-
qidao: {
|
|
76
|
-
accounts: {
|
|
77
|
-
default: {
|
|
78
|
-
enabled: true,
|
|
79
|
-
chatId: parseInt(chatId),
|
|
80
|
-
userId: userId ? parseInt(userId) : undefined,
|
|
81
|
-
serverUrl,
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
},
|
|
30
|
+
accountId: 'default',
|
|
31
|
+
enabled: qidaoConfig.enabled ?? false,
|
|
32
|
+
chatId: qidaoConfig.chatId,
|
|
33
|
+
userId: qidaoConfig.userId,
|
|
34
|
+
serverUrl: qidaoConfig.serverUrl ?? 'wss://oc.qidao.chat/ws',
|
|
86
35
|
};
|
|
87
|
-
|
|
88
|
-
return { cfg: newCfg, accountId: 'default' };
|
|
89
36
|
},
|
|
90
37
|
},
|
|
91
38
|
|
|
92
39
|
outbound: {
|
|
93
40
|
deliveryMode: 'direct',
|
|
94
41
|
|
|
95
|
-
sendText: async ({ text,
|
|
96
|
-
const connection = accountConnections.get(accountId ?? 'default');
|
|
97
|
-
|
|
42
|
+
sendText: async ({ text, chatId }) => {
|
|
98
43
|
if (!connection || !connection.isConnected()) {
|
|
99
|
-
return {
|
|
100
|
-
ok: false,
|
|
101
|
-
error: '未连接到栖岛服务'
|
|
102
|
-
};
|
|
44
|
+
return { ok: false, error: '未连接到栖岛服务' };
|
|
103
45
|
}
|
|
104
46
|
|
|
105
47
|
if (!chatId) {
|
|
106
|
-
return {
|
|
107
|
-
ok: false,
|
|
108
|
-
error: '未指定chatId'
|
|
109
|
-
};
|
|
48
|
+
return { ok: false, error: '未指定chatId' };
|
|
110
49
|
}
|
|
111
50
|
|
|
112
51
|
try {
|
|
113
52
|
await connection.sendMessage(parseInt(chatId), text);
|
|
114
53
|
return { ok: true };
|
|
115
54
|
} catch (error) {
|
|
116
|
-
return {
|
|
117
|
-
ok: false,
|
|
118
|
-
error: error.message
|
|
119
|
-
};
|
|
55
|
+
return { ok: false, error: error.message };
|
|
120
56
|
}
|
|
121
57
|
},
|
|
122
58
|
},
|
|
123
59
|
};
|
|
124
60
|
|
|
125
|
-
// 插件注册函数
|
|
126
61
|
export default function register(api) {
|
|
127
62
|
api.logger.info('栖岛聊天插件加载中...');
|
|
128
63
|
|
|
129
|
-
// 注册 Channel
|
|
130
64
|
api.registerChannel({ plugin: qidaoChannel });
|
|
131
65
|
|
|
132
|
-
// 异步初始化连接
|
|
133
66
|
setImmediate(async () => {
|
|
134
67
|
try {
|
|
135
68
|
const cfg = api.getGatewayConfig?.() || {};
|
|
136
|
-
const
|
|
69
|
+
const account = qidaoChannel.config.resolveAccount(cfg);
|
|
137
70
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
channelId: 'qidao',
|
|
180
|
-
accountId: accountId,
|
|
181
|
-
senderId: message.senderId.toString(),
|
|
182
|
-
senderName: message.senderName,
|
|
183
|
-
text: message.messageText,
|
|
184
|
-
timestamp: message.timestamp,
|
|
185
|
-
chatType: message.chatType === 0 ? 'direct' : 'group',
|
|
186
|
-
chatId: message.chatId.toString(),
|
|
187
|
-
});
|
|
188
|
-
}
|
|
71
|
+
if (!account.enabled) {
|
|
72
|
+
api.logger.info('栖岛聊天未启用');
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!account.chatId) {
|
|
77
|
+
api.logger.warn('栖岛聊天缺少chatId配置');
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
api.logger.info(`连接栖岛聊天 (chatId: ${account.chatId})`);
|
|
82
|
+
|
|
83
|
+
connection = new QidaoChannel({
|
|
84
|
+
serverUrl: account.serverUrl,
|
|
85
|
+
chatId: account.chatId,
|
|
86
|
+
userId: account.userId,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
connection.on('connect', () => {
|
|
90
|
+
api.logger.info('栖岛聊天已连接');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
connection.on('disconnect', () => {
|
|
94
|
+
api.logger.warn('栖岛聊天已断开');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
connection.on('error', (error) => {
|
|
98
|
+
api.logger.error(`栖岛聊天错误: ${error.message}`);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
connection.on('message', (message) => {
|
|
102
|
+
if (message.type === 'new_message') {
|
|
103
|
+
api.ingestMessage({
|
|
104
|
+
channelId: 'qidao',
|
|
105
|
+
accountId: 'default',
|
|
106
|
+
senderId: message.senderId.toString(),
|
|
107
|
+
senderName: message.senderName,
|
|
108
|
+
text: message.messageText,
|
|
109
|
+
timestamp: message.timestamp,
|
|
110
|
+
chatType: message.chatType === 0 ? 'direct' : 'group',
|
|
111
|
+
chatId: message.chatId.toString(),
|
|
189
112
|
});
|
|
190
|
-
|
|
191
|
-
await connection.connect();
|
|
192
|
-
accountConnections.set(accountId, connection);
|
|
193
|
-
|
|
194
|
-
} catch (error) {
|
|
195
|
-
api.logger.error(`栖岛账户 ${accountId} 连接失败: ${error.message}`);
|
|
196
113
|
}
|
|
197
|
-
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
await connection.connect();
|
|
117
|
+
|
|
198
118
|
} catch (error) {
|
|
199
119
|
api.logger.error(`栖岛聊天插件初始化失败: ${error.message}`);
|
|
200
120
|
}
|