qidao-openclaw-plugin 1.1.3 → 1.2.2

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 +69 -113
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.2",
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,48 +21,38 @@ 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',
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',
46
35
  };
47
36
  },
48
37
  },
49
38
 
50
- // 添加 setup 配置向导
51
- setup: {
39
+ onboarding: {
52
40
  configure: async ({ cfg, prompter }) => {
53
- const accounts = cfg.channels?.qidao?.accounts ?? {};
54
- const defaultAccount = accounts.default ?? {};
41
+ const qidaoConfig = cfg.channels?.qidao ?? {};
55
42
 
56
43
  const chatId = await prompter.text({
57
44
  message: '请输入栖岛 Chat ID:',
58
- default: defaultAccount.chatId?.toString(),
45
+ default: qidaoConfig.chatId?.toString() || '',
59
46
  });
60
47
 
61
48
  const userId = await prompter.text({
62
49
  message: '请输入栖岛 User ID (可选):',
63
- default: defaultAccount.userId?.toString() || '',
50
+ default: qidaoConfig.userId?.toString() || '',
64
51
  });
65
52
 
66
53
  const serverUrl = await prompter.text({
67
54
  message: '请输入服务器地址:',
68
- default: defaultAccount.serverUrl || 'wss://oc.qidao.chat/ws',
55
+ default: qidaoConfig.serverUrl || 'wss://oc.qidao.chat/ws',
69
56
  });
70
57
 
71
58
  const newCfg = {
@@ -73,14 +60,10 @@ const qidaoChannel = {
73
60
  channels: {
74
61
  ...cfg.channels,
75
62
  qidao: {
76
- accounts: {
77
- default: {
78
- enabled: true,
79
- chatId: parseInt(chatId),
80
- userId: userId ? parseInt(userId) : undefined,
81
- serverUrl,
82
- },
83
- },
63
+ enabled: true,
64
+ chatId: parseInt(chatId),
65
+ userId: userId ? parseInt(userId) : undefined,
66
+ serverUrl,
84
67
  },
85
68
  },
86
69
  };
@@ -92,109 +75,82 @@ const qidaoChannel = {
92
75
  outbound: {
93
76
  deliveryMode: 'direct',
94
77
 
95
- sendText: async ({ text, accountId, chatId }) => {
96
- const connection = accountConnections.get(accountId ?? 'default');
97
-
78
+ sendText: async ({ text, chatId }) => {
98
79
  if (!connection || !connection.isConnected()) {
99
- return {
100
- ok: false,
101
- error: '未连接到栖岛服务'
102
- };
80
+ return { ok: false, error: '未连接到栖岛服务' };
103
81
  }
104
82
 
105
83
  if (!chatId) {
106
- return {
107
- ok: false,
108
- error: '未指定chatId'
109
- };
84
+ return { ok: false, error: '未指定chatId' };
110
85
  }
111
86
 
112
87
  try {
113
88
  await connection.sendMessage(parseInt(chatId), text);
114
89
  return { ok: true };
115
90
  } catch (error) {
116
- return {
117
- ok: false,
118
- error: error.message
119
- };
91
+ return { ok: false, error: error.message };
120
92
  }
121
93
  },
122
94
  },
123
95
  };
124
96
 
125
- // 插件注册函数
126
97
  export default function register(api) {
127
98
  api.logger.info('栖岛聊天插件加载中...');
128
99
 
129
- // 注册 Channel
130
100
  api.registerChannel({ plugin: qidaoChannel });
131
101
 
132
- // 异步初始化连接
133
102
  setImmediate(async () => {
134
103
  try {
135
104
  const cfg = api.getGatewayConfig?.() || {};
136
- const accounts = cfg.channels?.qidao?.accounts ?? {};
105
+ const account = qidaoChannel.config.resolveAccount(cfg);
137
106
 
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
- }
107
+ if (!account.enabled) {
108
+ api.logger.info('栖岛聊天未启用');
109
+ return;
110
+ }
111
+
112
+ if (!account.chatId) {
113
+ api.logger.warn('栖岛聊天缺少chatId配置');
114
+ return;
115
+ }
116
+
117
+ api.logger.info(`连接栖岛聊天 (chatId: ${account.chatId})`);
118
+
119
+ connection = new QidaoChannel({
120
+ serverUrl: account.serverUrl,
121
+ chatId: account.chatId,
122
+ userId: account.userId,
123
+ });
124
+
125
+ connection.on('connect', () => {
126
+ api.logger.info('栖岛聊天已连接');
127
+ });
128
+
129
+ connection.on('disconnect', () => {
130
+ api.logger.warn('栖岛聊天已断开');
131
+ });
132
+
133
+ connection.on('error', (error) => {
134
+ api.logger.error(`栖岛聊天错误: ${error.message}`);
135
+ });
136
+
137
+ connection.on('message', (message) => {
138
+ if (message.type === 'new_message') {
139
+ api.ingestMessage({
140
+ channelId: 'qidao',
141
+ accountId: 'default',
142
+ senderId: message.senderId.toString(),
143
+ senderName: message.senderName,
144
+ text: message.messageText,
145
+ timestamp: message.timestamp,
146
+ chatType: message.chatType === 0 ? 'direct' : 'group',
147
+ chatId: message.chatId.toString(),
189
148
  });
190
-
191
- await connection.connect();
192
- accountConnections.set(accountId, connection);
193
-
194
- } catch (error) {
195
- api.logger.error(`栖岛账户 ${accountId} 连接失败: ${error.message}`);
196
149
  }
197
- }
150
+ });
151
+
152
+ await connection.connect();
153
+
198
154
  } catch (error) {
199
155
  api.logger.error(`栖岛聊天插件初始化失败: ${error.message}`);
200
156
  }