Forum Topics & Supergroups (message_thread_id)

Raw MD
Create, edit, close, and organize Telegram Forum topics, manage custom icon colors, and route updates via message_thread_id.

Telegram Forum Supergroups Overview

Telegram allows large supergroups to enable Topics, transforming single chat streams into threaded sub-forums (e.g. #General, #Announcements, #Support). Every topic has a unique message_thread_id (which equals the message_id of the topic creation action).

How Thread Routing Works
To send or reply to a message inside a specific topic, you simply supply 'message_thread_id' => $threadId in your sendMessage, sendPhoto, or sendDocument payload. If omitted, messages are posted to the General topic.

1. Creating Forum Topics Programmatically (createForumTopic)

Bots can programmatically spawn new discussion topics for customer tickets, project alerts, or product categories:

PHP — createForumTopic Implementation
<?php
// ── Botlify Cloud .env — auto-injected, never hardcode secrets ──
$BOT_TOKEN     = getenv('BOT_TOKEN');     // Telegram bot token from @BotFather
$ADMIN_CHAT_ID = getenv('ADMIN_CHAT_ID'); // Your numeric admin Telegram user ID
$BOT_USERNAME  = getenv('BOT_USERNAME');  // Bot username without @

declare(strict_types=1);

/**
 * Creates a dedicated topic with custom icon color
 * Supported RGB decimal icon colors:
 * 7322096 (Blue), 16766590 (Yellow), 13338331 (Violet), 9367192 (Green), 16749490 (Rose), 16478047 (Red)
 */
function create_support_ticket_topic(string|int $chatId, int $ticketId, string $customerName): int {
    $res = bot('createForumTopic', [
        'chat_id'          => $chatId,
        'name'             => "🎫 Ticket #{$ticketId} — {$customerName}",
        'icon_color'       => 7322096, // Telegram Blue
        // 'icon_custom_emoji_id' => '5368324170671202286' // Optional custom emoji
    ]);

    if ($res['ok'] ?? false) {
        $threadId = $res['result']['message_thread_id'];
        
        // Post welcome banner inside the new topic thread
        bot('sendMessage', [
            'chat_id'           => $chatId,
            'message_thread_id' => $threadId,
            'text'              => "👋 Support Topic Created for {$customerName}\n\nAdmins can reply directly in this thread. Customer will receive messages in real time.",
            'parse_mode'        => 'HTML'
        ]);

        return $threadId;
    }

    return 0;
}

2. Routing Incoming Messages Within Forum Threads

When users post messages in a forum supergroup, Telegram includes message_thread_id in the incoming webhook. Always capture and preserve this ID when responding:

PHP — Topic Thread Router
<?php
// ── Botlify Cloud .env — auto-injected, never hardcode secrets ──
$BOT_TOKEN     = getenv('BOT_TOKEN');     // Telegram bot token from @BotFather
$ADMIN_CHAT_ID = getenv('ADMIN_CHAT_ID'); // Your numeric admin Telegram user ID
$BOT_USERNAME  = getenv('BOT_USERNAME');  // Bot username without @

declare(strict_types=1);

// Detect if message was sent inside a specific forum topic
$threadId = $message['message_thread_id'] ?? null;

if ($text === '/status') {
    $replyPayload = [
        'chat_id'    => $chatId,
        'text'       => '✅ Botlify Cloud worker active in this thread.',
        'parse_mode' => 'HTML'
    ];

    // If message arrived inside a topic, reply strictly inside that topic
    if ($threadId !== null) {
        $replyPayload['message_thread_id'] = $threadId;
    }

    bot('sendMessage', $replyPayload);
    http_response_code(200);
    exit;
}

3. Editing, Closing, Reopening & Deleting Topics

When tickets are resolved or projects complete, bots can close or archive the topic:

PHP — Topic Lifecycle Management
<?php
// ── Botlify Cloud .env — auto-injected, never hardcode secrets ──
$BOT_TOKEN     = getenv('BOT_TOKEN');     // Telegram bot token from @BotFather
$ADMIN_CHAT_ID = getenv('ADMIN_CHAT_ID'); // Your numeric admin Telegram user ID
$BOT_USERNAME  = getenv('BOT_USERNAME');  // Bot username without @

declare(strict_types=1);

// 1. Edit Topic Title
function rename_topic(string|int $chatId, int $threadId, string $newTitle): void {
    bot('editForumTopic', [
        'chat_id'           => $chatId,
        'message_thread_id' => $threadId,
        'name'              => $newTitle
    ]);
}

// 2. Close Topic (Prevents further messages from regular members)
function close_resolved_topic(string|int $chatId, int $threadId): void {
    bot('closeForumTopic', [
        'chat_id'           => $chatId,
        'message_thread_id' => $threadId
    ]);
}

// 3. Reopen Topic
function reopen_topic(string|int $chatId, int $threadId): void {
    bot('reopenForumTopic', [
        'chat_id'           => $chatId,
        'message_thread_id' => $threadId
    ]);
}

// 4. Delete Topic Completely
function delete_topic(string|int $chatId, int $threadId): void {
    bot('deleteForumTopic', [
        'chat_id'           => $chatId,
        'message_thread_id' => $threadId
    ]);
}
Botlify Cloud Runtime
Credentials are auto-injected in .env — always load them with getenv(): BOT_TOKEN, ADMIN_CHAT_ID, BOT_USERNAME. Main database: database.db (SQLite, WAL mode). Runtime errors: error.log. Quick test: send to $ADMIN_CHAT_ID. Full details: Runtime Reference.