← Blog

Cómo hacer un bot de Telegram con Node.js y GPT-4o: tutorial completo

D
Damián Oliva
·10 de marzo de 2025

Por qué Telegram es la mejor plataforma para bots

He construido bots para WhatsApp, Discord y Telegram. Telegram gana por lejos para casos de uso de negocio: la API es pública y estable, no requiere número de teléfono business ni aprobación de Meta, soporta grupos, canales y chats privados de forma uniforme, y la librería node-telegram-bot-api es madura y bien documentada.

Setup inicial

Primero, creá tu bot con BotFather en Telegram. Escribí /newbot, seguí los pasos y guardá el token.

npm install node-telegram-bot-api openai dotenv
# .env
TELEGRAM_TOKEN=tu_token_aqui
OPENAI_API_KEY=sk-...

Estructura básica del bot

import TelegramBot from 'node-telegram-bot-api';
import OpenAI from 'openai';

const bot = new TelegramBot(process.env.TELEGRAM_TOKEN, { polling: true });
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

bot.on('message', async (msg) => {
  const chatId = msg.chat.id;
  const text = msg.text;

  if (!text || text.startsWith('/')) return;

  try {
    const response = await openai.chat.completions.create({
      model: 'gpt-4o',
      messages: [
        { role: 'system', content: 'Sos un asistente útil.' },
        { role: 'user', content: text },
      ],
    });

    await bot.sendMessage(chatId, response.choices[0].message.content);
  } catch (err) {
    await bot.sendMessage(chatId, 'Ocurrió un error. Intentá de nuevo.');
  }
});

Manteniendo contexto de conversación por usuario

const conversations = new Map(); // En producción, usar MongoDB o Redis

bot.on('message', async (msg) => {
  const chatId = msg.chat.id;
  const text = msg.text;
  if (!text || text.startsWith('/')) return;

  if (!conversations.has(chatId)) {
    conversations.set(chatId, []);
  }

  const history = conversations.get(chatId);
  history.push({ role: 'user', content: text });

  // Limitar historial a últimos 10 mensajes
  const recentHistory = history.slice(-10);

  const response = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages: [
      { role: 'system', content: 'Sos un asistente especializado.' },
      ...recentHistory,
    ],
  });

  const reply = response.choices[0].message.content;
  history.push({ role: 'assistant', content: reply });

  await bot.sendMessage(chatId, reply);
});

Comandos útiles

bot.onText(//start/, (msg) => {
  bot.sendMessage(msg.chat.id, '¡Hola! Soy tu asistente. ¿En qué te puedo ayudar?');
});

bot.onText(//limpiar/, (msg) => {
  conversations.delete(msg.chat.id);
  bot.sendMessage(msg.chat.id, 'Historial borrado. Empezamos de cero.');
});

Deploy con PM2

En producción uso polling con PM2 para mantener el proceso vivo:

pm2 start bot.js --name mi-bot
pm2 save
pm2 startup

Para bots de alta carga, cambiá polling por webhooks con un endpoint HTTPS en tu servidor Express.

Newsletter

Ideas directamente
a tu bandeja de entrada

Comparto lo que estoy construyendo, lo que aprendo y lo que me parece interesante del mundo tech y startups. Sin spam. Cuando tenga algo que valga la pena.

Sin spam. Unsubscribe en cualquier momento.