Technical docs

Connect an AI Teammate to Microsoft Teams

Overview

This reference explains how to connect one Alloy AI Teammate to Microsoft Teams through an Azure Bot. Use it when a customer wants to message an AI Teammate from Teams.

Requirements

  • An Alloy AI Teammate already exists.
  • A Microsoft Azure administrator can create and configure an Azure Bot resource.
  • A Microsoft Teams administrator can upload or approve custom apps for the tenant.
  • To deliver generated non-inline files in Teams channels, the bot app registration must have the Microsoft Graph

`Files.ReadWrite.All` application permission with tenant-wide admin consent. This permission allows the application to read and write files across all site collections in the tenant, so the customer must approve that access under its security policy.

  • Alloy automatically creates and maintains a default workflow for each AI Teammate. A missing default workflow is

a rare exception, usually caused by a failed setup, migration, or data issue. Teams messages can be saved before the workflow replies, but the AI will not respond until the sender is approved or enabled and the default workflow is present and runnable.

1. Open the MS Teams tab in Alloy

  1. Open the AI Teammate detail page in Alloy.
  2. Open the `MS Teams` tab.
  3. Copy the `Messaging endpoint`. It has this shape:

```text https://{api-domain}/webhooks/msteams/messages/{organizationId}/{employeeId} ```

Alloy generates this endpoint from the organization and AI Teammate. The same tab is also where the Azure Bot credentials are saved and where the Teams app package is downloaded after connection.

2. Create an Azure Bot

  1. In Microsoft Azure, open Marketplace and create an `Azure Bot`.
  2. Choose the bot name and tenant/resource settings required by the customer's Azure policy.
  3. When Azure asks for a Microsoft App ID, create a new Microsoft App ID unless the customer already has a

dedicated app registration for this bot.

  1. Finish creating the bot resource.

The Azure administrator performs this step. Alloy does not create Azure resources automatically.

3. Grant Microsoft Graph access for channel files

Generated non-inline files in Teams channels are uploaded to the channel's SharePoint-backed Files folder through Microsoft Graph. Configure this permission on the same Microsoft Entra app registration that supplies the Azure Bot Microsoft App ID:

  1. In the Microsoft Entra admin center, open `App registrations` and select the bot app registration.
  2. Open `API permissions` -> `Add a permission` -> `Microsoft Graph`.
  3. Select `Application permissions`, not `Delegated permissions`.
  4. Add `Files.ReadWrite.All`.
  5. Ask an authorized tenant administrator to select `Grant admin consent` for the tenant.
  6. Confirm that the permission is displayed as:

```text Files.ReadWrite.All Application Granted for the tenant ```

`Files.ReadWrite.All` is not a Teams manifest permission and must not be added to `manifest.json`. It is an Entra application permission used by Alloy's app-only Microsoft Graph token flow. It permits the app to read, create, update, and delete files in all site collections without a signed-in user and therefore requires explicit tenant administrator approval. See:

  • <https://learn.microsoft.com/graph/permissions-reference#filesreadwriteall>
  • <https://learn.microsoft.com/entra/identity-platform/quickstart-configure-app-access-web-apis>

The bot can still exchange text and supported inline images through Bot Framework without this Graph permission. Generated non-inline channel files require it. The current channel-file flow also requires the app tenant ID in Alloy, so a single-tenant app registration is recommended when channel file delivery is required.

4. Configure the Azure Bot endpoint

  1. Open the Azure Bot resource.
  2. Go to `Settings` -> `Configuration`.
  3. Paste the Alloy `Messaging endpoint` into `Messaging endpoint`.
  4. Keep the bot type aligned with the app registration:
  5. `Single Tenant` requires an App Tenant ID in Alloy.
  6. Multi-tenant bots can leave the tenant ID empty in Alloy.
  7. Save the Azure Bot configuration.

5. Copy Azure credentials into Alloy

In the Azure Bot configuration, copy:

  • `Microsoft App ID`
  • `App Tenant ID` when the bot is single-tenant

Then create a client secret for the app registration:

  1. Open the app registration or the `Manage Password` / client secret flow from the Azure Bot page.
  2. Create a new client secret.
  3. Copy the secret value immediately. Azure only shows it once.

Back in Alloy:

  1. Open the same AI Teammate `MS Teams` tab.
  2. Click `Connect`.
  3. Paste:
  4. `Microsoft App ID` into the app ID field.
  5. The client secret into the app password/client secret field.
  6. `App Tenant ID` into the tenant field when applicable.
  7. Save the connection.

Alloy stores the app ID and tenant ID for display. It does not return the app password through the read API.

6. Enable the Teams channel in Azure

In the Azure Bot resource:

  1. Open `Channels`.
  2. Add or enable the `Microsoft Teams` channel.
  3. Accept the channel terms and save.

Without the Teams channel, the bot can exist in Azure but will not receive Teams messages.

7. Download and upload the Teams app package

After the Alloy connection is saved:

  1. In Alloy, open the AI Teammate `MS Teams` tab.
  2. Download the `Teams app package`.
  3. In Microsoft Teams, open `Manage your apps`.
  4. Choose `Upload app`.
  5. Upload the ZIP package from Alloy.
  6. Add the uploaded app to the required chat, group chat, team, or tenant app catalog according to the

customer's Teams policy.

  1. Confirm the requested permissions and add the app.

