Telegram-бот с GPT на Node.js через AI Gateway (grammY)
Как сделать Telegram-бота с AI на Node.js: grammY или node-telegram-bot-api плюс openai SDK с base_url AI Gateway, память диалога по чату и ключи в переменных окружения.
Соберём AI-бота для Telegram на Node.js: grammY принимает сообщения, а официальный openai SDK обращается к модели. Достаточно направить SDK на AI Gateway через baseURL — и бот отвечает моделями из каталога. В конце — короткий вариант на node-telegram-bot-api.
Подготовка
Понадобятся токен бота от @BotFather и ключ AI Gateway sk-aigate-…. Оба секрета кладём в переменные окружения (TELEGRAM_TOKEN, AIGATE_API_KEY). Базовый URL шлюза — https://ai-gatewey.ru/v1.
npm install grammy openaiРеализация
- Клиент и хранилище контекста
Настраиваем
openaiна AI Gateway и заводим по чату короткую историю сообщений в обычномMap:import { Bot } from "grammy"; import OpenAI from "openai"; const bot = new Bot(process.env.TELEGRAM_TOKEN!); const ai = new OpenAI({ baseURL: "https://ai-gatewey.ru/v1", apiKey: process.env.AIGATE_API_KEY, }); type Msg = { role: "system" | "user" | "assistant"; content: string }; const history = new Map<number, Msg[]>(); const SYSTEM: Msg = { role: "system", content: "Ты дружелюбный ассистент. Отвечай кратко." }; - Обработчик с памятью диалога
На каждое текстовое сообщение дополняем историю чата, отправляем её модели и возвращаем ответ, попутно обрезая старые реплики:
bot.on("message:text", async (ctx) => { const chatId = ctx.chat.id; const hist = history.get(chatId) ?? [SYSTEM]; hist.push({ role: "user", content: ctx.message.text }); const resp = await ai.chat.completions.create({ model: "deepseek/deepseek-chat", messages: hist, }); const answer = resp.choices[0].message.content ?? "…"; hist.push({ role: "assistant", content: answer }); // держим системный промпт плюс 10 последних реплик history.set(chatId, [SYSTEM, ...hist.slice(-10)]); await ctx.reply(answer); }); bot.start(); - Альтернатива: node-telegram-bot-api
Если используете
node-telegram-bot-api, меняется только слой Telegram — вызов SDK тот же:const TelegramBot = require("node-telegram-bot-api"); const OpenAI = require("openai"); const bot = new TelegramBot(process.env.TELEGRAM_TOKEN, { polling: true }); const ai = new OpenAI({ baseURL: "https://ai-gatewey.ru/v1", apiKey: process.env.AIGATE_API_KEY, }); bot.on("message", async (msg) => { const resp = await ai.chat.completions.create({ model: "deepseek/deepseek-chat", messages: [{ role: "user", content: msg.text }], }); bot.sendMessage(msg.chat.id, resp.choices[0].message.content); });
Какие модели подойдут
Поток сообщений в ботах большой, ответы короткие — берут быструю дешёвую модель, качества которой хватает для большинства диалогов:
| Модель | Ввод, ₽/1М | Вывод, ₽/1М | Контекст |
|---|---|---|---|
| DeepSeek: DeepSeek V3 | 31 | 125 | 128K |
| OpenAI: GPT-5.4 Mini | 118 | 705 | 400K |
| Anthropic Claude Haiku Latest | 157 | 784 | 200K |
Частые вопросы
grammY или node-telegram-bot-api?
grammY современнее, типизирован под TypeScript и удобнее для middleware и сессий. node-telegram-bot-api проще и привычнее в старых проектах. Слой обращения к модели в обоих одинаковый.
Где хранить историю диалога в продакшене?
Map в памяти сбрасывается при перезапуске и не переживает горизонтальное масштабирование. Для боевого бота храните контекст в Redis или БД по идентификатору чата.
Стоит ли использовать webhooks вместо polling?
Для продакшена — да: webhooks экономят ресурсы и лучше масштабируются. Для разработки и небольших ботов polling (bot.start()) проще, ведь не нужен публичный HTTPS-адрес.
Telegram-бот с AI на Node.js — начните с ключа
Получить ключ