GPT-бот для Telegram на Python: подключаем OpenAI API и пишем чат-бота с ИИ

GPT-бот для Telegram на Python: подключаем OpenAI API и пишем чат-бота с ИИ

Нейросети сейчас везде, и персональный телеграм-бот на базе GPT - уже давно не редкость. Не будем отставать от трендов и запилим своего карманного ИИ-бота в телеграм. А чтобы он был особенным и уникальным, снабдим его встроенными вариантами системных промптов. 

Как работают нейросети и ChatGPT

Сейчас ИИ используется в медицине, науке, финансах, производстве, транспорте и других областях. Если сильно утрировать, то можно представить нейросеть как огромную конструкцию if … else.

У нас есть n-ное количество входных данных, дальше мы производим с ними различные манипуляции в скрытых слоях. На выходе получаем n-ное количество данных. В данном случае один «выход». Если вам интересно познакомиться с этой технологией подробнее, предлагаю посмотреть этот ролик. Теперь у вас есть представление о нейросетях и можно переходить к проекту.

Регистрация в OpenAI и получение токена GPT

Мы сделаем бота в Telegram, который будет отвечать на наши вопросы осмысленным и связным текстом. А также добавим возможность вести с нами диалог на основе предыдущих сообщений.

Анонсы всех видео, статей и полезностей - в нашем Telegram🔥
Присоединяйтесь, обсуждайте и автоматизируйте!

Чтобы вы могли использовать натренированную модель ИИ от OpenAI (создатели ChatGPT), вам нужен API токен для обращения к API ChatGPT. Получить ключ можно на странице https://platform.openai.com/api-keys. Для регистрации понадобятся электронная почта, имя пользователя и пароль.

Пользователи из России должны заходить на сайт с включённым VPN. Не рекомендуется указывать при регистрации почты на домене .ru.

После регистрации переходим в раздел «API keys»:

Дальше нажимаем «Create new secret key».

В открывшемся окошке копируйте ваш API токен:

Установка библиотек: aiogram 3 и openai

Ставим актуальные версии. С 2024 года OpenAI перешли на новый SDK (версии 1.x), а aiogram - на 3.x. Синтаксис у обоих заметно изменился.

pip install aiogram openai python-dotenv
  • aiogram 3 - асинхронный фреймворк для Telegram. Версия 2.x больше не развивается.
  • openai 1.x - официальный SDK OpenAI для работы с API ChatGPT. Старый openai.ChatCompletion.create() больше не работает, теперь через клиент client.chat.completions.create().
  • python-dotenv - для хранения токенов в .env, чтобы не светить их в коде.

Несколько слов про асинхронность. aiogram 3 построен на asyncio - поэтому обработчики объявляются через async def, а долгие операции вызываются с await. Для GPT-бота это критично: запрос к OpenAI API занимает несколько секунд, и пока один пользователь ждёт ответа, бот спокойно обслуживает остальных. Без асинхронности бот завис бы на каждом запросе и отвечал строго по очереди. Именно поэтому связка aiogram 3 плюс asyncio - стандарт для нагруженных Telegram-ботов.

Пишем ChatGPT-бота на aiogram: подключаем OpenAI API в Telegram

Для простоты соберём всё в один файл bot.py - для учебного бота этого достаточно. Сначала импорты и инициализация:

import asyncio
import os
from dotenv import load_dotenv
from openai import OpenAI
from aiogram import Bot, Dispatcher, F
from aiogram.filters import CommandStart, Command
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import StatesGroup, State
from aiogram.fsm.storage.memory import MemoryStorage
from aiogram.types import Message

load_dotenv()
BOT_TOKEN = os.getenv("BOT_TOKEN")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")

client = OpenAI(api_key=OPENAI_API_KEY)
bot = Bot(token=BOT_TOKEN)
dp = Dispatcher(storage=MemoryStorage())


class Chat(StatesGroup):
    talking = State()

Здесь OpenAI(api_key=...) - новый способ инициализации клиента. В старом SDK ключ задавали через openai.api_key = ..., сейчас создаётся объект клиента.

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

