Запускаем бота через Telegram SDK
Результат
Вы запустите обычного echo-бота, изменив только адрес Bot API. Скрепа проверена
с python-telegram-bot 22.8, aiogram 3.29.1 и Telegraf 4.16.3; выберите
один из трёх вариантов ниже.
Что понадобится
- пройденный быстрый старт;
- запущенный gateway профиля
telegram-v1-core-preview-4на127.0.0.1:8081; - bot token в окружении;
- Python 3 для первых двух вариантов либо Node.js для Telegraf.
export SKREPA_BOT_TOKEN='ваш-token-из-BotFather'
Перед запуском SDK убедитесь, что webhook отключён:
curl --fail-with-body -sS -X POST \
"http://127.0.0.1:8081/bot${SKREPA_BOT_TOKEN}/deleteWebhook"
Вариант A: python-telegram-bot
python3 -m venv .venv
.venv/bin/python -m pip install 'python-telegram-bot==22.8'
Создайте echo_bot.py:
import os
from telegram import Update
from telegram.ext import Application, ContextTypes, MessageHandler, filters
async def echo(update: Update, _context: ContextTypes.DEFAULT_TYPE) -> None:
if update.message and update.message.text:
await update.message.reply_text(update.message.text)
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(MessageHandler(filters.TEXT, echo))
application.run_polling(allowed_updates=["message"])
.venv/bin/python echo_bot.py
Вариант B: aiogram
python3 -m venv .venv
.venv/bin/python -m pip install 'aiogram==3.29.1'
Создайте echo_bot.py:
import asyncio
import os
from aiogram import Bot, Dispatcher, F
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.client.telegram import TelegramAPIServer
from aiogram.types import Message
dp = Dispatcher()
@dp.message(F.text)
async def echo(message: Message) -> None:
await message.answer(message.text)
async def main() -> None:
session = AiohttpSession(
api=TelegramAPIServer.from_base("http://127.0.0.1:8081")
)
bot = Bot(token=os.environ["SKREPA_BOT_TOKEN"], session=session)
await dp.start_polling(bot, allowed_updates=["message"])
asyncio.run(main())
.venv/bin/python echo_bot.py
Вариант C: Telegraf
npm init -y
npm install 'telegraf@4.16.3'
Создайте echo_bot.cjs:
const { Telegraf } = require('telegraf')
const bot = new Telegraf(process.env.SKREPA_BOT_TOKEN, {
telegram: { apiRoot: 'http://127.0.0.1:8081' },
})
bot.on('text', (ctx) => ctx.reply(ctx.message.text))
bot.launch({ allowedUpdates: ['message'] })
node echo_bot.cjs
Как проверить результат
- Откройте диалог с ботом в клиенте Скрепы.
- Отправьте строку
SDK работает. - Бот должен ответить той же строкой.
- Остановите пример с помощью
Ctrl+C.
SDK самостоятельно вызывает getMe, управляет polling и формирует
sendMessage. Суффикс /bot в python-telegram-bot.base_url обязателен:
библиотека добавляет к нему token и имя метода.
Типичные ошибки
| Симптом | Что проверить |
|---|---|
SDK обращается к api.telegram.org | base URL или apiRoot не передан при создании клиента |
HTTP 401 при инициализации | SKREPA_BOT_TOKEN экспортирован в том же терминале и остаётся действующим |
HTTP 409 при polling | webhook не удалён либо другой процесс уже получает updates этого runtime |
| бот видит сообщения, но не отвечает | обработчик зарегистрирован до запуска, входящее событие содержит текст |
ошибка unknown private chat | отвечайте через объект входящего update; произвольный Telegram chat_id gateway не знает |
Node.js искажает User.id, Chat.id или Message.message_id | обновите gateway до профиля preview-4; эти id укладываются в безопасные 52 бита |
Что гарантирует gateway
- стандартные GET, JSON POST и form-urlencoded запросы этих SDK принимаются без Skrepa-specific веток в обработчиках;
- объекты
User,Chat,Message,Updateи ошибки имеют стабильную Telegram-compatible форму активного профиля; User.id,Chat.idиMessage.message_idбезопасны для JavaScriptnumber;update_idобрабатывайте как отдельный курсор доставки;- входящие и исходящие приватные сообщения проходят через защищённый транспорт, хотя код SDK работает с обычным текстом на локальном HTTP-адресе;
- delivery state и криптографическое состояние принадлежат gateway, поэтому каталог его состояния должен сохраняться между перезапусками.