TypeScript type definitions and client for the Telegram Bot API using Zod schemas.
- π Type-Safe: Full TypeScript support with Zod schema validation
- π Modern: Built with Bun.sh and ESM modules
- π¦ Lightweight: Zero dependencies except Zod
- π― Focused: Currently supports webhook validation and essential bot methods
- π Validated: Automatic runtime validation of incoming webhook updates
- π¨ Keyboards: Full support for InlineKeyboardMarkup and ReplyKeyboardMarkup
# Using Bun (recommended)
bun add telegram-api-fetch
# Using npm
npm install telegram-api-fetch
# Using yarn
yarn add telegram-api-fetch
# Using pnpm
pnpm add telegram-api-fetchimport { TelegramBot } from 'telegram-api-fetch'
const bot = new TelegramBot({
botToken: process.env.TELEGRAM_BOT_TOKEN!
})await bot.setWebhook({
url: 'https://your-domain.com/webhook',
secret_token: 'your-secret-token',
allowed_updates: ['message', 'callback_query']
})// Simple text message
await bot.sendMessage({
chat_id: 123456789,
text: 'Hello from Telegram Bot API!'
})
// Message with inline keyboard
await bot.sendMessage({
chat_id: 123456789,
text: 'Choose an option:',
reply_markup: {
inline_keyboard: [
[
{ text: 'π Option 1', callback_data: 'opt_1' },
{ text: 'π Option 2', callback_data: 'opt_2' }
]
]
}
})
// Message with reply keyboard
await bot.sendMessage({
chat_id: 123456789,
text: 'Select from keyboard:',
reply_markup: {
keyboard: [
[{ text: 'Button 1' }, { text: 'Button 2' }],
[{ text: 'Share Contact', request_contact: true }]
],
resize_keyboard: true,
one_time_keyboard: true
}
})// Send photo by URL
await bot.sendPhoto({
chat_id: 123456789,
photo: 'https://example.com/image.jpg',
caption: 'Check this out!'
})
// Send photo with inline keyboard
await bot.sendPhoto({
chat_id: 123456789,
photo: 'https://example.com/image.jpg',
caption: 'Do you like it?',
reply_markup: {
inline_keyboard: [
[
{ text: 'π Like', callback_data: 'like' },
{ text: 'π Dislike', callback_data: 'dislike' }
]
]
}
})
// Send photo by file_id
await bot.sendPhoto({
chat_id: 123456789,
photo: 'AgACAgIAAxkBAAIBY2...'
})import { UpdateSchema, type Update } from 'telegram-api-fetch'
// In your webhook handler
app.post('/webhook', async (req, res) => {
// Verify secret token (recommended)
const secretToken = req.headers['x-telegram-bot-api-secret-token']
if (secretToken !== 'your-secret-token') {
return res.sendStatus(401)
}
// Validate and parse the update
const update: Update = UpdateSchema.parse(req.body)
// Handle text messages
if (update.message?.text) {
const chatId = update.message.chat.id
const text = update.message.text
await bot.sendMessage({
chat_id: chatId,
text: `You said: ${text}`
})
}
// Handle callback queries from inline keyboard buttons
if (update.callback_query) {
const query = update.callback_query
const data = query.data
const chatId = query.message?.chat.id
if (chatId && data) {
await bot.sendMessage({
chat_id: chatId,
text: `You selected: ${data}`
})
}
}
res.sendStatus(200)
})Callback queries are triggered when users click inline keyboard buttons:
import { type CallbackQuery } from 'telegram-api-fetch'
async function handleCallbackQuery(query: CallbackQuery) {
const chatId = query.message?.chat.id
if (!chatId || !query.data) return
// Parse callback data
if (query.data.startsWith('vehicle_')) {
const vehicleId = query.data.split('_')[1]
await bot.sendMessage({
chat_id: chatId,
text: `π Vehicle ${vehicleId} selected`,
reply_markup: {
inline_keyboard: [
[
{ text: 'β
Start Check', callback_data: `check_${vehicleId}` },
{ text: 'π Back', callback_data: 'list_vehicles' }
]
]
}
})
}
}
// In your webhook handler
if (update.callback_query) {
await handleCallbackQuery(update.callback_query)
}See the complete Callback Queries Guide for:
- Callback data patterns and best practices
- Multi-step workflows
- Type-safe callback handling
- Real-world examples based on actual use cases
Main client class for interacting with the Telegram Bot API.
new TelegramBot(config: TelegramConfig)Config Options:
botToken(string, required): Your bot token from @BotFatherbaseUrl(string, optional): API base URL (default:https://api.telegram.org)timeout(number, optional): Request timeout in milliseconds (default: 30000)
Configure a webhook to receive updates.
Parameters:
url(string): HTTPS URL to send updates tosecret_token(string, optional): Secret token for webhook verificationallowed_updates(string[], optional): List of update types to receivemax_connections(number, optional): Maximum simultaneous connectionsdrop_pending_updates(boolean, optional): Drop all pending updates
Send a text message.
Parameters:
chat_id(number | string): Target chat ID or usernametext(string): Message textparse_mode(string, optional): Parse mode (Markdown, HTML, MarkdownV2)reply_markup(object, optional): Inline or reply keyboardreply_to_message_id(number, optional): ID of message to reply todisable_notification(boolean, optional): Send silently- And more...
Send a photo.
Parameters:
chat_id(number | string): Target chat ID or usernamephoto(string | Blob | File): Photo URL, file_id, or file to uploadcaption(string, optional): Photo captionparse_mode(string, optional): Parse mode for captionreply_markup(object, optional): Inline or reply keyboard- And more...
All webhook types are validated using Zod schemas:
UpdateSchema: Main update objectMessageSchema: Message objectUserSchema: User objectChatSchema: Chat objectPhotoSizeSchema: Photo size objectCallbackQuerySchema: Callback query objectLocationSchema: Location objectMessageEntitySchema: Message entity object
{
inline_keyboard: [
[
{ text: 'Button 1', callback_data: 'data_1' },
{ text: 'Button 2', url: 'https://example.com' }
]
]
}{
keyboard: [
[{ text: 'Button 1' }, { text: 'Button 2' }],
[{ text: 'Share Contact', request_contact: true }]
],
resize_keyboard: true,
one_time_keyboard: true
}Check the examples/ directory for complete examples:
basic-bot.ts: Comprehensive bot example with all featureswebhook-handler.ts: Complete webhook handler with callbackscallback-example.ts: Advanced callback patterns and workflowsCALLBACKS.md: Complete guide to callback queries
This project uses Bun.sh as the runtime and package manager.
# Install dependencies
bun install
# Run tests
bun test
# Run tests in watch mode
bun test:watch
# Build the library
bun run build
# Run linter
bun run lint:fix
# Type check
bun run type-checkCurrently implemented methods:
- β
setWebhook- Configure webhook - β
sendMessage- Send text messages - β
sendPhoto- Send photos
- β Update validation with Zod schemas
- β Message types (text, photo, location)
- β User and Chat types
- β Callback queries (inline keyboard buttons)
- β Message entities (mentions, hashtags, links, etc.)
- β Inline keyboards with reply_markup
- β Reply keyboards
sendVideo- Send videossendAudio- Send audio filessendDocument- Send documentseditMessageText- Edit messagesdeleteMessage- Delete messages- And more...
Contributions are welcome! Please feel free to submit a Pull Request.
MIT Β© Dogalyir
This library provides type-safe TypeScript bindings for the Telegram Bot API, with automatic validation using Zod schemas. Perfect for building reliable Telegram bots with full type safety.