Skip to content

feat: Add OpenClaw AI agent integration#39939

Open
CHINMAYK121 wants to merge 4 commits intoRocketChat:developfrom
CHINMAYK121:feat/openclaw-integration
Open

feat: Add OpenClaw AI agent integration#39939
CHINMAYK121 wants to merge 4 commits intoRocketChat:developfrom
CHINMAYK121:feat/openclaw-integration

Conversation

@CHINMAYK121
Copy link
Copy Markdown

@CHINMAYK121 CHINMAYK121 commented Mar 29, 2026

Proposed changes (including videos or screenshots)

Issue(s)

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • New Features

    • Added OpenClaw AI Agent integration for Rocket.Chat
    • New /openclaw slash command to send prompts to an AI agent
    • Webhook endpoint receives AI responses and delivers them back to channels or threads
    • Admin-configurable settings for API URL, authentication, default model, bot username, and thread behavior
  • Documentation

    • Added OpenClaw integration README with setup instructions and architecture overview
    • Added localization support with English translations for configuration and user messaging

Adds a new OpenClaw integration module that allows Rocket.Chat users
to interact with OpenClaw autonomous AI agents directly from chat channels.

Features:
- /openclaw slash command to send prompts to the AI agent
- Incoming webhook endpoint (/api/v1/openclaw.webhook) for receiving AI responses
- Admin settings for API URL, auth token, default LLM model, bot username
- Bot message loop prevention and error handling
- Thread response support
- Full i18n support (20 translation keys)

New files:
- apps/meteor/app/openclaw/server/ (module with 7 source files)
- apps/meteor/app/openclaw/README.md (documentation)
- .changeset/openclaw-integration.md

Modified files:
- apps/meteor/server/importPackages.ts (register module)
- packages/i18n/src/locales/en.i18n.json (translations)
- Remove unused IMessage import from webhook.ts
- Use crypto.timingSafeEqual for webhook token comparison (timing attack prevention)
- Fix botUser type assertion in webhook.ts using explicit field spread
- validateConfig() now returns stable error codes (NOT_ENABLED, MISSING_API_URL,
  MISSING_AUTH_TOKEN) instead of hardcoded English strings
- Translate validateConfig() error codes via i18n at call boundary in slashCommand.ts
- Sanitize openclawLogger.debug payload - no longer logs raw prompt/PII data
- Treat malformed JSON as hard failure in sendToAgent() before response.ok check
- Change warn -> debug on rocket.cat fallback log in getOpenClawBotUser()
- Add fallback field to rocket.cat fallback debug log for observability
- Remove unused botUsername variable from slashCommand.ts
- Add OpenClaw_Error_Not_Enabled, OpenClaw_Error_Missing_API_URL,
  OpenClaw_Error_Missing_Auth_Token i18n keys to en.i18n.json
- Add language specifiers to README.md fenced code blocks (fixes MD040)
- Remove JSDoc blocks and inline comments per project coding guidelines
@CHINMAYK121 CHINMAYK121 requested review from a team as code owners March 29, 2026 07:15
@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot bot commented Mar 29, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 29, 2026

🦋 Changeset detected

Latest commit: 64d6782

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 41 packages
Name Type
@rocket.chat/meteor Minor
@rocket.chat/core-typings Minor
@rocket.chat/rest-typings Minor
@rocket.chat/uikit-playground Patch
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/ddp-client Patch
@rocket.chat/fuselage-ui-kit Major
@rocket.chat/gazzodown Major
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-avatar Major
@rocket.chat/ui-client Major
@rocket.chat/ui-contexts Major
@rocket.chat/ui-voip Major
@rocket.chat/web-ui-registration Major
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/abac Patch
@rocket.chat/federation-matrix Patch
@rocket.chat/license Patch
@rocket.chat/media-calls Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/pdf-worker Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/models Patch
@rocket.chat/network-broker Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/mock-providers Patch
@rocket.chat/ui-video-conf Major
@rocket.chat/instance-status Patch
@rocket.chat/omni-core Patch
@rocket.chat/server-fetch Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 29, 2026

Walkthrough

A complete OpenClaw AI agent integration is added to Rocket.Chat, including a /openclaw slash command for sending prompts to an OpenClaw instance, a webhook endpoint for receiving AI responses, admin-configurable settings (API URL, auth token, default model, bot username, thread behavior), message filtering and forwarding logic, and full localization support.

Changes