def ask_gpt(history: list) -> str:
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=history,
        temperature=0.7,
    )
    return response.choices[0].message.content
  • model - какую модель использовать. gpt-4o-mini дешёвая и быстрая, для чат-бота с искусственным интеллектом её хватает. Для более умных ответов можно поставить gpt-5.4-nano или gpt-5.4-mini.
  • messages - список сообщений в формате {"role": "user/assistant/system", "content": "текст"}. Это и есть контекст диалога.
  • temperature - креативность ответов от 0 до 1.

Дальше обработчики команд и сообщений:

@dp.message(CommandStart())
async def cmd_start(message: Message, state: FSMContext):
    await state.update_data(history=[
        {"role": "system", "content": "Ты дружелюбный ассистент. Отвечай кратко."}
    ])
    await state.set_state(Chat.talking)
    await message.answer(
        f"Привет, {message.from_user.full_name}!\n"
        f"Я GPT-бот на базе OpenAI API. Напиши сообщение - отвечу."
    )


@dp.message(Command("clear"))
async def cmd_clear(message: Message, state: FSMContext):
    await state.update_data(history=[
        {"role": "system", "content": "Ты дружелюбный ассистент. Отвечай кратко."}
    ])
    await message.answer("Память диалога очищена.")


@dp.message(Chat.talking, F.text)
async def chat(message: Message, state: FSMContext):
    data = await state.get_data()
    history = data.get("history", [])
    history.append({"role": "user", "content": message.text})

    thinking = await message.answer("ИИ думает...")
    try:
        answer = ask_gpt(history)
        history.append({"role": "assistant", "content": answer})
        await state.update_data(history=history)
        await thinking.edit_text(answer)
    except Exception as e:
        await thinking.edit_text(f"Ошибка: {e}")

Как работает память: при каждом сообщении пользователя мы добавляем его в history, отправляем весь список в OpenAI API, получаем ответ и тоже добавляем его в историю. Так бот помнит контекст. Команда /clear сбрасывает память.

Полный код ChatGPT-бота с искусственным интеллектом

Собираем всё вместе. Готовый bot.py:

import asyncio
import os
from dotenv import load_dotenv
from openai import OpenAI
from aiogram import Bot, Dispatcher, F
from aiogram.filters import CommandStart, Command
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import StatesGroup, State
from aiogram.fsm.storage.memory import MemoryStorage
from aiogram.types import Message

load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
bot = Bot(token=os.getenv("BOT_TOKEN"))
dp = Dispatcher(storage=MemoryStorage())

SYSTEM = {"role": "system", "content": "Ты дружелюбный ассистент. Отвечай кратко."}


class Chat(StatesGroup):
    talking = State()


def ask_gpt(history: list) -> str:
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=history,
        temperature=0.7,
    )
    return response.choices[0].message.content


@dp.message(CommandStart())
async def cmd_start(message: Message, state: FSMContext):
    await state.update_data(history=[SYSTEM])
    await state.set_state(Chat.talking)
    await message.answer(f"Привет, {message.from_user.full_name}! Напиши сообщение.")


@dp.message(Command("clear"))
async def cmd_clear(message: Message, state: FSMContext):
    await state.update_data(history=[SYSTEM])
    await message.answer("Память диалога очищена.")


@dp.message(Chat.talking, F.text)
async def chat(message: Message, state: FSMContext):
    data = await state.get_data()
    history = data.get("history", [SYSTEM])
    history.append({"role": "user", "content": message.text})
    thinking = await message.answer("ИИ думает...")
    try:
        answer = ask_gpt(history)
        history.append({"role": "assistant", "content": answer})
        await state.update_data(history=history)
        await thinking.edit_text(answer)
    except Exception as e:
        await thinking.edit_text(f"Ошибка: {e}")


async def main():
    await dp.start_polling(bot)


if __name__ == "__main__":
    asyncio.run(main())

Не забудьте создать файл .env рядом со скриптом:

BOT_TOKEN=токен_от_BotFather
OPENAI_API_KEY=ваш_ключ_OpenAI

Запускаем python bot.py, заходим в Telegram и общаемся с нашим GPT-ботом.

Встроенные роли: системные промпты на выбор

Помните, в начале обещали сделать ChatGPT-бота особенным? Системный промпт - это инструкция, которая задаёт боту характер и стиль ответов. Меняя его, из одного и того же кода получаем переводчика, репетитора или код-ревьюера. Добавим пользователю выбор роли прямо в чате через кнопки.

