Skip to main content
After this guide, people in your Microsoft 365 tenant can message your agent in Teams, mention it in a team channel, or talk to it in a group chat, and it answers where it was addressed. Teams is connected in the admin dashboard only. Lua’s shared bot needs nothing on Microsoft’s side beyond installing an app; bringing your own Azure Bot gives the agent your own identity and branding and unlocks the Microsoft Graph features below. Verified against lua-cli 3.38.0.

What you get

  • A personal chat with the agent for each person in the tenant, with files, pasted images, and cards.
  • Group chats and team channels where the agent sits with your team, answers when it is @mentioned, and keeps the rest of the conversation as context.
  • Speakers named in the transcript, so the agent knows who said what.
  • Your agent code sees the room: who is in it, who is speaking, and what the chat lets the agent do.
  • Proactive messages to one person or to a whole group conversation the agent is already in.

Two ways to connect

Everything the Bot Framework delivers works on both bots: mentions, replies, the list of people in a chat through the bot service, files sent in a direct message, pasted images, and cards. Four things go through Microsoft Graph and work only with your own Azure Bot:
  • The chat topic, so a renamed chat keeps its name.
  • The history from before the bot joined.
  • Reading which permissions a chat granted, so the agent can say what it is missing.
  • Files attached with the paperclip or dragged into a group chat or channel.
The reason is the app registration. Graph reads happen with the bot’s own app identity, and the shared bot’s registration lives in Lua’s tenant, so nothing in your tenant can be granted to it. With the shared bot the agent is told nothing about its permissions and the channel card in the admin dashboard shows Graph unavailable. Choose the shared bot to get started quickly in personal and group chats; choose your own bot when you want your branding, the chat topic, history, or files in groups. Before you begin
  • A Microsoft 365 tenant, and a Teams admin who can allow custom app uploads or approve an app for the organization.
  • For your own bot: an Azure subscription; see the bring-your-own guide for the values to collect.
  • An agent with a promoted production version; see Release an agent.
1

Dashboard: add the channel

In the admin dashboard open Agents, select the agent, select + in the Channels section of its Overview tab, and choose Microsoft Teams in Connect a channel. Choose Use Lua’s Teams bot or Bring your own Azure Bot.
2

Connect the bot

In the Add Lua to Microsoft Teams dialog select Download app package (.zip). Upload it in Teams under Apps › Manage your apps › Upload a custom app, or have your Teams admin publish it to the organization so everyone can add it. Then select Open connect link. It opens a chat with the bot and prefills a one-time connect:<token> message; send it. The bot replies Connected to agent: <agentId> and your tenant is bound to this agent. The token is single-use and expires after 24 hours; selecting the shared-bot option again issues a fresh one.
3

Add the bot where you want it

A personal chat needs nothing more: anyone in the tenant can open the app and write to it. To use the agent in a group chat or a team, open Apps in the Teams sidebar, find the app, open the menu next to Add and choose Add to a chat or Add to a team, then pick the chat or team. Each one is consented separately by the person who adds it.The bot cannot be added to an existing one-to-one chat between two people; that is a Teams rule. Add a third person to turn it into a group chat, or start a new group chat.
4

Re-add the bot after a new app version

A chat or team grants its permissions at the moment the bot is added, and keeps that grant afterwards. When you install a new version of the app, remove the bot and add it again in each group chat and each team, or it goes on running with the old grant. A version bump has been seen to reset a team’s grant until the app is re-added.
5

Verify

Send the bot a direct message with hello; it answers in the chat. Mention it in a group chat or a team channel it was added to; it answers there. lua channels list shows a TEAMS entry.

What works where

The rendering matrix has what every response component becomes on Teams. Inbound attachments are capped at 25 MB in every scope; a larger file is declined and the agent tells the person. Proactive sends. Channels.send({ channel: 'teams', to: { userId } }) reaches someone who has written to the agent, and to: { conversationId } reaches a group chat or channel the bot is already in, where everyone sees it. There is no way to start a group chat from code. When the agent already has a shared conversation for that chat the message is recorded there and persisted is true; otherwise it is delivered but not recorded, and persisted is false. user.send() reaches a person whose most recent conversation with the agent is a personal Teams chat; it never picks a group chat or channel.

Group chats and team channels