Cohort / File(s) Summary
Documentation
.changeset/openclaw-integration.md, apps/meteor/app/openclaw/README.md
Changeset marking minor version bump and detailed README describing OpenClaw integration architecture, setup, usage examples, webhook payload structure, and prerequisites.
Settings & Logging
apps/meteor/app/openclaw/server/settings.ts, apps/meteor/app/openclaw/server/logger.ts
Settings group registration with General and Agent sections (enable toggle, API URL, auth token, default model, bot username, thread behavior); initialized logger instance labeled "OpenClaw".
API Webhook Handler
apps/meteor/app/openclaw/server/api/webhook.ts
Unauthenticated POST endpoint accepting OpenClaw responses; validates token via timing-safe comparison, required fields (channel_id, text), resolves target room and bot user, delegates to message processor.
Slash Command
apps/meteor/app/openclaw/server/slashCommand.ts
/openclaw command handler validating config, resolving user language, forwarding prompts to agent, handling threaded/non-threaded responses via bot user or ephemeral messages, with i18n-backed descriptions and error notifications.
Client & Message Utilities
apps/meteor/app/openclaw/server/lib/openclawClient.ts, apps/meteor/app/openclaw/server/lib/messageHandler.ts
OpenClaw API client with payload interfaces, config validation, authenticated POST to /hooks/agent and /hooks/wake endpoints with 30s/10s timeouts and error handling; message filters for bot/system messages, payload formatters, forwarding with callback URL and thread routing.
Server Integration
apps/meteor/app/openclaw/server/index.ts, apps/meteor/server/importPackages.ts
Server entry module importing settings, slash command, and webhook; main server bootstrap file adding OpenClaw module import.
Localization
packages/i18n/src/locales/en.i18n.json
24 new English i18n keys for UI labels, settings descriptions, slash command usage, and error/status messages.
Test Configuration
apps/meteor/tests/e2e/containers/saml/config/simplesamlphp/config.php
Updated SimpleSAML logger constant from legacy SimpleSAML_Logger::DEBUG to namespaced SimpleSAML\Logger::DEBUG.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SlashCmd as Slash Command Handler
    participant MsgHandler as Message Handler
    participant OpenClawAPI as OpenClaw API
    participant Room as Rocket.Chat Room

    User->>SlashCmd: /openclaw [prompt]
    SlashCmd->>SlashCmd: Validate config
    SlashCmd->>SlashCmd: Get user & room
    SlashCmd->>MsgHandler: forwardMessageToAgent()
    MsgHandler->>OpenClawAPI: sendToAgent(payload)
    OpenClawAPI-->>MsgHandler: response
    MsgHandler-->>SlashCmd: agent response
    SlashCmd->>SlashCmd: Resolve bot user
    SlashCmd->>Room: sendMessage(response, optionally threaded)
    Room-->>User: Response posted to room
Loading
sequenceDiagram
    participant OpenClaw as OpenClaw Instance
    participant Webhook as Webhook Handler
    participant MsgProcessor as Message Processor
    participant BotUser as OpenClaw Bot
    participant Room as Rocket.Chat Room

    OpenClaw->>Webhook: POST /api/v1/openclaw.webhook
    Webhook->>Webhook: Verify token (timingSafeEqual)
    Webhook->>Webhook: Validate required fields
    Webhook->>Webhook: Resolve room & bot user
    Webhook->>MsgProcessor: processWebhookMessage()
    MsgProcessor->>BotUser: Load bot user
    MsgProcessor->>Room: Post message (with optional thread)
    Room-->>Webhook: Success response
    Webhook-->>OpenClaw: { message: 'Message delivered' }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Suggested labels

type: feature

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding an OpenClaw AI agent integration to Rocket.Chat with all key components.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 12 files

@CHINMAYK121 CHINMAYK121 changed the title Feat/openclaw integration feat: add OpenClaw integration Mar 29, 2026
@CHINMAYK121 CHINMAYK121 changed the title feat: add OpenClaw integration feat: Add OpenClaw AI agent integration Mar 29, 2026
@coderabbitai coderabbitai bot added the type: feature Pull requests that introduces new feature label Mar 29, 2026
@CHINMAYK121
Copy link
Copy Markdown
Author

I have signed the CLA

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/meteor/app/openclaw/server/lib/messageHandler.ts (1)

82-97: Consider handling case where rocket.cat fallback also doesn't exist.

