To build a Telegram bot, create it with @BotFather (/newbot) to get a token, write a small handler that reads updates and replies through the Bot API, and run it. Use long polling while you build and a webhook once it lives on an HTTPS host. For selling digital goods, Telegram requires Stars: send an invoice in XTR, answer the pre-checkout query fast, and deliver on successful_payment.
To build a Telegram bot, message @BotFather, send /newbot, and copy the token it gives you; then run a short script that fetches updates from the Bot API and replies with sendMessage. That gets a working bot in one sitting. Deploying it means moving the script to a host and, usually, switching from polling to a webhook.
By the end of this tutorial you will have a bot that answers /start and echoes messages, running on a server, plus the extra steps to charge for something inside it. The technical facts below were checked in October 2026 against Telegram's official bot tutorial, Bot API reference and Stars payments docs.
If you are still deciding between messaging channels for a business bot, start with our WhatsApp Business API guide, which compares access, pricing and rules. Telegram is the easier of the two to start with: no business verification, no per-message fees and a bot in minutes.
What you need before you start
- A Telegram account on your phone or desktop
- Node.js 18 or newer installed (for built-in fetch), or any language that can make HTTPS requests
- A place to keep secrets: an .env file locally, environment variables on the host
- For deployment: a host that gives you an HTTPS URL or keeps a process running
- A second Telegram account or a friend, to test the bot as a stranger would
Step 1: Create the bot with BotFather
BotFather is Telegram's own bot for registering and managing bots. Search for @BotFather (check for the verified badge), open the chat and send /newbot. It asks for two things:
- A display name. What users see at the top of the chat. You can change it later.
- A username. Unique across Telegram and it must end in "bot", for example
acme_orders_bot. This becomes the t.me link.
BotFather replies with a token that looks like 123456789:AA.... Expected result: you have a bot you can open at t.me/your_username, which does nothing yet, and a token.
While you are in BotFather, use /setdescription for the text people see before they press Start, and /setcommands to list commands like start - Begin so they show in the menu.
Step 2: Choose how your bot gets messages
Telegram gives a bot two ways to receive updates (new messages, button presses, payments). They are mutually exclusive: while a webhook is set, getUpdates will not return anything.
| Method | API call | How it works | Best for |
|---|---|---|---|
| Long polling | getUpdates | Your bot asks Telegram for new updates | Local development, small always-on servers |
| Webhook | setWebhook | Telegram POSTs each update to your HTTPS URL | Serverless hosts, production bots |
Long polling is the easy start: your script calls getUpdates with a timeout, Telegram holds the request open until something arrives, and you loop. No public URL, no certificates. A webhook is better once you deploy, because Telegram pushes each update to your URL and you can run on serverless platforms that only wake up for requests. Webhooks need HTTPS on one of the ports Telegram supports (443, 80, 88 or 8443).
Step 3: Write the handler
Here is a complete echo bot with no libraries. Save it as bot.mjs, set your token in the environment and run it:
// bot.mjs (Node 18+ has fetch built in)
const TOKEN = process.env.BOT_TOKEN
const API = `https://api.telegram.org/bot${TOKEN}`
let offset = 0
async function reply(chatId, text) {
await fetch(`${API}/sendMessage`, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ chat_id: chatId, text }),
})
}
while (true) {
const res = await fetch(`${API}/getUpdates?timeout=30&offset=${offset}`)
const { result = [] } = await res.json()
for (const update of result) {
offset = update.update_id + 1
const msg = update.message
if (!msg?.text) continue
if (msg.text === '/start') await reply(msg.chat.id, 'Hi. Send me any text.')
else await reply(msg.chat.id, `You said: ${msg.text}`)
}
}Run BOT_TOKEN=your_token node bot.mjs, open your bot in Telegram and press Start. Expected result: it replies to /start and echoes anything else. The offset line matters: it tells Telegram which updates you have handled, so you do not get the same message twice.
For anything beyond an echo, use a library. grammY and Telegraf (JavaScript), python-telegram-bot and aiogram (Python) wrap the same API with routing, keyboards and session state. The concepts stay the same: updates in, method calls out.
- 01User sends a message
In a private chat, group or via a button
- 02Telegram creates an Update
A JSON object with an update_id and the message
- 03Your bot receives it
Through getUpdates (polling) or a POST to your webhook
- 04Your code decides
Commands, AI calls, database lookups
- 05Bot API call back
sendMessage, sendPhoto, sendInvoice and so on
Step 4: Deploy it
Your laptop going to sleep turns the bot off, so it needs a home. Two common routes:
- Keep polling on an always-on server. A small VPS or any platform that runs a long-lived process. Run the same script under a process manager so it restarts after crashes. Nothing changes in the code.
- Switch to a webhook on a serverless host. Move the handler into an HTTPS route (a Next.js route handler, a Cloudflare Worker, a Vercel or Netlify function), deploy it, then register the URL once with
setWebhook.
// One request registers the webhook (run it once after deploying)
curl "https://api.telegram.org/bot$BOT_TOKEN/setWebhook" \
-d "url=https://your-app.example.com/telegram" \
-d "secret_token=$WEBHOOK_SECRET"
// In your HTTPS handler, reject anything without the matching header
if (req.headers['x-telegram-bot-api-secret-token'] !== process.env.WEBHOOK_SECRET) {
return res.status(401).end()
}
const update = req.body // same Update object getUpdates returned
// ...handle it exactly like the polling loop, then answer 200 quickly
res.status(200).end()The secret_token parameter makes Telegram send the header X-Telegram-Bot-Api-Secret-Token with every request, so your route can reject anyone else who finds the URL. Expected result: getWebhookInfo shows your URL with no recent errors, and the bot replies with your laptop closed.
- 1Create the bot
/newbot in BotFather, save the token as an environment variable
- 2Build locally with polling
getUpdates loop, test /start and a few messages
- 3Move the logic into an HTTPS route
Same handler, now reading the Update from the request body
- 4Deploy and set secrets on the host
BOT_TOKEN and a random WEBHOOK_SECRET
- 5Register the webhook
setWebhook with url and secret_token, once
- 6Verify
getWebhookInfo shows no errors and the bot answers
Step 5: Add payments with Telegram Stars
This is where a hobby bot becomes a product. Telegram's rules say digital goods and services sold in a bot must be paid for in Telegram Stars, its in-app currency (checked October 2026). The flow is three messages:
- Send an invoice with
sendInvoice(or a link fromcreateInvoiceLink), currencyXTRand an empty provider token. The price is a whole number of Stars. - Answer the pre-checkout query. Telegram sends a
pre_checkout_queryupdate and waits foranswerPreCheckoutQuery. If your bot does not answer within 10 seconds, the payment is cancelled, so keep this handler fast. - Deliver on
successful_payment. That message carries a charge ID; store it, because you need it to refund withrefundStarPayment.
Recurring access works through createInvoiceLink with a subscription_period of 30 days. What to sell, how to price it in Stars and how withdrawals work are in our Telegram bot monetization guide, and the free Telegram Bot Revenue Calculator turns a Stars price and a conversion rate into an estimate (arithmetic, not a forecast).
If you would rather build the paid product around the bot (a web app, a dashboard, an API with accounts and billing), that is what the AI SaaS Builder program covers end to end.
Troubleshooting
- Bot does not answer and getUpdates returns nothing. A webhook is still set. Call
deleteWebhook, then poll again. - Every message gets answered twice. Two copies of the bot are running (often a forgotten terminal), or you are not advancing
offset. - Webhook set but nothing arrives. Check
getWebhookInfo: it reports the last error, such as a certificate problem or a 500 from your route. The URL must be HTTPS on a supported port. - Bot ignores group messages. By default bots in groups have privacy mode on and only see commands and replies to them. Change it with
/setprivacyin BotFather, then remove and re-add the bot. - 401 Unauthorized. The token is wrong or was revoked. Copy it again from BotFather.
Habits that keep a live bot healthy
A bot that works on day one can still fail quietly a month later. A few habits prevent most of it:
- Answer the webhook fast. Return 200 as soon as you have the update and do slow work (AI calls, file generation) after, or in a queue. A route that times out gets retried, which shows up as duplicate replies.
- Make handlers idempotent. Store the
update_idor payment charge ID you have processed, so a retry never delivers a product twice. - Respect send limits. Telegram rate-limits how fast a bot can send messages. Broadcasting to every user at once gets you 429 errors; queue the sends and honour the retry time Telegram returns.
- Log errors, not messages. Record failures and update IDs, but keep users' message text and personal data out of your logs.
Where to go from here
Once the skeleton works, most useful bots add three things: inline keyboards so users tap instead of type, a database so the bot remembers each user, and an AI model call for free-text questions. Keep each in its own function so the update handler stays a short router. If you mostly want alerts and simple replies without maintaining code, an automation tool with a Telegram node can use the same BotFather token; our n8n beginner tutorial is the place to start, and self-hosting n8n keeps the running cost flat. For the AI step, building your first app on the Claude API covers the model call.
Telegram bot tutorial: FAQ
How do I create a Telegram bot?
Open a chat with @BotFather in Telegram, send /newbot, pick a display name and a username that ends in "bot". BotFather replies with an API token. Your code then calls the Bot API at api.telegram.org with that token to receive messages (through getUpdates or a webhook) and to reply with methods like sendMessage. Creating the bot is free and takes a few minutes.
What is the Telegram BotFather?
BotFather is Telegram's official bot for creating and managing bots. You use it to create a bot with /newbot, get or revoke its token, and set its name, description, profile picture and command list. It does not host or run your code: it only registers the bot. Your own server or script does the actual work through the Bot API.
Should I use polling or a webhook for my Telegram bot?
Use long polling (getUpdates) while you build: it runs from a laptop with no public URL. Switch to a webhook (setWebhook) when you deploy to a host that has an HTTPS address, especially a serverless one, because Telegram then pushes each update to you. You cannot use both at once: while a webhook is set, getUpdates does not return updates.
Is the Telegram Bot API free?
Yes. Telegram does not charge for creating bots or calling the Bot API. Your costs are hosting and whatever paid services your bot calls, such as an AI model API. Telegram does apply rate limits to how fast a bot can send messages, so a bot that broadcasts to many users has to queue its sends.
Do I need to know how to code to make a Telegram bot?
For a custom bot, some code helps, and this tutorial uses about 30 lines of JavaScript. Without code, automation tools such as n8n or Make have Telegram trigger and send nodes that use the same BotFather token, which is enough for alerts, simple replies and forms. Payments and complex conversations are easier in code.
How do Telegram bots take payments?
For digital goods and services, Telegram requires payments in Telegram Stars. Your bot sends an invoice with the currency XTR and an empty provider token, answers the pre-checkout query, and delivers the product when the successful_payment message arrives. Physical goods can still use third-party payment providers connected through BotFather.
The bot works. Now build the product around it.
AI SaaS Builder, included in All Access with Instagram Ignited, AI Influencers and Digital Products, covers building and shipping AI apps with accounts, billing and deployment, plus live coaching and the private community.
Keep building, free
Estimate what a Stars-priced bot could bring in, and join the free Telegram channel for what is working in automation right now.