> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abundly.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Microsoft Teams

> Connect your agent to Microsoft Teams so it appears as its own named bot

Your agent can communicate with you and your team through Microsoft Teams, appearing as its own named bot. In channels, users @mention the bot to start a conversation; follow-up replies in the same thread keep flowing without needing to @mention again. In DMs and group chats every message reaches the bot directly.

## Example use cases

* "@Releaser time to cut a new release" — triggers your deployment agent directly in a channel
* "@Researcher summarise everything we know about Acme Corp" — kicks off a research agent from Teams
* "@Standup post a daily standup summary to the Engineering channel every morning"

## Prerequisites

* Microsoft Teams with Developer Portal access
* Microsoft Entra admin center access (admin role, for the client secret and API permissions)
* Microsoft Teams Admin Center access (Teams administrator role)
* The Abundly agent you want to connect

## How to connect

The setup takes about 15–20 minutes across the Developer Portal, Microsoft Entra admin center, and Teams Admin Center.

<Steps>
  <Step title="Create the bot and a client secret">
    1. In Microsoft Teams, open the **Developer Portal** app (search for it in Apps)
    2. In the top bar, go to **Tools → Bots**, click **+ New Bot**, give it the same name as your agent (e.g. "Releaser"), and click **Add** — you're taken straight to the bot's **Configure** page
    3. Set the **Endpoint address** to the messaging endpoint URL shown in Abundly (format: `https://your-domain/api/ms-teams/bot/YOUR-AGENT-ID`) and click **Save**
    4. Go to **Client secrets** (in the bot's left-hand menu), click **Add a client secret for your bot**, and confirm
    5. **Copy the secret value immediately** — it will not be shown again. You'll paste this into Abundly's **Bot client secret** field

    <Note>
      Creating the bot here automatically creates a matching app registration in Microsoft Entra; the client secret you just made is stored on that registration. You'll grant Graph API permissions on the same registration in the next step, where you'll also pick up the Bot ID and Tenant ID with one-click copy buttons.
    </Note>
  </Step>

  <Step title="Grant Graph permissions and grab IDs in Microsoft Entra">
    1. Go to [entra.microsoft.com](https://entra.microsoft.com) and navigate to **Entra ID → App registrations**
    2. Find the app registration that was automatically created — it will have the same name as your bot — and click it to open the **Overview** page
    3. From the Overview page, copy:

       * **Application (client) ID** — this is your **Bot ID** (paste into Abundly's **Bot ID** field)
       * **Directory (tenant) ID** — this is your **Tenant ID** (paste into Abundly's **Tenant ID** field)

       Both fields have one-click copy buttons next to them — much easier than hunting these down elsewhere.
    4. Go to **API permissions → Add a permission → Microsoft Graph → Application permissions** and add:
       * `Team.ReadBasic.All`
       * `Channel.ReadBasic.All`
       * `ChannelMessage.Read.All`
       * `Chat.Read.All`
       * `User.Read.All`
    5. Click **Grant admin consent** and confirm

    <Note>
      Microsoft Entra ID is the new name for Azure Active Directory. If you prefer the Azure Portal, the same settings live under **Microsoft Entra ID → App registrations** at [portal.azure.com](https://portal.azure.com).
    </Note>
  </Step>

  <Step title="Enter credentials in Abundly">
    In your agent's settings, open the **Microsoft Teams** integration panel and enter:

    | Field                 | Where to find it                    |
    | --------------------- | ----------------------------------- |
    | **Bot ID**            | Application (client) ID from step 2 |
    | **Bot client secret** | Client secret from step 1           |
    | **Tenant ID**         | Directory (tenant) ID from step 2   |

    Click **Save**.
  </Step>

  <Step title="Create and publish the Teams app">
    1. Back in the Developer Portal, go to **Apps → New app** and give it any name (the manifest you paste below will overwrite name, description, bot, and scopes anyway). You'll land on the new app's **Basic information** page; copy the **App ID** shown at the top — you'll need it in step 3.
    2. Go to **Branding** and upload icons if desired (or skip — Teams shows a generic placeholder). Icons are binary uploads, not part of the JSON manifest, so this is the one thing the manifest paste can't set for you.
    3. Go to **App package editor** and replace the manifest with one of:
       * The **pre-filled manifest** in Abundly's Microsoft Teams integration panel (after credentials are saved, scroll to *App manifest* → *Copy manifest*) — this is already populated with your agent name, description, and Bot ID. **Before pasting, replace `REPLACE-WITH-TEAMS-APP-ID-FROM-DEV-PORTAL` with the App ID you copied in step 1.** Teams locks the app `id` at creation, so the paste fails if the manifest's `id` doesn't match.
       * The reference template below, substituting the placeholder values yourself:

    ```json Manifest template theme={null}
    {
      "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.16/MicrosoftTeams.schema.json",
      "version": "1.0.0",
      "manifestVersion": "1.16",
      "id": "YOUR-TEAMS-APP-GUID",
      "name": {
        "short": "YOUR-AGENT-NAME",
        "full": "YOUR-AGENT-NAME"
      },
      "developer": {
        "name": "YOUR-COMPANY-NAME",
        "websiteUrl": "https://your-company.com",
        "privacyUrl": "https://your-company.com/privacy",
        "termsOfUseUrl": "https://your-company.com/terms"
      },
      "description": {
        "short": "Abundly agent bot",
        "full": "Abundly agent bot for Microsoft Teams"
      },
      "icons": {
        "outline": "outline.png",
        "color": "color.png"
      },
      "accentColor": "#ffffff",
      "bots": [
        {
          "botId": "YOUR-BOT-ID-GUID",
          "scopes": ["personal", "team", "groupChat"],
          "isNotificationOnly": false,
          "supportsFiles": false
        }
      ],
      "webApplicationInfo": {
        "id": "YOUR-BOT-ID-GUID",
        "resource": "api://botid-YOUR-BOT-ID-GUID"
      },
      "authorization": {
        "permissions": {
          "resourceSpecific": [
            { "type": "Application", "name": "ChannelMessage.Read.Group" }
          ]
        }
      },
      "validDomains": []
    }
    ```

    The three GUIDs play **two distinct roles**:

    * `id` is the **Teams app's** own identity in your org's app catalog. It is auto-generated when you create the app shell (step 1) and **locked** thereafter — pasting a manifest with a different `id` triggers a "Property 'id' cannot be changed in the manifest" error. Use the App ID you copied in step 1.
    * `bots[0].botId` and `webApplicationInfo.id` must both equal your **Application (client) ID** from the Entra app registration overview (step 2). Teams ties RSC consent to `webApplicationInfo.id`, so it has to match the registration that owns the bot.

    <Note>
      **What `ChannelMessage.Read.Group` does.** This is a [Resource-Specific Consent (RSC)](https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent) permission, granted by a team owner at install time. Without it, Teams only delivers @mentions to the bot — so a user who replies in a thread without re-mentioning the bot would never reach the agent. With it, every channel message reaches our webhook, and Abundly only acts on @mentions or messages that continue an existing thread the user already opened with the bot.
    </Note>

    <Note>
      We currently recommend `manifestVersion: "1.16"`. Versions 1.25 and higher may require additional properties that are outside the scope of this guide. RSC requires `1.12` or higher.
    </Note>

    4. Click **Save** in the App package editor, then click **Update app package** when prompted (or via the banner that says "*Your changes have been saved locally, but not yet updated in the app package.*"). Without this step the app still uses the old manifest.
    5. Go to **Publish → Publish to org** and click **Get Started** (the publish action)

    The status should show **Published to org** or **Submitted (awaiting admin approval)**.

    <Note>
      The Developer Portal also offers **Publish → App validation**, but that's a preflight aimed at apps being submitted to AppSource (the public Microsoft Teams Store). For internal org publishing it's unnecessary — and it tends to surface scary "Failure" labels that are actually validator-side flake or store-only naming rules ("Short name should not contain 'Microsoft'", etc.). Skip it.
    </Note>

    <Note>
      **Icon requirements are strict.** Teams' validator rejects anything that doesn't match exactly:

      * **Color icon**: 192×192 PNG, full color
      * **Outline icon**: 32×32 PNG with **only pure white (`#FFFFFF`) and fully transparent pixels** — no anti-aliasing, no near-white. If you see "Outline icon is not transparent. It's Alpha,R,G,B: …", your export has soft edges; re-export with no smoothing.
    </Note>
  </Step>

  <Step title="Approve the app in Teams Admin Center">
    1. Go to [admin.teams.microsoft.com](https://admin.teams.microsoft.com)
    2. Navigate to **Teams apps → Manage apps** and search for your app name
    3. If the status shows **Blocked** (or pending approval), click on the app and click **Publish** to make it available org-wide

    <Note>
      Admin approval changes can take up to 30 minutes to propagate across the Microsoft Teams client.
    </Note>
  </Step>

  <Step title="Install the bot in a team">
    1. In Microsoft Teams, click **Apps** in the left rail
    2. Look under **Built for your org** (or **Added by your org**) and find your bot
    3. Click the bot, choose **Add to a team**, pick the team and channel, and confirm
    4. The team owner must accept the **ChannelMessage.Read.Group** permission when prompted — this is what lets the bot see follow-up replies in a thread without re-mention

    <Note>
      Allow up to 30 minutes after publishing for the app to appear under **Built for your org**. Try a hard refresh (or sign out / sign in) if it's slow to surface.
    </Note>

    <Note>
      Teams Admin Center's **Manage apps → Install** action only manages org-level availability — it does not actually install the bot into a team. Use the in-client **Apps → Built for your org** flow above to install into a team.
    </Note>

    <Check>
      The bot is now live. Users can @mention it in a channel to start a conversation; subsequent replies in that thread continue without needing to @mention again.
    </Check>
  </Step>
</Steps>

## How conversations work

Microsoft Teams is a full remote-chat surface — on par with Slack. Every Teams conversation maps to a persistent Abundly chat, giving the agent the same instructions, memory, and capabilities as it has in the portal.

* **Channel @mentions** start a new chat — the agent replies in the thread with full context.
* **Follow-up replies** in a thread the agent already joined continue the same chat without needing to @mention again.
* **Group chats** map to persistent chats — every message reaches the agent directly.
* **1:1 personal chats (DMs)** also map to persistent chats — the agent replies naturally.

These conversations appear in the sidebar alongside portal chats and can be filtered using the chat filter pill (e.g. *Hide remote chats*). Handoffs between Teams and the portal are seamless.

<Tip>
  Teams-originated chats are marked as "remote" and are read-only in the portal — reply from Teams to keep the thread in the agent's working context.
</Tip>

## Updating an existing install

Whenever you change the manifest (bumped `version`, added permissions, etc.), Teams will not automatically apply the change to teams that already have the bot installed — and the team owner is not re-prompted to consent to any new permissions. To apply the update:

1. Bump the manifest `version` in the Developer Portal (e.g. `1.0.0` → `1.0.1`) and re-publish the app to your org
2. In each team that has the bot installed: **Manage team → Apps → trash icon next to the bot → Remove**
3. Re-add the bot following step 6 above

Removing and re-adding (rather than the in-place "Update" option, which often does not re-trigger the consent dialog) is the most reliable way to ensure new permissions like `ChannelMessage.Read.Group` are actually granted.

## Things to know

<Note>
  **One app per agent** — each agent requires its own Microsoft Teams app and bot. There is no way to have multiple bot identities within a single Teams app.
</Note>

<Warning>
  **Secret expiry** — client secrets expire. Note the expiry date and rotate the secret in the Developer Portal (**Tools → Bots → your bot → Client secrets**) or Microsoft Entra (**your bot's app registration → Certificates & secrets**) and update it in Abundly before it expires.
</Warning>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Bot isn't responding to @mentions">
    * **Add the bot to the channel** — registering the bot in Entra is not enough; it must be installed into the Teams roster (step 6)
    * **Check the endpoint URL** — verify the messaging endpoint in the Developer Portal matches the URL shown in Abundly (`https://your-domain/api/ms-teams/bot/YOUR-AGENT-ID`)
    * **Verify credentials** — confirm the Bot ID, Bot client secret, and Tenant ID are entered correctly in Abundly
  </Accordion>

  <Accordion title="Bot replies to the first @mention but ignores follow-up messages in the thread">
    This is the symptom of `ChannelMessage.Read.Group` not being granted in the team where the bot is installed. The Bot Framework webhook only fires for @mentions in channels by default — the RSC permission is what unlocks delivery for in-thread replies.

    Verify and re-grant:

    1. In the team: **Manage team → Apps → click the bot row**. Look for **ChannelMessage.Read.Group (Application, Resource specific consent)** under Permissions.
    2. If it's missing, the consent never took. The most reliable fix is to bump the manifest `version`, re-publish, then **remove the bot from the team and re-add it** (see [Updating an existing install](#updating-an-existing-install) above). The in-place "Update" button often does not re-trigger the consent dialog.
    3. RSC `ChannelMessage.Read.Group` only delivers in **standard** channels. Private and shared channels use separate RSC permissions and do not deliver in-thread follow-ups via this permission.
    4. The team must have **owner** consent — only team owners see the consent prompt during install, and only owners can grant RSC.
    5. If everything looks granted but messages still don't arrive, give it 10–30 minutes — Microsoft has documented occasional propagation delays for RSC delivery.
  </Accordion>

  <Accordion title="&#x22;BotNotInConversationRoster&#x22; error">
    The bot has not been installed into the team. Complete step 6 to add it to the roster.
  </Accordion>

  <Accordion title="Can't find the bot under 'Built for your org'">
    * **Wait** — propagation from publish to visibility in the Teams client typically takes 5–30 minutes
    * Confirm the app is approved in the Admin Center (step 5) and its status is **Unblocked / Allowed**, not **Blocked**
    * Try a hard refresh in the Teams web client, or sign out/sign in on desktop
    * Try the Teams web client at [teams.microsoft.com](https://teams.microsoft.com) — the desktop client caches aggressively
  </Accordion>

  <Accordion title="&#x22;Permissions needed&#x22; warning when adding the bot">
    Go to Microsoft Teams Admin Center → **Teams apps → Permission policies → Global (Org-wide default)** and ensure custom apps are set to **Allow**. If you've just made this change, try a hard refresh in your browser before retrying.
  </Accordion>

  <Accordion title="Manifest validation errors">
    * Ensure `manifestVersion` is `"1.16"` — do not use 1.25 or higher
    * Ensure all fields in `developer` and `description` are filled in — empty `{}` objects will fail validation
    * Ensure the `id` field is a plain GUID with no extra characters or braces
    * **`Property 'id' cannot be changed in the manifest`** — Teams locks the Teams app `id` at app creation. The pasted manifest's `id` must equal the App ID shown on your app's **Basic information** page in the Developer Portal. The pre-filled manifest from Abundly leaves a `REPLACE-WITH-TEAMS-APP-ID-FROM-DEV-PORTAL` placeholder for exactly this reason — replace it with the real App ID before pasting.
    * **`webApplicationInfo.appId` required** error: this means RSC permissions are declared but `webApplicationInfo` is missing or its `id` is empty. Set `webApplicationInfo.id` to your **Bot ID** (same GUID as `bots[0].botId`).
  </Accordion>
</AccordionGroup>
