[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.

See the published Expert Workflows curriculum for the available projects. This three-part bot project focuses on private testing and deliberately invoked commands.

🛠️ Gather These First

  • Python installed and working; confirm that python --version runs before creating the virtual environment below
  • 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.

Check uniqueness separately from format. These names are illustrative; this article has not checked whether any example username is available. A name without the required bot suffix is not a valid test of availability.

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❌ (doesn’t end in bot; availability not checked)

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:
    message = update.effective_message
    if message is None:
        return
    await 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:
    message = update.effective_message
    if message is None:
        return
    await 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:
    message = update.effective_message
    if message is None or not message.text:
        return
    user = update.effective_user.first_name if update.effective_user else "Sender"
    response = f"{user}, you said: {message.text}"
    for i in range(0, len(response), 2000):
        await message.reply_text(response[i:i + 2000], parse_mode=None)


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

A polling conflict can indicate another process using the same token. Stop the competing instance and run one poller. Duplicate replies alone do not establish this cause; inspect the actual error and handler configuration.

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.

After a crash, confirm that the earlier bot process has exited before starting one replacement. If the conflict persists, check other terminals and hosts using the token.


📝 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.

Privacy mode limits which group messages a bot receives; it is not a blanket guarantee that every slash command is delivered or that all other messages are hidden. Use an explicitly addressed command such as /help@your_bot. Administrator bots can receive more messages, so avoid granting unnecessary admin rights. See the official privacy-mode rules.

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. Explain what the bot receives and where it goes. Part 1 exchanges messages between Telegram and your running Python process; it does not call an AI provider. Later parts add an external AI service, so use non-confidential test text and obtain informed permission first.

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 /status command that reports the process uptime and version. A reply proves that this command path responded at that moment. No reply does not identify whether the laptop, network, token or application caused the failure. Part 3 supplies the handler.

❓ 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.

Current offline experiment — 12 September 2026

The current code guards missing messages and absent sender identity, and splits an echo into plain-text pieces of at most 2,000 Python characters. This leaves conservative Unicode headroom within Telegram’s message limit. Setup commands use separate lines for Windows PowerShell 5.1.

10/10 checks passed with Python 3.11.4: the original seven checks plus a 4,096-emoji input, absent sender and missing-message cases. Rejoined replies preserved the complete input and prefix. Telegram and dotenv were stubbed; no live delivery or valid credentials were used.

Download current code and ten-check experiment (ZIP)
SHA-256: 1a3f9151cccfbd01eab779d51b1ba2d0c01145ccaea50d8d79dc1fa19f491aea. Run python test_bot_offline.py to reproduce.

Archived offline check — 31 August 2026

The following describes the earlier code revision. Use the current package above.

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.

Download the exact bot.py and seven-check offline test package. Extract it and run python test_bot_offline.py. The seven checks were rerun successfully on 10 September 2026. This package uses synthetic messages and substitutes Telegram objects; it does not demonstrate live delivery.

🔗 Next in This Series

Continue to Part 2: Giving Your Bot a Brain for /summarize, /draft, input limits and safe failure messages. Prompt instructions guide the model; they do not guarantee refusal or correctness.