primer docs

Channel Providers

What a channel provider is

A channel provider is a credential set for one messaging platform. It tells primer which Slack workspace, Telegram bot, or Discord bot to connect to. Every channel you create belongs to one provider, and the provider is what holds the tokens that let primer authenticate with the platform.

Three provider kinds are supported:

  • Telegram: a single bot token (one bot per provider). Telegram delivers messages via long polling; no public webhook URL is required.
  • Slack: a Slack app installed in one Slack workspace. Primer uses Socket Mode, so the app does not need a public-facing URL either. Two tokens are required.
  • Discord: a Discord application bot installed in one or more servers. The bot connects via the Discord Gateway and can optionally handle direct messages.

Each primer instance can have many providers, one per platform connection. A single provider can own multiple channels (for example, one Slack provider can own several Slack channel IDs).

Configuration fields

Telegram

Field Required Notes
bot_token yes The token generated by @BotFather in the format <id>:<hash> (at least 20 characters).
poll_timeout_seconds no Long-poll timeout per getUpdates call. Default 25, range 1--60. Telegram caps at 50 s; 25 balances latency against connection churn.

To get a bot token: open Telegram, message @BotFather, send /newbot, follow the prompts, and copy the token it returns.

BotFather: Done! Here is your token:
  123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
              paste this as bot_token

Slack

Field Required Notes
app_token yes App-level token starting with xapp-. Found in your Slack app's Basic Information panel under "App-Level Tokens". Required for Socket Mode.
bot_token yes Bot OAuth token starting with xoxb-. Found in the OAuth & Permissions page after installing the app to a workspace.
signing_secret no Only needed for HTTP event delivery mode. Socket Mode does not use it.

Primer connects over Socket Mode, so the app never needs a public Request URL: events, interactive button clicks, modal submissions, and slash commands all flow over the Socket Mode websocket. You enable each feature in the Slack app config, but you leave every "Request URL" field blank.

1. Create the app

Slack API dashboard  https://api.slack.com/apps
  Create New App  ->  From scratch
    App Name:        e.g. "primer"
    Pick a workspace  ->  Create App

You can also create the app from a manifest, but the from-scratch flow below is the reference path.

2. Enable Socket Mode and mint the app token

Settings  ->  Socket Mode  ->  Enable Socket Mode  (toggle on)
  When prompted, generate an App-Level Token:
    Token Name:  socket
    Scope:       connections:write
    ->  Generate  ->  Copy token  (starts with xapp-)

This xapp- token is the app_token field in the primer provider config.

3. Add the bot token scopes

Open OAuth & Permissions -> Scopes -> Bot Token Scopes and add the scopes for the channel type you will use. The scope family differs between public and private channels, so add the row that matches your target channel (add both if you will run both).

Scope Why primer needs it Public Private
chat:write Post and update prompts, replies, and the per-session thread anchor (chat.postMessage, chat.update, chat.postEphemeral, and native streaming). yes yes
channels:read Resolve and verify the target public channel (conversations.info). yes
channels:history Read message history when rebuilding an approval card after a decision (conversations.history). yes
groups:read Resolve and verify the target private channel. yes
groups:history Read message history for the same approval-card rebuild in a private channel. yes
files:write Upload outbound media into the channel (files.uploadV2). optional optional
files:read Download inbound files (images, documents, audio) users send. optional optional
info

channels:read/channels:history cover public channels only; groups:read/groups:history cover private channels. They are different scope families, not interchangeable. The files:* scopes are only needed if you use channel media (sending or receiving attachments); plain text chat works without them.

warning

conversations:* are Slack Web API methods, not OAuth scopes. Do not add conversations:read or conversations:history as scopes; they do not exist. The methods conversations.info and conversations.history are authorized by the channels:* (public) or groups:* (private) scopes above.

4. Enable Event Subscriptions

Primer consumes inbound messages as Slack events delivered over Socket Mode.

Features  ->  Event Subscriptions  ->  Enable Events  (toggle on)
  Request URL:  leave blank  (Socket Mode delivers events)
  Subscribe to bot events:
    message.channels   (public channels)
    message.groups     (private channels)

Add only the event matching your channel type (message.channels for public, message.groups for private, or both). Slack may prompt you to reinstall the app after you change event subscriptions.

5. Enable Interactivity

The tool-approval and ask_user prompts are Block Kit messages with Approve/Reject buttons, agent-select dropdowns, and a rejection-reason modal. Interactivity must be on for those clicks and modal submissions to reach primer.

Features  ->  Interactivity & Shortcuts  ->  Interactivity  (toggle on)
  Request URL:  leave blank  (Socket Mode delivers interactions)

6. Register slash commands

Primer offers /agent and /help on Slack. (/new, /list, and /switch are not used on Slack: each thread is its own chat, the channel's threads are the chat list, and a new thread is how you switch (see the channels page below).) Register each command under Features -> Slash Commands -> Create New Command, leaving the Request URL blank:

/agent   Pick a different agent for the current chat
/help    Show the available commands

/agent only takes effect when allow_agent_switch is enabled on the channel.

7. Install the app and copy the bot token

Settings  ->  Install App  ->  Install to Workspace  ->  Allow
  Copy Bot User OAuth Token  (starts with xoxb-)

This xoxb- token is the bot_token field in the primer provider config.

8. Invite the bot to the channel

Primer can only read and post in a channel the bot is a member of. In the target Slack channel, run:

/invite @primer
warning

For a private channel this invite is mandatory: the bot cannot see or join private channels on its own, and conversations.info will fail with channel_not_found until it is invited. Public channels also require the invite before primer can post.

warning

The app token and bot token have distinct prefixes and are not interchangeable. The app token must start with xapp- and the bot token must start with xoxb-. Using the wrong token in the wrong field causes an authentication failure that is not obvious from the platform error message.

Discord

Field Required Notes
bot_token yes Bot token from the Discord Developer Portal (at least 30 characters). Do not include the Bot prefix; primer adds it internally.
enable_dms no Whether the bot requests the dm_messages intent so it can read direct messages. Default true. Set to false for guild-only deployments.
warning

Discord requires the Message Content Intent to be enabled on the Developer Portal for your application (under Bot > Privileged Gateway Intents). Without it, inbound messages arrive with empty content.

To get a Discord bot token:

Discord Developer Portal  https://discord.com/developers/applications
  1. New Application  ->  name your bot
  2. Bot page  ->  Reset Token  ->  Copy (do NOT include "Bot " prefix)
  3. Bot page  ->  Privileged Gateway Intents
     Enable: Message Content Intent  (required)
  4. OAuth2  ->  URL Generator
     Scopes: bot
     Bot Permissions: Send Messages, Read Messages/View Channels
     ->  Copy Generated URL  ->  paste in browser to invite bot to server

Walkthrough: create a provider

channel-provider-create (live component)
Live component - open it in your console.
  1. Open Channels in the left sidebar, then select the Providers tab.
  2. Click New provider.
  3. Choose a platform from the dropdown (Telegram, Slack, or Discord). The platform field is locked after creation; to switch platforms, delete the provider and recreate it.
  4. Fill in the credentials for the chosen platform (see the field tables above).
  5. Optionally supply an ID. Leave blank to let primer generate one automatically.
  6. Click Create provider. The console navigates to the provider detail page.

After creating a provider, return to the Channels tab to add the specific rooms (channel IDs) that belong to this provider.

Create channels and bind them to workspaces.

Bind a channel to a workspace so session gates forward there.

Full REST schema for channel providers and channels.