Channels

✈️Telegram

Polling-based bot using the teloxide library. Feature flag: channel-telegram.

1. Create a bot

  1. Message @BotFather on Telegram
  2. Use the /newbot command and follow the instructions
  3. Copy the bot token

2. Get your user ID

  1. Message @userinfobot to get your Telegram user ID
  2. Or use @getidsbot

3. Configure

~/.oxicrab/config.json
{
  "channels": {
    "telegram": {
      "enabled": true,
      "token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
      "allowFrom": ["123456789"],
      "proxy": null
    }
  }
}
proxy is optional. Set it to an HTTP/SOCKS proxy URL if needed (e.g. "socks5://127.0.0.1:1080").

Supported features

Text messages Photo attachments Voice messages (OGG) Typing indicators Message editing Message deletion HTML formatting Sender allowlist

🎮Discord

WebSocket gateway using the serenity library. Feature flag: channel-discord.

1. Create a bot

  1. Go to discord.com/developers/applications
  2. Click "New Application"
  3. Go to the "Bot" section
  4. Click "Add Bot"
  5. Under "Token", click "Reset Token" and copy it
  6. Enable "Message Content Intent" under "Privileged Gateway Intents"

2. Invite bot to your server

  1. Go to "OAuth2" > "URL Generator"
  2. Select scopes: bot, applications.commands
  3. Select bot permissions: Send Messages, Read Message History
  4. Copy the generated URL, open it in browser, select your server and authorize

3. Get user IDs

  1. Enable Developer Mode in Discord (Settings > Advanced > Developer Mode)
  2. Right-click on users or channels and select "Copy ID"

4. Configure

~/.oxicrab/config.json
{
  "channels": {
    "discord": {
      "enabled": true,
      "token": "your-discord-bot-token",
      "allowFrom": ["123456789012345678"]
    }
  }
}

Supported features

Text messages Image attachments Audio attachments Typing indicators Message editing Message deletion Guild + DM support Sender allowlist

💼Slack

Socket Mode (WebSocket) via tokio-tungstenite. No public endpoint required. Feature flag: channel-slack.

1. Create a Slack app

  1. Go to api.slack.com/apps
  2. Click "Create New App" > "From scratch"
  3. Name your app and select your workspace

2. Enable Socket Mode

  1. Go to "Socket Mode" in the left sidebar
  2. Toggle "Enable Socket Mode" to ON
  3. Click "Generate Token" under "App-Level Tokens"
  4. Name it (e.g., "Socket Mode Token") and generate
  5. Copy the token (starts with xapp-)

3. Add bot token scopes

Go to "OAuth & Permissions" > "Bot Token Scopes" and add:

ScopePurpose
chat:writeSend and edit messages
channels:historyRead messages in public channels
groups:historyRead messages in private channels
im:historyRead direct messages
mpim:historyRead group direct messages
users:readLook up usernames from user IDs
files:readDownload image attachments from messages
files:writeUpload outbound media to channels
reactions:writeAdd emoji reactions to acknowledge messages

Optional but recommended:

ScopePurpose
users:writeSet bot presence to "active" on startup

Scroll up and click "Install to Workspace". Copy the "Bot User OAuth Token" (starts with xoxb-).

4. Enable App Home messaging

  1. Go to "App Home" in the left sidebar
  2. Under "Show Tabs", enable the Messages Tab
  3. Check "Allow users to send Slash commands and messages from the messages tab"
Important: Without this, users will see "Sending messages to this app has been turned off."

5. Subscribe to events

  1. Go to "Event Subscriptions"
  2. Enable "Enable Events"
  3. Subscribe to bot events: app_mention, message.channels, message.groups, message.im

6. Get user IDs

Click on a user's profile in Slack, click the three dots menu, select "Copy member ID".

7. Configure

~/.oxicrab/config.json
{
  "channels": {
    "slack": {
      "enabled": true,
      "botToken": "xoxb-1234567890-1234567890123-abcdefghijklmnopqrstuvwx",
      "appToken": "xapp-1-A1234567890-1234567890123-abcdefghijklmnopqrstuvwxyz1234567890",
      "allowFrom": ["U01234567"]
    }
  }
}
Note: The appToken must be a Socket Mode token (starts with xapp-), not a bot token. Socket Mode allows your app to receive events without exposing a public HTTP endpoint.

