Registration is only the beginning

BotFather creates a bot account and helps manage its settings. A program or suitable service still needs to handle messages for your intended workflow. Start with one simple task: showing a timetable, answering a common question or receiving an enquiry. Describe success in a single sentence. This avoids collecting unnecessary information or buying a complicated builder before understanding the task. If all you need is a publishing channel, you may not need a bot at all.

BotFather creates the bot account and token. A running program is needed for replies; keep the token secret.
Read the diagram from left to right. BotFather creates the bot account and token. A running program is needed for replies; keep the token secret.

Find the genuine BotFather

Open BotFather through Telegram’s official documentation and verify the exact @BotFather username. Do not trust an avatar or similar-looking profile alone. Send /newbot and follow the prompts for a display name and unique username. BotFather explains the requirements and whether the chosen username is available. Make the display name understandable and the username easy to share. Do not impersonate official Telegram support or another service with your bot; that misleads users.

Treat the token as a key

After registration, BotFather provides a Bot API token. It allows software to control the bot, so never publish it in a channel, screenshot, public repository or website client-side code. Store it in a protected server setting or the chosen platform’s secrets facility. If using a builder, assess its operator first and establish why you trust it to control the bot. Giving a token to a third-party service grants real access; it is not merely a cosmetic setting.

Connect a handler and one workflow

Create a separate new bot for this exercise. The complete example below needs Python 3.10 or later and no third-party packages. Install Python from python.org and check python3 --version on macOS/Linux or py -3 --version on Windows. Open a plain-text editor and save the code in the next section as telegram-echo-bot.py, not telegram-echo-bot.py.txt. Open a terminal in that file’s folder.

The example handles private chats only: it answers /start and /help, echoes ordinary text, and ignores photos and group messages. It does not write messages to disk or log their contents. Do not grant it administrator permissions. If a webhook or another handler is already running, use a new practice bot: this example does not remove existing settings and must not compete with a live service.

Save the complete example to a file

Copy all of this code unchanged. Do not paste your real token into it: the program reads TELEGRAM_BOT_TOKEN from its environment. The credential is used only by your computer and Telegram’s official Bot API.

"""Private-chat echo bot. Python 3.10+, standard library only."""

import json
import os
import sys
from urllib.request import Request, urlopen


class BotError(Exception):
    pass


def make_api(bot_token):
    def call(method, **params):
        try:
            request = Request(
                f"https://api.telegram.org/bot{bot_token}/{method}",
                data=json.dumps(params).encode("utf-8"),
                headers={"Content-Type": "application/json"},
            )
            with urlopen(request, timeout=35) as response:
                result = json.load(response)
            if not result["ok"]:
                raise BotError()
            return result["result"]
        except Exception:
            # Never print an exception containing the bot token or response body.
            raise BotError("Telegram request failed. Check the token and connection.") from None

    return call


def run(api):
    if api("getWebhookInfo").get("url"):
        raise BotError("A webhook is configured. Disable it explicitly before polling.")
    offset = 0
    while True:
        updates = api("getUpdates", offset=offset, timeout=25, allowed_updates=["message"])
        for update in updates:
            offset = update["update_id"] + 1
            message = update.get("message", {})
            chat = message.get("chat", {})
            text = message.get("text")
            if chat.get("type") != "private" or not isinstance(text, str) or not text:
                continue
            command = (text.split(maxsplit=1) or [""])[0].split("@")[0]
            if command in ("/start", "/help"):
                reply = "Bot is running. Send text and I will echo it."
            else:
                reply = text[:4096]
            api("sendMessage", chat_id=chat["id"], text=reply)


def main():
    bot_token = os.environ.get("TELEGRAM_BOT_TOKEN", "").strip()
    if not bot_token:
        print("Set TELEGRAM_BOT_TOKEN before starting the bot.", file=sys.stderr)
        return 1
    try:
        run(make_api(bot_token))
    except KeyboardInterrupt:
        return 0
    except BotError as error:
        print(error, file=sys.stderr)
        return 1
    except Exception:
        print("Bot stopped. Check the bot configuration and try again.", file=sys.stderr)
        return 1
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

Run it with Bash on macOS or Linux

