Пользователи и чаты
Каналы
Узнайте, как работать с Telegram-каналами на PHP: отправка постов, редактирование, получение количества подписчиков и особенности работы с группами обсуждения.
Канал (Channel) в Telegram — это инструмент для публичного вещания на неограниченную аудиторию. В отличие от групп (о которых мы говорили в главе Группы), обычные участники канала не могут отправлять сообщения, оставлять медиафайлы или видеть список других подписчиков. Писать в канал могут только администраторы (включая вашего бота), а пользователи могут лишь читать публикации, оставлять реакции и писать комментарии в привязанной группе обсуждения.
Идентификаторы канала
У каждого канала есть два типа идентификаторов:
- Публичный юзернейм (username) — например,
@my_channel_news. Он настраивается в свойствах публичного канала. Вы можете использовать его напрямую в Bot API вместо числового ID. - Внутренний числовой идентификатор (chat_id) — уникальный ID, который всегда начинается с префикса
-100(например,-1001234567890).
Для надёжной работы бота всегда используйте числовой chat_id. Юзернейм канала администраторы могут изменить в любой момент, что сломает логику бота, если юзернейм захардкожен в коде. Числовой ID канала остаётся неизменным на протяжении всей его жизни.
Как узнать ID канала? Самый простой способ — переслать любой пост из этого канала специальному боту (например, @userinfobot), либо вызвать метод getChat, передав туда публичный юзернейм канала.
Добавление бота в канал
Бот не может самостоятельно подписаться на канал или войти в него. Чтобы бот мог публиковать посты, его необходимо вручную добавить в канал в качестве администратора (через интерфейс Telegram: Информация о канале → Администраторы → Добавить администратора).
При добавлении обязательно предоставьте боту следующие права (permissions):
post_messages(Публикация сообщений) — без этого права бот не сможет отправлять посты.edit_messages(Редактирование сообщений) — позволяет изменять уже опубликованные ботом посты.delete_messages(Удаление сообщений) — даёт право удалять публикации.
Если вы попытаетесь отправить сообщение в канал, где бот не является администратором с правом публикации, Telegram API вернёт ошибку 400 Bad Request: chat not found или 403 Forbidden: bot is not a member of the channel.
Отправка постов в канал
Для отправки постов используется стандартный метод sendMessage. Вы можете форматировать текст с помощью HTML или Markdown, прикреплять медиафайлы и добавлять Inline-кнопки.
Используем функцию telegramApi(), которую мы создали в главе Первый запрос: getMe. Здесь мы вызываем её для отправки форматированного поста в канал.
<?php
// Токен получаем исключительно из переменных окружения
$token = getenv('TELEGRAM_BOT_TOKEN');
if (!$token) {
throw new RuntimeException('Переменная окружения TELEGRAM_BOT_TOKEN не задана');
}
// ID канала (всегда начинается с -100)
$channelId = '-1001234567890';
try {
// Отправляем пост с HTML-разметкой
$response = telegramApi($token, 'sendMessage', [
'chat_id' => $channelId,
'text' => "📢 <strong>Важное обновление проекта!</strong>\n\nМы запустили интеграцию с Telegram-каналами. Теперь бот умеет публиковать посты автоматически.",
'parse_mode' => 'HTML',
'disable_web_page_preview' => true
]);
// Выводим результат для отладки в терминале
echo "Пост успешно отправлен!\n";
echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n";
} catch (Exception $e) {
echo "Ошибка при отправке: " . $e->getMessage() . "\n";
}
При успешном вызове API возвращает объект Message. Обратите внимание, что структура ответа для канала имеет свои особенности:
{
"ok": true,
"result": {
"message_id": 145,
"sender_chat": {
"id": -1001234567890,
"title": "Мой тестовый канал",
"username": "my_test_channel",
"type": "channel"
},
"chat": {
"id": -1001234567890,
"title": "Мой тестовый канал",
"username": "my_test_channel",
"type": "channel"
},
"date": 1710000000,
"text": "📢 Важное обновление проекта!\n\nМы запустили интеграцию с Telegram-каналами. Теперь бот умеет публиковать посты автоматически.",
"entities": [
{
"offset": 2,
"length": 26,
"type": "bold"
}
]
}
}
Что анализировать в ответе:
message_id— уникальный идентификатор поста в рамках этого канала. Сохраните его в базу данных, если планируете позже редактировать или удалять этот пост.chat.typeимеет значениеchannel, что подтверждает отправку именно в канал.- Поле
sender_chatуказывает, что автором сообщения является сам канал, а не конкретный пользователь.
Получение информации о канале
Иногда боту нужно проверить количество подписчиков канала или получить его актуальное описание. Для этого используется метод getChat.
Используем функцию telegramApi(), которую мы создали в главе Первый запрос: getMe. Вызываем метод getChat для получения метаданных канала.
<?php
$token = getenv('TELEGRAM_BOT_TOKEN');
if (!$token) {
throw new RuntimeException('Переменная окружения TELEGRAM_BOT_TOKEN не задана');
}
$channelId = '-1001234567890';
try {
$chatInfo = telegramApi($token, 'getChat', [
'chat_id' => $channelId
]);
echo "Информация о канале:\n";
echo "Название: " . $chatInfo['title'] . "\n";
echo "Описание: " . ($chatInfo['description'] ?? 'нет описания') . "\n";
// Количество подписчиков доступно в поле member_count при вызове getChat
if (isset($chatInfo['member_count'])) {
echo "Количество подписчиков: " . $chatInfo['member_count'] . "\n";
}
} catch (Exception $e) {
echo "Не удалось получить информацию: " . $e->getMessage() . "\n";
}
Пример JSON-ответа от метода getChat для канала:
{
"ok": true,
"result": {
"id": -1001234567890,
"title": "Мой тестовый канал",
"username": "my_test_channel",
"type": "channel",
"description": "Канал для тестирования Bot API на PHP",
"member_count": 1420,
"linked_chat_id": -1001987654321
}
}
Важные поля:
member_count— текущее число подписчиков канала. Обратите внимание: это значение кэшируется на стороне Telegram и может обновляться с задержкой в несколько минут.linked_chat_id— идентификатор супергруппы, которая привязана к каналу в качестве чата обсуждения (комментариев). Если чат не привязан, этого поля в ответе не будет.
Группа обсуждения (Комментарии)
Если к каналу привязана группа обсуждения (Discussion Group), под каждым постом появляется кнопка «Прокомментировать».
С технической точки зрения, когда бот или администратор публикует пост в канале, Telegram автоматически пересылает этот пост в привязанную супергруппу. Все комментарии пользователей к этому посту пишутся внутри супергруппы в виде ответов (replies) на пересланное сообщение.
Если ваш бот состоит и в канале, и в группе обсуждения, он будет получать апдейты типа message из группы обсуждения. В таких сообщениях поле message.reply_to_message будет содержать оригинальный пост из канала. Подробнее о работе с супергруппами читайте в главе Группы.
Редактирование и удаление постов
Редактирование постов в канале происходит точно так же, как и в обычных чатах, но с обязательным указанием chat_id канала и message_id поста.
Используем функцию safeEditMessageText(), которую мы реализовали в главе Редактирование и удаление. Она позволяет безопасно обновить текст ранее отправленного поста.
<?php
$token = getenv('TELEGRAM_BOT_TOKEN');
if (!$token) {
throw new RuntimeException('Переменная окружения TELEGRAM_BOT_TOKEN не задана');
}
$channelId = '-1001234567890';
$messageId = 145; // ID поста, полученный при отправке
// Безопасно редактируем текст поста
$success = safeEditMessageText(
$token,
$channelId,
$messageId,
"📢 <strong>Обновление проекта!</strong>\n\nТекст поста был успешно отредактирован ботом.",
'HTML'
);
if ($success) {
echo "Пост успешно отредактирован!\n";
} else {
echo "Не удалось отредактировать пост.\n";
}
Важные отличия каналов от групп
При разработке логики для каналов учитывайте следующие архитектурные отличия:
- Отсутствие событий вступления/выхода: Telegram не присылает стандартные апдейты
new_chat_membersилиleft_chat_member, когда пользователи подписываются на канал или покидают его. Чтобы отслеживать подписки, нужно использовать специальный тип обновленийchat_member(требует предварительной настройки webhook или getUpdates). - Специфика Inline-кнопок: Если вы прикрепите Inline-клавиатуру к посту в канале, нажатия на кнопки с
callback_dataне будут отправлять апдейтыcallback_queryнапрямую из канала. Telegram доставитcallback_queryвашему боту только в том случае, если пользователь ранее запустил бота в личных сообщениях. Кнопки сurlработают всегда и без ограничений. - Анонимность авторов: По умолчанию посты публикуются от имени канала. В настройках канала можно включить «Подписи авторов», тогда в объекте
Messageпоявится полеauthor_signatureс именем администратора, опубликовавшего пост.
Дальше: HTTP-клиент на PHP