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
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 minutefunction 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.
Ditulis oleh
Hendra Wijaya