[Step 3-A-1/3] Your First Telegram Bot That Actually Answers — Office Worker Edition

📌 Expert Workflows · Step 3: AI Telegram Bot · Edition A (Office Worker) · Part 1 of 3

⚙️ How to use this tutorial. Follow the setup in order, keep the bot token out of screenshots and shared files, and test the bot first in a private chat. Troubleshooting sections describe common symptoms and checks; they are not records of a specific person’s results.

🎯 The Problem This Solves

Everything you’ve built so far has had exactly one user: you. Your PDF summarizer runs on your laptop. Your Chrome extension lives in your browser. If they break, you’re the only person who notices.

A bot is different. A bot has users — and the first time a colleague messages something you built and gets an answer back, the whole project changes character. That’s what makes this step the most interesting one in the course, and it’s also why we’ll spend real time on the parts that only matter when other people are involved.

By the end of this three-part build you’ll have a bot living in your team’s group chat that answers questions, summarizes long messages, and drafts replies — reachable from anyone’s phone, no installation on their side. This first part gets it registered and responding. No AI yet: today the goal is a bot that reliably says hello, because a bot that sometimes responds is worse than no bot at all.

Project context

Edition A — Office Worker. This edition uses an operations-team scenario to show how a beginner can move from a laptop-only script to a deliberately invoked Telegram bot. The example is instructional and does not claim a real employee, employer, deployment, or measured outcome.

The design goal is simple: place a deliberately invoked tool where requests already arrive, while keeping testing private and participation informed.

More technical? Edition C (AI Student) covers webhooks and deployment properly. Building for a shop or customers? Edition B (Reseller). For educators, Edition D (Classroom).

🛠️ Gather These First

  • Python installed and working — Step 1 Edition B covers this from scratch if you skipped it
  • A Telegram account on a supported phone or desktop, plus internet access; current app, data, and account terms may vary
  • No AI-provider key is used in Part 1. The bot still requires Telegram access, a running device or approved host, and network connectivity.

📝 Step 1: Meet BotFather

Telegram bots are created inside Telegram itself, by messaging a bot called BotFather — the official bot documentation covers the full command list. BotFather handles bot registration inside Telegram. Follow Telegram’s current Bot API instructions because available commands and account requirements can change.

  1. Open Telegram and search for @BotFather. Look for the blue verification tick; there are impostors.
  2. Send /newbot.
  3. It asks for a display name — what people see at the top of the chat. “Team Helper” is fine. This can be anything and you can change it later.
  4. It asks for a username — the unique @handle. This one has rules: it must be unique across all of Telegram and it must end in bot.
  5. BotFather replies with a token — a long string like 7123456789:AAH.... That’s your bot’s password.

Treat that token exactly like an API key. Anyone holding it controls your bot completely — reads its messages, sends messages as it. Don’t paste it into a chat, a screenshot, or a shared document. We’ll store it properly in a moment.

While you’re here, two commands worth running now: /setdescription (what people see before they start the bot) and /setabouttext (the short line on its profile). Small touches, but they’re the difference between a bot that looks abandoned and one people trust enough to message.


📝 Verification boundary. The commands and code below are tutorial examples. BotFather screens, library behaviour, and Telegram policies can change, so compare them with the linked official documentation before deployment.

Troubleshooting 1 — “Sorry, this username is already taken”

🔴 BEFORE

The first examples usehelper, thenteamhelper, thenteam_helper. Each time:

Sorry, this username is already taken. Please try something different.

A second example usesops_team_helperand got a different rejection:

Sorry, I don't like the username you chose. Please try something different.

🤔 Cause

Two separate rules, and the error messages don’t distinguish them clearly.

The first is uniqueness — Telegram has millions of bots and every obvious name went years ago.helper,assistant,summarizerwere never going to be available.

The second is format. A bot usernamemust end withbot, can only contain letters, numbers and underscores, and has length limits.ops_team_helperwas rejected because it didn’t end inbot— not because someone had taken it.

🟢 AFTER

Use a pattern that’s both compliant and naturally unique: something specific to you, plusbotat the end.

  • ops_helper_bot
  • northside_team_bot
  • helper❌ (taken, and doesn’t end in bot)