A personal chat is a private conversation between one person and the agent. A group chat is one shared conversation for everyone in it, and a team channel is one shared conversation per reply thread: the agent keeps a single transcript, knows who said what, and sees the people in the chat.
  • The agent answers when it is addressed. An @mention of the bot, or a tap on a card the agent posted, gets a reply in the chat. Everything else people say to each other is kept in the shared transcript without a reply, so the agent has the context when it is next mentioned.
  • Speakers are named. Each message reaches the agent with the sender’s name, and the agent’s own replies are attributed to it, so “what did Alice say?” works.
  • Rooms are named after the chat. A group chat takes its topic, or the members’ names when it has no topic. A channel thread is titled Team › Channel · opening words.
  • Your code sees the room. In a tool, a condition, or a processor, Lua.request.conversation lists the participants, marks the current speaker, carries the chat’s externalId to pass as to: { conversationId } on a later Channels.send, and reports access with canReadAllMessages, canReadMembers, canReadFiles, and the names of anything missing.
  • Personal memory stays personal. Nothing a person told the agent in a direct message is brought into a group chat.
  • Edits and deletes follow Teams. When someone edits a message, the stored copy is replaced by (edited) <new text>; when someone deletes it, it stays in the transcript as [message deleted], with its sender and time; a message brought back with Undo gets its text back (files it had stay removed). This applies in personal chats, group chats and channels, to the agent’s memory, the admin dashboard, and your org memory. An edit never gets a reply. The agent’s own replies, messages sent before 29 September 2026, a long conversation’s summary notes and files already copied are not changed.
  • The past is not lost. When the bot is added to a chat, or first mentioned in a channel thread, the newest 100 text messages sent before that are read once into the shared transcript, with the right names and times. This needs ChatMessage.Read.Chat or ChannelMessage.Read.Group and your own Azure Bot.
  • The agent knows what it lacks. When a chat did not grant something, the agent is told which permission is missing and who fixes it, so it says “I only see messages that mention me here” instead of guessing. The dashboard’s Group chats tab shows the same as a Limited permissions label with the missing names. Reading the grant is itself a Graph feature, so with Lua’s shared bot the agent is told nothing about its permissions.
  • The dashboard shows the room. Group chats have their own tab next to Conversations, with the transcript labelled by name. The tab is read-only; you cannot write into a group chat from it. A chat the bot was removed from shows Bot removed; disconnecting Teams in the dashboard archives every chat of that connection as Disconnected. Transcripts are kept, and a chat reopens with its memory when the bot is back and mentioned.

Permissions

Teams only delivers messages that mention the bot unless your app asks for more. The app package the admin dashboard downloads declares seven resource-specific consent permissions, application type. Whoever adds the bot to a chat or team consents for that chat or team, so no tenant administrator is involved.
  • Group chats: ChatMessage.Read.Chat, ChatMember.Read.Chat, ChatSettings.Read.Chat, TeamsAppInstallation.Read.Chat
  • Team channels: ChannelMessage.Read.Group, TeamMember.Read.Group, TeamsAppInstallation.Read.Group
The two TeamsAppInstallation permissions are what let Lua read which permissions the chat granted, so the agent can say what it is missing. One further permission is optional, tenant-wide, and not part of the manifest: Files.Read.All, a read-only Microsoft Graph application permission a Microsoft 365 administrator grants once on the app registration behind your own Azure Bot. It is what lets the agent open files people attach in group chats and channels. Teams permissions explains every one of them, with the exact steps for the administrator who approves them.

Limits

  • The Microsoft Graph features need your own Azure Bot; see Two ways to connect.
  • A bot cannot be added to an existing one-to-one chat between two people. Add a third person, or start a new group chat.
  • There is no way to create a group chat from code. A proactive send into a group only works for a chat the bot is already in.
  • Per-user agent overrides and link commands do not apply in group chats and team channels.
  • The Group chats tab in the admin dashboard is read-only.
  • One bot and tenant pair per agent. A second connection for the same App ID and tenant is refused with A Teams channel for this bot and tenant is already connected, and a tenant already bound to the shared bot answers This Microsoft Teams tenant is already connected to an agent.
  • The shared bot’s connect token: single-use, 24 hours.
  • Attachments: 25 MB.
  • Proactive sends are warm-only; there is no cold start.

Troubleshooting

The bot received a message from a tenant with no active channel. For the shared bot, send the connect: message from the admin dashboard link; for your own bot, check that the tenant ID you entered is the tenant the message came from.
The link is older than 24 hours or was already used. Select the shared-bot option again in the admin dashboard to get a new one.
The bot was added to the chat before the app carried the group-chat permissions, or the app version changed after it was added. Remove the bot from the chat and add it again; the grant is taken at install time. See Teams permissions.
That is expected. A team channel has no shared conversation until someone posts: a room opens per reply thread when the first message in that thread arrives. Post in a channel, mention the bot, and the thread appears in the Group chats tab.
Teams does not deliver files attached with the paperclip or dragged into a group chat or channel to bots. Lua reads them through Microsoft Graph instead, which needs Files.Read.All granted by a Microsoft 365 administrator on the bot’s app registration (how). With Lua’s shared bot this permission cannot be granted in your tenant; bring your own Azure Bot. Until then, ask the person to send the file in a direct message; pasted images work everywhere.
Reading the topic needs ChatSettings.Read.Chat and a Graph read, so it works only with your own Azure Bot. If you have one, the chat was added before the app carried that permission: remove the bot and add it again. Until then the room is named after its members.
That chat did not grant one of the permissions the app asks for, and the label lists which. The agent is told the same thing, so it explains the gap instead of guessing. For a chat permission, the person who added the app removes and re-adds it; for Files.Read.All, a Microsoft 365 administrator grants it once.

Next steps

Bring your own Azure Bot

Register the bot in Azure, point it at Lua, and build the Teams app.

Teams permissions

What each permission is for, who consents, and how to apply a new version.

Send proactive messages

Follow up with a person or a whole group conversation.

Channels reference

Channels.send, conversationId, and delivery status.

Response formatting

What each component becomes as an Adaptive Card.