Зачем Telegram-бот, а не просто ChatGPT
Telegram — это уже привычная среда. Бот в чате доступен всей команде без установки ничего дополнительного. Можно добавить в групповой чат, настроить под конкретный сценарий (суммаризация, перевод, код-ревью), ограничить доступ по user_id или боту не отвечать на случайные сообщения.
В этой статье — минимально рабочий вариант за ~30 минут. Два варианта: Python (aiogram 3) и Node.js (grammY). API — OpenAI-совместимый, то есть код работает с любой моделью через PlusVibe: ChatGPT, Claude, Gemini, DeepSeek.
Что понадобится
- Токен бота — получить у @BotFather командой
/newbot. - API-ключ PlusVibe — создать на plusvibeapi.ru/dashboard/keys. Начисляем 100 ₽ при регистрации, хватит на тысячи сообщений.
- Python 3.10+ или Node.js 18+ на сервере или локально.
Вариант 1: Python + aiogram 3
Установка
pip install aiogram openai
Код бота
import asyncio
import os
from aiogram import Bot, Dispatcher, types
from aiogram.filters import CommandStart
from openai import AsyncOpenAI
BOT_TOKEN = os.getenv("BOT_TOKEN") # токен от @BotFather
PLUSVIBE_KEY = os.getenv("PLUSVIBE_KEY") # ваш ключ с plusvibeapi.ru
MODEL = "gpt-5.4" # или "claude-opus-4.8", "gemini-2.5-flash"
client = AsyncOpenAI(
api_key=PLUSVIBE_KEY,
base_url="https://plusvibeapi.ru/v1",
)
bot = Bot(token=BOT_TOKEN)
dp = Dispatcher()
# История per-user (in-memory, сбрасывается при рестарте)
history: dict[int, list] = {}
@dp.message(CommandStart())
async def cmd_start(message: types.Message):
history[message.from_user.id] = []
await message.answer("Привет! Я AI-ассистент. Задайте вопрос.")
@dp.message()
async def handle_message(message: types.Message):
uid = message.from_user.id
if uid not in history:
history[uid] = []
history[uid].append({"role": "user", "content": message.text})
# Ограничиваем историю — последние 20 сообщений (10 пар)
if len(history[uid]) > 20:
history[uid] = history[uid][-20:]
await bot.send_chat_action(message.chat.id, "typing")
try:
response = await client.chat.completions.create(
model=MODEL,
messages=history[uid],
)
reply = response.choices[0].message.content
history[uid].append({"role": "assistant", "content": reply})
await message.answer(reply)
except Exception as e:
await message.answer(f"Ошибка: {e}")
async def main():
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
Запуск
BOT_TOKEN=токен_бота PLUSVIBE_KEY=sk-pv-... python bot.py
Для production — завернуть в systemd или screen, чтобы бот не умирал при выходе из SSH.
Вариант 2: Node.js + grammY
Установка
npm init -y
npm install grammy openai
Код бота
import { Bot } from "grammy";
import OpenAI from "openai";
const bot = new Bot(process.env.BOT_TOKEN);
const client = new OpenAI({
apiKey: process.env.PLUSVIBE_KEY,
baseURL: "https://plusvibeapi.ru/v1",
});
const MODEL = "gpt-5.4"; // или "claude-opus-4.8", "gemini-2.5-flash"
const history = new Map();
bot.command("start", (ctx) => {
history.set(ctx.from.id, []);
return ctx.reply("Привет! Задайте вопрос.");
});
bot.on("message:text", async (ctx) => {
const uid = ctx.from.id;
if (!history.has(uid)) history.set(uid, []);
const msgs = history.get(uid);
msgs.push({ role: "user", content: ctx.message.text });
// Последние 20 сообщений
if (msgs.length > 20) msgs.splice(0, msgs.length - 20);
await ctx.replyWithChatAction("typing");
try {
const response = await client.chat.completions.create({
model: MODEL,
messages: msgs,
});
const reply = response.choices[0].message.content;
msgs.push({ role: "assistant", content: reply });
await ctx.reply(reply);
} catch (e) {
await ctx.reply(`Ошибка: ${e.message}`);
}
});
bot.start();
Запуск
BOT_TOKEN=токен_бота PLUSVIBE_KEY=sk-pv-... node bot.mjs
Как сменить модель
Просто поменяйте константу MODEL. Все модели работают через один и тот же API:
gpt-5.4— GPT-5.4, отличный баланс скорости и качестваclaude-opus-4.8— Claude Opus 4.8, лучший для кода и анализаgemini-2.5-flash— Gemini 2.5 Flash, быстрый и дешёвыйdeepseek-v4-pro— deepseek-v4-pro" class="text-accent-violet hover:underline font-medium">DeepSeek V4 Pro, сильный в рассужденияхsonar-pro— Perplexity Sonar Pro, ответы с актуальными данными из интернета
Полный список — на странице моделей.
Полезные доработки
Системный промпт (личность бота)
Добавьте в начало массива сообщений системное сообщение:
const SYSTEM = {
role: "system",
content: "Ты — помощник по юридическим вопросам. Отвечай кратко, на русском, ссылайся на статьи законов.",
};
// При создании запроса:
messages: [SYSTEM, ...msgs],
Ограничение доступа по user_id
const ALLOWED_USERS = new Set([123456789, 987654321]); // ваши Telegram user_id
bot.on("message:text", async (ctx) => {
if (!ALLOWED_USERS.has(ctx.from.id)) {
return ctx.reply("Нет доступа.");
}
// ... основной код
});
Команда /reset для очистки истории
bot.command("reset", (ctx) => {
history.set(ctx.from.id, []);
return ctx.reply("История очищена.");
});
Потоковый ответ (streaming)
Telegram не поддерживает настоящий стриминг (нельзя редактировать сообщение в реальном времени так же плавно), но можно редактировать сообщение кусками:
const stream = await client.chat.completions.create({
model: MODEL,
messages: msgs,
stream: true,
});
const sent = await ctx.reply("...");
let text = "";
let lastUpdate = Date.now();
for await (const chunk of stream) {
text += chunk.choices[0]?.delta?.content ?? "";
// Обновляем не чаще раза в секунду (лимит Telegram API)
if (Date.now() - lastUpdate > 1000) {
await bot.api.editMessageText(ctx.chat.id, sent.message_id, text);
lastUpdate = Date.now();
}
}
await bot.api.editMessageText(ctx.chat.id, sent.message_id, text);
Деплой на сервер
Проще всего — VPS с Ubuntu. Бот работает как long-polling процесс, не нужен домен или SSL.
# systemd unit (Python-вариант)
# /etc/systemd/system/aibot.service
[Unit]
Description=AI Telegram Bot
After=network.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/aibot
Environment="BOT_TOKEN=токен"
Environment="PLUSVIBE_KEY=sk-pv-..."
ExecStart=/usr/bin/python3 bot.py
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl enable aibot
sudo systemctl start aibot
sudo systemctl status aibot
Итог
За ~30 минут получаем бота, который:
- Помнит контекст разговора (in-memory история)
- Работает с любой моделью через один ключ
- Легко расширяется: системный промпт, ограничение доступа, команды
Регистрируйтесь на plusvibeapi.ru — 100 ₽ на баланс сразу после подтверждения email.


