Discord-бот с LLM — это обычный Node.js-процесс: он получает события от Discord через discord.js и отправляет текст в Heli API через официальный SDK openai с base URL https://getheli.ru/v1. Ключ sk-heli- хранится в переменных окружения на сервере, где работает бот, а токен бота — отдельно от него.
Подготовка
- В Discord Developer Portal создайте приложение и бота, скопируйте токен бота.
- Чтобы бот видел текст обычных сообщений, включите в настройках бота привилегированный интент Message Content. Для slash-команд он не нужен.
- Пригласите бота на сервер со scope bot и applications.commands.
- Установите зависимости: npm install discord.js openai.
Ответ на упоминание
import { Client, Events, GatewayIntentBits } from "discord.js";
import OpenAI from "openai";
const heli = new OpenAI({ apiKey: process.env.HELI_API_KEY, baseURL: "https://getheli.ru/v1" });
const bot = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent],
});
bot.on(Events.MessageCreate, async (message) => {
if (message.author.bot || !message.mentions.has(bot.user)) return;
await message.channel.sendTyping();
const res = await heli.chat.completions.create({
model: "openai/gpt-5.4-mini",
messages: [
{ role: "system", content: "Ты помощник Discord-сервера. Отвечай кратко." },
{ role: "user", content: message.cleanContent },
],
max_tokens: 600,
});
const text = res.choices[0].message.content ?? "";
await message.reply(text.slice(0, 2000));
});
bot.login(process.env.DISCORD_TOKEN);Ограничения Discord, которые надо учесть
- Сообщение бота ограничено 2000 символами: длинный ответ режьте на части или задавайте max_tokens и просьбу отвечать кратко.
- На slash-команду бот обязан ответить в течение 3 секунд. Ответ модели часто дольше, поэтому сначала вызывайте interaction.deferReply(), а затем interaction.editReply() с готовым текстом.
- Не реагируйте на сообщения других ботов, иначе два бота могут отвечать друг другу бесконечно.
- Ограничьте частоту запросов на пользователя: один активный участник не должен расходовать общий баланс.
История диалога и выбор модели
Чтобы бот помнил контекст, храните последние сообщения канала или ветки и передавайте их в messages. Ограничивайте историю несколькими репликами: каждый токен истории оплачивается в каждом запросе. Для сервера с большим трафиком начните с недорогой быстрой модели, а сильную подключайте к отдельной команде.
Где запускать бота
Бот на discord.js держит постоянное WebSocket-соединение с Discord, поэтому ему нужен всегда работающий процесс: VPS, контейнер или сервер с менеджером процессов вроде pm2 или systemd, который перезапустит бота после сбоя. Обычная serverless-функция для такой схемы не подходит. Если нужны только slash-команды, Discord может присылать их HTTP-запросами на Interactions Endpoint URL — тогда бот работает как обычный веб-обработчик.
Помните, что сообщения участников уходят в модель. Опишите это в правилах сервера, а в системном промпте задайте рамки: о чём бот отвечает и что игнорирует.
Попробуйте Heli
Ключ sk-heli- появляется после подтверждения почты. Через Google и Яндекс — сразу в кабинете.