The fallback to rocket.cat could return undefined if that user doesn't exist in the system (unlikely but possible in edge cases). Callers should be prepared for a null return, which they already handle, but it's worth verifying this is intentional.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/openclaw/server/lib/messageHandler.ts` around lines 82 - 97,
getOpenClawBotUser currently falls back to Users.findOneByUsername('rocket.cat')
without handling the case that rocket.cat may also be missing; update
getOpenClawBotUser to capture the result of
Users.findOneByUsername('rocket.cat'), log a warning via openclawLogger
(including botUsername and that both bot and fallback are missing) if it returns
null/undefined, and then explicitly return null (or undefined consistent with
callers) so callers see the explicit fallback-failure; reference the function
getOpenClawBotUser, the Users.findOneByUsername call, and openclawLogger when
making this change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/meteor/tests/e2e/containers/saml/config/simplesamlphp/config.php`:
- Line 19: The change uses the namespaced class SimpleSAML\Logger::DEBUG which
does not exist in the pinned SimpleSAMLphp 1.15.4; either upgrade SimpleSAMLphp
to >=1.19.0 to use namespaced classes or revert the logging constant to the
PEAR-style SimpleSAML_Logger::DEBUG in the config entry for 'logging.level' so
the runtime will work with the current 1.15.4 image.

In `@packages/i18n/src/locales/en.i18n.json`:
- Line 4025: Replace the internal placeholder value for the i18n key
"OpenClaw_Slash_Params" with a user-facing, human-readable slash parameter label
(e.g., "Prompt" or "Claw prompt") so it matches the style of other slash param
labels; update the JSON value for "OpenClaw_Slash_Params" accordingly.

---

Nitpick comments:
In `@apps/meteor/app/openclaw/server/lib/messageHandler.ts`:
- Around line 82-97: getOpenClawBotUser currently falls back to
Users.findOneByUsername('rocket.cat') without handling the case that rocket.cat
may also be missing; update getOpenClawBotUser to capture the result of
Users.findOneByUsername('rocket.cat'), log a warning via openclawLogger
(including botUsername and that both bot and fallback are missing) if it returns
null/undefined, and then explicitly return null (or undefined consistent with
callers) so callers see the explicit fallback-failure; reference the function
getOpenClawBotUser, the Users.findOneByUsername call, and openclawLogger when
making this change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 351ee13d-5d18-450d-ac09-651f9e7ed387

📥 Commits

Reviewing files that changed from the base of the PR and between 4235cd9 and 64d6782.

📒 Files selected for processing (12)
  • .changeset/openclaw-integration.md
  • apps/meteor/app/openclaw/README.md
  • apps/meteor/app/openclaw/server/api/webhook.ts
  • apps/meteor/app/openclaw/server/index.ts
  • apps/meteor/app/openclaw/server/lib/messageHandler.ts
  • apps/meteor/app/openclaw/server/lib/openclawClient.ts
  • apps/meteor/app/openclaw/server/logger.ts
  • apps/meteor/app/openclaw/server/settings.ts
  • apps/meteor/app/openclaw/server/slashCommand.ts
  • apps/meteor/server/importPackages.ts
  • apps/meteor/tests/e2e/containers/saml/config/simplesamlphp/config.php
  • packages/i18n/src/locales/en.i18n.json
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/server/importPackages.ts
  • apps/meteor/app/openclaw/server/logger.ts
  • apps/meteor/app/openclaw/server/index.ts
  • apps/meteor/app/openclaw/server/settings.ts
  • apps/meteor/app/openclaw/server/api/webhook.ts
  • apps/meteor/app/openclaw/server/slashCommand.ts
  • apps/meteor/app/openclaw/server/lib/messageHandler.ts
  • apps/meteor/app/openclaw/server/lib/openclawClient.ts
