orbotodocs
Integrations

Chat bot for Slack, Microsoft Teams and Discord

Connect your instance to Slack, Microsoft Teams or Discord: agent notices land in your channels, and your team starts, claims, closes and asks from the chat.

Added in v0.215.0 The chat bot connects your orboto instance to the chat tool your team already uses. It posts what orboto would otherwise show in the inbox or send by mail - a ticket is ready for an agent, an agent finished, an agent hit an error, a capacity notice - into the channels you choose, with one thread per ticket. Your team answers in that thread, and starts, claims, closes or stops work with short commands. Every command runs as the orboto user the chat account is linked to, with that user's permissions and no more.

This is different from chat and webhook notifications. Those deliver a person's own notifications to a channel through an incoming webhook, one way. The chat bot is an installed app on your instance: it posts agent notices, listens, and acts for linked users.

What the bot does

Notices. A route (a chat channel assigned to a project) subscribes to any of these kinds:

KindWhen it is posted
Ticket readyA ticket becomes work for an agent: assigned to it, labelled for it, unblocked, created for it, or it needs a specification. See always-on agents for the wake-up rules behind it.
CompletedAn agent reports a task as done.
ErrorsAn agent reports an error.
CapacityA capacity notice about an agent session or claim (see build capacity).
Wake digestA digest of agent requests that wait because no live session received them, posted at most once an hour or per the route's cooldown, whichever is longer.

The first notice about a ticket opens a thread. Later notices and replies about the same ticket (or agent session) stay in it.

Commands. The same on every platform, as /orboto <command> (Slack and Discord), as a mention of the bot, or in a direct message:

CommandWhat happens
start ACME-12 [--yolo]Hands a start request to the project's control session, which starts the agent on its own machine (see start a project agent). When no control session is running, the request waits in the queue until one declares the project. orboto never starts an agent on the server itself.
stop <session>Asks a running agent session to stop. status shows the short session ids. The session's supervisor ends it on its machine.
status [project]The live agent sessions of the project. In a routed channel the project is known.
claim ACME-12Assigns the ticket to you and moves it to in progress. A specification gate on the ticket still applies and is named in the answer.
close ACME-12 [comment]Closes the ticket, with your comment if you add one.
ask <question>Asks the project's wiki. Without a wiki, or without an AI provider on the instance, you get the start of the project primer instead.
helpLists the commands.

In a channel routed to a project, commands accept that project's tickets only; a ticket of another project is refused with a pointer to the right channel.

Replies. A plain reply in a ticket thread reaches the agent that last posted there, as an info message from you. If a live session has it, it arrives at once; otherwise it waits in the agent's inbox. In Microsoft Teams, mention the bot in your reply, because Teams only passes mentions to a bot.

Before you start

  • You need the system administration permission to connect a platform, and project edit rights on a project to route a channel to it.
  • The instance must be reachable from the internet over HTTPS, because Slack, Microsoft and Discord call your instance. Every URL you have to paste into a platform comes from the connection itself: Admin → Integrations → Chat bot, then the connection's menu, Setup URLs.
  • Discord needs one more thing: the instance keeps one outgoing websocket connection to Discord open so it can read replies in threads. Commands in Discord work without it.
  • Every connection stores its secrets encrypted and never shows them again. To change them later, use Replace credentials in the connection's menu.

Connect Slack

  1. In orboto open Admin → Integrations → Chat bot and choose + Connect, then Slack. Enter a name, the App id and the Signing Secret (both in Slack under Your Apps → your app → Basic Information). If the app is already installed in your workspace, also paste the Bot User OAuth Token (starts with xoxb-). orboto checks the token with Slack and takes the workspace from it.
  2. No app yet? Save the connection with the Signing Secret and the client id and client secret of the app, then open the connection's menu and choose Slack app manifest. In Slack choose Your Apps → Create New App → From a manifest, pick your workspace and paste the manifest. Back in orboto, choose Install in Slack from the connection's menu. Slack sends you back to orboto and the connection turns active.
  3. In Slack, check that Event Subscriptions and the Slash Command /orboto point at the URLs under Setup URLs.
  4. Invite the bot to every channel you want to use: /invite @orboto. The bot only delivers to and hears channels it is a member of.

Existing Slack app: add the im:write scope and reinstall

The bot sends direct messages for private ticket details and private answers, which needs the im:write scope. The manifest includes it. A Slack app created before this scope was part of the manifest has to be reinstalled after you add the scope: Install App → Reinstall to Workspace. Until then the first direct message fails with Slack's missing_scope error.

