AI Tools18 min read

OpenClaw Multi-Channel Setup 2026: Telegram, Discord, Feishu, QQ, WeChat

Complete guide to deploying OpenClaw across multiple messaging platforms. Step-by-step tutorials for Telegram, Discord, Feishu, QQ, and WeChat bot configuration with code examples and troubleshooting.

10xClaw
10xClaw
March 21, 2026

OpenClaw Multi-Channel Setup 2026: Telegram, Discord, Feishu, QQ, WeChat

Deploy your OpenClaw AI assistant across all major messaging platforms. This comprehensive guide covers Telegram, Discord, Feishu (Lark), QQ, and WeChat integration with complete configuration examples.

Why Multi-Channel Deployment?

Meet Users Where They Are:

  • Global reach: Telegram (900M users), Discord (200M users)
  • China market: WeChat (1.3B users), QQ (600M users), Feishu (enterprise)
  • Unified AI: One OpenClaw instance, multiple channels
  • Cost efficiency: Share API costs across platforms
  • Use Cases:

  • Customer support across regions
  • Internal team assistants
  • Community engagement bots
  • Multi-region businesses
  • Architecture Overview

    ```

    ┌─────────────────────────────────────────┐

    │ OpenClaw Core Engine │

    │ (Claude/GPT-4/Gemini + Memory + Tools) │

    └──────────────┬──────────────────────────┘

    ┌───────┴───────┐

    │ Adapters │

    └───────┬───────┘

    ┌──────────┼──────────┬──────────┬──────────┐

    │ │ │ │ │

    ┌───▼───┐ ┌──▼───┐ ┌──▼───┐ ┌──▼───┐ ┌──▼────┐

    │Telegram│ │Discord│ │Feishu│ │ QQ │ │ WeChat │

    └────────┘ └───────┘ └──────┘ └──────┘ └────────┘

    ```

    Key Components:

  • Core Engine: Shared AI logic, memory, tools
  • Adapters: Platform-specific message handling
  • Webhook/Polling: Receive messages from platforms
  • Rate Limiting: Per-platform quotas
  • User Management: Unified user database
  • 1. Telegram Bot Setup

    Step 1: Create Bot with BotFather

    Open Telegram and search for `@BotFather`

    Create new bot:

    ```

    /newbot

    Bot name: My OpenClaw Assistant

    Username: myopenclaw_bot

    ```

    Save your token:

    ```

    Token: 123456789:ABCdefGHIjklMNOpqrsTUVwxyz

    ```

    Step 2: Configure OpenClaw

    Edit `.env`:

    ```env

    Telegram Configuration

    TELEGRAM_ENABLED=true

    TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrsTUVwxyz

    TELEGRAM_WEBHOOK_URL=https://your-domain.com/webhook/telegram

    TELEGRAM_ALLOWED_USERS= # Leave empty for public, or comma-separated user IDs

    ```

    Configure webhook (nded for production):

    ```bash

    curl -X POST "https://api.telegram.org/bot/setWebhook" \

    -H "Content-Type: application/json" \

    -d '{"url": "https://your-domain.com/webhook/telegram"}'

    ```

    Or use polling (easier for development):

    ```env

    TELEGRAM_USE_POLLING=true

    ```

    Step 3: Implement Telegram Adapter

    `adapters/telegram.js`:

    ```javascript

    const TelegramBot = require('node-telegram-bot-api');

    const { processMessage } = require('../core/engine');

    class TelegramAdapter {

    constructor(config) {

    this.bot = new TelegramBot(config.token polling: config.usePolling || false

    });

    this.setupHandlers();

    }

    setupHandlers() {

    // Text messages

    this.bot.on('message', async (msg) => {

    const chatId = msg.chat.id;

    const userId = `telegram_${msg.from.id}`;

    const text = msg.text;

    try {

    // Show typing indicator

    await this.bot.sendChatAction(chatId, 'typing');

    // Process with OpenClaw core

    const response = await processMessage({

    userId,

    message: text,

    platform: 'telegram',

    metadata: {

    chatId,

    username: msg.from.username,

    firstName: msg.from.first_name

    }

    });

    // Send response

    await this.bot.sendMessage(chatId, response.text, {

    parse_mode: 'Markdown',

    reply_to_message_id: msg.message_id

    });

    } catch (error) {

    console.error('Telegram error:', error);

    await this.bot.sendMessage(chatId, 'Sorry, an error occurred.');

    }

    });

    // Commands

    this.bot.onText(/\/start/, (msg) => {

    const chatId = msg.chat.id;

    this.bot.sendMessage(chatId,

    'Welcome to OpenClaw! I\'m your AI assistant. How can I help you today?'

    );

    });

    this.bot.onText(/\/help/, (msg) => {

    const chatId = msg.chat.id;

    this.bot.sendMessage(chatId,

    'Available commands:\n' +

    '/start - Start conversation\n' +

    '/help - Show this message\n' +

    '/clear - Clear conversation history\n' +

    '/model - Switch AI model'

    );

    });

    }

    // Webhook handler

    async handleWebhook(req, res) {

    try {

    await this.bot.processUpdate(req.body);

    res.sendStatus(200);

    } catch (error) {

    console.error('Webhook error:', error);

    res.sendStatus(500);

    }

    }

    }

    module.exports = TelegramAdapter;

    ```

    Step 4: Advanced Features

    Inline Keyboards:

    ```javascript

    await this.bot.sendMessage(chatId, 'Choose an option:', {

    reply_markup: {

    inline_keyboard: [

    [

    { text: 'Option 1', callback_data: 'opt1' },

    { text: 'Option 2', callback_data: 'opt2' }

    ]

    ]

    }

    });

    // Handle callbacks

    this.bot.on('callback_query', async (query) => {

    const data = query.data;

    // Process callback

    });

    ```

    File Handling:

    ```javascript

    this.bot.on('document', async (msg) => {

    const fileId = msg.document.file_id;

    const file = await this.bot.getFile(fileId);

    const fileUrl = `https://api.telegram.org/file/bot${token}/${file.file_path}`;

    // Download and process file

    });

    ```

    2. Discord Bot Setup

    Step 1: Create Discord Application

  • Visit Discord Developer Portal
  • Click "New Application"
  • Name: "OpenClaw Assistant"
  • Go to "Bot" tab → "Add Bot"
  • Copy bot token
  • Enable "Message Content Intent"
  • Step 2: Configure Permissions

    Bot Permissions (OAuth2 → URL Generator):

  • ✅ Read Messages/View Channels
  • ✅ Send Messages
  • ✅ Send Messages in Threads
  • ✅ Embed Links
  • ✅ Attach Files
  • ✅ Read Message History
  • ✅ Add Reactions
  • Generated URL:

    ```

    https://discord.com/api/oauth2/authorize?client_id=YOUR_CLIENT_ID&permissions=412317240384&scope=bot%20applications.commands

    ```

    Step 3: Configure OpenClaw

    `.env`:

    ```env

    Discord Configuration

    DISCORD_ENABLED=true

    DISCORD_BOT_TOKEN=your-discord-bot-token

    DISCORD_CLIENT_ID=your-client-id

    DISCORD_GUILD_ID=your-server-id # Optional: restrict to specific server

    ```

    Step 4: Implement Discord Adapter

    `adapters/discord.js`:

    ```javascript

    const { Client, GatewayIntentBits } = require('discord.js');

    const { processMessage } = require('../core/engine');

    class DiscordAdapter {

    constructor(config) {

    this.client = new Client({

    intents: [

    GatewayIntentBits.Guilds,

    GatewayIntentBits.GuildMessages,

    GatewayIntentBits.MessageContent,

    GatewayIntentBits.DirectMessages

    ]

    });

    this.setupHandlers();

    this.client.login(config.token);

    }

    setupHandlers() {

    this.client.on('ready', () => {

    console.log(`Discord bot logged in as ${this.client.user.tag}`);

    });

    this.client.on('messageCreate', async (message) => {

    // Ignore bot messages

    if (message.author.bot) return;

    // Only respond to mentions or DMs

    const isMentioned = message.mentions.has(this.client.user);

    const isDM = message.channel.type === 'DM';

    if (!isMentioned && !isDM) return;

    try {

    // Show typing indicator

    await message.channel.sendTyping();

    // Remove mention from message

    let text = message.content;

    if (isMentioned) {

    text = text.replace(`<@${this.client.user.id}>`, '').trim();

    }

    // Process with OpenClaw core

    const response = await processMessage({

    userId: `discord_${message.author.id}`,

    message: text,

    platform: 'discord',

    metadata: {

    channelId: message.channel.id,

    guildId: message.guild?.id,

    username: message.author.username

    }

    });

    // Send response (split if > 2000 chars)

    await this.sendLongMessage(message.channel, response.text);

    } catch (error) {

    console.error('Discord error:', error);

    await message.reply('Sorry, an error occurred.');

    }

    });

    }

    async sendLongMessage(channel, text) {

    const chunks = text.match(/[\s\S]{1,2000}/g) || [];

    for (const chunk of chunks) {

    await channel.send(chunk);

    }

    }

    }

    module.exports = DiscordAdapter;

    ```

    Step 5: Slash Commands

    Register commands:

    ```javascript

    const { REST, Routes, SlashCommandBuilder } = require('discord.js');

    const commands = [

    new SlashCommandBuilder()

    .setName('ask')

    .setDescription('Ask OpenClaw a question')

    .addStringOption(option =>

    option.setName('question')

    .setDescription('Your question')

    .setRequired(true)

    ),

    new SlashCommandBuilder()

    .setName('clear')

    .setDescription('Clear conversation history')

    ].map(command => command.toJSON());

    const rest = new REST({ version: '10' }).setToken(token);

    await rest.put(

    Routes.applicationCommands(clientId),

    { body: commands }

    );

    ```

    Handle slash commands:

    ```javascript

    this.client.on('interactionCreate', async (interaction) => {

    if (!interaction.isChatInputCommand()) return;

    if (interaction.commandName === 'ask') {

    const question = interaction.options.getString('question');

    await interaction.deferReply();

    const response = await processMessage({

    userId: `discord_${interaction.user.id}`,

    message: question,

    platform: 'discord'

    });

    await interaction.editReply(response.text);

    }

    });

    ```

    3. Feishu (Lark) Bot Setup

    Step 1: Create Feishu App

  • Visit Feishu Open Platform
  • Create new app
  • Get App ID and App Secret
  • Enable bot capability
  • Subscribe to message events
  • Step 2: Configure OpenClaw

    `.env`:

    ```env

    Feishu Configuration

    FEISHU_ENABLED=true

    FEISHU_APP_ID=cli_xxx

    FEISHU_APP_SECRET=xxx

    FEISHU_VERIFICATION_TOKEN=xxx

    FEISHU_ENCRYPT_KEY=xxx # Optional

    ```

    Step 3: Implement Feishu Adapter

    `adapters/feishu.js`:

    ```javascript

    const axios = require('axios');

    const crypto = require('crypto');

    class FeishuAdapter {

    constructor(config) {

    this.appId = config.appId;

    this.appSecret = config.appSecret;

    this.verificationToken = config.verificationToken;

    this.accessToken = null;

    this.tokenExpiry = 0;

    }

    async getAccessToken() {

    if (this.accessToken && Date.now() < this.tokenExpiry) {

    return this.accessToken;

    }

    const response = await axios.post(

    'https://open.feishu.cn/open-api/auth/v3/tenant_access_token/internal',

    {

    app_id: this.appId,

    app_secret: this.appSecret

    }

    );

    this.accessToken = response.data.tenant_access_token;

    this.tokenExpiry = Date.now() + (response.data.expire - 60) * 1000;

    return this.accessToken;

    }

    async handleEvent(req, res) {

    // Verify request

    if (req.body.token !== this.verificationToken) {

    return res.status(401).send('Invalid token');

    }

    // Handle URL verification

    if (req.body.type === 'url_verification') {

    return res.json({ challenge: req.body.challenge });

    }

    // Handle message event

    if (req.body.event?.type === 'message') {

    const event = req.body.event;

    // Ignore bot messages

    if (event.message.chat_type === 'bot') {

    return res.sendStatus(200);

    }

    // Process message

    const response = await processMessage({

    userId: `feishu_${event.sender.sender_id.user_id}`,

    message: JSON.parse(event.message.content).text,

    platform: 'feishu',

    metadata: {

    chatId: event.message.chat_id,

    messageId: event.message.message_id

    }

    });

    // Send reply

    await this.sendMessage(event.message.chat_id, response.text);

    }

    res.sendStatus(200);

    }

    async sendMessage(chatId, text) {

    const token = await this.getAccessToken();

    await axios.post(

    'https://open.feishu.cn/open-api/im/v1/messages',

    {

    receive_id: chatId,

    msg_type: 'text',

    content: JSON.stringify({ text })

    },

    {

    headers: {

    'Authorization': `Bearer ${token}`,

    'Content-Type': 'application/json'

    },

    params: {

    receive_id_type: 'chat_id'

    }

    }

    );

    }

    // Send interactive card

    async sendCard(chatId, card) {

    const token = await this.getAccessToken();

    await axios.post(

    'https://open.feishu.cn/open-api/im/v1/messages',

    {

    receive_id: chatId,

    msg_type: 'interactive',

    content: JSON.stringify(card)

    },

    {

    headers: {

    'Authorization': `Bearer ${token}`,

    'Content-Type': 'application/json'

    },

    params: {

    receive_id_type: 'chat_id'

    }

    }

    );

    }

    }

    module.exports = FeishuAdapter;

    ```

    Step 4: Interactive Cards

    Send rich card:

    ```javascript

    const card = {

    config: {

    wide_screen_mode: true

    },

    header: {

    title: {

    tag: 'plain_text',

    content: 'OpenClaw Response'

    }

    },

    elements: [

    {

    tag: 'div',

    text: {

    tag: 'lark_md',

    content: response.text

    }

    },

    {

    tag: 'action',

    actions: [

    {

    tag: 'button',

    text: {

    tag: 'plain_text',

    content: 'Continue'

    },

    type: 'primary',

    value: { action: 'continue' }

    }

    ]

    }

    ]

    };

    await this.sendCard(chatId, card);

    ```

    4. QQ Bot Setup

    Step 1: Register QQ Bot

  • Visit QQ Open Platform
  • Create bot application
  • Get App ID and Token
  • Or use go-cqhttp (community solution)
  • Step 2: Using go-cqhttp (Recommended)

    Install go-cqhttp:

    ```bash

    Download from https://github.com/Mrs4s/go-cqhttp/releases

    wget https://github.com/Mrs4s/go-cqhttp/releases/download/v1.0.0/go-cqhttp_linux_amd64.tar.gz

    tar -xzf go-cqhttp_linux_amd64.tar.gz

    ./go-cqhttp

    ```

    Configure `config.yml`:

    ```yaml

    account:

    uin: 123456789 # QQ number

    password: '' # Leave empty for QR code login

    message:

    post-format: array

    servers:

    - http:

    host: 127.0.0.1

    port: 5700

    timeout: 5

    post:

    - url: 'http://localhost:3000/webhook/qq'

    secret: 'your-secret'

    ```

    Step 3: Configure OpenClaw

    `.env`:

    ```env

    QQ Configuration

    QQ_ENABLED=true

    QQ_WEBHOOK_SECRET=your-secret

    QQ_API_URL=http://localhost:5700

    ```

    Step 4: Implement QQ Adapter

    `adapters/qq.js`:

    ```javascript

    const axios = require('axios');

    const crypto = require('crypto');

    class QQAdapter {

    constructor(config) {

    this.apiUrl = config.apiUrl;

    this.secret = config.secret;

    }

    async handleWebhook(req, res) {

    // Verify signature

    const signature = req.headers['x-signature'];

    if (signature) {

    const hash = crypto

    .createHmac('sha1', this.secret)

    .update(JSON.stringify(req.body))

    .digest('hex');

    if (`sha1=${hash}` !== signature) {

    return res.status(401).send('Invalid signature');

    }

    }

    const event = req.body;

    // Handle message

    if (event.post_type === 'message') {

    const userId = `qq_${event.user_id}`;

    const message = event.message;

    // Process with OpenClaw

    const response = await processMessage({

    userId,

    message: this.parseMessage(message),

    platform: 'qq',

    metadata: {

    groupId: event.group_id,

    messageId: event.message_id

    }

    });

    // Send reply

    await this.sendMessage(event, response.text);

    }

    res.sendStatus(200);

    }

    parseMessage(message) {

    if (typeof message === 'string') return message;

    // Parse CQ code format

    return message

    .map(seg => seg.type === 'text' ? seg.data.text : '')

    .join('');

    }

    async sendMessage(event, text) {

    const endpoint = event.message_type === 'group'

    ? '/send_group_msg'

    : '/send_private_msg';

    await axios.post(`${this.apiUrl}${endpoint}`, {

    [event.message_type === 'group' ? 'group_id' : 'user_id']:

    event.message_type === 'group' ? event.group_id : event.user_id,

    message: text

    });

    }

    }

    module.exports = QQAdapter;

    ```

    5. WeChat Bot Setup

    Option 1: Enterprise WeChat (Official)

    Step 1: Create Enterprise WeChat App

  • Register at Enterprise WeChat
  • Create internal app
  • Get Corp ID, Agent ID, Secret
  • Step 2: Configure OpenClaw

    `.env`:

    ```env

    WeChat Work Configuration

    WECHAT_WORK_ENABLED=true

    WECHAT_WORK_CORP_ID=wwxxx

    WECHAT_WORK_AGENT_ID=1000002

    WECHAT_WORK_SECRET=xxx

    WECHAT_WORK_TOKEN=xxx

    WECHAT_WORK_ENCODING_AES_KEY=xxx

    ```

    Step 3: Implement Adapter

    ```javascript

    const { WXWork } = require('wxwork-api');

    class WeChatWorkAdapter {

    constructor(config) {

    this.api = new WXWork({

    corpId: config.corpId,

    corpSecret: config.secret

    });

    }

    async handleMessage(req, res) {

    const message = req.body;

    if (message.MsgType === 'text') {

    const response = await processMessage({

    userId: `wechat_${message.FromUserName}`,

    message: message.Content,

    platform: 'wechat_work'

    });

    await this.sendMessage(message.FromUserName, response.text);

    }

    res.send('success');

    }

    async sendMessage(userId, text) {

    await this.api.sendText(userId, text);

    }

    }

    ```

    Option 2: Personal WeChat (Unofficial)

    ⚠️ Warning: Unofficial methods violate WeChat ToS and may result in account ban.

    Using wechaty (at your own risk):

    ```javascript

    const { Wechaty } = require('wechaty');

    const bot = new Wechaty();

    bot.on('message', async (message) => {

    if (message.self()) return;

    const text = message.text();

    const response = await processMessage({

    userId: `wechat_${message.talker().id}`,

    message: text,

    platform: 'wechat'

    });

    await message.say(response.text);

    });

    bot.start();

    ```

    6. Unified Management

    Multi-Channel Router

    `core/router.js`:

    ```javascript

    class MultiChannelRouter {

    constructor() {

    this.adapters = new Map();

    }

    registerAdapter(platform, adapter) {

    this.adapters.set(platform, adapter);

    }

    async routeMessage(userId, message, platform) {

    // Get user preferences

    const user = await this.getUserProfile(userId);

    // Apply platform-specific formatting

    let formattedMessage = message;

    switch (platform) {

    case 'telegram':

    formattedMessage = this.formatMarkdown(message);

    break;

    case 'discord':

    formattedMessage = this.formatDiscordMarkdown(message);

    break;

    case 'feishu':

    formattedMessage = this.formatFeishuMarkdown(message);

    break;

    default:

    formattedMessage = this.stripFormatting(message);

    }

    return formattedMessage;

    }

    formatMarkdown(text) {

    // Telegram markdown

    return text

    .replace(/\*\*(.*?)\*\*/g, '*$1*') // Bold

    .replace(/__(.*?)__/g, '_$1_'); // Italic

    }

    formatDiscordMarkdown(text) {

    // Discord markdown (similar to standard)

    return text;

    }

    formatFeishuMarkdown(text) {

    // Feishu uses different syntax

    return text

    .replace(/\*\*(.*?)\*\*/g, '$1')

    .replace(/__(.*?)__/g, '$1');

    }

    stripFormatting(text) {

    // Remove all markdown

    return text.replace(/[*_`~]/g, '');

    }

    }

    ```

    Rate Limiting

    Per-platform limits:

    ```javascript

    const rateLimits = {

    telegram: { requests: 30, window: 1000 }, // 30/sec

    discord: { requests: 50, window: 1000 }, // 50/sec

    feishu: { requests: 100, window: 60000 }, // 100/min

    qq: { requests: 20, window: 1000 }, // 20/sec

    wechat: { requests: 10, window: 1000 } // 10/sec

    };

    class RateLimiter {

    constructor(limits) {

    this.limits = limits;

    this.counters = new Map();

    }

    async checkLimit(platform) {

    const limit = this.limits[platform];

    const key = `${platform}_${Date.now() / limit.window | 0}`;

    const count = this.counters.get(key) || 0;

    if (count >= limit.requests) {

    throw new Error('Rate limit exceeded');

    }

    this.counters.set(key, count + 1);

    // Cleanup old counters

    setTimeout(() => this.counters.delete(key), limit.window);

    }

    }

    ```

    7. Monitoring and Analytics

    Track Multi-Channel Metrics

    ```javascript

    const metrics = {

    messageCount: new Map(),

    responseTime: new Map(),

    errorRate: new Map()

    };

    async function trackMessage(platform, duration, error = null) {

    // Increment message count

    const count = metrics.messageCount.get(platform) || 0;

    metrics.messageCount.set(platform, count + 1);

    // Track response time

    const times = metrics.responseTime.get(platform) || [];

    times.push(duration);

    metrics.responseTime.set(platform, times);

    // Track errors

    if (error) {

    const errors = metrics.errorRate.get(platform) || 0;

    metrics.errorRate.set(platform, errors + 1);

    }

    }

    // Generate report

    function generateReport() {

    const report = {};

    for (const [platform, count] of metrics.messageCount) {

    const times = metrics.responseTime.get(platform) || [];

    const errors = metrics.errorRate.get(platform) || 0;

    report[platform] = {

    messages: count,

    avgResponseTime: times.reduce((a, b) => a + b, 0) / times.length,

    errorRate: (errors / count * 100).toFixed(2) + '%'

    };

    }

    return report;

    }

    ```

    8. Best Practices

    Security

  • Validate webhooks: Always verify signatures
  • Rate limiting: Implement per-user and per-platform limits
  • Input sanitization: Clean user input before processing
  • Secret management: Use environment variables, never commit secrets
  • Performance

  • Async processing: Don't block webhook responses
  • Queue system: Use Redis/RabbitMQ for high load
  • Caching: Cache access tokens and frequent responses
  • Connection pooling: Reuse HTTP connections
  • User Experience

  • Typing indicators: Show bot is processing
  • Error messages: User-friendly error handling
  • Help commands: Clear documentation
  • Response formatting: Platform-appropriate markdown
  • Troubleshooting

    Telegram Issues

    Problem: Webhook not receiving messages

    ```bash

    Check webhook status

    curl https://api.telegram.org/bot/getWebhookInfo

    Delete webhook

    curl https://api.telegram.org/bot/deleteWebhook

    Set webhook again

    curl -X POST https://api.telegram.org/bot/setWebhook \

    -d "url=https://your-domain.com/webhook/telegram"

    ```

    Discord Issues

    Problem: Bot not responding to messages

  • Check "Message Content Intent" is enabled
  • Verify bot has "Read Messages" permission in channel
  • Check bot role is above other roles
  • Feishu Issues

    Problem: Access token expired

    ```javascript

    // Always refresh token before API calls

    const token = await this.getAccessToken();

    ```

    QQ Issues

    Problem: go-cqhttp login failed

  • Use QR code login instead of password
  • Check if account requires device verification
  • Try different go-cqhttp version
  • Conclusion

    You now have OpenClaw running across 5 major messaging platforms! This multi-channel setup allows you to:

  • Reach users globally (Telegram, Discord)
  • Serve China market (WeChat, QQ, Feishu)
  • Provide unified AI experience
  • Scale efficiently with shared infrastructure
  • Next Steps:

  • OpenClaw Model Configuration
  • OpenClaw Skills Guide
  • OpenClaw Performance Optimization
  • Need Help?

    Get professional assistance with your multi-channel OpenClaw deployment:

    Request Free Consultation →

    ---

    About the Author: The OpenClaw team maintains this open-source project and provides enterprise support for multi-channel deployments.

    Last Updated: March 21, 2026

    #OpenClaw#Telegram bot#Discord bot#Feishu bot#QQ bot#WeChat bot#multi-channel#chatbot deployment#messaging platforms
    Get Started

    Ready to Optimize Your AI Strategy?

    Get your free AI audit and discover optimization opportunities.

    START FREE AUDIT