Open Bash in your terminal (run bash first if necessary) and enter the file’s folder. Run the commands below. At the Bot token prompt, paste the token issued by BotFather and press Enter: its characters are hidden and its value does not enter the command history. Paste the complete block, including its parentheses: Bash reads all commands before asking for the token. The variable exists only inside this block and disappears when the program ends.

(
    read -r -s -p "Bot token: " TELEGRAM_BOT_TOKEN
    printf '\n'
    export TELEGRAM_BOT_TOKEN
    python3 telegram-echo-bot.py
)

Run it with PowerShell on Windows

Choose this instead of the Bash instructions on Windows. Open PowerShell in the file’s folder, run the commands below and enter the token at the hidden prompt. The py -3 command selects your installed Python 3; if it is unavailable, install Python and reopen the terminal first. The finally block clears the environment variable when the program ends.

& {
    $botCredential = Read-Host "Bot token" -AsSecureString
    $env:TELEGRAM_BOT_TOKEN = [System.Net.NetworkCredential]::new("", $botCredential).Password
    try {
        py -3 telegram-echo-bot.py
    } finally {
        Remove-Item Env:TELEGRAM_BOT_TOKEN -ErrorAction SilentlyContinue
        $botCredential.Dispose()
    }
}

Check the first reply and stop the bot

While the program is running, open a private chat with your own bot and send /start. Expect: Bot is running. Send text and I will echo it. Then send Hello: the bot should return the same text. /help shows the instructions. Photos and group messages receive no reply because this example deliberately ignores them.

Stop the program with Ctrl+C. A new message will not receive an immediate reply because your computer has stopped processing updates. If you send a message while it is stopped and restart shortly afterwards, Telegram may still have it queued and the example can reply on restart. This example does not persist its offset, so an unfinished batch may be processed again after a restart. Do not use it for payments or actions that cannot safely be repeated.

If you see Telegram request failed, check the connection and current token, then restart. Make sure only one instance is running. A webhook is configured means the bot already uses another delivery setup: create a new practice bot or review that existing connection yourself. Errors deliberately omit request URLs and the credential; do not publish the token to troubleshoot.

This is a local learning exercise. Continuous operation needs your own always-on server or a trusted platform, protected credentials, API error and rate-limit handling, and suitable state storage for applications or payments. The official core.telegram.org/bots/api documentation explains getUpdates and sendMessage; the example already connects them into a minimal, testable workflow.

Describe the bot and limit permissions

Use BotFather settings to add a description, image and supported commands. For group use, understand privacy mode and administrative permissions separately: message access depends on the role and configuration. Do not grant administrator status just to test a private-chat greeting. If the workflow collects contacts or enquiries, explain where they go and why they are needed. For an initial prototype, use test information rather than storing real phone numbers without an access and deletion procedure.

Example: a timetable bot

A learning club wants to show its timetable without repeated administrator replies. After /start, the bot explains that it covers the current week; /help provides the organiser’s contact. A user selects a day and receives the time with its timezone. This task needs no phone number, wallet access or channel administrator privileges. Test a normal day, a day without classes and an unknown command. A helpful error response offers a return to the menu instead of leaving the user waiting indefinitely.

If the bot is silent or the token leaked

If the bot is silent, check whether its handler is running, the token is correct and updates are arriving. Inspect logs without exposing secrets. If a token leaks, revoke it through BotFather management, obtain a replacement and update the handler’s protected configuration, then confirm the old token is no longer used. Deleting a message containing the token does not revoke copied access. Remove excessive group permissions separately. Token rotation does not automatically repair bad permissions or a leaked user database.

Before sharing the public link

Test from another authorised account: starting, completing the useful action, encountering an error and requesting help. Ensure users cannot see technical logs, keys or other people’s information. Decide who monitors availability and how a problematic feature can be disabled. Payments require a separate development stage with payment and support rules; do not add them casually. The first launch succeeds when a simple task works predictably and users understand the bot’s limitations and next step.

Leave a clear owner handover

Even for a small bot, document where its handler runs, who can configure it and how to stop replies if something fails. Do not put the token in the handover; identify its protected storage instead. Keep a command list and explanation for each permission. When a developer leaves, review access and maintenance responsibility. The bot may keep running after a contractor relationship ends, so control should not depend on one person’s memory.