🧠 Learnings (19)
📓 Common learnings
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:18.785Z
Learning: In Rocket.Chat PR reviews, maintain strict scope boundaries—when a PR is focused on a specific endpoint (e.g., rooms.favorite), avoid reviewing or suggesting changes to other endpoints that were incidentally refactored (e.g., rooms.invite) unless explicitly requested by maintainers.
Learnt from: smirk-dev
Repo: RocketChat/Rocket.Chat PR: 39625
File: apps/meteor/app/api/server/v1/push.ts:85-97
Timestamp: 2026-03-14T14:58:58.834Z
Learning: In RocketChat/Rocket.Chat, the `push.token` POST/DELETE endpoints in `apps/meteor/app/api/server/v1/push.ts` were already migrated to the chained router API pattern on `develop` prior to PR `#39625`. `cleanTokenResult` (which strips `authToken` and returns `PushTokenResult`) and `isPushTokenPOSTProps`/`isPushTokenDELETEProps` validators already exist on `develop`. PR `#39625` only migrates `push.get` and `push.info` to the chained pattern. Do not flag `cleanTokenResult` or `PushTokenResult` as newly introduced behavior-breaking changes when reviewing this PR.
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 0
File: :0-0
Timestamp: 2026-02-24T19:05:56.710Z
Learning: In Rocket.Chat PRs, keep feature PRs free of unrelated lockfile-only dependency bumps; prefer reverting lockfile drift or isolating such bumps into a separate "chore" commit/PR, and always use yarn install --immutable with the Yarn version pinned in package.json via Corepack.
📚 Learning: 2026-02-25T20:10:16.987Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38913
File: packages/ddp-client/src/legacy/types/SDKLegacy.ts:34-34
Timestamp: 2026-02-25T20:10:16.987Z
Learning: In the RocketChat/Rocket.Chat monorepo, packages/ddp-client and apps/meteor do not use TypeScript project references. Module augmentations in apps/meteor (e.g., declare module 'rocket.chat/rest-typings') are not visible when compiling packages/ddp-client in isolation, which is why legacy SDK methods that depend on OperationResult types for OpenAPI-migrated endpoints must remain commented out.

Applied to files:

  • apps/meteor/server/importPackages.ts
  • apps/meteor/app/openclaw/server/index.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • apps/meteor/server/importPackages.ts
  • apps/meteor/app/openclaw/server/logger.ts
  • apps/meteor/app/openclaw/server/index.ts
  • apps/meteor/app/openclaw/server/settings.ts
  • apps/meteor/app/openclaw/server/api/webhook.ts
  • apps/meteor/app/openclaw/server/slashCommand.ts
  • apps/meteor/app/openclaw/server/lib/messageHandler.ts
  • apps/meteor/app/openclaw/server/lib/openclawClient.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • apps/meteor/server/importPackages.ts
  • apps/meteor/app/openclaw/server/logger.ts
  • apps/meteor/app/openclaw/server/index.ts
  • apps/meteor/app/openclaw/server/settings.ts
  • apps/meteor/app/openclaw/server/api/webhook.ts
  • apps/meteor/app/openclaw/server/slashCommand.ts
  • apps/meteor/app/openclaw/server/lib/messageHandler.ts
  • apps/meteor/app/openclaw/server/lib/openclawClient.ts
📚 Learning: 2026-02-20T09:04:55.725Z
Learnt from: Shreyas2004wagh
Repo: RocketChat/Rocket.Chat PR: 38681
File: apps/meteor/server/modules/streamer/streamer.module.ts:307-313
Timestamp: 2026-02-20T09:04:55.725Z
Learning: In apps/meteor/server/modules/streamer/streamer.module.ts, the catch block in sendToManySubscriptions intentionally uses SystemLogger.debug (not error or warn) for per-subscription delivery failures to keep logs less noisy, as this was a deliberate design choice reviewed and approved by KevLehman.

Applied to files:

  • apps/meteor/app/openclaw/server/logger.ts
📚 Learning: 2026-02-24T19:09:09.561Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:09.561Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs for apps/meteor/app/api/server/v1 endpoints, maintainers prefer to avoid any logic changes; style-only cleanups (like removing inline comments) may be deferred to follow-ups to keep scope tight.

Applied to files:

  • .changeset/openclaw-integration.md
  • apps/meteor/app/openclaw/README.md
  • apps/meteor/app/openclaw/server/api/webhook.ts
📚 Learning: 2026-03-16T21:50:37.589Z
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39676
File: .changeset/migrate-users-register-openapi.md:3-3
Timestamp: 2026-03-16T21:50:37.589Z
Learning: For changes related to OpenAPI migrations in Rocket.Chat/OpenAPI, when removing endpoint types and validators from rocket.chat/rest-typings (e.g., UserRegisterParamsPOST, /v1/users.register) document this as a minor changeset (not breaking) per RocketChat/Rocket.Chat-Open-API#150 Rule 7. Note that the endpoint type is re-exposed via a module augmentation .d.ts in the consuming package (e.g., packages/web-ui-registration/src/users-register.d.ts). In reviews, ensure the changeset clearly states: this is a non-breaking change, the major version should not be bumped, and the changeset reflects a minor version bump. Do not treat this as a breaking change during OpenAPI migrations.

