Skip to main content

What You’ll Build

A bot that works on Discord, Telegram, and Slack simultaneously with a single codebase.

Prerequisites

BoostGPT Account

Sign up at app.boostgpt.co

Node.js

Version 14.0.0 or higher

Step 1: Install Dependencies

npm install boostgpt @boostgpt/router dotenv

Step 2: Get Your Tokens

BoostGPT

  1. Go to app.boostgpt.co
  2. Create a project and copy the Project ID
  3. Generate an API Key from API Keys
  4. Create a bot and copy the Bot ID

Discord

  1. Go to Discord Developer Portal
  2. Create a new application
  3. Go to Bot → Create bot
  4. Enable MESSAGE CONTENT INTENT
  5. Copy the bot token

Telegram

  1. Open Telegram and search for @BotFather
  2. Send /newbot and follow instructions
  3. Copy the token provided

Slack

  1. Go to api.slack.com/apps
  2. Create a new app
  3. Enable Socket Mode
  4. Add bot scopes: chat:write, channels:history, im:history
  5. Copy the Bot Token and App Token

Step 3: Configure Environment

Create .env:
.env
# BoostGPT
BOOSTGPT_API_KEY=your_api_key
BOOSTGPT_PROJECT_ID=your_project_id
BOOSTGPT_BOT_ID=your_bot_id

# Discord
DISCORD_TOKEN=your_discord_token

# Telegram
TELEGRAM_TOKEN=your_telegram_token

# Slack
SLACK_TOKEN=xoxb-your-bot-token
SLACK_SIGNING_SECRET=your_signing_secret
SLACK_APP_TOKEN=xapp-your-app-token

Step 4: Create Your Bot

Create bot.js:
bot.js
import 'dotenv/config';
import { 
  Router, 
  DiscordAdapter, 
  TelegramAdapter,
  SlackAdapter 
} from '@boostgpt/router';

const router = new Router({
  apiKey: process.env.BOOSTGPT_API_KEY,
  projectId: process.env.BOOSTGPT_PROJECT_ID,
  defaultBotId: process.env.BOOSTGPT_BOT_ID,
  adapters: [
    // Discord
    new DiscordAdapter({
      discordToken: process.env.DISCORD_TOKEN,
      replyInDMs: true,
      replyOnMention: true
    }),
    
    // Telegram
    new TelegramAdapter({
      telegramToken: process.env.TELEGRAM_TOKEN,
      welcomeMessage: 'Hi {name}! How can I help?'
    }),
    
    // Slack
    new SlackAdapter({
      slackToken: process.env.SLACK_TOKEN,
      slackSigningSecret: process.env.SLACK_SIGNING_SECRET,
      slackAppToken: process.env.SLACK_APP_TOKEN
    })
  ]
});

// Custom message handler
router.onMessage(async (message, context) => {
  // Log all messages
  console.log(`[${context.channel}] ${message.userName}: ${message.content}`);
  
  // Handle custom commands
  if (message.content === '/ping') {
    return 'Pong! 🏓';
  }
  
  if (message.content === '/status') {
    const status = router.getStatus();
    return `Bot is running on ${status.adapters.length} channels!`;
  }
  
  // Let BoostGPT AI handle everything else
  return null;
});

// Error handler
router.onError(async (error, message, context) => {
  console.error(`[${context.channel}] Error:`, error);
  return 'Sorry, I encountered an error. Please try again!';
});

// Start the router
await router.start();
console.log('✅ Bot is live on all channels!');

// Get status
const status = router.getStatus();
console.log('Running adapters:', status.adapters.map(a => a.channel).join(', '));

// Graceful shutdown
process.on('SIGINT', async () => {
  console.log('\n🛑 Shutting down gracefully...');
  await router.stop();
  console.log('✅ Shutdown complete');
  process.exit(0);
});

Step 5: Run Your Bot

node bot.js
You should see:
✅ Discord adapter started
✅ Telegram adapter started
✅ Slack adapter started
✅ Bot is live on all channels!
Running adapters: discord, telegram, slack
Your bot is now live on 3 platforms with one codebase!

Step 6: Test It

  • Mention your bot in a channel: @YourBot hello
  • Or DM it directly
  • Try /ping or /status

Understanding the Code

Message Object

Every message has this structure:
{
  content: "User's message",
  userId: "unique-user-id",
  userName: "username",
  metadata: {
    // Channel-specific data
    channelId: "...",
    messageId: "...",
    // etc.
  }
}

Context Object

The context provides channel information:
{
  channel: "discord" | "telegram" | "slack" | ...,
  adapter: AdapterInstance,
  router: RouterInstance,
  boostgpt: BoostGPTInstance
}

Message Handler Return Values

router.onMessage(async (message, context) => {
  // Return a string to send as reply
  return "Hello!";
  
  // Return null to let BoostGPT AI handle it
  return null;
  
  // Return nothing (undefined) - same as null
});

Advanced: Custom Logic Per Channel

router.onMessage(async (message, context) => {
  // Different behavior per channel
  if (context.channel === 'discord') {
    if (message.content.startsWith('!')) {
      return 'Discord commands start with /';
    }
  }
  
  if (context.channel === 'telegram') {
    if (message.content === '/start') {
      return 'Welcome to Telegram! 🎉';
    }
  }
  
  // Default: Let AI handle it
  return null;
});

Adding More Channels

Want to add WhatsApp or Crisp?
import { WhatsAppAdapter } from '@boostgpt/router';

adapters: [
  // ... existing adapters
  new WhatsAppAdapter({
    allowedContacts: ['1234567890'], // Optional whitelist
    useLocalAuth: true
  })
]
Scan the QR code when prompted.

Common Patterns

Broadcasting Messages

Send a message to all channels:
await router.broadcast('Server maintenance in 5 minutes!');

// Or specific channels only
await router.broadcast('Discord-only announcement', ['discord']);

Sending Direct Messages

// Send to specific user on specific channel
await router.sendMessage('discord', 'user-id-123', 'Hello!');

Dynamic Adapter Management

// Add adapter at runtime
const newAdapter = new DiscordAdapter({ discordToken: '...' });
await router.addAdapter(newAdapter);

// Remove adapter
await router.removeAdapter('discord');

Troubleshooting

Make sure MESSAGE CONTENT INTENT is enabled in Discord Developer Portal → Bot settings.
Start a chat with your bot first by searching for it in Telegram and clicking Start.
Verify Socket Mode is enabled and you’re using the correct App Token (starts with xapp-).
Check your BoostGPT API key and Project ID in .env.

Next Steps

API Reference

Explore all Router methods

Custom Adapters

Build your own channel adapter

Deployment

Deploy to production

Examples

See real-world use cases