@mks2508/telegram-message-builder-telegraf
v0.1.2
Published
Telegraf integration for telegram-message-builder with progress tracking, log viewer, and reusable components
Downloads
231
Readme
@mks2508/telegram-message-builder-telegraf
Telegraf integration for telegram-message-builder with high-level utilities for sending messages, tracking operations, and displaying logs.
Features
- TelegrafSender: Send messages and media to users, groups, and group topics
- ProgressManager: Track long-running operations with automatic UI updates and rate limiting
- LogViewer: Display logs with configurable pagination styles
- Predefined Menus: Reusable keyboard patterns (main menu, back button)
- Rate Limiting: Built-in rate limiter for Telegram group chats (20 msgs/min)
- Type Safe: Full TypeScript support with Result pattern for error handling
Installation
bun add telegraf @mks2508/telegram-message-builder @mks2508/telegram-message-builder-telegrafQuick Start
Sending Messages
import { Telegraf } from "telegraf";
import { TelegrafSender } from "@mks2508/telegram-message-builder-telegraf/sender";
import { TelegramMessageBuilder } from "@mks2508/telegram-message-builder";
import { TelegramKeyboardBuilder } from "@mks2508/telegram-message-builder";
const bot = new Telegraf(process.env.BOT_TOKEN);
const sender = new TelegrafSender(bot.telegram);
// Send to individual user
const message = TelegramMessageBuilder.text()
.title("Welcome")
.line("Status", "Active", { bold: true })
.build();
const keyboard = TelegramKeyboardBuilder.inline()
.callbackButton("OK", "confirm_ok")
.buildMarkup();
await sender.send(123456789, message, { keyboard });
// Send to group topic (string format)
await sender.send("-100123456789/123", message);
// Send to group topic (object format)
await sender.send({
chatId: -100123456789,
threadId: 123
}, message, {
silent: true,
protect: true
});Sending Media
import { TelegramMediaBuilder } from "@mks2508/telegram-message-builder";
// Photo with caption
const photo = TelegramMediaBuilder.photo("https://example.com/photo.jpg")
.caption("Beautiful sunset")
.build();
await sender.sendMedia(123456789, photo);
// Video with custom options
const video = TelegramMediaBuilder.video("/path/to/video.mp4")
.caption("Check this out!")
.build();
await sender.sendMedia(123456789, video, {
keyboard,
silent: true
});Progress Tracking
import { ProgressManager, ProgressState } from "@mks2508/telegram-message-builder-telegraf/progress";
const progress = new ProgressManager(telegram, {
updateInterval: 1000,
maxUpdatesPerMinute: 15
});
// Start tracking
await progress.start(chatId, threadId, {
total: 100,
label: "Processing files"
});
// Update progress
await progress.update(chatId, threadId, {
current: 50,
state: ProgressState.InProgress,
message: "Halfway there..."
});
// Complete
await progress.complete(chatId, threadId, {
message: "All done!",
showKeyboard: true
});
// Fail
await progress.fail(chatId, threadId, {
message: "Something went wrong",
error: new Error("Details...")
});Log Viewer
import { LogViewer } from "@mks2508/telegram-message-builder-telegraf/logviewer";
import { RateLimiter } from "@mks2508/telegram-message-builder-telegraf/logviewer";
const rateLimiter = new RateLimiter({
maxMessagesPerMinute: 20,
windowMs: 60000
});
const viewer = new LogViewer(telegram, {
type: "inline",
maxLines: 100,
linesPerPage: 10,
showLineNumbers: true
}, rateLimiter);
// Add logs
viewer.addLog({
level: "info",
timestamp: new Date(),
message: "Application started"
});
viewer.addLog({
level: "success",
timestamp: new Date(),
message: "Operation completed"
});
viewer.addLog({
level: "error",
timestamp: new Date(),
message: "Failed to connect",
metadata: { host: "localhost", port: 5432 }
});
// Display page 1
await viewer.display(chatId, threadId, 1);Predefined Menus
import {
createMainMenu,
createBackButton
} from "@mks2508/telegram-message-builder-telegraf/menus";
// Main menu with multiple options
const mainMenu = createMainMenu([
{ label: "Profile", data: "menu_profile" },
{ label: "Settings", data: "menu_settings" },
{ label: "Help", data: "menu_help" }
], {
layout: "vertical"
});
// Simple back button
const backButton = createBackButton("main_menu");API Reference
TelegrafSender
send(target, message, options?)
Send a text message to a chat.
Parameters:
target:IChatTarget- Chat target (number, string, or object)number: Simple chat ID (e.g.,123456789)string: Format"chatId/threadId"(e.g.,"-100123456789/123")object:{ chatId: number; threadId?: number }
message:TelegramMessage- Message built with TelegramMessageBuilderoptions?:ISendOptionsWithKeyboardkeyboard?: Inline keyboard markupparseMode?: Parse mode overridesilent?: Send without notificationprotect?: Protect content from forwardingdisableWebPagePreview?: Disable link previewsreplyTo?: Reply to specific message ID
Returns: Promise<Result<ISendResult, ResultError<AppErrorCode>>>
sendMedia(target, media, options?)
Send a media message (photo, video, document, audio, voice).
Parameters:
target:IChatTarget- Chat targetmedia:IMediaBuildResult- Media built with TelegramMediaBuilderoptions?:ISendOptionsWithKeyboard- Same options assend()
Returns: Promise<Result<ISendResult, ResultError<AppErrorCode>>>
parseTarget(target)
Parse chat target into chat ID and optional thread ID.
Returns: Result<IParsedChatTarget, ResultError<AppErrorCode>>
ProgressManager
Constructor Options
interface IProgressManagerConfig {
updateInterval: number; // Update interval in ms
maxUpdatesPerMinute: number; // Rate limit for updates
}Methods
start(chatId, threadId, options): Start tracking a new operationupdate(chatId, threadId, options): Update progresscomplete(chatId, threadId, options): Mark as completefail(chatId, threadId, options): Mark as failedcancel(chatId, threadId): Cancel tracking
LogViewer
Constructor Options
interface IPaginationConfig {
type: "classic" | "inline" | "virtual"; // Pagination style
maxLines: number; // Maximum log entries
linesPerPage: number; // Lines per page
showLineNumbers?: boolean; // Show line numbers
}Pagination Styles
- classic: « ‹ 1/10 › »
- inline: Page 1/10 • Previous/Next buttons
- virtual: Up/Down arrows for scrolling
Methods
addLog(entry): Add a single log entryaddLogs(entries): Add multiple log entriesclear(): Clear all logsdisplay(chatId, threadId, page): Display a specific pageupdate(chatId, messageId, page): Update existing messagegetLogCount(): Get total log countgetCurrentPage(): Get current page numbergetTotalPages(): Get total page count
RateLimiter
const rateLimiter = new RateLimiter({
maxMessagesPerMinute: 20,
windowMs: 60000
});
// Check if can send
const canSend = await rateLimiter.canUpdate(chatId);
// Queue update if rate limited
await rateLimiter.queueUpdate(async () => {
// Your update logic
});
// Record sent message
rateLimiter.recordSent(chatId);Chat ID Formats
The library supports multiple chat target formats:
// Individual user (positive ID)
sender.send(123456789, message);
// Group chat (negative supergroup ID)
sender.send(-100123456789, message);
// Group topic - string format
sender.send("-100123456789/123", message);
// Group topic - object format
sender.send({
chatId: -100123456789,
threadId: 123
}, message);
// Parse utility
import { parseChatTarget, formatChatId } from "@mks2508/telegram-message-builder-telegraf/utils";
const parsed = parseChatTarget("-100123456789/123");
// { chatId: -100123456789, threadId: 123 }
const formatted = formatChatId(-100123456789, 123);
// "-100123456789/123"
// Check chat type
import { isGroupChat, isUserChat, extractGroupId } from "@mks2508/telegram-message-builder-telegraf/utils";
isGroupChat(-100123456789); // true
isUserChat(123456789); // true
extractGroupId(-100123456789); // 123456789Error Handling
All methods return Result<T, E> types for safe error handling:
import { isErr } from "telegram-message-builder/utils";
const result = await sender.send(123456789, message);
if (isErr(result)) {
console.error("Failed to send:", result.error);
// Handle error
return;
}
// Success
console.log("Sent:", result.value.messageId);License
MIT
