Работа с Форумами и Топиками
Telegram позволяет преобразовывать супергруппы и личные сообщения в Форумы. В этом режиме сообщения разделяются на отдельные ветки — Топики (Topics).
ZenithGram предоставляет удобный API для управления топиками и отправки сообщений в конкретные ветки.
Управление топиками
Для работы с темами в классе ZG предусмотрен набор методов. Если бот получает обновление из конкретного топика, thread_id подставляется автоматически.
Создание и редактирование
$bot->onCommand('new_topic', '/create')->func(function(ZG $tg) {
// 1. Создаем новый топик
// Возвращает массив с информацией о созданном топике
$response = $tg->createTopic(
name: 'Обсуждение проекта',
icon_custom_emoji_id: '53101321...' // Опционально: кастомный эмодзи
);
$topicId = $tg->getMsgThreadId();
// 2. Отправляем сообщение в этот топик
$tg->msg("Топик создан! Добро пожаловать.")
->send(message_thread_id: $topicId);
// 3. Редактируем название (например, через время)
$tg->editTopic(
name: 'Архив проекта',
thread_id: $topicId // Явно указываем ID
);
});Управление состоянием (Закрыть/Открыть/Удалить)
// Закрываем текущий топик (откуда пришла команда)
$bot->onCommand('close', '/close')->func(function(ZG $tg) {
$tg->closeTopic();
$tg->msg("Тема закрыта администратором.")->send();
});
// Удаляем топик по ID
$tg->deleteTopic(thread_id: 12345);Работа с темой "General" (Основная)
Основная тема имеет особый статус, поэтому для неё существуют отдельные методы:
$tg->editGeneralTopic('Главный чат');
$tg->hideGeneralTopic(); // Скрыть из списка
$tg->unpinGeneralTopicMessages(); // Открепить все сообщенияОтправка сообщений в топики
Класс Message (через метод $tg->msg()) умеет отправлять сообщения в конкретные ветки.
- Автоматически: Если вы отвечаете на сообщение (
reply) или просто пишете в контексте обработчика, библиотека сама определитmessage_thread_id. - Вручную: Если нужно написать в другой топик.
// Отправка в конкретный топик ID 55
$tg->msg('Привет в ветку 55!')->send(message_thread_id: 55);
// Отправка в "General" (обычно null, но зависит от настроек чата)
$tg->msg('Привет всем!')->send(message_thread_id: null);MessageDraft в Топиках
MessageDraft — это инструмент для создания "живых" сообщений (стриминга), которые обновляются в реальном времени. Это идеально подходит для отображения прогресса операций, логов или загрузки данных.
При работе в форумах важно передавать message_thread_id в метод send(), чтобы драфт появился в нужной ветке.
Особые условия
Такой тип сообщений возможно использовать только в лс и при условии, что в вашем боте включен режим ThreadedMode
Пример: Система Тикетов (Ticket System)
В этом примере мы создадим топик для обращения пользователя и будем отображать статус обработки "в прямом эфире" с помощью MessageDraft.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use ZenithGram\ZenithGram\ZG;
use ZenithGram\ZenithGram\Bot;
use ZenithGram\ZenithGram\Enums\MessageParseMode;
$tg = ZG::create(BOT_TOKEN);
$bot = new Bot($tg);
$bot->onCommand('help', '/help')
->func(function(ZG $tg) {
// 1. Создаем топик для пользователя
$user = $tg->getUser();
$topicName = "Тикет #{$user->id}: {$user->firstName}";
$response = $tg->createTopic($topicName);
$threadId = $response['result']['message_thread_id'];
// 2. Создаем Draft в ЭТОМ топике
// Важно: передаем message_thread_id в send()
$draft = $tg->msgDraft("⏳ <b>Инициализация системы поддержки...</b>")
->parseMode(MessageParseMode::HTML)
->send(message_thread_id: $threadId);
// Эмуляция работы (в реальности тут запросы к БД/API)
sleep(1);
// 3. Обновляем сообщение (ID чата и треда драфт помнит сам)
$draft->setText("🔍 <b>Поиск свободного оператора...</b>")->send();
sleep(2);
// 4. Финальное обновление драфта
$draft->setText("✅ <b>Оператор найден!</b>\nОпишите вашу проблему ниже.")->send();
// 5. Отправляем уведомление пользователю в ЛС или общий чат
$tg->msg("Для вас создан тикет. Перейдите в тему: $topicName")->send();
});
$bot->run();Как это работает внутри
msgDraft()создает объект сообщения.- Первый вызов
send(message_thread_id: $id)отправляет сообщение в API и запоминаетmessage_id,chat_idиmessage_thread_idвнутри объекта$draft. - Последующие вызовы
setText()->send()используют запомненные данные для вызова методаeditMessageText, автоматически попадая в нужный топик.