Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 24 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
# TeamsBridge
Rocket.Chat app to support connecting collaborators across Rocket.Chat and Microsoft Teams
# Microsoft Teams Bridge

## Getting Started with Rocket.Chat App
Here are some commands to get started:
- `rc-apps package`: this command will generate a packaged app file (zip) which can be installed **if** it compiles with TypeScript
- `rc-apps deploy`: this will do what `package` does but will then ask you for your server url, username, and password to deploy it for you

## Getting Started with TeamsBridge App
See [Support document](./docs/support.md) for how to use TeamsBridge App.
Rocket.Chat app to support connecting collaborators across Rocket.Chat and Microsoft Teams. Messages, files, and member updates are relayed in real time so that users on each platform can collaborate without leaving their preferred tool.

## Documentation
Here are some links to examples and documentation:
- [Rocket.Chat Apps TypeScript Definitions Documentation](https://rocketchat.github.io/Rocket.Chat.Apps-engine/)
- [Rocket.Chat Apps TypeScript Definitions Repository](https://github.com/RocketChat/Rocket.Chat.Apps-engine)

| Guide | Description |
|-------|-------------|
| [Overview & Capabilities](./docs/capabilities.md) | What the app does, supported features, and architecture overview |
| [Setting Up the MS Teams Bridge](./docs/setup.md) | End-to-end admin guide — Azure registration, permissions, settings, and verification |
| [Creating a Bridged Room](./docs/bridged-rooms.md) | How to activate bridging and add Microsoft Teams users |
| [Slash Commands Reference](./docs/slash-commands.md) | Complete reference for all slash commands |
| [App Settings](./docs/settings.md) | Detailed explanation of every configurable setting |
| [FAQs](./docs/faq.md) | Frequently asked questions |
| [Troubleshooting](./docs/troubleshooting.md) | Common issues, root causes, and resolution steps |

## Development

### Commands

- `rc-apps package` — Generate a packaged app file (zip) which can be installed if it compiles with TypeScript
- `rc-apps deploy` — Package and deploy; will prompt for your server URL, username, and password

### Resources

- [Rocket.Chat Apps Engine Documentation](https://rocketchat.github.io/Rocket.Chat.Apps-engine/)
- [Rocket.Chat Apps Engine Repository](https://github.com/RocketChat/Rocket.Chat.Apps-engine)
- [Example Rocket.Chat Apps](https://github.com/graywolf336/RocketChatApps)
- Community Forums
- [App Requests](https://forums.rocket.chat/c/rocket-chat-apps/requests)
Expand Down
59 changes: 0 additions & 59 deletions docs/admin.md

This file was deleted.

153 changes: 153 additions & 0 deletions docs/bridged-rooms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Creating a Bridged Room

A **bridged room** is a Rocket.Chat room that actively relays messages between Rocket.Chat and Microsoft Teams. This guide explains how to set one up and start cross-platform communication.

---

## Prerequisites

Before bridging a room, make sure the [initial setup](./setup.md) is complete:

- ✅ App is installed and configured with Azure credentials
- ✅ API permissions are granted with admin consent
- ✅ App Bot User is logged in via `/teamsbridge-login-app-user`
- ✅ Setup verification passes (`/teamsbridge-setup-verification`)

---

## Step 1 — Add the Bot to a Room

To bridge a room, invite the App Bot User (e.g. `microsoftteamsbridge.bot`) as a member:

1. Open the room you want to bridge.
2. Click the **Members** panel.
3. Click **Add Members** and search for `microsoftteamsbridge.bot` (or whatever the bot's username is).
4. Add the bot to the room.

### What happens when the bot joins

- The room is flagged as a **bridged room** (`isBridged = true`)
- A notification message is sent to the room confirming that bridging is active:
> *"Hey, I been added to this room. So the room is now an active bridge room and I will start relaying messages between Rocket.Chat and Microsoft Teams."*
- If the App Bot User does not have a valid token (Step 5 of setup not done), room members are notified to contact an admin

### Supported Room Types

| Room Type | Can Be Bridged? |
|-----------|:-----------:|
| Private channel | ✅ |
| Private team | ✅ |
| Private discussion | ✅ |
| Public channel | ❌ |
| Direct message | ❌ |

### Deactivating a Bridge

To stop bridging a room, simply **remove the App Bot User** from the room. The room will no longer relay messages.

---

## Step 2 — Add Teams Users

Once a room is bridged, you can add Microsoft Teams users to the linked Teams thread:

### Using the Slash Command

1. Open the bridged room.
2. Run:
```
/teamsbridge-add-user
```
3. A contextual bar (side panel) opens with a **live search** from the Azure AD directory.
4. Type a display name to search for Teams users.
5. Select one or more users from the results.
6. Click **"Add users"** to add them to the linked Teams chat.

### Using the Room Action Button

1. Open the bridged room.
2. Click the **kebab menu** (⋮) or room action menu.
3. Select **"Add Teams user"**.
4. The same contextual bar opens — search, select, and add users.

> **Note:** If you attempt to add a user in a room that is **not bridged**, you will receive an error message:
> *"This room is not bridged to Microsoft Teams. To activate bridging, add me to this room."*

---

## Step 3 — Start Messaging

Once the room is bridged and Teams users have been added, messages flow automatically:

- **RC → Teams:** Any message sent in the bridged room is relayed to the linked Teams chat.
- **Teams → RC:** Any message sent in the Teams chat is relayed back to the Rocket.Chat room.

### How Messages Appear

| Sender | Logged In? | Appears in Teams As |
|--------|:----------:|-------------------|
| RC user | Yes (via `/teamsbridge-login-teams`) | Their own Teams identity |
| RC user | No | App Bot User with a blockquote showing the sender's name |

| Sender | Has Linked RC Account? | Appears in RC As |
|--------|:----------------------:|-----------------|
| Teams user | Yes | Their RC identity |
| Teams user | No | App Bot User with the Teams user's display name as alias |

---

## Optional: Individual User Login

Individual Rocket.Chat users can **optionally** link their personal Microsoft Teams account for identity-preserved messaging:

1. Run the slash command in any room:
```
/teamsbridge-login-teams
```
2. Click the **"Login Teams"** button in the message.
3. Complete the Microsoft OAuth login in the browser.

### Benefits of Logging In

- Messages appear under the user's **own Teams identity** instead of the bot's
- Direct identity preservation in both directions

### Without Logging In

- Messages are **still bridged** — they are relayed through the App Bot User
- In Teams, the message appears with a **[Bridged Message]** header and the sender's display name in a blockquote
- This is perfectly functional and is the default experience for most users

---

## Viewing Teams Members

To see which Microsoft Teams users are currently in the linked Teams chat:

### Using the Slash Command

```
/teamsbridge-view-members
```

### Using the Room Action Button

1. Click the kebab menu (⋮) in the bridged room.
2. Select **"View Teams members"**.

A contextual bar opens listing all members of the linked Teams thread.

---

## Checking Bridge Status

To verify whether the current room is actively bridged:

```
/teamsbridge-status
```

| Response | Meaning |
|----------|---------|
| ✅ *"This room is bridged to Microsoft Teams…"* | Room is actively bridged |
| ❌ *"This room is not bridged to Microsoft Teams…"* | Bot is not in the room — add it to activate bridging |
138 changes: 138 additions & 0 deletions docs/capabilities.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Overview & App Capabilities

## What Is the Microsoft Teams Bridge?

The Microsoft Teams Bridge is a Rocket.Chat app that connects Rocket.Chat rooms with Microsoft Teams chats, enabling real-time cross-platform collaboration. Users on either platform can send and receive messages without switching tools.

---

## Key Concepts

Before diving in, it helps to understand the terminology used throughout the documentation.

| Term | Definition |
|------|-----------|
| **App Bot User** | A single system-level Rocket.Chat user (e.g. `microsoftteamsbridge.bot`) created automatically when the app is installed. This is the only bot account used by the bridge — there is **no** per-Teams-user bot. It acts as the relay identity for all bridged messages. |
| **App Bot User's Linked Teams Account** | The Microsoft Teams account the App Bot User is logged into via OAuth. Also referred to as the **Bridge User**. An admin completes this login via `/teamsbridge-login-app-user`. |
| **Bridged Room** | A Rocket.Chat room where the App Bot User has been added as a member. Only bridged rooms relay messages between Rocket.Chat and Microsoft Teams. A room becomes bridged when the bot joins, and stops being bridged when the bot leaves. |
| **Logged-in RC User** | A Rocket.Chat user who has optionally linked their personal Microsoft Teams account using `/teamsbridge-login-teams`. |
| **Non-logged-in RC User** | A Rocket.Chat user who has **not** linked a personal Teams account. Their messages are still bridged — they are relayed through the App Bot User's linked Teams account using a rich blockquote format that includes their display name. |
| **Teams Thread** | The Microsoft Teams chat (group or 1:1) linked to a Rocket.Chat bridged room. Created automatically when the first message is sent or when a Teams user is added. |

---

## Supported Features

### Message Relay

| Feature | Status |
|---------|--------|
| Text messages (RC → Teams) | ✅ Supported |
| Text messages (Teams → RC) | ✅ Supported |
| Emoji rendering | ✅ Supported |
| URL link parsing & preview | ✅ Supported |
| Rich text / Markdown formatting | ✅ Supported |
| Message edits (RC → Teams) | ✅ Supported |
| Message edits (Teams → RC) | ✅ Supported |
| Message deletions (RC → Teams) | ✅ Supported |
| Message deletions (Teams → RC) | ✅ Supported |

### File Sharing

| Feature | Status |
|---------|--------|
| File uploads (RC → Teams via OneDrive) | ✅ Supported |
| File downloads (Teams → RC) | ✅ Supported |

### Member Management

| Feature | Status |
|---------|--------|
| Add Teams users to a bridged room | ✅ Supported |
| View Teams members in a linked chat | ✅ Supported |
| Live search of Azure AD directory | ✅ Supported |
| Automatic member sync on room join/leave | ✅ Supported |

### Identity & Authentication

| Feature | Status |
|---------|--------|
| OAuth2 login for the App Bot User | ✅ Supported |
| OAuth2 login for individual RC users | ✅ Supported (optional) |
| Identity-preserved messaging (logged-in users) | ✅ Supported |
| Bridged message format (non-logged-in users) | ✅ Supported |
| Automatic token refresh | ✅ Supported |
| Webhook subscription auto-renewal | ✅ Supported |

### Room Types

| Room Type | Supported |
|-----------|-----------|
| Private channels | ✅ Yes |
| Private teams | ✅ Yes |
| Private discussions | ✅ Yes |
| Public channels | ❌ No |
| Direct messages | ❌ No |

---

## How Message Relay Works

Understanding the message flow is key to understanding why individual user login is **optional**.

### Outbound (Rocket.Chat → Microsoft Teams)

```
RC user sends a message in a bridged room
├─ Is the RC user logged in to Teams? (/teamsbridge-login-teams)
│ │
│ ├─ YES → Message is sent via the user's own Teams token
│ │ (appears in Teams under their true identity)
│ │
│ └─ NO → Is the App Bot User logged in? (/teamsbridge-login-app-user)
│ │
│ ├─ YES → Message is relayed via the App Bot User's token
│ │ (appears in Teams using a rich blockquote format
│ │ with the sender's display name)
│ │
│ └─ NO → Message is NOT relayed to Teams
│ (room members are notified that admin login is required)
```

### Inbound (Microsoft Teams → Rocket.Chat)

```
Teams user sends a message in a linked Teams thread
├─ Is the App Bot User logged in & webhook subscription active?
│ │
│ ├─ NO → Messages are NOT received by Rocket.Chat
│ │
│ └─ YES → Message is processed by the bridge
│ │
│ └─ Does this Teams user have a linked RC account?
│ │
│ ├─ YES → Message appears in RC under their true RC identity
│ │
│ └─ NO → Message appears in RC from the App Bot User
│ (using the Teams user's display name as a message alias)
```

> **Key takeaway:** Individual RC users do **not** need to log in for the bridge to function. If they are not logged in, their messages are relayed through the App Bot User's linked Teams account using a rich blockquote format that carries their name. Logging in is optional and provides the benefit of messages appearing under their own Teams identity.

---

## Architecture Overview

The app is built on the Rocket.Chat Apps Engine and uses the following components:

| Component | Purpose |
|-----------|---------|
| **OAuth2 Authentication** | Handles delegated and app-level token flows against Microsoft Entra ID |
| **Microsoft Graph API** | All read/write operations — messages, chats, members, subscriptions |
| **Webhook Subscriptions** | Receives real-time notifications from Teams via Microsoft Graph change notifications |
| **Scheduled Jobs** | Auto-renews tokens and subscriptions, cleans up stale data |
| **Slash Commands** | User-facing commands for login, setup, status, and management |
| **UI Action Buttons** | Context menu buttons for adding Teams users and viewing members |
| **Persistence Layer** | Stores user mappings, room mappings, message mappings, and token data |
Loading
Loading