Skip to content

marcusgreenwood/chat-bridge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chat Bridge

A self-hosted bridge that relays messages between Slack, Microsoft Teams, and Google Chat. Post in a bridged channel on one platform and the message appears on the others, with the original sender’s name and avatar preserved where the platform allows.

Use it when your organization uses more than one chat system and you want a single shared channel (e.g. “engineering-general”) that stays in sync across all of them—without moving everyone to one product or maintaining separate threads everywhere.


How it works

Each platform runs a bot that listens for new messages and forwards them to the other connected platforms:

  • Slack – Bot posts with the sender’s display name and avatar (chat:write.customize). Messages show an “APP” badge.
  • Teams – Bot sends an Adaptive Card with the sender’s avatar, name, and a “via Slack” / “via Google Chat” label.
  • Google Chat – Bot sends a Card v2 with the sender’s avatar and name in the card header.

Channels are linked with /bridge commands. Create a bridge group from any channel, then have each channel join that group—no config file edits or restarts.


Prerequisites

  • Node.js 20+
  • Permission to create apps/bots on at least two of: Slack, Microsoft Teams, Google Chat
  • Google Chat: paid Google Workspace and (for full setup) org admin for app approval

Quick start

cd chat-bridge
npm install

cp config/bridge.example.yaml config/bridge.yaml
cp .env.example .env
# Add credentials for at least two platforms (see "Adding a new chat app" below)

npm run dev

Then link channels with /bridge create <name> and /bridge join <name> on each platform.


Adding a new chat app

Setup is done via CLI tools where possible; anything that must be done in a browser or portal is documented in the /docs guides.

General flow:

  1. Install and authenticate the platform’s CLI (Slack CLI, gcloud, or Azure CLI).
  2. Run the matching setup script from the repo root. It will create or select resources and print the values to add to .env.
  3. Do any remaining steps in the UI (e.g. enable Socket Mode for Slack, configure the Chat app in Google Cloud, set the bot messaging endpoint for Teams, upload the Teams app package).
  4. In config/bridge.yaml, set platforms.<platform>.enabled: true for that platform.
  5. Restart the bridge and invite the bot into the channels you want to bridge.

Detailed steps per platform:

Platform CLI / script Manual steps (browser/portal) documented in
Slack ./scripts/setup-slack.sh docs/slack.md
Google Chat ./scripts/setup-gcloud.sh docs/gchat.md
Microsoft Teams ./scripts/setup-azure.sh docs/teams.md

Slack (Slack CLI)

  • Prereq: Slack CLI installed and slack login done.
  • Run: ./scripts/setup-slack.sh (optionally SLACK_TEAM_ID=T01234 ./scripts/setup-slack.sh).
  • Script: Lists workspaces, lets you pick one, prints the create-app URL and the path to config/slack-app-manifest.yaml for “Create from manifest.”
  • You do in the browser: Enable Socket Mode, create app-level token, install app, copy SLACK_APP_TOKEN, SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET into .env. Full list: docs/slack.md.

Google Chat (gcloud)

  • Prereq: gcloud installed and gcloud auth login done.
  • Run: ./scripts/setup-gcloud.sh (or GCP_PROJECT_ID=my-project ./scripts/setup-gcloud.sh).
  • Script: Enables Chat, Pub/Sub, and Workspace Events APIs; creates service account, topic, subscription, and JSON key at config/gchat-service-account.json; prints env vars.
  • You do in the console: Configure the Chat app (name, avatar, connection = Pub/Sub topic, /bridge command, permissions). Uncheck "Build this Chat app as a Workspace add-on" so the Cloud Pub/Sub option appears under Connection settings. Full steps: docs/gchat.md.