Applied to files:

  • .changeset/openclaw-integration.md
📚 Learning: 2025-12-02T22:23:49.593Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37654
File: apps/meteor/client/hooks/useAppSlashCommands.ts:32-38
Timestamp: 2025-12-02T22:23:49.593Z
Learning: In apps/meteor/client/hooks/useAppSlashCommands.ts, the `data?.forEach((command) => slashCommands.add(command))` call during render is intentional. The query is configured with `structuralSharing: false` to prevent React Query from keeping stable data references, and `slashCommands.add` is idempotent, so executing on every render is acceptable and ensures the command registry stays current.

Applied to files:

  • apps/meteor/app/openclaw/server/index.ts
  • apps/meteor/app/openclaw/server/slashCommand.ts
📚 Learning: 2026-03-12T10:26:26.697Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39340
File: apps/meteor/app/api/server/v1/im.ts:1349-1398
Timestamp: 2026-03-12T10:26:26.697Z
Learning: In `apps/meteor/app/api/server/v1/im.ts` (PR `#39340`), the `DmEndpoints` type intentionally includes temporary stub entries for `/v1/im.kick`, `/v1/dm.kick`, `/v1/im.leave`, and `/v1/dm.leave` (using `DmKickProps` and `DmLeaveProps`) even though no route handlers exist for them yet. These stubs were added to preserve type compatibility after removing the original `DmLeaveProps` and related files. They are planned for cleanup in a follow-up PR. Do not flag these as missing implementations when reviewing this file until the follow-up is merged.

Applied to files:

  • apps/meteor/app/openclaw/server/index.ts
  • apps/meteor/app/openclaw/server/api/webhook.ts
  • apps/meteor/app/openclaw/server/lib/messageHandler.ts
📚 Learning: 2026-03-15T14:31:28.969Z
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39647
File: apps/meteor/app/api/server/v1/users.ts:710-757
Timestamp: 2026-03-15T14:31:28.969Z
Learning: In RocketChat/Rocket.Chat, the `UserCreateParamsPOST` type in `apps/meteor/app/api/server/v1/users.ts` (migrated from `packages/rest-typings/src/v1/users/UserCreateParamsPOST.ts`) intentionally has `fields: string` (non-optional) and `settings?: IUserSettings` without a corresponding AJV schema entry. This is a pre-existing divergence carried over verbatim from the original rest-typings source (PR `#39647`). Do not flag this type/schema misalignment during the OpenAPI migration review — it is tracked as a separate follow-up fix.

Applied to files:

  • apps/meteor/app/openclaw/server/settings.ts
  • apps/meteor/app/openclaw/server/api/webhook.ts
📚 Learning: 2025-11-05T20:53:57.761Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37357
File: apps/meteor/ee/server/startup/federation.ts:39-74
Timestamp: 2025-11-05T20:53:57.761Z
Learning: In Rocket.Chat (apps/meteor/app/settings/server/CachedSettings.ts), the settings.watchMultiple() method immediately invokes its callback with current values if all requested settings exist in the store, then continues watching for subsequent changes. It does not wait for a setting to change before the first invocation.

Applied to files:

  • apps/meteor/app/openclaw/server/settings.ts
📚 Learning: 2026-03-14T14:58:58.834Z
Learnt from: smirk-dev
Repo: RocketChat/Rocket.Chat PR: 39625
File: apps/meteor/app/api/server/v1/push.ts:85-97
Timestamp: 2026-03-14T14:58:58.834Z
Learning: In RocketChat/Rocket.Chat, the `push.token` POST/DELETE endpoints in `apps/meteor/app/api/server/v1/push.ts` were already migrated to the chained router API pattern on `develop` prior to PR `#39625`. `cleanTokenResult` (which strips `authToken` and returns `PushTokenResult`) and `isPushTokenPOSTProps`/`isPushTokenDELETEProps` validators already exist on `develop`. PR `#39625` only migrates `push.get` and `push.info` to the chained pattern. Do not flag `cleanTokenResult` or `PushTokenResult` as newly introduced behavior-breaking changes when reviewing this PR.

Applied to files:

  • apps/meteor/app/openclaw/server/api/webhook.ts
  • apps/meteor/app/openclaw/server/lib/messageHandler.ts