The package contains a generated Teams manifest plus icons. The manifest uses schema version `1.25`, uses the AI Teammate name and description, supports personal, team, and group chat scopes, declares tier-1 channel features, enables bot file support, and points Teams to the Azure Bot app ID.

8. Enable Teams chats in Alloy

When the bot sees a personal chat, channel, or group message, Alloy creates or reuses a channel-chat record. New records are disabled by default. Enable a chat before allowing the bot to operate there.

Use the AI Teammate `MS Teams` tab or the API to enable or disable entries in the unified `Microsoft Teams chats` list. Personal chats always count as directly addressed. Channels and group chats also require a bot mention or a reply in a thread whose root addressed the bot.

Until a chat is enabled, a directly addressed message receives a static notice that the chat is not enabled. The workflow does not run.

Runtime behavior

  • Teams webhook route:

`POST /webhooks/msteams/messages/{organizationId}/{employeeId}`

  • AI Teammate Teams settings:
  • `GET /api/organizations/{orgId}/employees/{employeeId}/msteams`
  • `POST /api/organizations/{orgId}/employees/{employeeId}/msteams`
  • `DELETE /api/organizations/{orgId}/employees/{employeeId}/msteams`
  • Teams app package:

`GET /api/organizations/{orgId}/employees/{employeeId}/msteams/package`

  • The generated package manifest uses the deployment's configured backend brand name as `developer.name`; the default is `Alloy`.
  • Employee name and description determine the app display name and description. The current schema `1.25` manifest enables file support and tier-1 channel features and does not include a `packageName` field.
  • Known Teams chats:
  • `GET /api/organizations/{orgId}/employees/{employeeId}/msteams/chats`
  • `PUT /api/organizations/{orgId}/employees/{employeeId}/msteams/chats/{chatId}/status`
  • use the internal `employee_channel_chat_id` returned by the list as `chatId`

Inbound Teams activities are accepted only when the employee has Teams credentials configured. Alloy ignores non-message activities, duplicate deliveries, and empty messages without downloadable attachments.

After a Teams chat is enabled, Alloy downloads accepted attachments, stores the conversation and message, strips the bot mention from the prompt text, captures Teams routing metadata for replies, and starts the AI Teammate workflow only when:

  • shared conversations address the bot with a mention, or reply inside a thread whose root addressed the bot; if a reply `<at>`-mentions a different bot, the owning bot does not re-engage and the mentioned bot answers
  • automation is enabled for the conversation
  • the organization has available tokens
  • the AI Teammate default workflow is present and has a starting step

When the personal contact is not approved or the Teams channel/group is disabled, a directly addressed message receives:

`This chat isn't enabled for this AI employee yet. Please ask your {brand} administrator to enable it in the employee's channel settings.`

Personal chats always count as directly addressed. Channels and group chats receive the notice only for an explicit bot mention. The disabled gate retains the channel-chat registration but runs before attachment download, conversation/message persistence, and workflow creation.

Attachments are capped at `10` files, `10 MB` per file, and `30 MB` total per inbound message. Image attachments can be forwarded into the workflow input. Non-image attachments can be saved with the message but are not passed into the AI input payload.

During AI reply generation, Alloy sends a best-effort Bot Framework typing activity into the Teams conversation using stored Teams routing metadata.

Generated reply attachments are delivered by Teams conversation scope:

  • Attachment-only replies are supported.
  • PNG, JPEG, and GIF files can be sent inline while the estimated activity remains within the `90 KB` Teams activity budget.
  • Personal chats use a separate file-consent card for each non-inline file. If the recipient accepts, Alloy uploads the file and posts a Teams file-info activity. If the recipient declines, Alloy posts `File upload canceled: {name}`.
  • Teams channels upload non-inline files to the channel's SharePoint-backed Files folder through Microsoft Graph and append a `Files:` link list to the reply.
  • Group chats do not currently deliver generated files. If the reply also contains text, the text can still be sent.
  • A channel upload or delivery-preparation failure marks the Alloy message as `failed`. Personal consent uploads track their own pending, uploading, uploaded, declined, or failed state.

Troubleshooting

  • If Azure rejects messages, confirm the Azure Bot `Messaging endpoint` exactly matches the Alloy endpoint.
  • If Teams cannot find the app, confirm the ZIP package was uploaded to the correct Teams tenant or app catalog.
  • If Teams returns the disabled-chat notice instead of an AI answer, enable the relevant entry in `Microsoft Teams chats` on the AI Teammate `MS Teams` tab.
  • If messages reach Alloy but still do not run the AI after enablement:
  • for channels and groups, confirm the message mentioned the bot or is in a thread whose root addressed the bot
  • if the message mentions a different bot, the original bot yields to the mentioned one
  • confirm the teammate default workflow is present and runnable; a missing default workflow is a rare setup or data issue
  • If replies fail in a single-tenant setup, confirm the tenant ID in Alloy matches the Azure app registration.
  • If channel text replies work but generated files fail with a Graph authorization error, confirm that the bot app

registration has the `Files.ReadWrite.All` Microsoft Graph application permission, tenant-wide admin consent, and the correct app tenant ID saved in Alloy.

  • If a personal generated file is not delivered, confirm the recipient accepted its Teams file-consent card. A declined file is canceled, and an upload failure is recorded separately from the original consent activity.
  • Generated-file delivery is not available in group chats.
  • If the app package cannot be downloaded, confirm the AI Teammate has a saved Microsoft App ID.

Start building your AI team