The vast majority of Telegram bot tutorials online assume you already know how to set up a Linux server, configure webhooks, and deploy code. If you're not a full-time engineer, that's roughly fourteen assumptions too many. This walkthrough is for the person who has an idea for a useful bot and wants to actually ship it, without needing to learn DevOps first.
To keep it concrete, we'll build the same bot I built for a friend last month: a bot that takes a Telegram channel handle and returns the subscriber count plus a link to its listing on a directory. It's about 60 lines of real code and took two hours including deployment. The principles apply to any simple bot you'd want to build.
Step 1: Talk to @BotFather
Every Telegram bot starts with the same conversation. Open Telegram, search @BotFather, hit Start. Send /newbot. It will ask for a display name (visible to users) and a username (must end in _bot). Pick something you can live with — you can rename the display name later but the username sticks.
BotFather will reply with an API token that looks something like 7123456789:AAFX...long-string.... Copy it immediately into a notes app. That token is your bot's password. Never paste it into a public repo, a Discord server, or a screenshot.
While you're at BotFather, also run /setdescription and /setabouttext. These show up when users first open your bot. Write them like a product description, not an engineering changelog.
Step 2: Pick the boring language
If you've never written code before, use Python. Not because it's the best language — because it has the fewest surprises when something breaks, and the Telegram library ecosystem around it is the most forgiving.
Install python-telegram-bot. It's the library most of the real-world bots on Telegram actually use under the hood. The syntax is readable enough that you can debug by squinting.
Step 3: The 20-line bot
A minimum viable Telegram bot is genuinely this short:
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
from telegram import Update
BOT_TOKEN = "your-token-from-botfather"
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text(
"Hi. Send me a Telegram channel handle like @channelname "
"and I'll look it up."
)
async def lookup(update: Update, context: ContextTypes.DEFAULT_TYPE):
handle = update.message.text.strip().lstrip('@')
# ... fetch channel data here, see step 4
await update.message.reply_text(f"Looking up @{handle}...")
app = ApplicationBuilder().token(BOT_TOKEN).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, lookup))
app.run_polling()
Run it. On your laptop. With python bot.py. If the token is right, your bot is alive right now. Open Telegram, search its username, hit Start. It will respond.
This is the moment most tutorials skip explaining: the bot is live because your laptop is running the script. Close your laptop, bot goes offline. That's fine for testing — the hosting part comes later.
Step 4: Make it actually do something
A bot that echoes back text is not useful. Replace the placeholder lookup with a function that fetches real data. For our channel-lookup example, the simplest path is to call a public page, parse the subscriber count, and return it.
If you're targeting a directory like ours, the cleanest approach is to format a direct link based on the handle: https://telegramgroups.co/channel/{handle}. That way your bot doesn't need to scrape anything — it returns a clickable link that the user can open for richer info. Less to break, less to maintain.
async def lookup(update, context):
handle = update.message.text.strip().lstrip('@')
if not handle.isalnum() and '_' not in handle:
await update.message.reply_text("That doesn't look like a valid handle.")
return
url = f"https://telegramgroups.co/channel/{handle}"
await update.message.reply_text(
f"Here's what we have on @{handle}:\n{url}",
disable_web_page_preview=False
)
That's the whole feature. Validation, formatting, reply. Real bots are usually 90% boilerplate and 10% feature code.
Step 5: Hosting (the part that scares people)
To leave your laptop closed and still have the bot work, you need to run the script somewhere that's always online. For a hobby bot with light traffic, the cheapest good options are:
- Railway.app — free tier handles thousands of messages/day. Connect a GitHub repo, it deploys automatically on push. Closest thing to "deploy with one click."
- Fly.io — slightly steeper learning curve, but generous free tier and good reliability.
- A $5/month DigitalOcean droplet — the old-school option. Runs any bot forever. Requires SSH comfort.
Start with Railway. Upload your script and a requirements.txt with python-telegram-bot in it. Set BOT_TOKEN as an environment variable in the Railway dashboard (never hardcode it into the repo). Hit deploy. Your bot now lives in the cloud.
What to build next
Once the first bot is live, the second one is easier by an order of magnitude. Ideas that work well as small bots:
- A summary bot that returns the top 5 channels in a category — you can pull from our categories listing
- A "channel of the day" bot that posts a random popular channel to a group each morning
- A reminder bot that pings you when a specific channel posts (webhook-based)
- A utility bot for your own community — polls, member count, FAQ answers
If your bot is genuinely useful to Telegram users, you can list it as a Mini App or submit the launcher group to our directory so others can find it.
The honest part
You will hit weird bugs. Your bot will crash at 3 AM because the library got updated. You'll push a change that breaks the /start command for a day. This is fine. The bar for a useful Telegram bot is surprisingly low, and shipping a slightly janky bot that works 95% of the time will beat never shipping the perfect one.
The Telegram bot API is genuinely one of the friendliest APIs to learn on. Ship something small. See how many people use it. Iterate from there.