Node-telegram-bot-api compatible wrapper built on top of GramJS (telegram npm package)
npm install gramjs-node-telegram-bot-api-wrapperA thin wrapper around telegram (GramJS) that mimics the familiar node-telegram-bot-api interface. It focuses on polling (no webhook) and supports both BotFather tokens and userbot logins.
- Familiar API surface: sendMessage, sendPhoto, sendDocument, sendAudio, sendVoice, sendVideo, sendAnimation, sendSticker, sendDice, sendLocation, sendVenue, sendContact, sendPoll, stopPoll, sendChatAction, editMessageText, editMessageCaption, deleteMessage, answerCallbackQuery, forwardMessage, getUpdates, getChat, getChatMember, getChatMemberCount, getChatAdministrators, leaveChat, onText, and events such as message, channel_post, edited_message, edited_channel_post, callback_query, and inline_query.
- Polling only (no webhook) while still exposing a getUpdates queue for compatibility.
- Works as a bot or userbot (via stringSession or one-time phoneCode login).
- Builds for ESM and CJS and ships TypeScript typings.
``bash`
npm install gramjs-wrapper-node-telegram-bot-api
- ESM / TypeScript
`ts`
import TelegramBot from "gramjs-wrapper-node-telegram-bot-api";
- CommonJS
`js`
const TelegramBot = require("gramjs-wrapper-node-telegram-bot-api");
TelegramBot is available as both the default export and a named export, so destructuring works if you prefer.
`ts
import TelegramBot from "gramjs-wrapper-node-telegram-bot-api";
const bot = new TelegramBot("BOT_TOKEN", {
apiId: Number(process.env.TELEGRAM_API_ID),
apiHash: process.env.TELEGRAM_API_HASH!,
polling: true,
});
bot.on("message", (msg) => {
bot.sendMessage(msg.chat.id, Hello ${msg.from?.first_name ?? ""});
});
bot.onText(/\/start/, async (msg) => {
await bot.sendMessage(msg.chat.id, "Bot is ready!");
});
`
Common GramJS scenarios are supported:
- Reuse an existing stringSession ✅
- First-time login with OTP sent via Telegram app or SMS ✅
- Two-factor password (2FA) ✅
phoneNumber, phoneCode, and password can be strings or async functions that prompt for input (for example, via CLI). If they are omitted and the process runs in a TTY, the wrapper will prompt in the terminal.
`ts`
const bot = new TelegramBot({
stringSession: process.env.TELEGRAM_SESSION, // exported earlier
phoneNumber: "+62123456789", // required if there is no session yet
phoneCode: async () => {
// Wait for manual input from CLI (readline or your own mechanism)
return process.env.TELEGRAM_CODE ?? "";
},
password: process.env.TELEGRAM_PASSWORD, // optional when 2FA is enabled
}, {
apiId: Number(process.env.TELEGRAM_API_ID),
apiHash: process.env.TELEGRAM_API_HASH!,
polling: true,
});
If codes or passwords are missing and stdin/stdout is a TTY, the wrapper will prompt directly in the terminal. This makes first-time logins easy without additional code.
After logging in once, export and store the session for future runs:
`ts`
console.log(bot.exportSession());
- No webhook endpoint is provided (polling only).
- Some file_id/file_unique_id values are synthesized for compatibility and are not official Bot API IDs.stringSession
- For userbots, non-interactive login requires either a stored or a combination of phoneNumber + phoneCode (OTP) plus password when two-factor is enabled.getUpdates
- reads from the internal real-time polling queue (not HTTP long polling). Offset and limit parameters are supported for compatibility.
- Telegram usually sends OTP codes to the official app before SMS. The wrapper will prompt when GramJS asks for the code, so you can copy it from the app.
- If two-factor is enabled, make sure password is provided (string or async function) so the login flow can finish.exportSession()` result in an environment variable so subsequent runs skip OTP.
- Store the