openclaw-rocketchat 0.1.0

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 (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +694 -0
  3. package/README.md +730 -0
  4. package/dist/cli/add-bot.d.ts +2 -0
  5. package/dist/cli/add-bot.d.ts.map +1 -0
  6. package/dist/cli/add-bot.js +138 -0
  7. package/dist/cli/add-bot.js.map +1 -0
  8. package/dist/cli/add-group.d.ts +2 -0
  9. package/dist/cli/add-group.d.ts.map +1 -0
  10. package/dist/cli/add-group.js +145 -0
  11. package/dist/cli/add-group.js.map +1 -0
  12. package/dist/cli/add-user.d.ts +2 -0
  13. package/dist/cli/add-user.d.ts.map +1 -0
  14. package/dist/cli/add-user.js +186 -0
  15. package/dist/cli/add-user.js.map +1 -0
  16. package/dist/cli/invite.d.ts +2 -0
  17. package/dist/cli/invite.d.ts.map +1 -0
  18. package/dist/cli/invite.js +194 -0
  19. package/dist/cli/invite.js.map +1 -0
  20. package/dist/cli/prompts.d.ts +24 -0
  21. package/dist/cli/prompts.d.ts.map +1 -0
  22. package/dist/cli/prompts.js +134 -0
  23. package/dist/cli/prompts.js.map +1 -0
  24. package/dist/cli/remove-user.d.ts +2 -0
  25. package/dist/cli/remove-user.d.ts.map +1 -0
  26. package/dist/cli/remove-user.js +108 -0
  27. package/dist/cli/remove-user.js.map +1 -0
  28. package/dist/cli/setup.d.ts +2 -0
  29. package/dist/cli/setup.d.ts.map +1 -0
  30. package/dist/cli/setup.js +446 -0
  31. package/dist/cli/setup.js.map +1 -0
  32. package/dist/cli/status.d.ts +2 -0
  33. package/dist/cli/status.d.ts.map +1 -0
  34. package/dist/cli/status.js +161 -0
  35. package/dist/cli/status.js.map +1 -0
  36. package/dist/cli/uninstall.d.ts +2 -0
  37. package/dist/cli/uninstall.d.ts.map +1 -0
  38. package/dist/cli/uninstall.js +81 -0
  39. package/dist/cli/uninstall.js.map +1 -0
  40. package/dist/config/credentials.d.ts +26 -0
  41. package/dist/config/credentials.d.ts.map +1 -0
  42. package/dist/config/credentials.js +169 -0
  43. package/dist/config/credentials.js.map +1 -0
  44. package/dist/config/writer.d.ts +52 -0
  45. package/dist/config/writer.d.ts.map +1 -0
  46. package/dist/config/writer.js +170 -0
  47. package/dist/config/writer.js.map +1 -0
  48. package/dist/docker/compose.d.ts +10 -0
  49. package/dist/docker/compose.d.ts.map +1 -0
  50. package/dist/docker/compose.js +56 -0
  51. package/dist/docker/compose.js.map +1 -0
  52. package/dist/docker/manager.d.ts +38 -0
  53. package/dist/docker/manager.d.ts.map +1 -0
  54. package/dist/docker/manager.js +219 -0
  55. package/dist/docker/manager.js.map +1 -0
  56. package/dist/index.d.ts +5 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +203 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/rc-api/rest-client.d.ts +64 -0
  61. package/dist/rc-api/rest-client.d.ts.map +1 -0
  62. package/dist/rc-api/rest-client.js +268 -0
  63. package/dist/rc-api/rest-client.js.map +1 -0
  64. package/dist/rc-api/types.d.ts +158 -0
  65. package/dist/rc-api/types.d.ts.map +1 -0
  66. package/dist/rc-api/types.js +5 -0
  67. package/dist/rc-api/types.js.map +1 -0
  68. package/dist/rc-api/ws-client.d.ts +47 -0
  69. package/dist/rc-api/ws-client.d.ts.map +1 -0
  70. package/dist/rc-api/ws-client.js +308 -0
  71. package/dist/rc-api/ws-client.js.map +1 -0
  72. package/dist/service/bot-manager.d.ts +34 -0
  73. package/dist/service/bot-manager.d.ts.map +1 -0
  74. package/dist/service/bot-manager.js +156 -0
  75. package/dist/service/bot-manager.js.map +1 -0
  76. package/dist/service/channel.d.ts +35 -0
  77. package/dist/service/channel.d.ts.map +1 -0
  78. package/dist/service/channel.js +157 -0
  79. package/dist/service/channel.js.map +1 -0
  80. package/dist/service/message-handler.d.ts +45 -0
  81. package/dist/service/message-handler.d.ts.map +1 -0
  82. package/dist/service/message-handler.js +207 -0
  83. package/dist/service/message-handler.js.map +1 -0
  84. package/openclaw.plugin.json +45 -0
  85. package/package.json +61 -0
@@ -0,0 +1,157 @@
1
+ // ============================================================
2
+ // 频道后台服务主逻辑
3
+ // Gateway 启动时自动运行:连接 RC、管理机器人、桥接消息
4
+ // ============================================================
5
+ import { RocketChatRestClient } from "../rc-api/rest-client.js";
6
+ import { BotManager } from "./bot-manager.js";
7
+ import { MessageHandler } from "./message-handler.js";
8
+ import { loadAdminCredentials, loadBotCredentials, } from "../config/credentials.js";
9
+ export class ChannelService {
10
+ config;
11
+ bindings;
12
+ botManager = null;
13
+ messageHandler = null;
14
+ adminClient = null;
15
+ logger;
16
+ running = false;
17
+ constructor(options) {
18
+ this.config = options.config;
19
+ this.bindings = options.bindings || [];
20
+ this.logger = options.logger || {
21
+ info: (msg) => console.log(`[RC ChannelService] ${msg}`),
22
+ error: (msg) => console.error(`[RC ChannelService] ${msg}`),
23
+ };
24
+ }
25
+ // ----------------------------------------------------------
26
+ // 生命周期
27
+ // ----------------------------------------------------------
28
+ /** 启动服务 */
29
+ async start() {
30
+ if (this.running)
31
+ return;
32
+ if (!this.config.enabled) {
33
+ this.logger.info("Rocket.Chat 插件未启用,跳过启动");
34
+ return;
35
+ }
36
+ if (!this.config.serverUrl) {
37
+ this.logger.error("未配置 serverUrl,无法启动");
38
+ return;
39
+ }
40
+ this.logger.info(`正在连接 Rocket.Chat: ${this.config.serverUrl}`);
41
+ // 1. 验证管理员连接
42
+ const adminCreds = await loadAdminCredentials();
43
+ if (!adminCreds) {
44
+ this.logger.error("未找到管理员凭据,请先运行 setup");
45
+ return;
46
+ }
47
+ this.adminClient = new RocketChatRestClient(this.config.serverUrl);
48
+ this.adminClient.setAuth(adminCreds.userId, adminCreds.authToken);
49
+ try {
50
+ await this.adminClient.serverInfo();
51
+ this.logger.info("Rocket.Chat 服务器连接成功");
52
+ }
53
+ catch (err) {
54
+ this.logger.error(`无法连接 Rocket.Chat: ${err.message}`);
55
+ return;
56
+ }
57
+ // 2. 初始化 BotManager
58
+ this.botManager = new BotManager(this.config.serverUrl, this.logger);
59
+ // 3. 初始化 MessageHandler
60
+ this.messageHandler = new MessageHandler({
61
+ botManager: this.botManager,
62
+ config: this.config,
63
+ logger: this.logger,
64
+ });
65
+ // 4. 设置消息回调
66
+ this.botManager.onMessage((msg, roomId, botUsername, agentId) => {
67
+ this.messageHandler.handleInbound(msg, roomId, botUsername, agentId);
68
+ });
69
+ // 5. 连接所有机器人
70
+ await this.connectBots();
71
+ // 6. 确保所有群组存在并订阅
72
+ await this.ensureGroups();
73
+ this.running = true;
74
+ this.logger.info("Rocket.Chat 频道服务已启动");
75
+ }
76
+ /** 停止服务 */
77
+ stop() {
78
+ if (!this.running)
79
+ return;
80
+ this.botManager?.disconnectAll();
81
+ this.running = false;
82
+ this.logger.info("Rocket.Chat 频道服务已停止");
83
+ }
84
+ /** 获取 MessageHandler(用于出站消息) */
85
+ getMessageHandler() {
86
+ return this.messageHandler;
87
+ }
88
+ /** 获取 BotManager */
89
+ getBotManager() {
90
+ return this.botManager;
91
+ }
92
+ // ----------------------------------------------------------
93
+ // 内部:连接机器人
94
+ // ----------------------------------------------------------
95
+ async connectBots() {
96
+ const accounts = this.config.accounts || {};
97
+ const botCreds = await loadBotCredentials();
98
+ for (const [accountId, account] of Object.entries(accounts)) {
99
+ const creds = botCreds[account.botUsername];
100
+ if (!creds) {
101
+ this.logger.error(`机器人 ${account.botUsername} 无凭据,跳过`);
102
+ continue;
103
+ }
104
+ try {
105
+ // 从 bindings 中查找该 account 绑定的 agentId
106
+ const binding = this.bindings.find((b) => b.match?.channel === "rocketchat" && b.match?.accountId === accountId);
107
+ const agentId = binding?.agentId || accountId;
108
+ await this.botManager.addBot(account.botUsername, creds.password, creds.userId, agentId, account.botDisplayName);
109
+ // 订阅该机器人所有相关的 DM
110
+ await this.subscribeBotDMs(account.botUsername);
111
+ }
112
+ catch (err) {
113
+ this.logger.error(`机器人 ${account.botUsername} 启动失败: ${err.message}`);
114
+ }
115
+ }
116
+ }
117
+ /** 订阅机器人的所有 DM */
118
+ async subscribeBotDMs(botUsername) {
119
+ const restClient = this.botManager.getRestClient(botUsername);
120
+ if (!restClient)
121
+ return;
122
+ try {
123
+ const dms = await restClient.listDirectMessages();
124
+ for (const dm of dms) {
125
+ await this.botManager.subscribeRoom(botUsername, dm._id);
126
+ }
127
+ }
128
+ catch (err) {
129
+ this.logger.error(`${botUsername}: 获取 DM 列表失败: ${err.message}`);
130
+ }
131
+ }
132
+ // ----------------------------------------------------------
133
+ // 内部:确保群组存在
134
+ // ----------------------------------------------------------
135
+ async ensureGroups() {
136
+ const groups = this.config.groups || {};
137
+ for (const [groupName, groupConfig] of Object.entries(groups)) {
138
+ try {
139
+ // 检查群组是否存在
140
+ const groupInfo = await this.adminClient.getGroupInfo(undefined, groupName);
141
+ if (groupInfo) {
142
+ // 群组存在,为其中的每个机器人订阅消息
143
+ for (const botUsername of groupConfig.bots || []) {
144
+ await this.botManager.subscribeRoom(botUsername, groupInfo._id);
145
+ }
146
+ }
147
+ else {
148
+ this.logger.error(`群组「${groupName}」不存在!请运行: openclaw rocketchat add-group`);
149
+ }
150
+ }
151
+ catch (err) {
152
+ this.logger.error(`检查群组「${groupName}」失败: ${err.message}`);
153
+ }
154
+ }
155
+ }
156
+ }
157
+ //# sourceMappingURL=channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/service/channel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { RcMessage, RocketchatChannelConfig } from "../rc-api/types.js";
2
+ import type { BotManager } from "./bot-manager.js";
3
+ interface MessageHandlerOptions {
4
+ botManager: BotManager;
5
+ config: Partial<RocketchatChannelConfig>;
6
+ logger?: {
7
+ info: (msg: string) => void;
8
+ error: (msg: string) => void;
9
+ };
10
+ }
11
+ export declare class MessageHandler {
12
+ private botManager;
13
+ private config;
14
+ private logger;
15
+ /** 正在处理中的消息 ID 集合(防止并发重复处理) */
16
+ private processingMessages;
17
+ constructor(options: MessageHandlerOptions);
18
+ /**
19
+ * 处理入站消息
20
+ * 由 BotManager 的 onMessage 回调调用
21
+ */
22
+ handleInbound(msg: RcMessage, roomId: string, botUsername: string, agentId: string): Promise<void>;
23
+ /**
24
+ * 发送 Agent 回复到 Rocket.Chat
25
+ * 由频道插件的 outbound.sendText 调用
26
+ */
27
+ handleOutbound(text: string, botUsername: string, roomId: string): Promise<void>;
28
+ /**
29
+ * 判断机器人是否应该响应该消息
30
+ * - DM 消息:始终响应
31
+ * - 群组消息:根据 requireMention 规则判断
32
+ */
33
+ private shouldRespond;
34
+ /**
35
+ * 通过 openclaw CLI 将消息发送给 Agent
36
+ */
37
+ private sendToOpenClaw;
38
+ /**
39
+ * 将长文本分块
40
+ * 尽量按段落或代码块边界分割
41
+ */
42
+ private splitText;
43
+ }
44
+ export {};
45
+ //# sourceMappingURL=message-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-handler.d.ts","sourceRoot":"","sources":["../../src/service/message-handler.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAOnD,UAAU,qBAAqB;IAC7B,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CACxE;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,MAAM,CAAgE;IAC9E,+BAA+B;IAC/B,OAAO,CAAC,kBAAkB,CAAqB;gBAEnC,OAAO,EAAE,qBAAqB;IAa1C;;;OAGG;IACG,aAAa,CACjB,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC;IA2EhB;;;OAGG;IACG,cAAc,CAClB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IAuBhB;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAsBrB;;OAEG;YACW,cAAc;IA4C5B;;;OAGG;IACH,OAAO,CAAC,SAAS;CAyClB"}
@@ -0,0 +1,207 @@
1
+ // ============================================================
2
+ // 消息桥接:RC 消息 <-> OpenClaw Agent
3
+ // 入站:接收 RC 消息 → 路由到 Agent
4
+ // 出站:Agent 回复 → 格式化 → 发回 RC
5
+ // ============================================================
6
+ import { execFile } from "node:child_process";
7
+ import { promisify } from "node:util";
8
+ const execFileAsync = promisify(execFile);
9
+ /** 长文本分块大小(Rocket.Chat 单条消息建议不超过 4000 字符) */
10
+ const MAX_MESSAGE_LENGTH = 4000;
11
+ export class MessageHandler {
12
+ botManager;
13
+ config;
14
+ logger;
15
+ /** 正在处理中的消息 ID 集合(防止并发重复处理) */
16
+ processingMessages = new Set();
17
+ constructor(options) {
18
+ this.botManager = options.botManager;
19
+ this.config = options.config;
20
+ this.logger = options.logger || {
21
+ info: (msg) => console.log(`[RC MessageHandler] ${msg}`),
22
+ error: (msg) => console.error(`[RC MessageHandler] ${msg}`),
23
+ };
24
+ }
25
+ // ----------------------------------------------------------
26
+ // 入站:RC 消息 → OpenClaw Agent
27
+ // ----------------------------------------------------------
28
+ /**
29
+ * 处理入站消息
30
+ * 由 BotManager 的 onMessage 回调调用
31
+ */
32
+ async handleInbound(msg, roomId, botUsername, agentId) {
33
+ // 消息去重:防止同一条消息被多个 bot 或重连后重复处理
34
+ const msgKey = `${roomId}:${msg._id}`;
35
+ if (this.processingMessages.has(msgKey))
36
+ return;
37
+ this.processingMessages.add(msgKey);
38
+ // 处理完成后清理(30 秒超时兜底)
39
+ const cleanup = () => this.processingMessages.delete(msgKey);
40
+ setTimeout(cleanup, 30000);
41
+ // 检查 @提及 规则(群组消息)
42
+ if (!this.shouldRespond(msg, botUsername, roomId)) {
43
+ cleanup();
44
+ return;
45
+ }
46
+ // 提取消息文本
47
+ let text = msg.msg || "";
48
+ // 处理附件(图片、文件、语音)
49
+ if (msg.attachments?.length) {
50
+ for (const att of msg.attachments) {
51
+ if (att.image_url) {
52
+ text += `\n[图片: ${att.image_url}]`;
53
+ }
54
+ else if (att.audio_url) {
55
+ text += `\n[语音: ${att.audio_url}]`;
56
+ }
57
+ else if (att.title_link) {
58
+ text += `\n[文件: ${att.title_link}]`;
59
+ }
60
+ }
61
+ }
62
+ if (!text.trim()) {
63
+ return;
64
+ }
65
+ // 通过 openclaw message send CLI 发送给 Agent
66
+ this.logger.info(`入站: ${msg.u.username} -> ${botUsername} (Agent: ${agentId}): ${text.slice(0, 100)}...`);
67
+ try {
68
+ await this.sendToOpenClaw(text, botUsername, msg.u.username, roomId);
69
+ }
70
+ catch (err) {
71
+ const errMsg = err.message || "";
72
+ this.logger.error(`发送到 OpenClaw 失败: ${errMsg}`);
73
+ // 如果 Agent 不存在或绑定丢失,回复用户一条友好提示
74
+ if (errMsg.includes("agent") ||
75
+ errMsg.includes("not found") ||
76
+ errMsg.includes("binding") ||
77
+ errMsg.includes("No matching")) {
78
+ try {
79
+ await this.handleOutbound("⚠️ 抱歉,我绑定的 AI Agent 当前不可用。请联系管理员检查 Agent 配置。", botUsername, roomId);
80
+ }
81
+ catch {
82
+ // 回复也失败,只能记日志
83
+ }
84
+ }
85
+ }
86
+ }
87
+ // ----------------------------------------------------------
88
+ // 出站:OpenClaw Agent → RC
89
+ // ----------------------------------------------------------
90
+ /**
91
+ * 发送 Agent 回复到 Rocket.Chat
92
+ * 由频道插件的 outbound.sendText 调用
93
+ */
94
+ async handleOutbound(text, botUsername, roomId) {
95
+ this.logger.info(`出站: ${botUsername} -> ${roomId}: ${text.slice(0, 100)}...`);
96
+ // 长文本分块发送
97
+ const chunks = this.splitText(text, MAX_MESSAGE_LENGTH);
98
+ for (const chunk of chunks) {
99
+ try {
100
+ await this.botManager.sendMessage(botUsername, roomId, chunk);
101
+ }
102
+ catch (err) {
103
+ this.logger.error(`发送消息失败: ${err.message}`);
104
+ }
105
+ }
106
+ }
107
+ // ----------------------------------------------------------
108
+ // 内部:消息路由
109
+ // ----------------------------------------------------------
110
+ /**
111
+ * 判断机器人是否应该响应该消息
112
+ * - DM 消息:始终响应
113
+ * - 群组消息:根据 requireMention 规则判断
114
+ */
115
+ shouldRespond(msg, botUsername, roomId) {
116
+ // 检查是否在群组中且需要 @提及
117
+ const groups = this.config.groups || {};
118
+ for (const [, groupConfig] of Object.entries(groups)) {
119
+ if (groupConfig.bots?.includes(botUsername) && groupConfig.requireMention) {
120
+ // 需要 @提及 才响应
121
+ const isMentioned = msg.mentions?.some((m) => m.username === botUsername);
122
+ if (!isMentioned) {
123
+ return false;
124
+ }
125
+ }
126
+ }
127
+ return true;
128
+ }
129
+ /**
130
+ * 通过 openclaw CLI 将消息发送给 Agent
131
+ */
132
+ async sendToOpenClaw(text, accountId, senderId, roomId) {
133
+ // 基本校验:确保标识符不为空、不包含控制字符
134
+ if (!accountId || !senderId || !roomId) {
135
+ this.logger.error("sendToOpenClaw: 缺少必要的标识符参数");
136
+ return;
137
+ }
138
+ try {
139
+ // execFileAsync 不走 shell,参数不会被 shell 解析,注入风险极低
140
+ await execFileAsync("openclaw", [
141
+ "message",
142
+ "send",
143
+ "--channel",
144
+ "rocketchat",
145
+ "--account",
146
+ accountId,
147
+ "--target",
148
+ roomId,
149
+ "--sender",
150
+ senderId,
151
+ "-m",
152
+ text,
153
+ ], { timeout: 30000 });
154
+ }
155
+ catch (err) {
156
+ // 如果 openclaw CLI 不可用,记录错误但不抛出
157
+ this.logger.error(`openclaw message send 失败: ${err.message}`);
158
+ }
159
+ }
160
+ // ----------------------------------------------------------
161
+ // 工具
162
+ // ----------------------------------------------------------
163
+ /**
164
+ * 将长文本分块
165
+ * 尽量按段落或代码块边界分割
166
+ */
167
+ splitText(text, maxLength) {
168
+ if (text.length <= maxLength) {
169
+ return [text];
170
+ }
171
+ const chunks = [];
172
+ let remaining = text;
173
+ while (remaining.length > 0) {
174
+ if (remaining.length <= maxLength) {
175
+ chunks.push(remaining);
176
+ break;
177
+ }
178
+ // 优先在代码块边界分割
179
+ let splitIndex = remaining.lastIndexOf("\n```\n", maxLength);
180
+ if (splitIndex > maxLength * 0.5) {
181
+ splitIndex += 5; // 包含 \n```\n
182
+ }
183
+ else {
184
+ // 在段落边界分割
185
+ splitIndex = remaining.lastIndexOf("\n\n", maxLength);
186
+ if (splitIndex > maxLength * 0.5) {
187
+ splitIndex += 2;
188
+ }
189
+ else {
190
+ // 在换行处分割
191
+ splitIndex = remaining.lastIndexOf("\n", maxLength);
192
+ if (splitIndex > maxLength * 0.5) {
193
+ splitIndex += 1;
194
+ }
195
+ else {
196
+ // 强制分割
197
+ splitIndex = maxLength;
198
+ }
199
+ }
200
+ }
201
+ chunks.push(remaining.slice(0, splitIndex));
202
+ remaining = remaining.slice(splitIndex);
203
+ }
204
+ return chunks;
205
+ }
206
+ }
207
+ //# sourceMappingURL=message-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-handler.js","sourceRoot":"","sources":["../../src/service/message-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ {
2
+ "id": "rocketchat",
3
+ "name": "Rocket.Chat",
4
+ "description": "Rocket.Chat channel plugin for OpenClaw — connect via mobile app, ideal for China mainland users",
5
+ "version": "0.1.0",
6
+ "channels": ["rocketchat"],
7
+ "configSchema": {
8
+ "type": "object",
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "enabled": { "type": "boolean", "default": false },
12
+ "serverUrl": {
13
+ "type": "string",
14
+ "description": "Rocket.Chat server URL, e.g. http://192.168.1.100:3000"
15
+ },
16
+ "port": { "type": "number", "default": 3000 },
17
+ "dmPolicy": {
18
+ "type": "string",
19
+ "enum": ["pairing", "allowlist", "open"],
20
+ "default": "pairing"
21
+ },
22
+ "accounts": {
23
+ "type": "object",
24
+ "additionalProperties": {
25
+ "type": "object",
26
+ "properties": {
27
+ "botUsername": { "type": "string" },
28
+ "botDisplayName": { "type": "string" }
29
+ },
30
+ "required": ["botUsername"]
31
+ }
32
+ },
33
+ "groups": {
34
+ "type": "object",
35
+ "additionalProperties": {
36
+ "type": "object",
37
+ "properties": {
38
+ "requireMention": { "type": "boolean", "default": false },
39
+ "bots": { "type": "array", "items": { "type": "string" } }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "openclaw-rocketchat",
3
+ "version": "0.1.0",
4
+ "description": "Rocket.Chat channel plugin for OpenClaw — connect via mobile app, ideal for China mainland users",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "dev": "tsc --watch",
10
+ "test": "vitest run",
11
+ "lint": "eslint src/",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "openclaw": {
15
+ "extensions": [
16
+ "./src/index.ts"
17
+ ],
18
+ "channel": {
19
+ "id": "rocketchat",
20
+ "label": "Rocket.Chat",
21
+ "selectionLabel": "Rocket.Chat (self-hosted)",
22
+ "docsPath": "/channels/rocketchat",
23
+ "blurb": "Self-hosted team chat via Rocket.Chat, ideal for China mainland users.",
24
+ "order": 70,
25
+ "aliases": [
26
+ "rc",
27
+ "rocket"
28
+ ]
29
+ }
30
+ },
31
+ "files": [
32
+ "dist/",
33
+ "openclaw.plugin.json"
34
+ ],
35
+ "keywords": [
36
+ "openclaw",
37
+ "openclaw-plugin",
38
+ "rocketchat",
39
+ "rocket.chat",
40
+ "china",
41
+ "im",
42
+ "chat"
43
+ ],
44
+ "license": "MIT",
45
+ "engines": {
46
+ "node": ">=22.0.0"
47
+ },
48
+ "dependencies": {
49
+ "json5": "^2.2.3",
50
+ "ws": "^8.18.0"
51
+ },
52
+ "devDependencies": {
53
+ "typescript": "^5.7.0",
54
+ "@types/node": "^22.0.0",
55
+ "@types/ws": "^8.5.0",
56
+ "vitest": "^3.0.0"
57
+ },
58
+ "publishConfig": {
59
+ "access": "public"
60
+ }
61
+ }