
Manjot SinghOriginal Resource: This guide is officially published on the IRCTC Developer Platform. Have you ever...
Original Resource: This guide is officially published on the IRCTC Developer Platform.
Have you ever been stuck at a railway platform frantically refreshing slow apps to find out where your train is or whether your RAC/WL ticket confirmed?
In this tutorial, we will build a production-ready WhatsApp bot in Node.js & TypeScript that lets you check live train running status, delay minutes, and 10-digit PNR status directly in WhatsApp with zero Twilio or Meta WhatsApp Business API costs.
User sends WhatsApp message (!live 12557)
│
▼
[@whiskeysockets/baileys Multi-Device Socket]
│
▼
Command Parser (!live <train> | !pnr <pnr>)
│
▼
[IRCTC API Gateway: https://api.irctc.dev]
│
▼
Formatted WhatsApp Response (Delays, Halts, Coach & Berths)
Create a new directory and install @whiskeysockets/baileys (for WhatsApp Web multi-device connection), qrcode-terminal, irctc-api, and dotenv:
mkdir irctc-whatsapp-bot && cd irctc-whatsapp-bot
npm init -y
npm install @whiskeysockets/baileys qrcode-terminal irctc-api dotenv
npm install -D typescript @types/node ts-node
npx tsc --init
Create a .env file in your root folder:
IRCTC_API_KEY=your_irctc_api_key_here
BOT_PREFIX=!
NODE_ENV=production
Create src/index.ts and set up the Baileys socket with persistent multi-file authentication so you only have to scan the QR code once:
import makeWASocket, {
DisconnectReason,
useMultiFileAuthState
} from '@whiskeysockets/baileys';
import { Boom } from '@hapi/boom';
import qrcode from 'qrcode-terminal';
import { IrctcApi } from 'irctc-api';
import dotenv from 'dotenv';
dotenv.config();
const irctc = new IrctcApi({
apiKey: process.env.IRCTC_API_KEY || ''
});
async function startBot() {
const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys');
const sock = makeWASocket({
auth: state,
printQRInTerminal: false
});
sock.ev.on('connection.update', (update) => {
const { connection, lastDisconnect, qr } = update;
if (qr) {
console.log('⚡ Scan this QR code with WhatsApp on your phone:');
qrcode.generate(qr, { small: true });
}
if (connection === 'close') {
const shouldReconnect =
(lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut;
if (shouldReconnect) startBot();
} else if (connection === 'open') {
console.log('✅ IRCTC WhatsApp Bot is online!');
}
});
sock.ev.on('creds.update', saveCreds);
// Incoming Message Handler
sock.ev.on('messages.upsert', async ({ messages, type }) => {
if (type !== 'notify') return;
const msg = messages[0];
if (!msg.message || msg.key.fromMe) return;
const sender = msg.key.remoteJid!;
const text =
msg.message.conversation ||
msg.message.extendedTextMessage?.text ||
'';
const trimmed = text.trim();
// 1. Live Running Status Command (!live 12557)
if (trimmed.startsWith('!live ')) {
const trainNo = trimmed.replace('!live ', '').trim();
try {
await sock.sendMessage(sender, { text: `🔍 Checking live status for ${trainNo}...` });
const live = await irctc.live.getStatus(trainNo);
const reply = `🚆 *Train ${live.trainNumber} — ${live.trainName}*
📍 *Current Location:* ${live.currentLocation} (${live.locationStatus})
⏱️ *Status:* ${live.currentDelayMin > 0 ? `Delayed by ${live.currentDelayMin} mins 🔴` : 'Running On Time 🟢'}
🎯 *Next Station:* ${live.stops?.find((s: any) => s.status === 'upcoming')?.stationName || 'In Transit'}
⚡ _Powered by irctc.dev_`;
await sock.sendMessage(sender, { text: reply });
} catch (err: any) {
await sock.sendMessage(sender, { text: `❌ ${err.message}` });
}
}
// 2. Real-Time PNR Status Command (!pnr 2265248473)
if (trimmed.startsWith('!pnr ')) {
const pnr = trimmed.replace('!pnr ', '').trim();
try {
await sock.sendMessage(sender, { text: `🔍 Verifying PNR ${pnr}...` });
const data = await irctc.pnr.check(pnr);
const passengerList = (data.passengers || [])
.map((p: any, i: number) => ` • P${i + 1}: *${p.currentStatus}* (Coach ${p.coach || 'N.A'}, Seat ${p.berthNumber || 'N.A'} [${p.berth || 'N.A'}])`)
.join('\n');
const reply = `🎫 *IRCTC PNR Status: ${pnr}*
🚆 *Train:* ${data.trainNumber} - ${data.trainName}
🗓️ *Date:* ${data.journeyDate} (${data.from?.code} ➔ ${data.to?.code})
📊 *Charting:* ${data.chartStatus}
👥 *Passenger Manifest:*
${passengerList}
⚡ _Powered by irctc.dev_`;
await sock.sendMessage(sender, { text: reply });
} catch (err: any) {
await sock.sendMessage(sender, { text: `❌ ${err.message}` });
}
}
});
return sock;
}
startBot();
Start your bot in development:
npx ts-node src/index.ts
!live 12557 (Fetches live GPS status, platform, and delay in under 400ms).!pnr 2265248473 (Fetches passenger coach and berth allocations).If you want to test the underlying Indian Railways API directly without setting up WhatsApp, run:
npx irctc-api live 12557
npx irctc-api pnr 2265248473
You can claim 10,000 free requests directly at irctc.dev/dashboard.