Full reference guide for TBL (Tele Bot Lang)
TBL (Tele Bot Lang) is a lightweight scripting language designed specifically for Telegram bot development. It provides a JavaScript-inspired syntax with built-in functions for rapid bot creation, without the overhead of external dependencies.
await, Promise are validThis section explains the basic steps to create and test your first Telegram bot using TBL.
/newbot to create a new bot.bot).const botToken = "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ";
Create a /start command for user onboarding:
Bot.sendMessage("Hello " + user.first_name + "! Welcome to my bot.")
Example: /help command:
Bot.sendMessage("Available commands:\n/start - Start bot\n/help - Show help")
The latest TBL update introduces major new features for developers, giving more control, flexibility, and integration possibilities. Here’s a breakdown of everything new:
TBL now supports Webhook mode. You can call bot commands directly using HTTP requests — perfect for building websites, dashboards, or automation tools that interact with your bot in real-time.
Bot.read() MethodA new method Bot.read("/command") allows you to read another command’s source code as a string.
It’s ideal for dynamic command management, code previews, or admin tools.
// Example usage
let code = Bot.read("/start")
Bot.sendMessage("Here's the code for /start:\n" + code)
Use case: Create AI code analyzers, AI chatbot or documentation systems inside your bot.
TBL’s sandbox now supports the safe version of Node.js’s Buffer class. You can process binary data, files, and base64 strings directly in your commands.
// Example
let buf = Buffer.from("TBL Rocks!")
Bot.sendMessage("Buffer length: " + buf.length)
Use case: Work with files, encodings, and binary data safely inside the TBL VM.
Bot.runCommand()Bot.runCommand() has been improved — it now runs inside any update type (messages, callbacks, inline queries, webhooks, etc.).
Previously, it only worked with message updates.
// Works everywhere now
Bot.runCommand("/start")
Use case: Trigger other commands programmatically — regardless of where the update originated.
TBL now supports Dynamic Commands — allowing any update type to have its own handler in the form /handle_{type}.
For example, when a user joins a group, TBL automatically runs /handle_new_chat_member if it exists.
/*Command: /handle_new_chat_member*/
Bot.sendMessage("👋 Welcome " + user.first_name + "!")
This applies to all non-message updates like chat_member, poll_answer, message_reaction, etc.
/handle_chat_member → runs when user status changes/handle_poll_answer → runs on poll responses/handle_message_reaction → runs on new reactions/handle_chat_boost → runs on chat boost updatesSpecial Commands like /inline_query and /channel_update are still supported and prioritized.
/handle_{type} pattern.Commands are the core building blocks of TBL. Instead of using event listeners like bot.on(), TBL follows a command-driven model.
Each command acts like a rule: when the trigger matches, the bot runs its script.
A command can include these parts:
/start, hi, /help)/startWelcome! Choose an option:Help, About\nContactBot.sendMessage("Hello " + user.first_name + "!")
In this example:
/start triggers the commandAnswers are quick static messages. They appear before any code runs.
/*Command: /help
answer: I can do these things:
- /start → Start the bot
- /about → Info about me*/
Bot.sendMessage("Extra help details...")
If need_reply is set to true, the bot waits for the next user message before continuing.
/*command: /ask
answer: What is your favorite color?
need_reply: true*/
Bot.sendMessage("You answered: " + message)
Aliases let one command have multiple triggers.
/*Command: /hello
aliases: hi, hey, hola*/
Bot.sendMessage("Hello there!")
Commands can show custom keyboards:
Yes,No\n → Yes\nNo/*Command: /menu
answer: Choose an option:
keyboard: Yes,No\nMaybe*/
Bot.sendMessage("Waiting for your choice...")
TBL provides special system-level commands:
**TBL now supports dynamic command handlers for every Telegram update type.
Any update (other than messages) can be handled automatically by creating a command following this pattern:
/handle_{update_type} → will be executed for that specific update type.For example:
/*Command: /handle_chat_member*/
Bot.sendMessage("A chat member update occurred!")
This feature works for all update types listed in the Telegram Bot API, including:
my_chat_memberchat_memberchat_join_requestbusiness_messageedited_business_messagepollpoll_answermessage_reactionmessage_reaction_countchat_boostremoved_chat_boostIf a /handle_{update_type} command is not defined, the update will fall back to /channel_update (for channel-related updates) or * as a universal fallback.
Handles inline mode queries (when users type @yourbot query in Telegram).
Command: /inline_query
Bot.sendMessage("You searched: " + request.query)
Handles channel posts automatically.
Command: /channel_update
Bot.sendMessage("New channel post received!")
/buy_ticket, not /cmd69/handle_{type} for any special update typeawaitTBL provides a set of predefined global variables. These are available in every command, so you don’t need to declare them manually. They make it easier to work with Telegram updates, users, chats, and the bot itself.
The raw Telegram update object. Contains everything Telegram sends (messages, edits, queries, etc.).
{
"update_id": 109608973,
"message": {
"message_id": 17261,
"from": {
"id": 5723455420,
"is_bot": false,
"first_name": "Soumyadeep ∞",
"username": "soumyadeepdas765",
"language_code": "en",
"is_premium": true
},
"chat": {
"id": 5723455420,
"first_name": "Soumyadeep ∞",
"username": "soumyadeepdas765",
"type": "private"
},
"date": 1758100437,
"text": "/start",
"entities": [
{
"offset": 0,
"length": 6,
"type": "bot_command"
}
]
}
}
Simplified version of update. TBL automatically detects the type of update. like when the update type is message then request will be update.message
And in Webhook request object contains info like ip, body, params, header etc..
Contains only the text of a message (if applicable).
"Hello bot"
Information about the user interacting with the bot.
{
"id": 5723455420,
"is_bot": false,
"first_name": "Soumyadeep ∞",
"username": "soumyadeepdas765",
"language_code": "en",
"is_premium": true,
"last_name": "",
"telegramid": 5723455420,
"premium": true,
"blocked": false,
"block_reason": null,
"blocked_at": null,
"just_created": false //can be true if just started the bot for first time ,
}
Details about the current chat (private, group, or channel).
{
"id": 5723455420,
"first_name": "Soumyadeep ∞",
"username": "soumyadeepdas765",
"type": "private",
"chatid": 5723455420,
"chatId": 5723455420,
"blocked": false,
"block_reason": null,
"blocked_at": null,
"just_created": true
}
Information about the bot including owner, status, and platform info.
{
"id": 42, // bot id in our platform , a unique identifier for each bot
"token": "123456:ABC...",
"name": "DemoBot",
"bot_id": 987654321, // Bot actual Telegram id
"owner": "somemail@telebothost.com",//bot owner mail
"status": "working",
"created_at": "2025-01-01",
"updated_at": "2025-01-10
}
TBL includes a built-in sleep function that lets your bot pause execution for a short moment — up to 10,000 ms (10 seconds) in total.
Use it like this:
sleep(1000); // sleep for 1000 ms (1 second)
The plan object contains the user’s subscription details.
You can access limits, features.
The owner object contains information about the bot owner, including
email address, plan details, and API keys.
Extra text after a command. Example: "/start hello" → params = "hello".
"hello"
Custom data passed between commands when chaining or using API callbacks.
//passing custom
{
"name": "Alice",
"step": 2
}
//when callback of Telegram Api call
{
"ok": true,
"result": {...}
}
Contains the response body from an HTTP request.
Helper function to print any object for debugging.
like if you did inspect(data) it will return bot Details
msg is a simplified version of update. It’s only available for message updates.
Whenever a message update is received, msg will contain the same object as update.message.
It's a object that gives information about error got by ! command
import functions from another command easily. Learn More Here
TBL provides several predefined classes. These classes give you direct access
to Telegram features, user data, and external utilities.
The most important one is Api, which works as a direct wrapper
for the official Telegram Bot API.
The Api class lets you call any Telegram method.
You can use it directly, with callbacks, async/await, or with chained message methods.
sendMessage or sendmessage.
The simplest way to use Api is to call a method directly.
No await is needed. The message will be sent in the background.
// Send a simple message
Api.sendMessage({ text: "Hello user!" })
// Send a photo
Api.sendPhoto({ photo: "https://example.com/cat.jpg", caption: "Cute cat" })
on_run Callback
You can pass on_run to any Api call to run another command when the call finishes.
Useful if you want to continue logic in a separate command.
// Get bot info and continue in another command
Api.getMe({ on_run: "afterGetMe" })
// Inside "afterGetMe" command
if (options.ok) {
Api.sendMessage({ text: "Bot username: @" + options.result.username })
}
For sequential logic, you can use async/await.
This lets you store results in variables and act on them immediately.
let me = await Api.getMe()
if (me.ok) {
Api.sendMessage({ text: "My bot id is " + me.result.id })
}
let sent = await Api.sendMessage({ text: "Hello again!" })
Bot.inspect(sent) // Full Telegram response
Every response object returned from Bot.sendMessage(), Api.sendMessage(), etc. now supports chained methods.
These let you quickly react, edit, reply, pin, forward, or delete the message.
// Send a message and chain methods
let data = await Api.sendMessage({text: "Hello user!"})
await data.pin() // Pin the message
await data.react("👍") // Add reaction
await data.editText("Updated text") // Edit message text
await data.reply("Replied Message") // Reply to message
dn → disable notification
Api.xxx
Sometimes a specific Telegram Bot API method may not exist inside the built-in
TBL Api class. In such cases, you don’t have to wait for an update—TBL
allows you to call any official Telegram method dynamically using:
Api.call("methodName", { /* parameters */ })
This is extremely useful when Telegram introduces a new API feature. As long as
Telegram supports the method, you can use it immediately through
Api.call().
getChat Dynamically
Suppose getChat is not available in TBL's built-in methods. You can still
execute it like this:
Api.call("getChat", {
chat_id: 4444443444
})
How it works:
• "getChat" is the official Telegram method name
• The second argument is an object with parameters
• TBL automatically sends this request to Telegram and returns the response
This ensures your bot can instantly use any Telegram method—even those not built into TBL yet.
The Bot class is used for controlling your bot directly.
It provides methods for running commands, sending messages, and managing persistent bot-level properties.
Unlike Api, the Bot methods are designed to be easier to use inside commands.
The following methods are available in the Bot class:
You can tell the bot to run another command. This is useful if you want to move the user to a new flow. These methods don’t return any value – they just execute the command.
// Run another command
Bot.runCommand("/start")
// Run with options
Bot.runCommand("/start", { key: 111 })
// key is available now in /start and accessible with options.key
The Bot.read() method returns only the raw source code of a command as a plain string.
It does not include metadata such as answer, keyboard, or need_reply.
// Read the raw code of a command
let code = Bot.read("/start")
// Display or use the command code
Bot.sendMessage(code)
The Bot.readCommand() method returns a full command object, including both
the code and all metadata fields like aliases, keyboard,
need_reply, and more.
// Read full command structure
let cmd = Bot.readCommand("/start")
Bot.sendMessage(JSON.stringify(cmd, null, 2))
Example response:
{
"code": "const {random} = require(\"/send\");\n\nconst x = random(1, 100);\nBot.sendMessage(\"Random: \" + x);",
"answer": null,
"keyboard": null,
"aliases": [],
"allow_only_group": false,
"need_reply": false
}
These methods send messages or media to the current chat.
They return the Telegram API response (if awaited).
Using await is optional – you can wait for the result or send without waiting.
With await it also supports Api Chained methods.
// === Send Text ===
// Simple text
Bot.sendMessage("Hello user!")
// Text (object format)
Bot.sendMessage({ text: "Hello user!" })
// With HTML formatting
let res = await Bot.sendMessage("Hello friend", { parse_mode: "HTML" })
Bot.inspect(res)
// === Send Keyboard ===
// String format
Bot.sendKeyboard("Choose an option:", "Yes,No")
// Object format
Bot.sendKeyboard({ text: "Choose an option:", keyboard: "Yes,No" })
// === Send Media (supports string & object) ===
// Photo
Bot.sendPhoto("photo.jpg")
Bot.sendPhoto({ photo: "photo.jpg", caption: "Nice view!" })
// Document
Bot.sendDocument("file.pdf", "Here is your pdf")
Bot.sendDocument({ document: "file.pdf", caption: "Here is your file" })
// Audio
Bot.sendAudio("music.mp3")
Bot.sendAudio({
audio: "music.mp3",
caption: "Here is your music"
})
// Video
Bot.sendVideo("video.mp4")
Bot.sendVideo({ video: "video.mp4", caption: "Watch this" })
// Voice
Bot.sendVoice("voice.ogg")
Bot.sendVoice({ voice: "voice.ogg", caption: "Voice note" })
// === Debugging ===
Bot.inspect({ user: "Alice", id: 123 })
//Or multiple data inspect
Bot.inspect("User data:", user, { id: 123 }, someArray)
// === API Chaining Example ===
let data = await Bot.sendMessage("Pinned message")
data.pin() // pin the previous message
Bot properties are simple key-value storage.
They let you save data that belongs to the bot itself (not a specific user).
All property methods are synchronous, so await is not required.
// Set properties
Bot.set("version", "1.2.3", "String")
Bot.set("config", { apiKey: "xyz" }, "Json")
// Get values
let v = Bot.get("version") // "1.2.3"
let c = Bot.get("config") // { apiKey: "xyz" }
// Delete one property
Bot.del("version")
// Get all properties
let all = Bot.getAll()
// Delete all
Bot.delAll()
// Check if a property exists
let has = Bot.has("config") // true
// Count all properties
let count = Bot.count() // e.g. 1
// Get all property names
let names = Bot.getNames() // ["config"]
The following data types are supported when storing bot properties:
type parameter is optional in Bot.set().
If not provided, the type is automatically detected.All property methods have short aliases. They work exactly the same, just different names.
// Setting values
Bot.setProp("theme", "dark", "String")
Bot.setProperty("lang", "en", "String")
// Getting values
Bot.getProp("theme") // "dark"
Bot.getProperty("lang") // "en"
// Deleting values
Bot.delProp("theme")
Bot.delProperty("lang")
// Get all / delete all
Bot.getAllProp()
Bot.getAllProperty()
Bot.delAllProp()
Bot.delAllProperty()
// Checking and counting
Bot.hasProp("theme")
Bot.countProps()
Bot.getPropNames()
The Bot.getUsers() method returns an array of user IDs who have interacted with your bot.
This method must be awaited as it returns a Promise.
// Get all users
let data = await Bot.getUsers()
// Returns type is Array
// Must needs to be awaited
/*
Filter available
getUsers({ chatType: "group/private/channel" , premiumOnly: true })
Filters are totally optional, by default we return all chats exclude channel ids
*/
Api.sendMessage({text: data})
// To get your bot user's, say goodbye to manually store in props
// We have this new feature in TBL
//This feature is not 100% stable now
// Examples with filters
// Get only group chats
let groupUsers = await Bot.getUsers({ chatType: "group" })
// Get only private chats
let privateUsers = await Bot.getUsers({ chatType: "private" })
// Get only premium users
let premiumUsers = await Bot.getUsers({ premiumOnly: true }) //these are private chats
// Send the results
Bot.sendMessage("Group users: " + groupUsers.length)
Bot.sendMessage("Premium users: " + premiumUsers.length)
Note: By default, channel IDs are excluded from the results.
Use chatType: "channel" to specifically get channel IDs if needed.
Both Api and Bot can send messages, but they serve different purposes.
Api.call() for any Telegram method (even new ones)
Api.sendMessage({ chat_id: user.telegramid, text: "Hello from Api!" })
Api.call("getChat", { chat_id: 123456 })
Bot.inspect() and bot properties
Bot.sendMessage("Hello from Bot!") // auto chat_id
Bot.sendPhoto({ photo: "pic.jpg" }) // simple helper
Bot.inspect("Debug:", user, chat) // multi-argument inspect
Summary:
Api gives full access to every Telegram method.
Bot provides simplified helpers for common tasks inside commands.
The HTTP class allows your bot to make external API requests (GET, POST, etc.) and handle responses flexibly.
It supports direct calls with await, chaining commands for success/error handling.
Simple GET request:
// GET request using direct URL
let data = await HTTP.get("https://jsonplaceholder.typicode.com/todos/1")
Bot.inspect(data)
// we will have data.content(raw string ), data.headers, data.cookies, data.data(parsed)
/* Demo data
{
ok: true,
status: 200,
statusText: 'OK',
content: '{"ok":true,"ping":true}', //content is String
data: {
ok: true,
ping: true
}, // if it JSON then auto parsed
headers: {
'content-type': 'application/json; charset=utf-8'
...more
},
cookies: []
}
*/
// GET request using object with options
let data2 = await HTTP.get({
url: "https://jsonplaceholder.typicode.com/todos/2",
headers: { "Authorization": "Bearer ABC123" }
})
Bot.inspect(data2)
POST request example:
// POST request
let payload = { name: "Alice", age: 25 }
let response = await HTTP.post({
url: "https://jsonplaceholder.typicode.com/posts",
body: payload,
headers: { "Authorization": "Bearer ABC123" }
})
Bot.inspect(response)
tbl_options
You can define commands to run automatically on success or error.
If error command is missing, the success command will run instead.
// HTTP GET with success/error commands
HTTP.get({
url: "https://jsonplaceholder.typicode.com/todos/1",
success: "onSuccess",
error: "onError",
tbl_options: {key : value} //optinal for passing custom values only
})
// you can get tbl_options on next command like
tbl_options.key
// "onSuccess" command will receive options = HTTP response
// "onError" command will receive options = HTTP error
// on success you will get content and in error command you will get error
// error command only run when there an internal error like request failed due to some reasons like
// wrong url, API have 500 etc...
//
// Example success command
/*command: onSuccess*/
Bot.sendMessage("Fetched title: " + content)
// Example error command
/*command: onError*/
Bot.sendMessage("HTTP request failed: " + error.status)
// GET with query params and headers, and success/error commands
HTTP.get({
url: "https://api.example.com/search",
query: { q: "telebot", limit: 5 },
headers: { "X-Api-Key": "123ABC" },
timeout: 5000,
success: "searchSuccess",
error: "searchError"
})
response object on callback command: { ok, status, data or error }.await to wait for the response or skip it if not needed.error command is missing, the success command will run instead.The User class is used to store and manage data for each user individually. Every user has their own private storage, and these methods let you save, read, and delete that data.
Use these methods to save and read single values for the current user.
// Save user data
User.set("name", "Alice")
User.set("age", 25, "number")
// Read user data
let name = User.get("name") // "Alice"
let age = User.getProp("age") // 25
Bot.sendMessage("Name: " + name + ", Age: " + age)
// → Name: Alice, Age: 25
Remove specific values when you don’t need them anymore.
If the property doesn’t exist, it just returns null when read.
// Delete property
User.del("age")
let age = User.get("age") // null
Bot.sendMessage("After delete, age = " + age)
// → After delete, age = null
You can work with all stored data at once. This is useful to inspect or reset the user’s storage.
// Save multiple values
User.set("country", "India")
User.set("verified", true, "boolean")
// Get all user data
let all = User.getAll()
Bot.inspect(all)
// → { "name": "Alice", "country": "India", "verified": true }
// Delete all properties
User.delAll()
let all2 = User.getAll()
Bot.inspect(all2)
// → {}
Check if data exists, count stored keys, or list property names.
// Check if property exists
let hasName = User.has("name") // true or false
// Count total properties
let total = User.count() // e.g. 2
// Get property names
let names = User.getNames() // ["name", "country"]
Bot.inspect({ hasName, total, names })
// → { "hasName": true, "total": 2, "names": ["name", "country"] }
get, set, and del have multiple aliases (like getProp, getProperty).await — they just return undefined.The Global class is used to store and manage data at the account level. All data stored here is shared across all bots under the same owner account and can be accessed by any bot.
Use these methods to save and read global values that are accessible to all your bots.
// Save global data (shared across all bots)
Global.set("company_name", "TechCorp")
Global.set("max_bot_instances", 5, "number")
Global.set("supported_languages", ["en", "es", "fr"], "list")
// Read global data
let company = Global.get("company_name") // "TechCorp"
let maxBots = Global.getProp("max_bot_instances") // 5
let languages = Global.get("supported_languages") // ["en", "es", "fr"]
Bot.sendMessage("Company: " + company + ", Max Bots: " + maxBots)
// → Company: TechCorp, Max Bots: 5
Remove global values when they are no longer needed across all bots.
// Delete global property
Global.del("max_bot_instances")
let maxBots = Global.get("max_bot_instances") // null
Bot.sendMessage("After delete, max bots = " + maxBots)
// → After delete, max bots = null
Manage all global data at once. Useful for configuration management and data migration.
// Save multiple global values
Global.set("api_key", "sk-123456789")
Global.set("webhook_url", "https://api.example.com/webhook")
Global.set("maintenance_mode", false, "boolean")
// Get all global data
let allGlobal = Global.getAll()
Bot.inspect(allGlobal)
// → { "company_name": "TechCorp", "api_key": "sk-123456789", "webhook_url": "https://...", "maintenance_mode": false }
// Delete all global properties
Global.delAll()
let allEmpty = Global.getAll()
Bot.inspect(allEmpty)
// → {}
Check if global data exists, count stored keys, or list all global property names.
// Check if global property exists
let hasCompany = Global.has("company_name") // true or false
// Count total global properties
let totalGlobal = Global.count() // e.g. 3
// Get all global property names
let globalNames = Global.getNames() // ["company_name", "api_key", "webhook_url"]
Bot.inspect({ hasCompany, totalGlobal, globalNames })
// → { "hasCompany": true, "totalGlobal": 3, "globalNames": ["company_name", "api_key", "webhook_url"] }
Monitor your total storage usage across all data types: Bot properties + User properties + Global properties.
// Get detailed storage information (includes bot + user + global data)
let storageInfo = Global.getStorageInfo()
Bot.inspect(storageInfo)
// → { "size": 1572864, "prop_count": 42, "last_calc": "2024-01-15T10:30:00.000Z" }
// Get storage usage percentage (0-100%)
let usagePercent = Global.getStorageUsage()
Bot.sendMessage("Storage usage: " + usagePercent + "%")
// → Storage usage: 7.5%
// Check if storage is near limit (90% threshold)
if (Global.isStorageNearLimit()) {
Bot.sendMessage("⚠️ Storage almost full! Please clean up some data.")
}
// Get available storage in MB
let availableMB = Global.getAvailableStorage()
Bot.sendMessage("Available storage: " + availableMB + " MB")
// → Available storage: 18.5 MB
Additional methods for validation and debugging of global storage.
// Check if owner configuration is valid
if (Global.isOwnerValid()) {
Bot.sendMessage("✅ Global storage is properly configured")
} else {
Bot.sendMessage("❌ Owner mail configuration missing")
}
// Get owner email (for debugging)
let ownerMail = Global.getOwnerMail()
Bot.sendMessage("Owner account: " + ownerMail)
// → Owner account: owner@example.com
Common use cases for global storage across multiple bots.
// Example 1: Shared configuration for all bots
Global.set("theme_config", {
primary_color: "#3B82F6",
font_family: "Inter",
dark_mode: true
}, "json")
// Example 2: Feature flags across bot network
Global.set("beta_features", {
new_chat_ui: true,
voice_messages: false,
ai_analytics: true
}, "json")
// Example 3: Rate limiting across all bots
Global.set("total_requests_today", 0, "number")
// Increment shared counter
let currentRequests = Global.get("total_requests_today")
Global.set("total_requests_today", currentRequests + 1, "number")
// Example 4: Maintenance mode for all bots
if (Global.get("maintenance_mode")) {
Bot.sendMessage("🔧 System under maintenance. Please try again later.")
return
}
The Webhook class is used to generate secure URLs for your bot’s webhook endpoints.
These URLs can trigger bot commands directly from external sources — like web pages, APIs, or user dashboards —
while keeping data protected with cryptographic signatures.
Global webhooks are public endpoints anyone can access. Ideal for open integrations, landing pages, or APIs that don’t require authentication.
Webhook.getGlobalUrl()User-based webhooks are tied to a specific user and contain a secure signature for that user. Perfect for personalized dashboards, user actions, or account-specific operations.
Webhook.getUrl() or Webhook.getUrlFor()getUrl(command, { options, params, redirect })Generates a secure user-based webhook for the current user. You can include optional parameters and redirect URLs.
let syncUrl = Webhook.getUrl("syncGameData", {
options: { level: 10 },
params: { ref: "profile", lang: "en" }
})
Api.sendMessage({
text: `Sync your game data: ${syncUrl}`
})
getUrlFor({ user_id, command, options, params, redirect })Generates a webhook for a specific user. Ideal for sending personalized links or actions to a given user ID.
let upgradeUrl = Webhook.getUrlFor({
user_id: 123,
command: "syncGameData",
redirect: "https://telebothost.com",
options: { plan: "pro" },
params: { ref: "upgrade" }
})
Api.sendMessage({
text: `Upgrade your plan here: ${upgradeUrl}`
})
getGlobalUrl(command, { options, params, redirect })Creates a globally accessible webhook URL that does not require user authentication. You can attach query parameters or redirect links for external flows.
let statsUrl = Webhook.getGlobalUrl("getStats", {
options: { days: 30 },
redirect: "https://telebothost.com",
params: { ref: "home" }
})
Api.sendMessage({
text: `View global statistics: ${statsUrl}`
})
params for visible query strings (e.g., tracking or page context)options for internal, signed dataredirect if the webhook should lead back to an external pageuser-based URLs publicly| Method | Access Type | Use Case |
|---|---|---|
getGlobalUrl() | Public | Open APIs, landing pages |
getUrl() | Private (current user) | User dashboard, game data |
getUrlFor() | Private (specific user) | Account links, user actions |
The Webapp class is used to generate clean, global URLs for your bot’s
web integrations — such as dashboards, pages, or lightweight APIs.
Unlike Webhook, these URLs are not cryptographically signed,
making them ideal for open, public, or embed-style resources.
Use the Webapp class whenever you need a static or semi-dynamic link for:
getUrl(command, { options, params })
Generates a global webapp URL for the specified command.
You can include options for internal configuration
and params for visible query parameters.
let dashboardUrl = Webapp.getUrl("dashboard", {
options: { theme: "dark", userId: 123 },
params: { ref: "home", lang: "en" }
})
Api.sendMessage({
text: `Open the web dashboard: ${dashboardUrl}`
})
Webapp for public or semi-public resources onlyparams for readable URL parameters (e.g. ?ref=home&lang=en)options for app-level configurationWebhookres)
The res object allows webhook and Webapp commands to send structured HTTP responses.
It supports JSON, HTML, XML, text, redirects, and template rendering with EJS.
set(key, value)Sets HTTP headers on the response object.
res.set("Content-Type", "application/json")
.set("X-Custom-Header", "my-value")
status(code)Sets the HTTP response status code.
res.status(200)
res.status(404)
res.status(500)
send(body)Sends a response with any content type.
res.send("Hello World")
res.send({ message: "Success", data: { id: 1 } })
res.status(201).send("Resource created")
json(obj)Sends a JSON response with application/json content type.
res.json({
status: "success",
user: user.name,
data: processedData
})
html(content)Sends an HTML response. Auto-renders EJS templates if tags detected.
res.html("<h1>Welcome</h1><p>Hello World</p>")
res.html(`
<h1>Welcome <%= user.first_name %></h1>
<p>Your ID: <%= user.id %></p>
<% if (user.premium) { %>
<div class='premium'>Premium User</div>
<% } %>
`)
xml(content)Sends an XML response with application/xml content type.
res.xml('<?xml version="1.0"?><response><status>success</status></response>')
text(content)Sends a plain text response. Auto-renders EJS templates if tags detected.
res.text("This is plain text")
const textTemplate = 'Hello <%= name %>, welcome!'
res.text(textTemplate)
redirect(url)Redirects the request to a different URL.
res.redirect("https://example.com/success")
res.redirect("/another-command")
render(commandPath, options)Renders another command's code as response with automatic content type detection.
res.render("user-profile")
res.render("api-data.json", {
data: { user: { name: "John", age: 30 } }
})
res.render("dashboard.html", {
data: {
user: user,
stats: userStats,
params: params
}
})
res.render() automatically detects content type from file extension:
res.render("page.html") // Content-Type: text/html
res.render("data.json") // Content-Type: application/json
res.render("script.js") // Content-Type: application/javascript
res.render("style.css") // Content-Type: text/css
res.render("api.xml") // Content-Type: application/xml
res.render("plain-text") // Content-Type: text/plain
All template rendering methods have access to multiple data sources:
// Webapp URL: /webapp/showProfile?section=settings&view=compact
res.render("profile-template.html", {
data: {
user: user, // Current user object
profile: userProfile, // Additional profile data
preferences: userPrefs // User preferences
}
})
//in rendered Command use like <%= profile %>
// In profile-template.html, you can access:
// - user, profile, preferences
// - params (from URL query string: {section: "settings", view: "compact"})
// - All TBL variables (msg, Api, State, etc.)
let userData = {
id: user.id,
name: user.first_name,
premium: user.premium || false,
join_date: user.join_date
}
// user object Only avilable on user based webhook
res.status(200)
.set("Access-Control-Allow-Origin", "*")
.json({
status: "success",
data: userData,
timestamp: Date.now()
})
The msg class lets you interact with Telegram messages.
You can send, reply, edit, delete, forward, copy, react, and perform chat actions.
All methods return promises, but using await is optional — only required if you need the response object.
msg.reply(), msg.send()msg.replyPhoto(), msg.replyVideo(), msg.replyDocument()msg.editText(), msg.delete(), msg.react(), msg.pin(), msg.unpin()msg.forward(), msg.copy()msg.replySticker(), msg.replyDice()msg.sendChatAction()
// Reply to the current message
msg.reply("Hello!") // Fire-and-forget
let result = await msg.reply("Hello!"); // Use await if you need the API response
// Send a new message
msg.send("This is a new message")
await msg.send("This is a new message", { parse_mode: "Markdown" }) // await optional
// Reply with a photo
msg.replyPhoto("https://example.com/cat.jpg", { caption: "Cute cat 🐱" })
await msg.replyPhoto("https://example.com/cat.jpg", { caption: "Cute cat 🐱" }) // await optional
// Reply with a video
msg.replyVideo("https://example.com/video.mp4")
await msg.replyVideo("https://example.com/video.mp4", { caption: "Watch this!" })
// Reply with a document
msg.replyDocument("file.pdf")
await msg.replyDocument("file.pdf")
// Edit message text
msg.editText("Updated text")
// Delete message
msg.delete(msg.message_id)
await msg.delete(msg.message_id)
// Add reactions
msg.react("👍")
msg.react("🔥", true) // Big emoji
// Pin & unpin messages only for group or super group with proper admin Rights
msg.pin()
msg.unpin(msg.message_id)
// Forward message
msg.forward(123456789)
await msg.forward(123456789)
// Copy message
msg.copy(123456789, { caption: "Copied message" })
await msg.copy(123456789, { caption: "Copied message" })
// Reply with a sticker
msg.replySticker("CAACAgUAAxkBAAECX-9g1...")
await msg.replySticker("CAACAgUAAxkBAAECX-9g1...")
// Reply with a dice
msg.replyDice("🎲")
await msg.replyDice("🎲")
// Show typing indicator
msg.sendChatAction("typing")
await msg.sendChatAction("typing") // await optional
// Other actions: "upload_photo", "record_video", "record_audio", "upload_document"
The msg object contains the full Telegram message data:
msg.text - Message textmsg.chat - Chat info (id, type, title, etc.)msg.from - Sender infomsg.message_id - Unique message IDmsg.date - TimestampAll methods also work in lowercase (e.g., msg.replyphoto).
Markdown parsing is enabled by default for text methods.
The modules object gives you access to popular Node.js libraries directly in TBL.
Use modules.moduleName.method() to perform common tasks like encryption, validation, date handling, CSV/YAML parsing, random data generation, and more.
JWT is used for creating and verifying JSON Web Tokens. Useful for authentication, session management, or secure data transfer.
Docs: jsonwebtoken
// Create a token
const token = modules.JWT.sign({ userId: 123 }, "secret");
// Verify a token
const decoded = modules.JWT.verify(token, "secret");
// Demo response:
// token → "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
// decoded → { userId: 123, iat: 1690000000 }
bcrypt hashes passwords and verifies them. Essential for secure password storage.
Docs: bcrypt
// Hash a password
const hash = await modules.bcrypt.hash("password123", 10);
// Verify password
const match = await modules.bcrypt.compare("password123", hash);
// Demo response:
// hash → "$2b$10$e0N...."
// match → true
crypto provides cryptographic functions, including hashing, encryption, and decryption.
Docs: Node.js crypto
// Create SHA256 hash
const hash = modules.crypto.createHash("sha256").update("data").digest("hex");
// Demo response:
// hash → "3a6eb...9f1"
Parses CSV strings into JSON objects. Useful for reading CSV files in bots or scripts.
Docs: csv-parse
// Parse CSV string
const result = modules.ParseCSV.parse("name,age\nAlice,25\nBob,30");
// Demo response:
// result → [{ name: "Alice", age: "25" }, { name: "Bob", age: "30" }]
Parses YAML strings into JSON objects. Useful for reading YAML configuration files.
Docs: js-yaml
// Parse YAML string
const result = modules.ParseYML.parse("name: Alice\nage: 25");
// Demo response:
// result → { name: "Alice", age: 25 }
Generates unique identifiers (UUID v4 or v6). Useful for unique keys, transaction IDs, or session identifiers.
Docs: uuid
// Generate v4 UUID
const id = modules.UUID.uuidv4();
// Demo response:
// id → "550e8400-e29b-41d4-a716-446655440000"
A powerful library for date and time manipulation. Format, parse, and calculate dates easily.
Docs: momentjs
// Format current date
const dateStr = modules.moment().format("YYYY-MM-DD");
// Demo response:
// dateStr → "2025-09-19"
A utility library for array, object, and function operations. Very handy for filtering, mapping, and transforming data.
Docs: lodash
// Filter array
const result = modules.lodash.filter([1,2,3,4], n => n > 2);
// Demo response:
// result → [3,4]
Generates random alphanumeric strings, useful for temporary passwords, tokens, or unique identifiers.
Docs: randomstring
// Generate 10-character random string
const str = modules.randomstring.generate(10);
// Demo response:
// str → "a1b2c3d4e5"
Validates strings like emails, URLs, and other formats.
Docs: validator
// Validate email
const valid = modules.validator.isEmail("test@example.com");
// Demo response:
// valid → true
Generates random data, such as names, addresses, and phone numbers.
Docs: chancejs
// Generate random name
const name = modules.chance.name();
// Demo response:
// name → "Alice Johnson"
Mathematical functions like square root, powers, trigonometry, etc.
Docs: mathjs
// Square root
const val = modules.math.sqrt(25);
// Demo response:
// val → 5
Parses and formats query strings.
Docs: qs
// Parse query string
const obj = modules.qs.parse("a=1&b=2");
// Demo response:
// obj → { a: "1", b: "2" }
Parse and manipulate HTML in Node.js (like jQuery). Useful for scraping and DOM manipulation.
Docs: cheerio
// Load HTML
const $ = modules.cheerio.load("<p>Hello</p>");
const text = $("p").text();
// Demo response:
// text → "Hello"
Lightweight alternative to Moment.js for date and time operations.
Docs: dayjs
// Format current date
const today = modules.dayjs().format("YYYY-MM-DD");
// Demo response:
// today → "2025-09-19"
//We have our own Basic library for time parsing too
Schema validation library for structured data. Useful for input validation.
Docs: zod
// Validate string
const result = modules.zod.string().parse("Hello");
// Demo response:
// result → "Hello"
Generates short unique IDs for objects, users, or temporary references. Useful when you need compact unique identifiers.
Docs: shortid
// Generate short ID
const id = modules.shortid.generate();
// Demo response:
// id → "ppBqWA9"
Deeply merges multiple objects. Useful for combining configs or nested data structures.
Docs: deepmerge
// Merge two objects
const merged = modules.deepmerge({ a: 1, b: { x: 1 } }, { b: { y: 2 }, c: 3 });
// Demo response:
// merged → { a: 1, b: { x: 1, y: 2 }, c: 3 }
Formats durations (milliseconds) into human-readable strings, like "2 hours" or "5 minutes".
Docs: humanize-duration
// Convert milliseconds to human-readable
const duration = modules.humanizeDuration(3600000);
// Demo response:
// duration → "1 hour"
Parses user-agent strings to extract browser, OS, and device information. Useful for analytics, logs, or customizing content.
Docs: ua-parser-js
// Parse user-agent
const ua = modules.uaParser.parse("Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
// Demo response:
// ua → { browser: { name: "Firefox", version: "xx" }, os: { name: "Windows", version: "10" }, device: { model: "", type: "", vendor: "" } }
A powerful Ethereum library for interacting with EVM chains. Use it to send transactions, read contract data, sign messages, and more.
Docs: ethers v6
// Import ethers
const ethers = modules.ethers;
// Create a provider (HTTPS only — WebSocket not supported)
const provider = new ethers.JsonRpcProvider("https://rpc.example.com");
// Read blockchain data
const block = await provider.getBlockNumber();
// Example:
// block → 18902345
You no longer need to use modules.crypto.xxx; you can directly access methods with crypto.xxx.
The crypto library is now included by default since it’s one of the most commonly used modules.
Similarly, the form-data library is also included by default as FormData, allowing you to use FormData.xxx directly.
The Libs class gives direct access to TBL’s built-in libraries.
Each library contains ready-to-use helpers for randomization, date/time operations, resource tracking, referral systems, Telegram utilities, and membership checking.
Use the syntax Libs.<library>.<method>().
Most methods return promises—await is optional unless you need the returned value.
// Create or get a user resource (e.g., balance)
let coins = Libs.ResourcesLib.userRes("coins")
coins.add(50) // add value
let current = coins.value() // get current value
// Global resource example
let globalCounter = Libs.ResourcesLib.anotherRes("visits")
globalCounter.add(1)
Persistent storage for user or global properties. Full ResourcesLib Documentation
// Current date/time in custom mask
let now = Libs.dateTimeFormat.getCurrentDate("yyyy-mm-dd HH:MM:ss")
// Add days to a date
let future = Libs.dateTimeFormat.addDays(new Date(), 7)
// Time difference between two dates
let diff = Libs.dateTimeFormat.getTimeDifference("2025-01-01","2025-02-01")
Full set of date formatting and calculation utilities. Full dateTimeFormat Documentation
// Check if a user is a member of specific channels
let joined = await Libs.mcl.check(user.id, ["@Chan1", "@Chan2"])
/* returns
{
all_joined: true,
valid: [ '@Channel1', '@Channel2' ],
left: [],
invalid: [],
details: [
{
channel: '@Channel1',
member: { /* full getChatMember response */ }
}
]
}
*/
Validate user subscriptions across one or more Telegram channels or groups before allowing bot actions. Full MCL Documentation
// Random integer between 1 and 10
let num = Libs.random.randomInt(1, 10)
// Random string of 8 letters
let str = Libs.random.randomString(8, { charset: "alpha" })
// Random date within range
let date = Libs.random.randomDate(new Date(2023,0,1), new Date(2025,0,1))
// Random color
let color = Libs.random.randomColor("rgb")
Comprehensive random generation utilities. Full random Documentation
// Create a referral link
let refLink = Libs.refLib.getRefLink(bot.name)
// Count referrals for a user
let count = Libs.refLib.getRefCount(user.id)
Tools for building and tracking referral systems. Full refLib Documentation
// Get a user’s full name
let fullName = Libs.tgutil.getFullName(user)
// Create a clickable HTML link to a user profile
let link = Libs.tgutil.getLinkFor(user, "html")
// Escape text for Markdown
let safeText = Libs.tgutil.escapeText("*Hello*", "markdown")
// Create an inline button
let btn = Libs.tgutil.createInlineButton("Press Me", "/callback_data")
Telegram-specific helpers for mentions, chat links, message links, and safe text formatting. Full tgutil Documentation
await only if the lib is asynchronous like MCL lib
The TBL class provides methods to manage bots in TeleBotHost.
You can clone bots, transfer bot using this class
TBL.clone creates a copy of an existing bot, optionally including all properties and starting it immediately.
You can also pass custom properties to the cloned bot.
const res = TBL.clone({
bot_id: bot.id, // Required: ID of the bot to clone
start_now: true, // Optional: start cloned bot immediately
bot_token: '12345:abc', // Required if start_now=true
all_prop: true, // Optional: copy all bot properties
bot_props: { // Optional: custom properties
theme: 'dark',
welcome: 'Welcome to my new bot!'
}
});
// Inspect the cloned bot
Bot.inspect(res);
TBL.transfer allows you to transfer the bot to another TeleBotHost user.
const result = TBL.transfer({
bot_id: bot.id, // Bot ID to transfer
to_mail: 'newuser@telebothost.com' // Target owner's email
});
TBL.clone and TBL.transfer are synchronous and return immediately after the operation finishes.Bot.inspect(res) to verify bot details after cloning or transferring.start_now: true, ensure a valid bot_token is provided.bot_props are automatically type-detected (string, number, boolean, etc.).The require function allows you to import and reuse code from other commands as modules. This helps you organize code, avoid duplication, and build complex features by combining smaller modules.
// Create a command that exports functions
function greet(name) {
return "Hello " + name
}
function calculate(a, b) {
return a + b
}
// Export functions to make them available to other commands
module.exports = { greet, calculate }
// Import and use the module in another command
const utils = require("/greet_module")
// Use the imported functions
const message = utils.greet("John")
const result = utils.calculate(10, 5)
Bot.sendMessage(message + " - Calculation: " + result)
// Import specific functions only
const { greet, calculate } = require("/greet_module")
// Use directly without utils prefix
Bot.sendMessage(greet("Alice"))
Bot.sendMessage("Sum: " + calculate(7, 3))
Key Points:
• Use module.exports to export from a module
• Use require("/command_name") to import modules
• Share functions, variables, and objects between commands
• only work between Commands, doesn't support external libraries like Native Node.js
The Free Plan in TBL provides a secure sandbox for running bots with limited resources. It’s designed for small projects, testing, and basic automation.
Promise.all()For Getting premium plans see our Pricing Page