Сначала соберём словарь готовых промптов:

PROMPTS = {
    "assistant": "Ты дружелюбный ассистент. Отвечай кратко и по делу.",
    "translator": "Ты профессиональный переводчик. Переводи текст пользователя "
                  "на английский, а английский - на русский. Только перевод, без пояснений.",
    "coder": "Ты senior-разработчик. Помогаешь с кодом, объясняешь ошибки, "
             "предлагаешь улучшения. Отвечай с примерами кода.",
    "copywriter": "Ты опытный копирайтер. Пишешь цепляющие тексты для соцсетей "
                  "и рекламы. Живой язык, без канцелярита и клише.",
    "tutor": "Ты терпеливый репетитор по английскому. Объясняешь правила простыми "
             "словами, приводишь примеры, мягко исправляешь ошибки.",
    "brief": "Отвечай максимально кратко - одно-два предложения, только суть.",
}

PROMPT_NAMES = {
    "assistant": "Ассистент",
    "translator": "Переводчик",
    "coder": "Программист",
    "copywriter": "Копирайтер",
    "tutor": "Репетитор английского",
    "brief": "Краткий режим",
}

Теперь сделаем клавиатуру выбора и команду /role:

from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from aiogram import F

def roles_keyboard() -> InlineKeyboardMarkup:
    buttons = [
        [InlineKeyboardButton(text=name, callback_data=f"role:{key}")]
        for key, name in PROMPT_NAMES.items()
    ]
    return InlineKeyboardMarkup(inline_keyboard=buttons)


@dp.message(Command("role"))
async def cmd_role(message: Message):
    await message.answer("Выбери роль для бота:", reply_markup=roles_keyboard())


@dp.callback_query(F.data.startswith("role:"))
async def set_role(call: CallbackQuery, state: FSMContext):
    key = call.data.split(":")[1]
    prompt = PROMPTS.get(key, PROMPTS["assistant"])
    # Ставим новый системный промпт и сбрасываем историю
    await state.update_data(history=[{"role": "system", "content": prompt}])
    await state.set_state(Chat.talking)
    await call.message.answer(f"Готово! Теперь я - {PROMPT_NAMES[key]}.")
    await call.answer()

Что тут происходит:

  • roles_keyboard() собирает кнопки из словаря - по кнопке на каждую роль.
  • callback_data=f"role:{key}" кодирует выбор в данные кнопки, чтобы потом понять что нажали.
  • @dp.callback_query(F.data.startswith("role:")) ловит нажатие любой роли.
  • При выборе роли мы перезаписываем системный промпт в истории и сбрасываем диалог - бот начинает с чистого листа уже в новой роли.

Не забудьте добавить импорт CallbackQuery в начало файла:

from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton

Теперь у пользователя есть команда /role - нажал, выбрал «Переводчик», и бот переводит. Выбрал «Программист» - помогает с кодом. Один бот, шесть характеров. По аналогии можно добавить любые свои промпты в словарь PROMPTS - хоть гадалку, хоть шеф-повара.

Совет: храните системные промпты осмысленно. Чем точнее инструкция в промпте, тем стабильнее ведёт себя бот. «Ты переводчик» работает хуже, чем «Ты профессиональный переводчик, переводи только текст, без пояснений и комментариев».

Сколько стоит GPT-бот на OpenAI API

OpenAI API платный, но для ChatGPT-бота расходы небольшие. Оплата идёт за токены - кусочки текста (примерно 1 токен = 0.75 слова для английского, для русского чуть больше).

Цены на популярные модели (за 1 млн токенов, ввод/вывод):

МодельВводВыводКогда брать
GPT-5.4 nano~$0.20~$1.25Дешёвый чат-бот, лучший баланс цены и качества
GPT-4o mini~$0.15~$0.60Самый дешёвый, базовые задачи
GPT-5.4 mini~$0.75~$4.50Когда нужно поумнее
GPT-5.4~$2.50~$15Качество, сложные диалоги
o3~$2~$8Рассуждения, логика, код