📚 Learning: 2026-03-03T11:11:48.541Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39230
File: apps/meteor/app/api/server/v1/chat.ts:214-222
Timestamp: 2026-03-03T11:11:48.541Z
Learning: In apps/meteor/server/lib/moderation/reportMessage.ts, the reportMessage function validates that description is not empty or whitespace-only with `if (!description.trim())`. When migrating the chat.reportMessage endpoint to OpenAPI, adding minLength validation to the schema preserves this existing behavior.

Applied to files:

  • apps/meteor/app/openclaw/server/api/webhook.ts
  • apps/meteor/app/openclaw/server/slashCommand.ts
  • apps/meteor/app/openclaw/server/lib/messageHandler.ts
📚 Learning: 2026-03-20T13:52:29.575Z
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 39553
File: apps/meteor/app/api/server/v1/stats.ts:98-117
Timestamp: 2026-03-20T13:52:29.575Z
Learning: In `apps/meteor/app/api/server/v1/stats.ts`, the `statistics.telemetry` POST endpoint intentionally has no `body` AJV schema in its route options. The proper request body shape (a `params` array of telemetry event objects) has not been formally defined yet, so body validation is deferred to a follow-up. Do not flag the missing body schema for this endpoint during OpenAPI migration reviews.

Applied to files:

  • apps/meteor/app/openclaw/server/api/webhook.ts
📚 Learning: 2026-03-10T08:13:52.153Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39414
File: apps/meteor/app/api/server/v1/rooms.ts:1241-1297
Timestamp: 2026-03-10T08:13:52.153Z
Learning: In the RocketChat/Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1/rooms.ts, the pattern `ajv.compile<void>({...})` is intentionally used for the 200 response schema even when the endpoint returns `{ success: true }`. This is an established convention across all migrated endpoints (rooms.leave, rooms.favorite, rooms.delete, rooms.muteUser, rooms.unmuteUser). Do not flag this as a type mismatch during reviews of these migration PRs.

Applied to files:

  • apps/meteor/app/openclaw/server/api/webhook.ts
📚 Learning: 2025-11-19T12:32:29.696Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37547
File: packages/i18n/src/locales/en.i18n.json:634-634
Timestamp: 2025-11-19T12:32:29.696Z
Learning: Repo: RocketChat/Rocket.Chat
Context: i18n workflow
Learning: In this repository, new translation keys should be added to packages/i18n/src/locales/en.i18n.json only; other locale files are populated via the external translation pipeline and/or fall back to English. Do not request adding the same key to all locale files in future reviews.

Applied to files:

  • packages/i18n/src/locales/en.i18n.json
📚 Learning: 2025-11-19T18:20:07.720Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37419
File: packages/i18n/src/locales/en.i18n.json:918-921
Timestamp: 2025-11-19T18:20:07.720Z
Learning: Repo: RocketChat/Rocket.Chat — i18n/formatting
Learning: This repository uses a custom message formatting parser in UI blocks/messages; do not assume standard Markdown rules. For keys like Call_ended_bold, Call_not_answered_bold, Call_failed_bold, and Call_transferred_bold in packages/i18n/src/locales/en.i18n.json, retain the existing single-asterisk emphasis unless maintainers request otherwise.

Applied to files:

  • packages/i18n/src/locales/en.i18n.json
📚 Learning: 2026-03-11T22:04:20.529Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 39545
File: apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts:59-61
Timestamp: 2026-03-11T22:04:20.529Z
Learning: In `apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts`, the `msg.u._id === uid` early-return in the `streamNewMessage` handler is intentional: the "New messages" indicator is designed to notify about messages from other users only. Self-sent messages — including those sent from a different session/device — are always skipped, by design. Do not flag this as a multi-session regression.

Applied to files:

  • apps/meteor/app/openclaw/server/lib/messageHandler.ts
📚 Learning: 2026-03-11T18:17:53.972Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39425
File: apps/meteor/client/lib/chats/flows/processMessageUploads.ts:112-119
Timestamp: 2026-03-11T18:17:53.972Z
Learning: In `apps/meteor/client/lib/chats/flows/processMessageUploads.ts`, when sending multiple file uploads, each file is confirmed via its own `/rooms.mediaConfirm/${rid}/${fileId}` call and produces a separate message. Only the first file's confirm payload carries the composed message text (`msg`); all subsequent files receive `msg: ''`. This one-message-per-file behavior is intentional by design — do not flag it as a bug or suggest batching into a single message.