The display name is what people commonly see in the chat, while the username is used for search, mentions, and links. Telegram currently documents a 5–32 character username made from Latin letters, numbers, or underscores and normally ending in bot. Confirm the current rule in the official Bot Features guide before publishing or deploying.


📝 Step 2: The Project

Same structure as Step 1, in a new folder:

mkdir team-bot && cd team-bot
python -m venv .venv

# macOS/Linux
source .venv/bin/activate
# Windows PowerShell
.venv\Scripts\Activate.ps1

pip install python-telegram-bot python-dotenv

Version boundary: this article uses the asynchronous Application, coroutine callback, MessageHandler, and run_polling() pattern documented by python-telegram-bot. Record the installed version with pip show python-telegram-bot and check its matching official documentation before copying the example; later releases can change parameters or behaviour.

Create.env:

TELEGRAM_TOKEN=paste_your_token_here

And.gitignore— before your first commit, not after:

.venv/
.env
__pycache__/

That.envline matters more here than it did in Step 1. A leaked API key costs money; a leaked bot token lets a strangerimpersonate your bot to your colleagues.Different kind of bad.

📝 Step 3: A Bot That Says Hello

Createbot.py:

import os
from pathlib import Path
from dotenv import load_dotenv
from telegram import Update
from telegram.ext import (
    Application,
    CommandHandler,
    MessageHandler,
    ContextTypes,
    filters,
)

load_dotenv(dotenv_path=Path(__file__).resolve().parent / ".env")
TOKEN = os.getenv("TELEGRAM_TOKEN", "").strip()

if not TOKEN:
    raise SystemExit("No TELEGRAM_TOKEN found. Check your .env file.")


async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    await update.message.reply_text(
        "Hi! I'm the team helper.\n\n"
        "Send me any message and I'll echo it back for now.\n"
        "Type /help to see what I can do."
    )


async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    await update.message.reply_text(
        "Right now I can:\n"
        "/start – say hello\n"
        "/help – show this message\n\n"
        "Send me any text and I'll repeat it back."
    )


async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user = update.effective_user.first_name
    await update.message.reply_text(f"{user}, you said: {update.message.text}")


def main() -> None:
    app = Application.builder().token(TOKEN).build()

    app.add_handler(CommandHandler("start", start))
    app.add_handler(CommandHandler("help", help_command))
    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))

    print("Bot is running. Press Ctrl+C to stop.")
    app.run_polling()


if __name__ == "__main__":
    main()

Run it:

python bot.py

A successful local start prints Bot is running. Then open Telegram, locate the bot by its username, and press Start. If the message does not appear or the bot does not reply, stop here and check the token, network connection, and running process.

The expected result is one reply to each test message. Record the observed result rather than assuming delivery from the absence of a terminal error.

Worth understanding what just happened, because it explains most of part 3’s problems. Your script isn’t sitting on a server — it’srepeatedly asking Telegram “any new messages for me?”That’s calledpolling, and it means your bot is alive exactly as long aspython bot.pyis running. Close the terminal, sleep the laptop, and the bot goes silent.


Troubleshooting 2 — The bot that answered twice, then not at all

🔴 BEFORE

Symptom: the bot replies twice, then one process reports a polling conflict. A common cause is two local processes using the same bot token at the same time.

telegram.error.Conflict: Conflict: terminated by other getUpdates request;
make sure that only one bot instance is running

🤔 Cause

Only one process may poll a given bot token at a time. With two copies running, both were asking Telegram for messages, each grabbing some — hence duplicate replies — until Telegram refused one outright.

It’s an easy state to end up in: you press Ctrl+C, the terminal seems to return, but the process is still winding down; or you run it in an editor’s built-in terminal and forget it’s there.

🟢 AFTER

Confirm the old one is dead before starting a new one.Ctrl+C in the terminal, wait for the prompt, then start.

If you’re not sure what’s running:

# macOS/Linux
ps aux | grep bot.py

# Windows PowerShell
Get-Process python