Connect Microsoft Teams

  1. In Azure, create an Azure Bot with a Microsoft Entra app registration and a client secret.
  2. In orboto choose + Connect → Microsoft Teams and enter the Microsoft App ID and the client secret. For a single-tenant registration, also enter the tenant id.
  3. In Azure, set the bot's messaging endpoint to the Messaging endpoint shown under Setup URLs, add the Microsoft Teams channel, and install the app in your team.
  4. Mention the bot once in a channel, for example @orboto help. That first message tells orboto where to answer. Before it, the bot cannot post into Teams.

Connect Discord

  1. In the Discord Developer Portal create an application with a bot. Under Bot, turn on the Message Content intent.
  2. In orboto choose + Connect → Discord and enter the application id and Public Key (both under General Information), the bot token (under Bot) and your server id. To find the server id, turn on Developer Mode in Discord, right-click the server and choose Copy Server ID.
  3. Paste the Interactions Endpoint URL from Setup URLs into the application under General Information. Discord checks it immediately.
  4. Invite the bot to your server (OAuth2 → URL Generator) with the scopes bot and applications.commands and the permissions Send Messages, Create Public Threads, Send Messages in Threads and Read Message History.
  5. In orboto, open the connection's menu and choose Register the /orboto command.

Connection health and workspace pinning

Each connection shows its state (healthy, waiting for the first event, needs attention, paused, or waiting for the install), the time of the last event and a log of the latest events. Use Pause and Resume to switch a connection off without losing its setup, and Remove connection to delete it. Removing takes its routes, threads, user links and logs with it; the app stays installed on the chat platform until you remove it there.

A connection can be tied to one workspace (a Slack workspace, a Teams tenant or a Discord server). If you leave the workspace empty, the first workspace that sends a correctly signed event is trusted and pinned. That is convenient, but it means whoever reaches the endpoint first with a valid signature wins, so enter the workspace yourself where you can. Each workspace can belong to only one connection.

To move a connection to another workspace, choose Release the pinned workspace in its menu and give a reason. The next workspace that sends a signed event is then trusted and pinned. The release is recorded in the audit log with your reason.

The bot acts only for people it can tie to an orboto account. Each person links once:

  1. Write to the bot - /orboto help, a mention or a direct message.
  2. While your chat account is not linked, the bot answers with a code and nothing else. In Slack and Discord the code is visible to you alone; in Teams it comes in a 1:1 chat.
  3. In orboto open your profile → Chat bot, enter the code and choose Link. The code is valid for 15 minutes by default; admins can set 5 to 60 minutes under Limits.

Linking needs a signed-in browser session, the same as approving an OAuth app. A script with an API key cannot link a chat account. The Chat bot section appears in every profile.

You can revoke your own link in your profile. Admins see every link under Admin → Integrations → Chat bot (pending, linked and revoked) and can revoke any of them with a reason. When an orboto account is deactivated, its links stay for the audit trail and the bot answers that chat account only with "ask an admin"; an admin has to revoke the link before the chat account can be linked again.

Route a channel to a project

Under Admin → Integrations → Chat bot choose + Route a channel. A route has:

  • a project and a connection,
  • the channel id (Slack: the channel details, the id starts with C; Teams: the channel link contains 19:...@thread.tacv2; Discord: with Developer Mode on, right-click the channel and choose Copy Channel ID) and an optional name for the list,
  • the notices the channel gets: ticket ready, completed, errors, capacity, wake digest,
  • the cooldown in minutes (0 to 1440, default 10): within the cooldown, the same kind of notice for the same ticket is held back and appears as "held back" in the delivery log,
  • Post answers to "ask" in the channel (publicAnswers, off by default).

Routing needs project edit rights on that project. Use Send a test message in a route's menu to check the setup; it reports whether the post was sent or the platform's error. Failed posts are retried after 1, 5, 15 and 60 minutes and then stay failed in the delivery log (Recent deliveries), where an admin can retry them.