На практике: один обычный диалог из 10 сообщений на GPT-5.4 nano или GPT-4o mini стоит доли цента. Тысяча активных пользователей в месяц - несколько долларов. Цены OpenAI постепенно снижаются, а модели обновляются - актуальный прайс всегда смотрите на platform.openai.com. Чтобы не словить сюрприз, в личном кабинете можно выставить лимит расходов (Usage limits).

Важный нюанс: чем длиннее контекст (история диалога), тем больше токенов уходит на каждый запрос. Если бот популярный - стоит обрезать историю до последних 10-15 сообщений, иначе расходы растут.

Российские альтернативы OpenAI API: GigaChat и YandexGPT

OpenAI API из России работает только через обходные пути (оплата зарубежной картой, VPN для регистрации). Если это неудобно - есть российские нейросети с похожим API.

GigaChat от Сбера. Есть бесплатный тариф, API совместим по логике с OpenAI. Регистрация через Сбер ID, оплата в рублях.

YandexGPT. Доступен через Yandex Cloud, оплата картой РФ. Хорошо работает с русским языком.

Самое удобное - у обоих есть OpenAI-совместимый режим. Это значит, что наш код менять почти не нужно - достаточно сменить base_url и ключ:

client = OpenAI(
    api_key="ваш_ключ_gigachat",
    base_url="https://gigachat.devices.sberbank.ru/api/v1",
)

Дальше тот же client.chat.completions.create(). Меняется только название модели. Так наш бот с искусственным интеллектом работает на российской нейросети без переписывания логики.

Деплой ChatGPT-бота на сервер

Локально ChatGPT-бот живёт пока включён компьютер. Для постоянной работы - VDS. Простого тарифа за 300-400 рублей в месяц (например, Hostland) хватит с запасом.

Через systemd на Linux-сервере:

[Unit]
Description=GPT Telegram bot
After=network.target

[Service]
WorkingDirectory=/opt/gptbot
ExecStart=/usr/bin/python3 /opt/gptbot/bot.py
Restart=always
EnvironmentFile=/opt/gptbot/.env

[Install]
WantedBy=multi-user.target

Сохраняем как /etc/systemd/system/gptbot.service, запускаем systemctl enable --now gptbot. Бот сам перезапускается при падении и ребуте. Токены подтягиваются из .env через EnvironmentFile.

FAQ: ChatGPT-бот на Python

Какой OpenAI API нужен для бота?

Нужен ключ с platform.openai.com (раздел API keys → Create new secret key) и пополненный баланс. Для чат-бота подойдёт модель gpt-4o-mini - она дешёвая. Старый бесплатный ChatGPT через веб-интерфейс для бота не подходит, нужен именно API.

Чем GPT-бот на API отличается от обычного ChatGPT?

Веб-версия ChatGPT - это интерфейс для человека. API - программный доступ: ваш бот сам отправляет запросы и получает ответы. Через API можно встроить нейросеть в Telegram, сайт, приложение и автоматизировать что угодно.

Можно ли сделать GPT-бота бесплатно?

Сам код и библиотеки бесплатны. OpenAI API платный, но дешёвый (доли цента за диалог). Полностью бесплатно - через российский GigaChat, у него есть бесплатный тариф с лимитами.

Как сделать чтобы бот помнил контекст диалога?

Хранить историю сообщений в FSM-состоянии и передавать её целиком в каждый запрос к OpenAI API. В нашем коде это список history - туда добавляются и вопросы пользователя, и ответы бота.

Какую модель выбрать для чат-бота с искусственным интеллектом?

gpt-4o-mini или gpt-5.4-nano для большинства задач - баланс цены и качества. gpt-5.4 или o3 если нужны сложные рассуждения и точность. Для русского языка все работают хорошо, можно также взять YandexGPT или GigaChat.

Заключение

ChatGPT - всего лишь один из множества вариантов. Claude, Gemini и множество других (в том числе OpenSource - полностью открытых) моделей могут помочь вам в ежедневной рутине. Сегодня собрать своего ИИ-бота в Telegram довольно просто, а с учётом персонализации именно под вас он может приносить действительно огромную пользу.

Полезные ссылки

Документация OpenAI: https://openai.com/api/docs/
Документация Aiogram: https://docs.aiogram.dev/en/latest/