And a habit worth adopting now:one terminal for the bot, a different one for everything else.Never start the bot from a window you’ll also use forpip install.

If your bot behaves strangely after a crash, stop everything, wait ten seconds, and start once. Telegram takes a moment to release the previous connection.


📝 Step 4: Adding It to a Group Chat

A bot in a private chat is a demo. In your team’s group chat, it’s a tool.

Add it like any member: open the group → members → Add → search your bot’s username → add.

One behaviour will confuse you immediately. By default, bots in groups haveprivacy modeenabled, meaning your bot only sees messages that start with/or that reply directly to it. It cannot read general group conversation.

Privacy mode is a deliberate protection. If a bot is configured to receive general group conversation, messages may be transmitted to the services used by the bot, including an external AI provider in later parts. Obtain informed permission, minimize the data collected, and avoid confidential workplace text.

Keep privacy mode on and design around it: people invoke the bot deliberately with a command, or by replying to it. Explicit beats ambient, and it’s the same least-privilege thinking fromAI Agents and Automationapplied to a chat room.

⚠️ Don’t Close the Tab Yet

You have a bot that echoes. Three things to settle before adding intelligence in part 2.

Tell your team before you add it.A new member appearing in a work group chat that reads and responds to messages deserves a sentence of explanation: what it does, who built it, what happens to the text it receives. Do that now, while the answer is “nothing leaves this laptop,” and you’ll have an easy conversation instead of an awkward one later.

Check your workplace’s rules.Many organisations have policies about which tools may touch internal communication, and a bot forwarding messages to an external AI service is squarely within scope. Ask before part 2, not after.

Understand what “running” means. The bot is available only while the script and its network connection remain active. A sleeping laptop stops local polling. Treat this as a private experiment until you have selected an approved host, reviewed its current cost and security terms, and added monitoring.

There’s a shift happening here worth naming. Every project so far failed privately: a broken script cost you an afternoon and nobody else noticed. A bot failspublicly, in a chat where colleagues are watching, and “it worked on my machine an hour ago” is not an explanation anyone finds satisfying. That’s not a reason to avoid shipping it — it’s the reason professional software has status pages, version numbers, and staged rollouts. You’re about to feel why, at small scale, with forgiving users. That’s the best possible way to learn it.

✅ What You Have Now

At this point the project files contain command and echo handlers, load the token from an environment file, and start a polling application. Actual Telegram registration, delivery, privacy mode, and conflict handling still require a private live check with your own account. For authoritative details, see the Telegram Bot API reference.

And an understanding of polling, which is the concept the next two parts build on.

💡 For the Ambitious

Add a/statuscommand that replies with the current time and the bot’s version number. Trivial to write, and genuinely useful: when a colleague says “the bot is broken,”/statusinstantly tells you whether it’s running at all or whether something more interesting is wrong.

❓ Put It Into Practice

Test first in a private chat or a dedicated test group with informed participants. Record which commands were tried, what the bot received, and whether privacy mode limited the expected messages. Do not paste confidential workplace content into a tutorial bot.

Verified Offline Code Check

On 31 August 2026, the Python example above was copied from this draft and checked locally with Python 3.11.4. The check used synthetic names and messages plus offline stubs; it did not use a valid Telegram token or contact Telegram.

Check Result
Python syntax parsing PASS
/start response text PASS
/help response text PASS
Echo response with synthetic input PASS
Token loaded from an environment variable PASS
No embedded credential in bot.py PASS
Polling entry point present PASS

SHA-256 of the checked bot.py: EAD7A60EE12B424DBF553D4598D0A7E77B56F75BC7C9A9FE0B2239C097C45028

Limit: this offline check does not verify BotFather registration, Telegram delivery, group privacy mode, polling conflicts, network recovery, or concurrent-user behaviour. Those require a private live test with an informed participant and a revocable test token.

🔗 Next in This Series

[Step 3-A-2/3] Giving Your Bot a Brain— where the echo becomes an actual assistant:/summarizefor the long message someone just pasted,/replyfor a first draft, and the guardrails that stop it answering things it shouldn’t. Plus the error that makes a bot look broken when it’s really just thinking.