Supported features

Text messages Image attachments Audio attachments 3-step file upload Message editing Message deletion Emoji reactions Markdown formatting Sender allowlist

📱WhatsApp

Linked-device mode using whatsapp-rust. Runs as a secondary device on your phone. Feature flag: channel-whatsapp.

1. First-time setup

  1. Run ./oxicrab gateway with WhatsApp enabled in config
  2. Scan the QR code displayed in the terminal with your phone (WhatsApp > Settings > Linked Devices > Link a Device)
  3. Session is automatically stored in ~/.oxicrab/whatsapp/whatsapp.db

2. Configure

~/.oxicrab/config.json
{
  "channels": {
    "whatsapp": {
      "enabled": true,
      "allowFrom": ["15037348571"]
    }
  }
}

Phone number format

Use phone numbers in international format (country code + number). No spaces, dashes, or plus signs.

Example: "15037348571" for US number +1 (503) 734-8571

Note: WhatsApp requires the Rust nightly toolchain to compile.

Supported features

Text messages Image attachments Voice/audio messages QR code auth Group conversations Persistent sessions Sender allowlist

📞Twilio (SMS/MMS)

Webhook-based using axum. Supports both SMS API and Conversations API. Feature flag: channel-twilio.

1. Get credentials

  1. Sign up at console.twilio.com
  2. Copy your Account SID and Auth Token from the dashboard

2. Buy a phone number

  1. Go to Phone Numbers > Buy a Number
  2. Ensure SMS capability is checked
  3. Note the number in E.164 format (e.g. +15551234567)

3. Create a Conversation Service

  1. Go to Messaging > Conversations > Manage > Create Service
  2. Note the Conversation Service SID

4. Configure webhooks

  1. Go to Conversations > Manage > [Your Service] > Webhooks
  2. Set Post-Webhook URL to your server's public URL (e.g. https://your-server.example.com/twilio/webhook)
  3. Subscribe to events: onMessageAdded
  4. Method: POST

5. Add participants to conversations

Conversations need participants before messages flow:

curl -X POST "https://conversations.twilio.com/v1/Conversations/{ConversationSid}/Participants" \
  -u "YOUR_ACCOUNT_SID:YOUR_AUTH_TOKEN" \
  --data-urlencode "MessagingBinding.Address=+19876543210" \
  --data-urlencode "MessagingBinding.ProxyAddress=+15551234567"

6. Expose your webhook

The webhook server must be reachable from the internet. Options:

  1. Cloudflare Tunnel (recommended): cloudflared tunnel run — free, stable, no open ports
  2. ngrok: ngrok http 8080 — quick for development
  3. Reverse proxy: nginx/caddy with TLS termination

7. Configure

~/.oxicrab/config.json
{
  "channels": {
    "twilio": {
      "enabled": true,
      "accountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "authToken": "your-auth-token",
      "phoneNumber": "+15551234567",
      "webhookPort": 8080,
      "webhookPath": "/twilio/webhook",
      "webhookUrl": "https://your-server.example.com/twilio/webhook",
      "allowFrom": []
    }
  }
}
webhookUrl must match exactly what Twilio POSTs to (used for HMAC-SHA1 signature validation). allowFrom empty means all senders are allowed; add phone numbers to restrict.

Supported features

SMS sending/receiving Conversations API HMAC-SHA1 signature validation Message chunking (1600 chars) Sender allowlist

Common patterns

Selective compilation

Each channel is a Cargo feature flag. Build only what you deploy:

# All channels (default)
cargo build --release

# Only Telegram and Slack
cargo build --release --no-default-features --features channel-telegram,channel-slack

# No channels (agent CLI only)
cargo build --release --no-default-features

Allowlist filtering

All channels support an optional allowFrom array. When empty, all senders are accepted. When populated, only listed IDs can interact with the bot.

Media handling

Inbound media (images, voice messages) is downloaded and saved to ~/.oxicrab/media/ with channel-specific prefixes. Voice messages are automatically transcribed if the transcription service is configured.

Auto-reconnection

All channels implement exponential backoff retry loops (5–60 seconds). Reconnection is automatic after network disconnects or backend errors.