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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +60 -140
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qidao-openclaw-plugin",
3
- "version": "1.1.3",
3
+ "version": "1.2.1",
4
4
  "type": "module",
5
5
  "main": "./src/index.js",
6
6
  "description": "OpenClaw 栖岛聊天 Channel 插件 - 连接到栖岛聊天服务",
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: (cfg) => {
28
- const accounts = cfg.channels?.qidao?.accounts ?? {};
29
- return Object.keys(accounts);
30
- },
24
+ listAccountIds: () => ['default'],
31
25
 
32
- resolveAccount: (cfg, accountId) => {
33
- const accounts = cfg.channels?.qidao?.accounts ?? {};
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: accountId ?? 'default',
42
- enabled: account.enabled ?? true,
43
- chatId: account.chatId,
44
- userId: account.userId,
45
- serverUrl: account.serverUrl ?? 'wss://oc.qidao.chat/ws',
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, accountId, chatId }) => {
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 accounts = cfg.channels?.qidao?.accounts ?? {};
69
+ const account = qidaoChannel.config.resolveAccount(cfg);
137
70
 
138
- for (const [accountId, accountConfig] of Object.entries(accounts)) {
139
- if (accountConfig.enabled === false) {
140
- api.logger.info(`栖岛账户 ${accountId} 已禁用`);
141
- continue;
142
- }
143
-
144
- if (!accountConfig.chatId) {
145
- api.logger.warn(`栖岛账户 ${accountId} 缺少chatId配置`);
146
- continue;
147
- }
148
-
149
- const serverUrl = accountConfig.serverUrl ?? 'wss://oc.qidao.chat/ws';
150
-
151
- api.logger.info(`连接栖岛账户: ${accountId} (chatId: ${accountConfig.chatId})`);
152
-
153
- try {
154
- const connection = new QidaoChannel({
155
- serverUrl,
156
- chatId: accountConfig.chatId,
157
- userId: accountConfig.userId,
158
- });
159
-
160
- // 监听连接事件
161
- connection.on('connect', () => {
162
- api.logger.info(`栖岛账户 ${accountId} 已连接`);
163
- });
164
-
165
- connection.on('disconnect', () => {
166
- api.logger.warn(`栖岛账户 ${accountId} 已断开`);
167
- });
168
-
169
- connection.on('error', (error) => {
170
- api.logger.error(`栖岛账户 ${accountId} 错误: ${error.message}`);
171
- });
172
-
173
- // 监听栖岛消息,转发给OpenClaw
174
- connection.on('message', (message) => {
175
- api.logger.debug(`栖岛账户 ${accountId} 收到消息:`, message);
176
-
177
- if (message.type === 'new_message') {
178
- api.ingestMessage({
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
  }