Applied to files:

  • apps/meteor/app/openclaw/server/lib/messageHandler.ts
🔇 Additional comments (15)
.changeset/openclaw-integration.md (1)

1-17: Changeset is well-scoped and correctly versioned.

This is clear, accurate for the feature scope, and minor is the right bump for an additive integration.

apps/meteor/app/openclaw/server/logger.ts (1)

1-3: Looks good — shared logger is cleanly defined and exported.

This is a solid, minimal logger module for the integration surface.

As per coding guidelines, the implementation remains concise and avoids inline implementation comments.

packages/i18n/src/locales/en.i18n.json (1)

4007-4024: OpenClaw i18n additions are well-structured.

The new keys are consistently namespaced and cover settings, command help, and error/status messaging clearly.

Also applies to: 4026-4030

apps/meteor/app/openclaw/server/settings.ts (1)

1-65: LGTM!

The settings registration follows established Rocket.Chat patterns. The auth token is correctly marked as secret: true, and the conditional enableQuery logic properly gates dependent settings on OpenClaw_Enabled.

apps/meteor/app/openclaw/server/lib/openclawClient.ts (3)

39-59: LGTM!

The validateConfig() function returns stable, specific error codes that can be mapped to localized messages at the call site. The config validation order (enabled → API URL → auth token) is logical.


61-131: LGTM!

The sendToAgent implementation is well-structured:

  • Config validation before making requests
  • Sanitized logging (no prompts/PII in logs)
  • Proper malformed JSON handling as a hard failure
  • Clear error messages with HTTP status context
  • Appropriate 30-second timeout for AI agent requests

133-168: LGTM!

The wakeAgent function follows the same pattern as sendToAgent with a shorter 10-second timeout appropriate for a wake event.

apps/meteor/app/openclaw/server/lib/messageHandler.ts (1)

9-32: LGTM!

The shouldProcessMessage function correctly implements bot loop prevention by filtering out:

  • System messages (message.t)
  • Empty messages
  • Bot-originated messages (message.bot)
  • Messages from the configured OpenClaw bot username
apps/meteor/app/openclaw/server/api/webhook.ts (2)

10-20: LGTM!

The safeCompare function correctly implements timing-safe comparison:

  • Type guard for string input
  • Length check before timingSafeEqual (required since it throws on mismatched lengths)
  • Uses Buffer.from with explicit UTF-8 encoding

22-114: LGTM!

The webhook handler has solid security practices:

  • Feature enablement check before processing
  • Timing-safe token validation
  • Proper input type validation for all fields
  • Room and bot user existence verification
  • Structured error responses without leaking internal details

The messagePayload and defaultValues construction correctly matches the Payload and DefaultValues types expected by processWebhookMessage.

apps/meteor/app/openclaw/server/slashCommand.ts (2)

19-108: LGTM overall, minor threading logic observation.

The slash command implementation is well-structured with proper:

  • User language resolution for i18n
  • Config validation with localized errors
  • Processing indicator for user feedback
  • Graceful fallback to ephemeral messages if bot user unavailable

One observation on lines 92: the thread response condition respondInThread && message.tmid only threads if the slash command was invoked from within an existing thread. If the intent is to always create/use threads when OpenClaw_Respond_In_Thread is enabled, this would need adjustment. The current behavior seems intentional for "respond in the same thread context."


109-113: [No action needed—this comment is based on incorrect assumptions.]

The /openclaw command's lack of a permission field is intentional and not a security gap. Many slash commands intentionally omit permission fields, including /status, /me, /help, and /hide. These are utility commands that don't perform administrative actions requiring role-based access control.

The openclaw command has access control at the configuration level (the validateConfig() check at line 29 ensures the feature is enabled and properly configured), which is the appropriate pattern for feature-gated functionality rather than role-based restrictions.

			> Likely an incorrect or invalid review comment.
apps/meteor/app/openclaw/README.md (1)

1-54: LGTM!

The documentation is comprehensive and accurately reflects the implementation:

  • Features section covers slash command, webhook, and admin settings
  • Setup steps match the settings registered in settings.ts
  • Webhook payload example includes the correct required fields (token, channel_id, text) and optional thread_id
  • Architecture diagram clearly shows the bidirectional flow
apps/meteor/server/importPackages.ts (1)

44-44: LGTM!

