Files
upstream-rocketchat/docs/features/slackbridge-manual-tests.md
upstream-mirror 30810eecd7
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 2s
snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:21:02 +05:00

12 KiB

SlackBridge Manual Test Plan

The SlackBridge is a bi-directional bridge between a Rocket.Chat workspace and one or more Slack workspaces — each token line in the SlackBridge settings gets its own connection and adapter. It has no automated end-to-end coverage: exercising it requires a real Slack workspace, a real bot installation, and a human watching both sides at once. This document is the checklist to walk through when touching the bridge.

Scope: the matrices below assume a single bridged Slack workspace — configure exactly one token per setting while running them. Bridging several workspaces at once is a supported configuration that this plan does not cover; see Coverage gaps.

Code lives in apps/meteor/server/bridges/slack/ — SlackAdapter.ts handles Slack → Rocket.Chat, RocketAdapter.ts handles Rocket.Chat → Slack (hooked in through the afterSaveMessage, afterDeleteMessage, afterSetReaction and afterUnsetReaction callbacks). Settings are declared in apps/meteor/server/settings/slackbridge.ts.

Setup

Configure the bridge in Admin → Settings → SlackBridge:

Setting Notes
SlackBridge_Enabled Master switch. Must be on.
SlackBridge_UseLegacy Chooses the connection mode — see below. Run the matrices in the mode you are testing.
SlackBridge_APIToken Legacy mode only (RTM).
SlackBridge_BotToken, SlackBridge_SigningSecret, SlackBridge_AppToken App mode only (Bolt / Socket Mode).
SlackBridge_Out_Enabled Required for anything to flow Rocket.Chat → Slack.
SlackBridge_Out_All / SlackBridge_Out_Channels Which Rocket.Chat rooms are bridged out.
SlackBridge_Reactions_Enabled Gates reaction propagation in both directions.
SlackBridge_AliasFormat Optional, Slack → Rocket.Chat only. %s is the Slack username; test with %s (via Slack).
SlackBridge_FileUpload_Enabled Gates file transfer.

Two connection modes exist and they use different Slack event plumbing, so a regression can appear in one and not the other. Run the full matrix in both when changing anything in the connect/event-subscription path:

  • Legacy (SlackBridge_UseLegacy: true) — RTM connection with an API token.
  • App (SlackBridge_UseLegacy: false) — Slack app using bot token, signing secret and app token.

You also need:

  • A Slack workspace where you can create channels and install/invite the bot (referred to below as rocketbot).
  • At least one channel that exists on both sides with rocketbot in it, and one that exists on both sides without rocketbot in it. Several cases below hinge on that difference.
  • A second Slack user, if possible — some behaviors only show up when the message author is not the same account as the bot.

Watch SlackBridge logs (slackLogger / rocketLogger) while testing; several expected failures are only visible there.

How to read the matrices

  • Origin — where the message being acted on was originally posted.
  • Action performed on — the side where the tester performs the action.
  • Every matrix must also be repeated on a channel that rocketbot is not a member of. Nothing should propagate in either direction for those channels, and nothing should error.

Sending messages

# Origin Action performed on Expected result
1 Slack Slack Message appears in the linked Rocket.Chat room, under the alias SlackBridge_AliasFormat produces.
2 Rocket.Chat Rocket.Chat Message appears in the linked Slack channel, posted by rocketbot with the sender's username and avatar.

SlackBridge_AliasFormat only affects case 1: addAliasToMsg sets alias on the Rocket.Chat message, so with %s (via Slack) a message from Slack user alice shows as alice (via Slack). Case 2 carries the sender's identity through chat.postMessage's username/icon_url and ignores the setting entirely. Set the format, run case 1 with it set and again with it empty, then restore the original value before moving on — the later matrices assume the workspace's normal setup.

Repeat both on a channel without rocketbot: neither message crosses over.

Editing messages

Slack does not allow an app to edit messages it did not post, and it does not allow humans to edit bot messages. Two of the four cases are therefore expected failures — they are listed because "nothing crashes and the local side stays consistent" is the requirement.

