Getting started

BotFather and token

Creating a bot via @BotFather, obtaining and securely storing a token in PHP, checking the token using the getMe method with JSON response parsing.

@BotFather is the official Telegram bot for creating and configuring bots. Without it, you won't have an API token, which means no access to the Bot API.

Creating a Bot: Step-by-Step

  1. Open Telegram → search for @BotFather (with a verification checkmark).
  2. Send the /newbot command.
  3. Enter a display name (any name up to 64 characters, visible to users in chat).
  4. Enter a username — unique, Latin letters, numbers, underscores, must end with bot (for example: my_shop_bot).
  5. BotFather will reply with a message containing an HTTP API token like 123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw.

Anatomy of a Token

A token consists of two parts separated by a colon:

  • 123456789 — numeric bot ID (the same one returned by getMe in the id field).
  • AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw — secret authorization key.

Never publish your full token. In logs and screenshots, mask the second part: 123456789:AAH***.

Storing the Token in a PHP Project

Rule: the token lives only in environment variables or in a local config file that is not committed to Git.

# .env (пример, не коммитить)
TELEGRAM_BOT_TOKEN=123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw
<?php
// config/bootstrap.php или начало скрипта
$token = getenv('TELEGRAM_BOT_TOKEN');
if ($token === false || $token === '') {
throw new RuntimeException('TELEGRAM_BOT_TOKEN is not set. Check .env or server env.');
}
// Базовая валидация формата (не гарантирует валидность, но отсекает опечатки)
if (!preg_match('/^\d+:[A-Za-z0-9_-]{35}$/', $token)) {
throw new RuntimeException('TELEGRAM_BOT_TOKEN has invalid format');
}

echo "Token loaded, bot ID: " . explode(':', $token)[0] . PHP_EOL;

Run in the terminal: php config/bootstrap.php — you should see Token loaded, bot ID: 123456789. If an exception occurs, check .env and php -i | grep -i env.

What to Do if the Token Leaks

  1. In BotFather, send /revoke → select your bot → confirm. The old token will instantly become invalid.
  2. Copy the new token from BotFather's response.
  3. Update .env / environment variables on the server.
  4. Restart workers / reload PHP-FPM / redeploy the container.

Useful BotFather Commands (Cheat Sheet)

  • /setdescription — bot description (up to 512 characters, visible in profile).
  • /setabouttext — "About" text (up to 120 characters, under the name).
  • /setuserpic — avatar (640×640 image, PNG/JPG).
  • /setcommands — list of commands for the menu (format: command - Description, one per line).
  • /setdomain — domain for Telegram Login Widget and Mini App.
  • /setmenubutton — menu button to launch Mini App.
  • /deletebot — permanently delete the bot.

Verifying the Token via Code (Using the Wrapper from the Previous Chapter)

In Chapter Bot API vs MTProto, we wrote the telegramApi() function — here we simply call it for the getMe method.

<?php
require_once __DIR__ . '/config/bootstrap.php'; // загрузили $token
require_once __DIR__ . '/src/TelegramClient.php'; // там функция telegramApi()

$response = telegramApi($token, 'getMe');

// Как посмотреть результат в терминале:
print_r($response);
// или для JSON-красоты:
echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

Expected successful API response:

{
"ok": true,
"result": {
"id": 123456789,
"is_bot": true,
"first_name": "My Shop",
"username": "my_shop_bot",
"can_join_groups": true,
"can_read_all_group_messages": false,
"supports_inline_queries": false,
"can_connect_to_business": false,
"has_main_web_app": false
}
}

Field breakdown:

  • ok: true — request succeeded, token is valid, bot is alive.
  • result.id — numeric bot ID (must match the first part of the token).
  • result.username — your username without @, use it in deep links and code.
  • result.can_read_all_group_messages — false by default; enable via /setprivacy in BotFather if the bot needs to see all messages in groups.

Common errors (ok: false field):

  • 401 Unauthorized + description: "Unauthorized" — token is invalid or revoked.
  • 400 Bad Request + description: "Bad Request: chat not found" — does not apply to getMe, but will be encountered later when sending messages.

If you see ok: true, congratulations! Your bot is ready to work. Next, we'll learn how to receive updates from users.

Next: Первый запрос: getMe — разбор ответа и проверка токена