@cloudrise/openclaw-channel-rocketchat 0.1.15 → 0.1.16

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 CHANGED
@@ -145,6 +145,10 @@ Then restart the gateway.
145
145
 
146
146
  ## Features
147
147
 
148
+ - **Inbound attachments**: receives images, PDFs/documents, and audio; forwards them to OpenClaw for vision/document understanding and transcription.
149
+ - **Outbound attachments**: can send local file paths as real Rocket.Chat uploads (inline previews when supported).
150
+ - **Reactions**: can react to messages with emoji (via `chat.react`).
151
+
148
152
  - **File attachments**: receives images, PDFs, documents, audio uploaded to Rocket.Chat and passes them to the vision model.
149
153
  - **Model prefix**: honors `messages.responsePrefix` (e.g. `({model}) `) so replies can include the model name.
150
154
 
@@ -335,4 +339,4 @@ This repository is intended to be publishable (no secrets committed).
335
339
 
336
340
  ## License
337
341
 
338
- MIT
342
+ MIT
package/index.ts CHANGED
@@ -11,6 +11,9 @@ import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
11
11
  import { rocketChatPlugin } from "./src/channel.js";
12
12
  import { setRocketChatRuntime } from "./src/runtime.js";
13
13
 
14
+ // Re-export send/react functions for OpenClaw message tool
15
+ export { reactMessageRocketChat, sendMessageRocketChat } from "./src/rocketchat/send.js";
16
+
14
17
  const plugin = {
15
18
  id: "rocketchat",
16
19
  name: "Rocket.Chat",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudrise/openclaw-channel-rocketchat",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Rocket.Chat channel plugin for OpenClaw (Cloudrise)",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/channel.ts CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  } from "./rocketchat/accounts.js";
16
16
  import { normalizeRocketChatBaseUrl } from "./rocketchat/client.js";
17
17
  import { monitorRocketChatProvider } from "./rocketchat/monitor.js";
18
- import { sendMessageRocketChat } from "./rocketchat/send.js";
18
+ import { reactMessageRocketChat, sendMessageRocketChat } from "./rocketchat/send.js";
19
19
  import { getRocketChatRuntime } from "./runtime.js";
20
20
 
21
21
  const meta = {
@@ -333,3 +333,35 @@ export async function uploadRocketChatFile(
333
333
  ts: confirmData.message.ts,
334
334
  };
335
335
  }
336
+
337
+ /**
338
+ * React to a message with an emoji.
339
+ * @param emoji - Emoji name (e.g., "thumbsup", ":rocket:", or unicode "🚀")
340
+ * @param shouldReact - true to add reaction, false to remove (default: true)
341
+ */
342
+ export async function reactRocketChatMessage(
343
+ client: RocketChatClient,
344
+ messageId: string,
345
+ emoji: string,
346
+ shouldReact = true
347
+ ): Promise<void> {
348
+ // Normalize emoji format - RC accepts "thumbsup", ":thumbsup:", or unicode
349
+ const normalizedEmoji = emoji.startsWith(":") ? emoji : `:${emoji.replace(/:/g, "")}:`;
350
+
351
+ const res = await rcFetch<{ success: boolean }>(
352
+ client,
353
+ "/api/v1/chat.react",
354
+ {
355
+ method: "POST",
356
+ body: JSON.stringify({
357
+ messageId,
358
+ emoji: normalizedEmoji,
359
+ shouldReact,
360
+ }),
361
+ }
362
+ );
363
+
364
+ if (!res.success) {
365
+ throw new Error("Rocket.Chat reaction failed");
366
+ }
367
+ }
@@ -13,6 +13,7 @@ import {
13
13
  fetchRocketChatUserByUsername,
14
14
  normalizeRocketChatBaseUrl,
15
15
  postRocketChatMessage,
16
+ reactRocketChatMessage,
16
17
  uploadRocketChatFile,
17
18
  type RocketChatUser,
18
19
  } from "./client.js";
@@ -261,3 +262,58 @@ export async function sendMessageRocketChat(
261
262
  roomId: post.rid ?? roomId,
262
263
  };
263
264
  }
265
+
266
+ export type RocketChatReactOpts = {
267
+ accountId?: string;
268
+ shouldReact?: boolean;
269
+ };
270
+
271
+ /**
272
+ * React to a Rocket.Chat message with an emoji.
273
+ * @param messageId - The message ID to react to
274
+ * @param emoji - Emoji name (e.g., "thumbsup", ":rocket:", "🚀")
275
+ */
276
+ export async function reactMessageRocketChat(
277
+ messageId: string,
278
+ emoji: string,
279
+ opts: RocketChatReactOpts = {}
280
+ ): Promise<void> {
281
+ const core = getRocketChatRuntime();
282
+ const logger = core?.logging?.getChildLogger?.({ module: "rocketchat" });
283
+ const cfg = core?.config?.loadConfig?.() ?? {};
284
+
285
+ const account = resolveRocketChatAccount({ cfg, accountId: opts.accountId });
286
+
287
+ const authToken = account.authToken?.trim();
288
+ if (!authToken) {
289
+ throw new Error(
290
+ `Rocket.Chat authToken missing for account "${account.accountId}"`
291
+ );
292
+ }
293
+
294
+ const userId = account.userId?.trim();
295
+ if (!userId) {
296
+ throw new Error(
297
+ `Rocket.Chat userId missing for account "${account.accountId}"`
298
+ );
299
+ }
300
+
301
+ const baseUrl = normalizeRocketChatBaseUrl(account.baseUrl);
302
+ if (!baseUrl) {
303
+ throw new Error(
304
+ `Rocket.Chat baseUrl missing for account "${account.accountId}"`
305
+ );
306
+ }
307
+
308
+ const client = createRocketChatClient({ baseUrl, userId, authToken });
309
+
310
+ logger?.debug?.(`Reacting to message ${messageId} with ${emoji}`);
311
+
312
+ await reactRocketChatMessage(client, messageId, emoji, opts.shouldReact ?? true);
313
+
314
+ core?.channel?.activity?.record?.({
315
+ channel: "rocketchat",
316
+ accountId: account.accountId,
317
+ direction: "outbound",
318
+ });
319
+ }