---
title: Gateway
url: https://arcana.otnelhq.com/docs/gateway
---

# Chat Gateways



Arcana can act as an AI assistant inside Telegram, Discord, Slack, and WhatsApp. Each platform runs as a separate adapter; you can enable one or all simultaneously.



```bash
arcana gateway
```



Requires a **Pro** or **Enterprise** license. Complete `arcana console login` (or set `ARCANA_LICENSE_KEY`) before starting the gateway.




## Configuration



Add a `gateway` block to your config — project `arcana.json`, global `~/.config/arcana/arcana.json`, or the legacy `~/.arcana/config.json`:



```json
{
  "provider": "openai",
  "model": "gpt-4o",
  "gateway": {
    "telegram": { "token": "111:xxx", "allowedUsers": ["12345678"] },
    "discord": { "token": "xxx", "allowedChannels": ["987654321"] },
    "slack": { "botToken": "xoxb-xxx", "signingSecret": "xxx", "allowedChannels": ["C0123ABC"] },
    "whatsapp": { "phoneNumberId": "123456", "accessToken": "xxx", "appSecret": "xxx", "allowedUsers": ["14155551234"] }
  }
}
```



You can also pass tokens on the command line:



```bash
arcana gateway --telegram-token "111:xxx"
arcana gateway --discord-token "xxx"
```




## Platform setup




### Telegram



1. Message [@BotFather](https://t.me/BotFather) and create a new bot.
2. Copy the bot token into your config.
3. Add your Telegram user ID to `allowedUsers`. Forward a message to [@userinfobot](https://t.me/userinfobot) or call the Bot API `getUpdates` endpoint to find `from.id`.




### Discord



1. Create an application at [discord.com/developers](https://discord.com/developers/applications).
2. Bot → copy the token. Enable **Message Content Intent**.
3. Invite the bot with `Send Messages` + `Read Message History`.
4. Add the channel ID to `allowedChannels`.



Discord replies are capped at 2000 characters; longer responses are truncated.




### Slack



1. Create an app at [api.slack.com/apps](https://api.slack.com/apps).
2. OAuth scopes: `chat:write`, `channels:history`, `im:history`.
3. Install the app and copy the Bot User OAuth Token (`xoxb-...`) and Signing Secret.
4. Event Subscriptions: enable and request `message.channels` / `message.im`.
5. Add the channel ID to `allowedChannels`.




### WhatsApp



Uses the Meta Cloud API via webhooks (default port 3100).



1. Create a Meta Business App and add the WhatsApp product.
2. Copy Phone Number ID and Access Token into config. Set `appSecret` for production signature verification.
3. Expose the webhook (e.g. `ngrok http 3100`) and configure the callback URL + `messages` subscription in the Meta dashboard.
4. Add allowed phone numbers (country code, no `+`) to `allowedUsers`.



WhatsApp messages are capped at 4096 characters.




## Security



### Allowlists (required)



Every platform requires an allowlist. The gateway refuses to start with an empty or missing allowlist unless `ARCANA_GATEWAY_OPEN=1` is set (local dev only).



| Platform | Allowlist field | What to put |
| --- | --- | --- |
| Telegram | `allowedUsers` | Telegram user IDs (numeric) |
| Discord | `allowedChannels` | Discord channel IDs |
| Slack | `allowedChannels` | Slack channel IDs (`C0...`) |
| WhatsApp | `allowedUsers` | Phone numbers with country code, no `+` |




### WhatsApp webhook signatures



The adapter verifies `x-hub-signature-256` using your `appSecret`. Required in production. Set `ARCANA_WHATSAPP_INSECURE=1` only for local development.




### Dev escape hatches



| Env / CLI | Effect |
| --- | --- |
| `ARCANA_GATEWAY_OPEN=1` | Allow empty platform allowlists (local dev only) |
| `ARCANA_WHATSAPP_INSECURE=1` | Skip WhatsApp signature verification (dev only) |
| `WHATSAPP_WEBHOOK_PORT` | Override webhook listen port (default `3100`) |




## How it works



- Each platform gets its own adapter that translates messages to/from Arcana.
- Every chat ID gets its own agent session with conversation history and memory integration.
- Destructive shell commands are blocked by default.
- The agent has a capped tool-call budget per turn.
- Provider keys and model selection come from your main Arcana config.