# Origin Action performed on Expected result
1 Slack Slack Edit propagates to Rocket.Chat.
2 Rocket.Chat Rocket.Chat Edit propagates to Slack.
3 Slack Rocket.Chat Expected failure. Rocket.Chat shows the edit; Slack is unchanged. chat.update is rejected because the message is not the bot's.
4 Rocket.Chat Slack Expected failure. Slack does not even offer the edit affordance for a bot message.

Repeat on a channel without rocketbot: edits stay local on both sides.

Deleting messages

Case 3 needs care about who deletes. A Rocket.Chat-origin message is authored on Slack by rocketbot, and Slack offers no delete affordance for an app's message to a regular member, so pick one of:

  • Delete it from the Slack UI as a workspace owner or admin — they can delete any message, including an app's.
  • Call chat.delete with the very token the bridge is configured with, so the caller is rocketbot itself: SlackBridge_APIToken in legacy/RTM mode, SlackBridge_BotToken in app/Socket Mode. Any other token fails with cant_delete_message, which is case 4's failure, not case 3's.

Both routes emit the same message_deleted event, so either is a valid way to run the case.

# Origin Action performed on Expected result
1 Slack Slack Deletion propagates to Rocket.Chat.
2 Rocket.Chat Rocket.Chat Deletion propagates to Slack.
3 Rocket.Chat Slack Deletion propagates to Rocket.Chat — deleted as a workspace admin or via chat.delete with rocketbot's own token, per the note above.
4 Slack Rocket.Chat Expected failure. The message is deleted in Rocket.Chat only; Slack keeps it, since chat.delete cannot remove another user's message.

Repeat on a channel without rocketbot: deletions stay local on both sides.

Reactions

Requires SlackBridge_Reactions_Enabled. Reactions sent to Slack are added by the bot account, so on the Slack side every Rocket.Chat reaction shows up as rocketbot's reaction regardless of who actually reacted.

# Origin Action performed on Expected result
1 Slack Slack Reaction appears on the Rocket.Chat message.
2 Rocket.Chat Slack Reaction appears on the Rocket.Chat message.
3 Rocket.Chat Rocket.Chat Reaction appears on the Slack message (as rocketbot).
4 Slack Rocket.Chat Reaction appears on the Slack message (as rocketbot).

Also check removal of each reaction, and confirm a reaction is not echoed back to its origin (the bridge de-duplicates through its reactions map — a double-count means that broke).

Repeat on a channel without rocketbot: reactions stay local.

SlackBridge_Reactions_Enabled toggle

Setting state Expected result
Disabled React to both a Slack-origin and a Rocket.Chat-origin message from both sides — nothing propagates, no errors.
Enabled Re-run the same reactions — they propagate as in the matrix above, without restarting the server.

Channel lifecycle

These cases cover how the bridge reacts to channels appearing, disappearing, and the bot joining or leaving. Send a message from each side after every step and verify propagation.

Channel exists on both sides, rocketbot not in the Slack channel

  1. Confirm nothing propagates in either direction.
  2. Invite rocketbot to the Slack channel.
  3. Send from Slack and from Rocket.Chat — both directions now work.

Channel exists on Rocket.Chat only

  1. Create the matching channel in Slack and invite rocketbot.
  2. Send from Rocket.Chat — it reaches Slack.
  3. Send from Slack — it reaches Rocket.Chat.

Channel exists on Slack only

  1. Invite rocketbot to the Slack channel.
  2. Send from Slack — the Rocket.Chat channel is created and receives the message.
  3. Send from Rocket.Chat — it reaches Slack.

Channel exists on both sides with rocketbot

  1. Delete the Rocket.Chat channel, then send from Slack — behaves like the "Slack only" case above (the channel is recreated).
  2. Remove rocketbot from the Slack channel, then send from Slack and from Rocket.Chat — nothing propagates in either direction, and no errors are logged.

Coverage gaps

The matrices above are the historical manual suite and deliberately mirror it. They do not cover, and it is worth checking manually when relevant:

  • File uploads (SlackBridge_FileUpload_Enabled).
  • Slack history import (/slackbridge-import, slackbridge_import.server.ts).
  • Threads (thread_ts mapping in postMessage).
  • Private channels and DMs.
  • SlackBridge_ExcludeBotnames filtering.
  • The Remove Channel Links admin action (SlackBridge_Remove_Channel_Links).
  • Multiple Slack workspaces bridged at once (one token per line in each token setting).