The OpenClaw server module import is correctly placed in alphabetical order and follows the established side-effect import pattern used by other modules in this file.

apps/meteor/app/openclaw/server/index.ts (1)

1-3: LGTM!

Clean entry point that correctly imports modules in the right order: settings first (so they're registered before dependent modules), then slash command and webhook.

'technicalcontact_email' => 'na@example.org',
'timezone' => null,
'logging.level' => SimpleSAML_Logger::DEBUG,
'logging.level' => SimpleSAML\Logger::DEBUG,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check SimpleSAMLphp version and verify Logger class namespace

# Find composer.json or package files that define SimpleSAMLphp version
fd -t f 'composer.json' apps/meteor/tests/e2e/containers/saml/ --exec cat {}

# Search for SimpleSAMLphp version references
rg -n 'simplesamlphp.*version|SimpleSAML' apps/meteor/tests/e2e/containers/saml/ -A 2 -B 2

Repository: RocketChat/Rocket.Chat

Length of output: 2879


🌐 Web query:

SimpleSAMLphp version history PSR-4 namespacing when introduced

💡 Result:

PSR-4 namespacing was introduced for SimpleSAMLphp modules in version 1.19.0, released on 2021-01-21. This added a PSR-4 autoloader allowing modules to declare classes under the SimpleSAML\Module namespace. Core classes began migrating to namespaces earlier (e.g., around 1.17), with PSR-4 as the goal, but full PSR-4 support for modules started here. By SimpleSAMLphp 2.0 (2023-02-23), namespaces were more comprehensively used, including non-static utils classes under SimpleSAML\Utils.

Citations:


Critical issue: Change is incompatible with SimpleSAMLphp 1.15.4 and will cause runtime failure.

The Dockerfile specifies SimpleSAMLphp 1.15.4, which predates the PSR-4 namespace migration. PSR-4 namespacing (SimpleSAML\Logger) was introduced in SimpleSAMLphp 1.19.0. The codebase uses version 1.15.4, which only supports the deprecated PEAR-style naming (SimpleSAML_Logger::DEBUG).

The change from SimpleSAML_Logger::DEBUG to SimpleSAML\Logger::DEBUG will cause a runtime failure because the namespaced class does not exist in version 1.15.4. Either upgrade SimpleSAMLphp to a version that supports namespaces (1.19.0+) or revert this change to use the correct API for version 1.15.4.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/tests/e2e/containers/saml/config/simplesamlphp/config.php` at
line 19, The change uses the namespaced class SimpleSAML\Logger::DEBUG which
does not exist in the pinned SimpleSAMLphp 1.15.4; either upgrade SimpleSAMLphp
to >=1.19.0 to use namespaced classes or revert the logging constant to the
PEAR-style SimpleSAML_Logger::DEBUG in the config entry for 'logging.level' so
the runtime will work with the current 1.15.4 image.

"OpenClaw_Respond_In_Thread": "Respond in Thread",
"OpenClaw_Respond_In_Thread_Description": "When enabled, OpenClaw responses will be posted as thread replies instead of channel messages.",
"OpenClaw_Slash_Description": "Send a prompt to the OpenClaw AI agent",
"OpenClaw_Slash_Params": "your_prompt_here",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use a user-facing slash parameter label.

At Line 4025, your_prompt_here reads like an internal placeholder and is inconsistent with other slash param labels. Prefer a human-readable form.

💡 Suggested tweak
-  "OpenClaw_Slash_Params": "your_prompt_here",
+  "OpenClaw_Slash_Params": "your prompt",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"OpenClaw_Slash_Params": "your_prompt_here",
"OpenClaw_Slash_Params": "your prompt",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/i18n/src/locales/en.i18n.json` at line 4025, Replace the internal
placeholder value for the i18n key "OpenClaw_Slash_Params" with a user-facing,
human-readable slash parameter label (e.g., "Prompt" or "Claw prompt") so it
matches the style of other slash param labels; update the JSON value for
"OpenClaw_Slash_Params" accordingly.

@debdutdeb
Copy link
Copy Markdown
Member

Hi, thanks for the contribution, however, we are unlikely (99.999999999999% sure) to accept this. This is a fine idea, but should be carried forward via an App. Adding to core doesn't make sense. Does not directly natively go with the product.

@CHINMAYK121
Copy link
Copy Markdown
Author

CHINMAYK121 commented Mar 29, 2026 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community type: feature Pull requests that introduces new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants