Salin dan Bagikan
Cara Membuat Telegram Bot dengan Node.js - Panduan lengkap membuat Telegram Bot dengan Node.js untuk automation

Cara Membuat Telegram Bot dengan Node.js

Telegram Bot memungkinkan automation dan interaksi dengan user. Mari pelajari cara membuatnya dengan Node.js.

Membuat Bot di Telegram

Daftar Bot dengan BotFather

1. Buka Telegram
2. Cari @BotFather
3. Kirim /newbot
4. Masukkan nama bot (display name)
5. Masukkan username (harus berakhir 'bot')
6. Simpan token yang diberikan

Bot Commands Setup

Kirim ke BotFather:
/setcommands

Pilih bot, lalu kirim:
start - Memulai bot
help - Bantuan
menu - Tampilkan menu

Setup Project Node.js

Initialize Project

mkdir telegram-bot
cd telegram-bot
npm init -y

# Install dependencies
npm install node-telegram-bot-api dotenv

Environment Setup

# .env
TELEGRAM_BOT_TOKEN=your_bot_token_here

Basic Bot

// index.js
require("dotenv").config();
const TelegramBot = require("node-telegram-bot-api");

const token = process.env.TELEGRAM_BOT_TOKEN;
const bot = new TelegramBot(token, { polling: true });

// Handle /start command
bot.onText(/\/start/, (msg) => {
  const chatId = msg.chat.id;
  const name = msg.from.first_name;

  bot.sendMessage(chatId, `Halo ${name}! 👋\nSelamat datang di bot saya.`);
});

// Handle /help command
bot.onText(/\/help/, (msg) => {
  const chatId = msg.chat.id;
  const helpText = `
📚 *Daftar Perintah:*

/start - Memulai bot
/help - Tampilkan bantuan
/menu - Tampilkan menu
/info - Info bot

_Kirim pesan apa saja untuk berinteraksi._
    `;
  bot.sendMessage(chatId, helpText, { parse_mode: "Markdown" });
});

console.log("Bot is running...");

Handling Messages

Text Messages

// Handle any text message
bot.on("message", (msg) => {
  const chatId = msg.chat.id;
  const text = msg.text;

  // Skip commands
  if (text && text.startsWith("/")) return;

  bot.sendMessage(chatId, `Kamu mengirim: ${text}`);
});

// Handle specific text
bot.onText(/halo|hai|hi/i, (msg) => {
  const chatId = msg.chat.id;
  bot.sendMessage(chatId, "Halo juga! 😊");
});

// Handle with regex groups
bot.onText(/\/echo (.+)/, (msg, match) => {
  const chatId = msg.chat.id;
  const response = match[1]; // Captured text
  bot.sendMessage(chatId, response);
});

Send Different Content Types

// Send photo
bot.sendPhoto(chatId, "https://example.com/photo.jpg", {
  caption: "Ini adalah foto",
});

// Send from file
bot.sendPhoto(chatId, "./images/photo.jpg");

// Send document
bot.sendDocument(chatId, "./files/document.pdf");

// Send location
bot.sendLocation(chatId, -6.2088, 106.8456); // Jakarta

// Send contact
bot.sendContact(chatId, "+62812345678", "John Doe");

// Send sticker
bot.sendSticker(chatId, "sticker_file_id");

Inline Keyboards

Basic Keyboard

bot.onText(/\/menu/, (msg) => {
  const chatId = msg.chat.id;

  const keyboard = {
    reply_markup: {
      inline_keyboard: [
        [
          { text: "📊 Status", callback_data: "status" },
          { text: "⚙️ Settings", callback_data: "settings" },
        ],
        [
          { text: "❓ Help", callback_data: "help" },
          { text: "📞 Contact", callback_data: "contact" },
        ],
        [{ text: "🌐 Visit Website", url: "https://example.com" }],
      ],
    },
  };

  bot.sendMessage(chatId, "Pilih menu:", keyboard);
});

// Handle callback query
bot.on("callback_query", async (query) => {
  const chatId = query.message.chat.id;
  const data = query.data;

  // Answer callback to remove loading
  await bot.answerCallbackQuery(query.id);

  switch (data) {
    case "status":
      bot.sendMessage(chatId, "✅ Bot berjalan normal");
      break;
    case "settings":
      bot.sendMessage(chatId, "⚙️ Menu settings");
      break;
    case "help":
      bot.sendMessage(chatId, "❓ Bantuan...");
      break;
    case "contact":
      bot.sendMessage(chatId, "📞 Hubungi: @username");
      break;
  }
});

Reply Keyboard

bot.onText(/\/keyboard/, (msg) => {
  const chatId = msg.chat.id;

  const keyboard = {
    reply_markup: {
      keyboard: [
        ["📊 Status", "⚙️ Settings"],
        ["❓ Help", "📞 Contact"],
        ["❌ Close"],
      ],
      resize_keyboard: true,
      one_time_keyboard: false,
    },
  };

  bot.sendMessage(chatId, "Keyboard tersedia:", keyboard);
});

// Remove keyboard
bot.onText(/❌ Close/, (msg) => {
  const chatId = msg.chat.id;
  bot.sendMessage(chatId, "Keyboard dihapus", {
    reply_markup: { remove_keyboard: true },
  });
});

Conversation Flow

Simple State Management

// Store user states
const userStates = {};

bot.onText(/\/feedback/, (msg) => {
  const chatId = msg.chat.id;
  userStates[chatId] = { step: "waiting_feedback" };
  bot.sendMessage(chatId, "Silakan kirim feedback Anda:");
});

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

  if (text.startsWith("/")) return;

  const state = userStates[chatId];

  if (state && state.step === "waiting_feedback") {
    // Save feedback
    console.log(`Feedback from ${chatId}: ${text}`);

    bot.sendMessage(chatId, "Terima kasih atas feedback Anda! 🙏");
    delete userStates[chatId];
  }
});

Multi-Step Form

const forms = {};

bot.onText(/\/register/, (msg) => {
  const chatId = msg.chat.id;
  forms[chatId] = { step: 1, data: {} };
  bot.sendMessage(chatId, "Langkah 1/3: Masukkan nama Anda:");
});

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

  if (text.startsWith("/")) return;
  if (!forms[chatId]) return;

  const form = forms[chatId];

  switch (form.step) {
    case 1:
      form.data.name = text;
      form.step = 2;
      bot.sendMessage(chatId, "Langkah 2/3: Masukkan email:");
      break;

    case 2:
      if (!text.includes("@")) {
        bot.sendMessage(chatId, "Email tidak valid. Coba lagi:");
        return;
      }
      form.data.email = text;
      form.step = 3;
      bot.sendMessage(chatId, "Langkah 3/3: Masukkan nomor HP:");
      break;

    case 3:
      form.data.phone = text;

      // Complete registration
      const summary = `
✅ *Registrasi Selesai!*

Nama: ${form.data.name}
Email: ${form.data.email}
Phone: ${form.data.phone}
            `;
      bot.sendMessage(chatId, summary, { parse_mode: "Markdown" });
      delete forms[chatId];
      break;
  }
});

Webhook Mode (Production)

Setup with Express

const express = require("express");
const TelegramBot = require("node-telegram-bot-api");

const token = process.env.TELEGRAM_BOT_TOKEN;
const url = process.env.WEBHOOK_URL; // Your server URL

const app = express();
app.use(express.json());

// Create bot without polling
const bot = new TelegramBot(token);
bot.setWebHook(`${url}/bot${token}`);

// Webhook endpoint
app.post(`/bot${token}`, (req, res) => {
  bot.processUpdate(req.body);
  res.sendStatus(200);
});

// Your bot logic here
bot.onText(/\/start/, (msg) => {
  bot.sendMessage(msg.chat.id, "Hello!");
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Advanced Features

Broadcast Message

// Store subscribers
const subscribers = new Set();

bot.onText(/\/subscribe/, (msg) => {
  const chatId = msg.chat.id;
  subscribers.add(chatId);
  bot.sendMessage(chatId, "✅ Berhasil subscribe!");
});

bot.onText(/\/unsubscribe/, (msg) => {
  const chatId = msg.chat.id;
  subscribers.delete(chatId);
  bot.sendMessage(chatId, "❌ Berhasil unsubscribe");
});

// Admin broadcast
bot.onText(/\/broadcast (.+)/, async (msg, match) => {
  const adminId = 123456789; // Your Telegram ID
  if (msg.from.id !== adminId) return;

  const message = match[1];
  let sent = 0;

  for (const chatId of subscribers) {
    try {
      await bot.sendMessage(chatId, message);
      sent++;
    } catch (error) {
      subscribers.delete(chatId); // Remove invalid
    }
  }

  bot.sendMessage(msg.chat.id, `Broadcast terkirim ke ${sent} users`);
});

Rate Limiting

const rateLimits = {};
const RATE_LIMIT = 5; // messages per minute

function checkRateLimit(chatId) {
  const now = Date.now();

  if (!rateLimits[chatId]) {
    rateLimits[chatId] = { count: 1, resetAt: now + 60000 };
    return true;
  }

  if (now > rateLimits[chatId].resetAt) {
    rateLimits[chatId] = { count: 1, resetAt: now + 60000 };
    return true;
  }

  if (rateLimits[chatId].count >= RATE_LIMIT) {
    return false;
  }

  rateLimits[chatId].count++;
  return true;
}

bot.on("message", (msg) => {
  if (!checkRateLimit(msg.chat.id)) {
    bot.sendMessage(msg.chat.id, "Terlalu banyak request. Tunggu sebentar.");
    return;
  }

  // Process message
});

Database Integration

With MongoDB

const mongoose = require("mongoose");

mongoose.connect("mongodb://localhost:27017/telegram_bot");

const userSchema = new mongoose.Schema({
  chatId: { type: Number, unique: true },
  username: String,
  firstName: String,
  createdAt: { type: Date, default: Date.now },
  settings: {
    notifications: { type: Boolean, default: true },
  },
});

const User = mongoose.model("User", userSchema);

// Save user on /start
bot.onText(/\/start/, async (msg) => {
  const chatId = msg.chat.id;

  await User.findOneAndUpdate(
    { chatId },
    {
      chatId,
      username: msg.from.username,
      firstName: msg.from.first_name,
    },
    { upsert: true }
  );

  bot.sendMessage(chatId, "Selamat datang!");
});

Error Handling

Robust Error Handling

bot.on("polling_error", (error) => {
  console.error("Polling error:", error);
});

bot.on("webhook_error", (error) => {
  console.error("Webhook error:", error);
});

// Wrap handlers
function safeHandler(handler) {
  return async (msg, match) => {
    try {
      await handler(msg, match);
    } catch (error) {
      console.error("Handler error:", error);
      bot.sendMessage(msg.chat.id, "Terjadi kesalahan. Coba lagi nanti.");
    }
  };
}

bot.onText(
  /\/risky/,
  safeHandler(async (msg) => {
    // Your code that might throw
  })
);

Kesimpulan

Telegram Bot dengan Node.js sangat versatile untuk berbagai automation. Mulai dengan bot sederhana lalu tambahkan fitur sesuai kebutuhan.

Artikel Terkait

Link Postingan : https://www.tirinfo.com/cara-membuat-telegram-bot-nodejs/

Hendra WIjaya
Tirinfo
5 minutes.
7 January 2026