ChatGPT через Telegram: как сделать бота на Python

В этой статье

Готовый Telegram-бот с ответами ChatGPT можно найти за пару минут, но это не то же самое, что собственный бот. В своём варианте вы сами храните токены, выбираете модель в API-проекте и понимаете, на каком участке возникла ошибка. Ниже — минимальная локальная схема: Telegram получает сообщение, Python передаёт его в OpenAI API, а ответ возвращается в тот же чат.

Что понадобится

Для примера нужны:

  • аккаунт Telegram и доступ к @BotFather;
  • Python 3.10 или новее;
  • отдельный API-ключ OpenAI и модель, доступная вашему API-проекту;
  • установленный пакет python-telegram-bot ветки 22.x.

Подписка ChatGPT и доступ к OpenAI API — разные вещи. Для программного вызова нужен отдельный API-ключ, а доступность конкретной модели и условия биллинга проверяются в вашем API-проекте на момент запуска. Это соответствует сценарию первого API-запроса OpenAI. Developer quickstart OpenAI API

Если хочется сначала проверить только API, без Telegram-обвязки, можно выполнить отдельный первый запрос к OpenAI API из Python. Так проще понять, что ключ и модель работают, прежде чем искать ошибку в обработчике сообщений.

Создание такого бота решается кодом и API-ключом, поэтому покупка готового цифрового сервиса для самой инструкции не нужна. Если позже понадобится отдельный платный сервис для работы рядом с ботом, каталог услуг Amber Market доступен по ссылке на каталог услуг, но в этом примере он не требуется.

Создайте бота в Telegram

  1. Откройте в Telegram чат с @BotFather.
  2. Отправьте команду /newbot.
  3. Укажите отображаемое имя бота.
  4. Задайте username, который заканчивается на bot.
  5. Скопируйте выданный токен.

Токен Telegram — это пароль от управления ботом. Не вставляйте его в Python-файл, README или публичный репозиторий. Telegram описывает этот порядок в руководстве для разработчиков; если токен утёк, его нужно перевыпустить через @BotFather. Bots: An introduction for developers

Отдельно создайте API-ключ OpenAI в нужном API-проекте. В статье используются условные значения: настоящие ключи должны храниться только в переменных окружения или другом локальном хранилище секретов.

Подготовьте проект Python

Создайте пустую папку и виртуальное окружение:

python -m venv .venv

Активируйте его в Windows:

.venv\Scripts\Activate.ps1

Или в macOS/Linux:

source .venv/bin/activate

Установите зафиксированную для примера ветку библиотек:

pip install "python-telegram-bot==22.8" openai

python-telegram-bot 22.8 собирает приложение через ApplicationBuilder и позволяет добавить обработчик текстовых сообщений. Если позже вы перейдёте на другую major-версию, синтаксис нужно сверить с её документацией. Документация python-telegram-bot

Передайте ключи через переменные окружения

В PowerShell текущего окна задайте значения так:

$env:TELEGRAM_BOT_TOKEN = "токен-от-BotFather"
$env:OPENAI_API_KEY = "ваш-api-ключ"
$env:OPENAI_MODEL = "доступная-модель-в-вашем-проекте"

В macOS/Linux команда выглядит так:

export TELEGRAM_BOT_TOKEN='токен-от-BotFather'
export OPENAI_API_KEY='ваш-api-ключ'
export OPENAI_MODEL='доступная-модель-в-вашем-проекте'

Не добавляйте эти строки с реальными значениями в Git. До запуска полезно проверить только наличие переменных, не печатая их содержимое:

import os

for name in ("TELEGRAM_BOT_TOKEN", "OPENAI_API_KEY", "OPENAI_MODEL"):
    if not os.getenv(name):
        raise RuntimeError(f"Не задана переменная окружения: {name}")

Минимальный бот с polling

Сохраните следующий код в bot.py:

import logging
import os

from openai import AsyncOpenAI
from telegram import Update
from telegram.ext import (
    ApplicationBuilder,
    CommandHandler,
    ContextTypes,
    MessageHandler,
    filters,
)


logging.basicConfig(
    format="%(asctime)s %(levelname)s %(name)s: %(message)s",
    level=logging.INFO,
)


def required_env(name: str) -> str:
    value = os.getenv(name)
    if not value:
        raise RuntimeError(f"Не задана переменная окружения: {name}")
    return value


telegram_token = required_env("TELEGRAM_BOT_TOKEN")
openai_key = required_env("OPENAI_API_KEY")
model = required_env("OPENAI_MODEL")
openai_client = AsyncOpenAI(api_key=openai_key)


async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    if update.message:
        await update.message.reply_text(
            "Напишите вопрос, и я передам его в OpenAI API."
        )


async def answer(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    if not update.message or not update.message.text:
        return

    try:
        response = await openai_client.responses.create(
            model=model,
            input=update.message.text,
        )
        text = response.output_text or "Модель не вернула текстовый ответ."
        for offset in range(0, len(text), 2000):
            await update.message.reply_text(text[offset:offset + 2000])
    except Exception:
        logging.exception("Ошибка при запросе к OpenAI API")
        await update.message.reply_text(
            "Не удалось получить ответ. Проверьте журнал запуска и настройки API."
        )


def main() -> None:
    application = ApplicationBuilder().token(telegram_token).build()
    application.add_handler(CommandHandler("start", start))
    application.add_handler(
        MessageHandler(filters.TEXT & ~filters.COMMAND, answer)
    )
    application.run_polling()


if __name__ == "__main__":
    main()

Здесь нет webhook и отдельного веб-сервера. run_polling() запускает получение обновлений через Telegram Bot API: библиотека периодически ждёт новые сообщения, а обработчик answer получает текст и передаёт его в Responses API. Для локального учебного бота этого достаточно; Telegram также поддерживает webhook как другой способ доставки обновлений. Telegram Bot API

Запустите и проверьте ответ

В том же окне, где активировано окружение и заданы переменные, запустите:

python bot.py

Проверка идёт по короткому маршруту:

  1. Откройте своего бота по username из @BotFather.
  2. Нажмите Start или отправьте /start.
  3. Убедитесь, что бот прислал приветственное сообщение.
  4. Отправьте обезличенный тестовый запрос, например: Назови три способа проверить JSON в Python.
  5. Проверьте, что ответ пришёл в тот же личный чат.

Если /start не отвечает, сначала посмотрите на окно, где работает python bot.py: процесс должен оставаться запущенным. Если команда отвечает, но обычное сообщение не возвращает текст, проверьте имя переменной OPENAI_MODEL, доступ ключа к этой модели и наличие API-баланса или другого разрешённого условия использования.

Полезно диагностировать слои по очереди. Сначала проверьте отдельный запрос к OpenAI API, затем Telegram-токен и только после этого обработку сообщения. Если нужно отделить проблему API от Python-кода, можно сделать проверку OpenAI API через curl.

Что важно не расширять в первом варианте

Этот пример намеренно решает одну задачу: принять текст и вернуть текстовый ответ. Он не хранит историю диалога в базе данных, не ограничивает частоту запросов, не обрабатывает платежи и не предназначен для production-развёртывания. Такие функции потребуют отдельной архитектуры и проверки безопасности.

Для первого запуска оставьте polling и локальное окружение. Когда бот начнёт работать стабильно, можно отдельно спроектировать хранение контекста, обработку ошибок и переход на webhook. При любом расширении сохраняйте тот же принцип: ключи остаются вне исходного кода, а модель берётся из настроек API-проекта, а не подразумевается автоматически.

Источники

Есть следующая задача?Ещё по теме «Telegram-боты» →