Privacy

  • Everything runs as the linked user. A command goes through the same checks as the same action in the app. The bot has no account of its own that acts, and each command uses a short-lived credential (60 seconds) for the linked user that is revoked right after the command.
  • The channel is the viewer. Everybody in a channel reads what the bot posts, whether or not they are a project member. For a private ticket, a ticket in a private milestone, or a ticket under a private parent, the channel only gets the ticket key and the kind of notice. The full text goes as a direct message to the linked people who are assigned to the ticket or reported it, who are project members, and who are allowed to read it - and to nobody else.
  • ask answers privately by default, because the answer comes from the asker's own wiki access. In Slack the answer is visible only to you; in Discord and Teams it arrives as a direct message. Turn on Post answers to "ask" in the channel on a route to answer in the channel instead. If a private answer cannot be delivered (the person closed direct messages from the bot), the channel gets a short hint that the answer could not be sent, and the reason stays in the connection's event log.
  • Unlinked users see only the code. Nothing else about your instance is shown to a chat account that is not linked.
  • Audit. Connections, routes and links are audited when they change, and every command is audited as the linked user.

IP allowlist

If your instance restricts access with an IP allowlist, bot commands are exempt. They run from the instance itself as the linked user, in the same way as inbound email, so the chat platform's addresses never have to be on your list. Every other call from the same address is still checked. The exemption is limited to the bot's own short-lived credentials, and each command is recorded in the audit log with its origin, the platform and the chat user. The connection's health states that commands run this way.

Limits

  • Connections per instance: 3 by default (one for each platform fits that). Admins change it under Limits to any value from 1 to 50. It is a limit, not a feature gate: the chat bot is part of every plan, and when the limit is reached a further connection is refused until you raise it or remove one.
  • A connection is unique per platform workspace.
  • The bot only reaches channels it is a member of.
  • Slack resends an event it believes was not answered; orboto acts on each event once.
  • Discord refuses requests with timestamps older than five minutes, the same window Slack documents.
  • Microsoft Teams cannot receive a post before the bot got its first message in the team.

Manage it from the CLI

The same setup is available with orboto chat-bot (the CLI must be signed in as an admin; secrets are read as one JSON object from standard input and never from arguments).

CommandWhat it does
orboto chat-bot connections [--health ID] [--manifest ID]Lists connections, shows one connection's health, or prints the Slack manifest.
orboto chat-bot connections add --platform slack|teams|discord --name N --app-id ID [--workspace ID] [--tenant ID] [--public-key HEX] [--allow ID,ID]Connects a platform.
orboto chat-bot connections set --id ID [--enabled|--disabled] [--name N] [--workspace ID] [--allow ID,ID]Renames, pauses or resumes a connection.
orboto chat-bot connections rotate --id IDReplaces secrets.
orboto chat-bot connections install --id IDPrints the Slack authorize URL for the OAuth install.
orboto chat-bot connections register-commands --id IDRegisters /orboto in a Discord server.
orboto chat-bot connections unpin --id ID --reason "..."Releases the pinned workspace (audited).
orboto chat-bot connections remove --id ID --yesRemoves a connection with its routes, threads and links.
orboto chat-bot routes [--project KEY]Lists routes.
orboto chat-bot routes add --project KEY --connection ID --channel CHANNEL [--channel-name N] [--kinds ticket_ready,complete,error,capacity,wake_digest] [--cooldown 10] [--public-answers]Routes a channel.
orboto chat-bot routes set --project KEY --route ID [--kinds ...] [--cooldown N] [--enabled|--disabled] [--public-answers|--private-answers]Changes a route.
orboto chat-bot routes remove --project KEY --route ID --yesRemoves a route.
orboto chat-bot send-test --project KEY --route IDPosts a test message.
orboto chat-bot links [--mine]Lists linked chat users, or your own.
orboto chat-bot links revoke --id ID [--admin] [--reason "..."]Revokes a link.
orboto chat-bot settings [--max-connections N] [--code-ttl MINUTES]Shows or changes the limits.
orboto chat-bot deliveries [--status failed] and deliveries retry --id IDReads the delivery log and retries a failed post.

Confirming a link code is the one thing the CLI cannot do; it needs the profile page in a browser.

What is not verified live yet

Be aware before you rely on it in production: the first live connection of each platform is still to come. The wire formats - request signatures, the event and command payloads, the message shapes and the direct-message calls - were built and tested against the vendors' documentation using recorded fakes. Not yet exercised against a real workspace are the Slack OAuth install and slash commands, Microsoft Teams with Microsoft's real signing keys and the answer shape when the bot opens a new thread in a channel, and the Discord gateway connection with real signatures. If a platform behaves differently from this page, the connection's health and event log show what arrived and why it was refused; please report it.

On this page