В этой статье
Если под «GPT-3 чат-ботом» вы имеете в виду своего Telegram-бота, который отвечает через OpenAI API, схема выглядит так: Telegram принимает сообщение, ваш Python-код передаёт его модели, а затем отправляет полученный текст обратно пользователю. Это не готовый бот из каталога и не подписка ChatGPT, а небольшая собственная интеграция.
Что понадобится
Нужны три вещи:
- аккаунт в Telegram;
- токен бота от @BotFather;
- отдельный ключ OpenAI API с доступом к выбранной модели.
Токен Telegram — это пароль от управления ботом. Не вставляйте его в исходный код, Git-репозиторий и сообщения об ошибках. То же правило относится к OPENAI_API_KEY: ключ хранится в переменных окружения и не выводится в лог.
Если вам нужно только личное общение с ChatGPT, а не собственный Telegram-бот, можно посмотреть каталог услуг Amber Market. В нём есть карточка ChatGPT с месячными вариантами; условия и цены проверьте перед оформлением. Такая подписка не является пополнением OpenAI API и сама по себе не выдаёт ключ для созданного вами бота: для программы всё равно нужен отдельный доступ к API.
Для примера нужен Python 3.10 или новее и официальная библиотека OpenAI. Установите её в виртуальном окружении:
python -m venv .venv
source .venv/bin/activate # Windows: .venv\\Scripts\\activate
python -m pip install openai
Создайте бота через @BotFather командой /newbot и сохраните выданный токен. Затем задайте переменные окружения. В PowerShell это можно сделать так:
$env:TELEGRAM_BOT_TOKEN = "токен-от-BotFather"
$env:OPENAI_API_KEY = "ключ-OpenAI"
$env:OPENAI_MODEL = "gpt-3.5-turbo-0125"
В Linux или macOS используются команды export. Значение OPENAI_MODEL здесь только пример: gpt-3.5-turbo-0125 относится к legacy-линейке GPT-3.5, поэтому сначала проверьте, доступен ли этот идентификатор в вашем проекте по актуальной документации и каталогу моделей OpenAI. Если API вернёт ошибку о недоступной модели, замените только это значение на идентификатор из текущего каталога OpenAI.
Как работает первый запуск
Для учебного бота удобнее начать с long polling. Программа периодически вызывает Telegram Bot API методом getUpdates, получает новые сообщения и отправляет ответы методом sendMessage. Для sendMessage нужны chat_id и текст ответа. Webhook решает ту же задачу другим способом, но для первого запуска потребовал бы публичного HTTPS-адреса. Long polling и webhook одновременно для одного бота не используются — это два взаимоисключающих способа получать обновления, описанных в Telegram Bot API.
Сохраните следующий код в bot.py:
import json
import os
import time
import urllib.error
import urllib.parse
import urllib.request
from openai import OpenAI
TELEGRAM_TOKEN = os.environ["TELEGRAM_BOT_TOKEN"]
MODEL = os.environ.get("OPENAI_MODEL", "gpt-3.5-turbo-0125")
TELEGRAM_API = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}"
client = OpenAI() # библиотека сама читает OPENAI_API_KEY
def telegram_call(method: str, data: dict) -> dict:
"""Вызвать метод Telegram Bot API и вернуть JSON-ответ."""
body = urllib.parse.urlencode(
{key: value for key, value in data.items() if value is not None}
).encode("utf-8")
request = urllib.request.Request(
f"{TELEGRAM_API}/{method}",
data=body,
method="POST",
)
with urllib.request.urlopen(request, timeout=40) as response:
result = json.load(response)
if not result.get("ok"):
raise RuntimeError(f"Telegram API error: {result}")
return result
def make_answer(user_text: str) -> str:
completion = client.chat.completions.create(
model=MODEL,
messages=[
{
"role": "system",
"content": "Отвечай по-русски, кратко и по существу.",
},
{"role": "user", "content": user_text},
],
)
answer = completion.choices[0].message.content
return answer or "Модель не вернула текстовый ответ."
def main() -> None:
offset = None
print(f"Бот запущен, модель: {MODEL}")
while True:
try:
updates = telegram_call(
"getUpdates",
{
"timeout": 30,
"offset": offset,
"allowed_updates": json.dumps(["message"]),
},
).get("result", [])
for update in updates:
offset = update["update_id"] + 1
message = update.get("message", {})
text = message.get("text")
chat = message.get("chat", {})
if not text or "id" not in chat:
continue
if text == "/start":
answer = "Напишите вопрос, и я передам его модели."
else:
answer = make_answer(text)
for start in range(0, len(answer), 2000):
telegram_call(
"sendMessage",
{"chat_id": chat["id"], "text": answer[start:start + 2000]},
)
except (urllib.error.URLError, TimeoutError, OSError) as error:
print(f"Сетевая ошибка: {type(error).__name__}. Повтор через 5 секунд.")
time.sleep(5)
except Exception as error:
# Не выводим текст исключения: он может содержать секреты.
print(f"Ошибка обработки: {type(error).__name__}. Повтор через 5 секунд.")
time.sleep(5)
if __name__ == "__main__":
main()
В коде offset не даёт обрабатывать один и тот же update снова после следующего запроса. Поле message.text отбрасывает сообщения без текста, а chat.id определяет диалог, куда нужно вернуть результат. Вызов client.chat.completions.create передаёт модели список сообщений с ролями system и user; такой формат и возвращаемое сообщение assistant описаны в справочнике Chat Completions OpenAI. Структура доступных параметров зависит от конкретной модели.
Как проверить бота по шагам
Сначала убедитесь, что Telegram-токен действителен. В отдельном окне терминала выполните запрос к getMe:
curl "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getMe"
В Windows PowerShell можно выполнить:
Invoke-RestMethod "https://api.telegram.org/bot$env:TELEGRAM_BOT_TOKEN/getMe"
В успешном ответе будет ok: true и данные бота. После этого запустите программу:
python bot.py
Откройте бота в Telegram, отправьте /start, затем обычную фразу. В первом случае сработает локальное приветствие, во втором появится запрос к OpenAI API и ответ модели.
Если Telegram отвечает, но модель недоступна, проверьте текст ошибки и значение OPENAI_MODEL. Для старого идентификатора GPT-3.5 доступ может отличаться от проекта к проекту; это не означает, что нужно менять весь код. Замените модель на доступный идентификатор и повторите запуск.
Проверьте также журналы терминала: в них не должны появиться значения TELEGRAM_BOT_TOKEN или OPENAI_API_KEY. Если ключ случайно попал в публичный репозиторий или лог, отзовите его и создайте новый.
Что добавить перед публикацией
Long polling подходит для небольшого собственного бота и проверки идеи. Для постоянной работы понадобятся отдельный процесс, ограничение частоты запросов, хранение истории диалога и более аккуратная обработка ошибок OpenAI. Когда появится публичный HTTPS-сервис, можно перейти на webhook. Масштабирование и очередь запросов лучше проектировать отдельно: учебный цикл выше намеренно оставляет один запрос к модели последовательным.
Если нужен именно готовый бесплатный бот в Telegram, а не разработка своей интеграции, это уже другая задача — для неё пригодится отдельная инструкция о бесплатном боте.