Бот в группах и каналах
Что получится
Один бот будет отвечать в обычной supergroup и protected MLS group,
показывать сведения об участниках, создавать ссылки с заявкой на вступление,
одобрять заявки и публиковать текст в канале.
Что понадобится
- выполненный quickstart по созданию бота и запуску gateway;
- бот с возможностями
groups,channels; - gateway профиля
telegram-v1-core-preview-4наhttp://127.0.0.1:8081; - Python 3 и
SKREPA_BOT_TOKEN; - право администратора для бота в тестовой группе и право публикации в канале.
Проверьте listener и профиль:
set -o pipefail
curl --fail-with-body -sS http://127.0.0.1:8081/healthz | jq .
Запускаем group/channel-бота
python3 -m venv .venv
.venv/bin/python -m pip install 'python-telegram-bot==22.8'
Сохраните как community_bot.py:
import os
from telegram import Update
from telegram.ext import (
Application,
ChatJoinRequestHandler,
CommandHandler,
ContextTypes,
MessageHandler,
filters,
)
async def chat_info(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
chat = await context.bot.get_chat(update.effective_chat.id)
count = await context.bot.get_chat_member_count(chat.id)
admins = await context.bot.get_chat_administrators(chat.id)
await update.effective_message.reply_text(
f"chat_id={chat.id}\ntype={chat.type}\n"
f"members={count}\nadmins={len(admins)}"
)
async def invite(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
link = await context.bot.create_chat_invite_link(
chat_id=update.effective_chat.id,
name="Заявка через community bot",
creates_join_request=True,
)
await update.effective_message.reply_text(link.invite_link)
async def approve(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
request = update.chat_join_request
await context.bot.approve_chat_join_request(
chat_id=request.chat.id,
user_id=request.from_user.id,
)
async def member(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if len(context.args) != 1:
await update.effective_message.reply_text("Использование: /member USER_ID")
return
value = await context.bot.get_chat_member(
update.effective_chat.id, int(context.args[0])
)
await update.effective_message.reply_text(
f"{value.user.full_name}: {value.status}"
)
async def publish(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if len(context.args) < 2:
await update.effective_message.reply_text(
"Использование: /publish CHANNEL_CHAT_ID текст"
)
return
channel_id = int(context.args[0])
sent = await context.bot.send_message(channel_id, " ".join(context.args[1:]))
await update.effective_message.reply_text(
f"Опубликован channel_post {sent.message_id}"
)
async def observe_channel(update: Update, _context: ContextTypes.DEFAULT_TYPE) -> None:
print(f"channel chat_id: {update.effective_chat.id}", flush=True)
application = (
Application.builder()
.token(os.environ["SKREPA_BOT_TOKEN"])
.base_url("http://127.0.0.1:8081/bot")
.base_file_url("http://127.0.0.1:8081/file/bot")
.build()
)
application.add_handler(CommandHandler("chat", chat_info))
application.add_handler(CommandHandler("invite", invite))
application.add_handler(CommandHandler("member", member))
application.add_handler(CommandHandler("publish", publish))
application.add_handler(ChatJoinRequestHandler(approve))
application.add_handler(MessageHandler(filters.ChatType.CHANNEL, observe_channel))
application.run_polling(
allowed_updates=["message", "channel_post", "chat_join_request"]
)
Запустите .venv/bin/python community_bot.py.
Обычная группа и участники
- В клиенте Скрепы создайте обычную группу и добавьте бота.
- Выдайте боту административные права, включая управление приглашениями и участниками.
- Отправьте в группе
/chat. Бот вернёт стабильный отрицательныйchat_id, типsupergroup, число участников и администраторов. - Возьмите numeric user ID из входящего update или журнала своего приложения
и выполните
/member USER_ID.
Для модерации SDK также предоставляет ban_chat_member,
unban_chat_member и promote_chat_member. Эти вызовы подчиняются правам,
которые выдали боту в клиенте Скрепы.
Ссылка и заявка на вступление
- Отправьте
/inviteв группе. - Передайте полученную ссылку второй тестовой учётной записи.
- Откройте ссылку и отправьте заявку из клиента Скрепы.
- Запущенный пример получит
chat_join_requestи одобрит пользователя.
Чтобы разобрать решение вручную, удалите ChatJoinRequestHandler и вызовите
approve_chat_join_request(chat_id, user_id) либо
decline_chat_join_request(chat_id, user_id) из своей бизнес-логики.
Обычная invite-ссылка может иметь expire_date и member_limit. Ссылка с
creates_join_request=True не сочетается с member_limit.
Protected MLS group
Создайте в клиенте protected group, добавьте туда того же бота и снова
отправьте /chat. Прикладной код и Telegram-объекты остаются прежними. Gateway
самостоятельно вводит bot device в MLS group и хранит epoch state в постоянном
state_dir. Первый вход может занять чуть больше времени; дождитесь события об
участии бота перед отправкой команды.
Публикация в канале
- Создайте канал, добавьте бота и разрешите ему публиковать.
- Опубликуйте в канале короткий текст. В терминале появится отрицательный
channel chat_id. - В приватном диалоге с ботом отправьте
/publish CHANNEL_CHAT_ID Новая публикация. - Убедитесь, что текст появился в канале, а бот подтвердил
message_id.
Входящие публикации доступны как update.channel_post; сообщения групп — как
update.message. Изменения участия можно дополнительно получать через
my_chat_member и chat_member, добавив их в allowed_updates.
Типичные ошибки
403: у бота отсутствует нужная роль или право в группе/канале.404 chat not found: gateway ещё не получил membership-событие либо используетсяchat_idдругого runtime.- Заявка не приходит: ссылка создана без
creates_join_requestилиchat_join_requestотсутствует в явномallowed_updates. - Protected group молчит сразу после добавления: дождитесь завершения MLS join;
не удаляйте и не разделяйте между процессами
state_dir. - Публикация попала в группу: проверьте отрицательный ID и
type=channelчерезgetChat.
Границы поддержки
Группы отображаются как supergroup, каналы — как channel. Их ID стабилен
для gateway и безопасен для JavaScript. Каналы поддерживают текстовую
публикацию и административные операции. Media-публикации в каналах и forum
topics пока не поддерживаются. Создание самих групп и каналов выполняется в
клиенте Скрепы.