Microsoft Teams (Azure CLI)

  • Prereq: Azure CLI installed and az login done.
  • Run: ./scripts/setup-azure.sh (or set TEAMS_APP_NAME / AZURE_SUBSCRIPTION_ID / TEAMS_APP_ID to skip prompts).
  • Script: Creates (or reuses) Azure AD app, client secret, resource group, Azure Bot, and Teams channel; prints env vars.
  • You do: Set messaging endpoint (az bot update ... --endpoint "https://YOUR_PUBLIC_URL/api/teams/messages"), optionally add Graph User.Read.All for avatars, create and upload the Teams app package. Full list: docs/teams.md.

Linking channels

After the bot is in channels on at least two platforms:

  1. In any channel, run: /bridge create engineering-general (or any name).
  2. In each channel you want in that bridge, run: /bridge join engineering-general.

Messages in any linked channel are relayed to the others. Use /bridge status and /bridge list to inspect; /bridge leave to unlink.

Command Description
/bridge create <name> Create a new bridge group
/bridge join <group-id> Link this channel to a bridge group
/bridge leave Unlink this channel
/bridge status Show this channel’s bridge group
/bridge list List all bridge groups

Running in production

  • Local / dev: npm run dev and expose with ngrok (ngrok http 3000). Set Teams bot messaging endpoint to the ngrok URL.

  • Server: Build with npm run build, run with node dist/index.js (or a process manager like pm2). Set server.publicUrl in config and use SSL (e.g. Let’s Encrypt).

  • Docker: Build and run with a Dockerfile that copies dist/, config/, and migrations; mount data/ and config/ for persistence:

    FROM node:20-slim
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci --production
    COPY dist/ ./dist/
    COPY config/ ./config/
    COPY src/storage/migrations/ ./src/storage/migrations/
    CMD ["node", "dist/index.js"]
    npm run build
    docker build -t chat-bridge .
    docker run -d --name chat-bridge -p 3000:3000 \
      -v $(pwd)/data:/app/data -v $(pwd)/config:/app/config \
      --env-file .env chat-bridge

Architecture

┌──────────┐     ┌──────────┐     ┌──────────┐
│  Slack   │     │  Teams   │     │  GChat   │
│ Adapter  │     │ Adapter  │     │ Adapter  │
└────┬─────┘     └────┬─────┘     └────┬─────┘
     │                │                │
     └────────┬───────┴────────┬───────┘
              ▼                ▼
         ┌──────────────────────────┐
         │      Relay Engine        │
         └────────────┬─────────────┘
                      ▼
         ┌──────────────────────────┐
         │  Queue Manager (p-queue) │
         │  Per-channel rate limits │
         └────────────┬─────────────┘
                      ▼
         ┌──────────────────────────┐
         │  SQLite (better-sqlite3) │
         │  Message/thread mappings │
         │  User profile cache      │
         │  Bridge group config     │
         └──────────────────────────┘
  • Storage: SQLite; single file, no extra services.
  • Rate limits: Per-channel queues (e.g. 1 msg/sec for Slack and Google Chat).
  • Sender identity: Slack uses chat:write.customize; Teams and Google Chat use cards with avatar and name because bots can’t impersonate users.
  • Threads: Parent messages and replies are mapped so threads stay aligned across platforms.

Troubleshooting

  • Bot doesn’t receive messages: Slack – bot invited to channel and message.channels/message.groups subscribed. Teams – messaging endpoint correct and reachable. Google Chat – Pub/Sub subscription and Workspace Events subscription in place (see docs/gchat.md).
  • Messages not relaying: Confirm channels are linked (/bridge status), check logs (logging.level: "debug"), and ensure the bridge group has channels on at least two platforms.
  • Rate limits: Queues back off on 429; persistent errors may mean the channel is too active for the platform limit.
  • Thread replies: Only messages that went through the bridge have thread mapping; older parents won’t link.

Development

npm run dev          # Hot reload (tsx watch)
npm run build        # Compile TypeScript
npm run start        # Run compiled build
npm test             # Tests
npm run lint         # Lint

License

MIT

About

A self-hosted bridge that relays messages between Slack, Microsoft Teams, and Google Chat.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors