Docs
Bots
A bot binds one Cortex Agent to a chat platform — Slack, Microsoft Teams, Google Chat, or Discord. Mention the bot and the agent's answer streams into a thread. All four platforms are covered below: Slack first, then Teams, then Google Chat, then Discord.
Create a bot
Open the form
Bots → Create bot (owners and admins). You need at least one connection first — bots answer through it.
Name the bot
The @handle people mention in Slack, Teams, Google Chat, or Discord. Lowercase letters, numbers, hyphens, and underscores, starting with a letter or number — e.g.
finance_bot.Pick the connection and agent
Choosing a connection loads its agents from Snowflake; pick the one this bot runs. The binding is one bot to one agent — fixed afterwards (to re-point a bot, create a new one).
Choose platform, transport, and channel access
Pick Slack, Microsoft Teams, Google Chat, or Discordas the platform. For Slack, socket mode is the default and right for most setups — details below. Teams and Google Chat are webhook-only: there is no socket option, and your Gondola instance must be reachable over public HTTPS. Discord is the opposite — it connects outbound to Discord's gateway socket, so no public URL is needed to receive messages. Channel access is optional and Slack-only (see below) — Teams and Google Chat bots always respond in every channel or chat they're installed in.
Create bot
You land on the bot's page, which walks you through the platform setup next — the Slack app setup, Microsoft Teams setup, Google Chat setup, or Discord setup card, depending on the platform you picked.
Set up the Slack app
The Slack app setup card on the bot's page lists every step — about five minutes in your Slack workspace settings.
Create the Slack app
Open api.slack.com/apps → Create New App → From a manifest, pick your workspace, and paste the manifest Gondola generated for the bot. It preconfigures the bot scopes and events, and either enables socket mode or fills in the webhook Request URL, depending on the transport.
Updating an existing app? Scopes added to the manifest after you first created the app (for example,
users:read) must be added manually under OAuth & Permissions, then the app reinstalled to your workspace for the new scopes to take effect.Socket mode only: generate an app-level token
In the Slack app: Basic Information → App-Level Tokens → Generate Token and Scopes, add the
connections:writescope, and copy thexapp-token.Install and copy credentials
Install the app to your workspace and copy the Bot User OAuth Token (
xoxb-). Webhook bots also need the Signing Secret from Basic Information.Paste the credentials into Gondola
Save them in the setup card. Gondola verifies the bot token against Slack before saving, then shows the workspace it connected to and starts the bot. Tokens are stored AES-256-GCM encrypted and never shown again. If the credentials save but the runtime can't start, the card shows a warning with the reason.
Set up Microsoft Teams
Teams connects through a per-bot Azure app registration and bot resource — the same per-customer isolation model Gondola uses for Slack. There is no socket mode for Teams; the Bot Framework pushes activities to Gondola over HTTPS, so your instance must be reachable from the public internet. The Microsoft Teams setup card on the bot's page walks through the same steps below.
Prerequisites
- An Azure AD (Microsoft Entra ID) tenant you can create app registrations in.
- Teams admin rights in that tenant — needed to approve or sideload the app package.
- Your Gondola instance reachable over public HTTPS. The production origin is the webhook base URL.
Create the Gondola bot with platform Teams
In the bot create form, pick Microsoft Teams as the platform. Teams is webhook-only, so the transport is fixed to webhook and channel access is not editable — the bot responds in every channel or chat it's installed in. Note the bot ID from its URL (
/bots/<botId>); you'll use it in the webhook path next.Register the Azure app and bot
The Teams CLI creates the app registration, the Azure Bot resource, and wires the messaging endpoint in one step. Run it from any machine with Node 18+:
shellnpx @microsoft/teams.cli app create \ --endpoint https://<your-gondola-host>/api/teams/events/<botId> npx @microsoft/teams.cli app doctor <appId>
app createprints the App (client) ID, the tenant ID, and prompts you to generate a client secret. Save all three — you'll enter them in Gondola in step 6.Prefer the portal? Create an app registration (Microsoft Entra ID → App registrations → New registration) with a client secret under Certificates & secrets, then an Azure Bot resource (Create a resource → Azure Bot) of type Existing App Registration pointing at it.
Set the messaging endpoint
The Bot Framework sends messages to a single messaging endpoint per bot. Gondola's is:
endpointhttps://<your-gondola-host>/api/teams/events/<botId>
The CLI sets this for you. In the portal, open the Azure Bot resource → Configuration → set Messaging endpoint to the URL above and save. It must be HTTPS and publicly reachable — Bot Framework does not call private networks.
Pick MultiTenant or SingleTenant
The app registration's supported account type decides who the bot accepts messages from:
- MultiTenant (
AzureADMultipleOrgs) — accepts messages from any tenant. Simplest for a shared bot across customers. No tenant ID required in Gondola. - SingleTenant (
AzureADMyOrg) — accepts messages from one specific tenant. The per-customer isolation model. You mustsupply that tenant's Entra tenant ID in Gondola.
Match the choice you made in Azure when you enter credentials below.
- MultiTenant (
Paste the credentials into Gondola
In the Teams setup card on the bot's page, enter the App ID (the Entra client ID), the app password (the secret Value, not the Secret ID), the app type, and — for SingleTenant — the tenant ID. Gondola validates the credentials against Microsoft on save; if the bot's runtime status flips to healthy, you're done. Credentials are stored AES-256-GCM encrypted and never shown again.
Install the app into Teams
After registration the bot exists in Azure but isn't installed anywhere. Two paths:
- Sideload (dev/test) — in the Teams client, Apps → Manage your apps → Upload an app, and upload the app package (a
.zipmanifest fromteams.cli app packageor the Developer Portal). Requires Upload custom appsto be enabled in the tenant's Teams admin policy. - Org-wide approval(production) — submit the app through the Teams admin center. The Teams admin approves it once and it appears in the org's app catalog for everyone. Use this when sideload is blocked by policy.
- Sideload (dev/test) — in the Teams client, Apps → Manage your apps → Upload an app, and upload the app package (a
@mention to test
Once installed, @mention the bot in a channel or chat to start a conversation. v1 responds to @mentions only by default. To read all messages without an @mention, add RSC permissions (
ChannelMessage.Read.Group,ChatMessage.Read.Chat) to the app manifest — they're accepted at install time, no portal consent step.
Set up Google Chat
Google Chat connects through a GCP project with a service account and a published Chat app. There is no socket mode; Google pushes events to Gondola over HTTPS, so your instance must be reachable from the public internet. The Google Chat setup card on the bot's page walks through the same steps below — for the complete walkthrough, see the Google Chat setup walkthrough below.
Create a GCP project, service account, and key
Open the Google Cloud console and create a project (or reuse one), then enable the Google Chat API. Under IAM & Admin, create a service account — no roles are needed — and download its JSON key from the Keys tab.
If key creation is blocked, your organization has set the
iam.disableServiceAccountKeyCreationpolicy — ask your GCP admin to create the key or exempt the project.Configure the Chat app
On the Google Chat API page, open the Configuration tab, publish the app, and turn on Receive 1:1 messages and Join spaces and group conversations. Under Connection settings, choose App URL and paste
https://<your-gondola-host>/api/gchat/events/<botId>. Google signs every request to this URL and uses it as the verification audience, so it must match the endpoint URL you enter in Gondola.Add the bot to a space
In Google Chat, open or create a space → click the space name → Apps → Add apps, and add the app you published. The bot answers when @mentioned in that space, and can also be messaged 1:1.
Paste the credentials into Gondola
In the Google Chat setup card on the bot's page, enter the service account JSON key, the project number (from IAM & Admin → Settings — not the project name), and the endpoint URL (the App URL from step 2). Gondola validates the credentials against Google on save; if the bot's runtime status flips to healthy, you're done. Credentials are stored AES-256-GCM encrypted and never shown again.
Set up Discord
Discord connects through a per-customer Discord application — you create your own app in the Developer Portal, with your own bot name, avatar, and token. The bot holds a persistent gateway socket to Discord (outbound, like Slack socket mode), so no public URL is needed to receive messages — but Discord pings your instance's interactions endpoint URL to verify it, so that endpoint must be reachable over public HTTPS. The Discord setup card on the bot's page walks through the same steps below — for the complete walkthrough, see the Discord setup walkthrough below.
Create a Discord application
Open the Discord Developer Portal → New Application→ name it after your bot.
Create the bot and copy its token
Open the Bot tab → Add Bot→ copy the token (Reset Token if none is shown). Keep it secret — anyone with it has full control of the bot.
Enable the Message Content Intent
On the Bot tab, under Privileged Gateway Intents, toggle Message Content Intent ON. It is required — without it the bot cannot read message text. The Server Members Intent is optional and not needed.
Note the Application ID and Public Key
Both are under General Information. You'll paste them into Gondola in the last step.
Invite the bot to your server
Under OAuth2 → URL Generator, select the
botandapplications.commandsscopes plus the bot permissions — Send Messages, Send Messages in Threads, Create Public Threads, Manage Threads, Read Message History, Add Reactions, Attach Files — then open the generated URL and invite the bot to your server. The setup card also shows a ready-made invite link that fills in from the Application ID.Set the interactions endpoint
Under General Information → Interactions Endpoint URL, paste
https://<your-gondola-host>/api/discord/events/<botId>. Discord sends a PING to this URL immediately to verify it — the bot must be running to answer, so save the credentials in Gondola first, then paste the URL.Paste the credentials into Gondola
In the Discord setup card on the bot's page, enter the bot token, the public key (the 64-character hex key from General Information), and the application ID. Gondola validates the bot token against Discord on save; if the bot's runtime status flips to healthy, you're done. The token is stored AES-256-GCM encrypted and never shown again.
Socket mode vs webhook
This choice applies to Slack bots. Teams and Google Chat are webhook-only, and Discord is gateway-only — there is no socket or webhook option for any of the three, covered in the sections above.
| Socket Mode (default) | Webhook | |
|---|---|---|
| How it connects | The bot connects outbound from the Gondola server to Slack. | Slack pushes events over HTTPS to https://<your-gondola-host>/api/slack/events/<bot-id>. |
| Network needs | None — no public URL, tunnel, or inbound rule. | The Gondola host must be publicly reachable over HTTPS. |
| Credentials | Bot token (xoxb-) + app-level token (xapp-). | Bot token (xoxb-) + signing secret. |
Use socket mode unless you have a reason not to. For webhook bots, timing matters: Slack verifies the Request URL immediately, and only a running bot can answer the challenge — so activate the bot in Gondola first, then save the Request URL in your Slack app's settings. The generated manifest already carries the URL, which means Slack may ask to verify it while you create the app; retry once the bot is active.
You can switch transport later from the bot page (Bot info → Edit). Save the credentials the new transport needs from the Slack setup card afterwards.
Status and runtime
A bot is always in one of four states:
- Setup needed — created, but no platform credentials saved yet.
- Active — credentials saved; the bot should be listening.
- Disabled — deactivated by someone in the workspace.
- Error — something failed; the recorded message shows on the badge and in the runtime card.
The Runtime card on the bot page shows whether the bot process is currently running, its transport, and the last error. Owners and admins get Activate / Deactivate buttons here — deactivating stops the platform connection, activating starts it again.
A bot can also show an amber Last error line while staying Active: transient problems (a stream failure, a Snowflake credential error) are recorded without taking the bot down.
Channel access
Channel access is a Slack-only feature. Teams and Google Chat bots always respond in every channel or chat they're installed in — there's no allowlist, because neither platform exposes a comparable channel-ID restriction.
For a Slack bot, with no channels listed the bot responds in every channel it's invited to. Direct messages always work, regardless of the list.
To restrict a Slack bot, add Slack channel IDs in the create form or later via Bot info → Edit. An ID looks like C012AB3CD45 — find it in Slack by clicking the channel name at the top of the conversation and opening the About tab; the Channel ID is at the bottom. Channel names such as #general are not accepted because Slack events identify conversations by ID, not display name.
Activity
The bot page's Activity button opens a summary plus the conversation list:
- Summary — total conversations, transport, whether the runtime is running, and the last recorded error.
- Conversations — one row per chat thread the bot has answered in: channel, thread timestamp, last activity, and the Snowflake thread it maps to.
Conversations appear after someone mentions the bot or replies in one of its threads.
How threads work
When someone mentions the bot, its answer streams into a chat thread off that message — a Slack thread, a Teams reply chain, or a Google Chat thread. Gondola records which Snowflake conversation each thread belongs to, so a reply in the same thread continues the same conversation — follow-ups keep the context of what came before. A new mention outside the thread starts a fresh conversation.
Deleting a bot
The Danger zone card on the bot page (owners and admins) deletes the bot after a confirmation. Deleting removes its platform credentials and conversation history, and cannot be undone.