English (UK)

PHP Telegram bot tutorial step by step

This post is made to teach you how to create and set up a simple fully functional Telegram bot written in pure PHP.
There are many good ready to use SDKs written in PHP.
This is only a simple tutorial that explains how to interact with the Telegram APIs without use of any SDK.

Bots are third-party applications that run inside Telegram. Users can interact with bots by sending them messages, commands and inline requests.
At the core, Telegram Bots are special accounts that do not require an additional phone number to set up.
Messages, commands and requests sent by users are passed to the software running on your servers.
Telegram intermediary server handles all encryption and communication with the Telegram API for you.
You communicate with this server via a simple HTTPS-interface that offers a simplified version of the Telegram API.
Telegram Bot API is an HTTP-based interface created for developers keen on building bots for Telegram.

How do I create a bot? There's a... bot for that.
BotFather is the one bot to rule them all. It will help you create new bots and change settings for existing ones.
Message @BotFather with the /newbot command to create a new bot. The BotFather will ask you for a name and username, then generate an authorization token for your new bot.
If you don't know how to message by username, click the search field on your Telegram app and type @BotFather, where you should be able to initiate a conversation. Be careful not to send it to the wrong contact, because some users have similar usernames to BotFather.

The name of your bot is displayed in contact details and elsewhere.

The Username is a short name, to be used in mentions and telegram.me links. Usernames are 5-32 characters long and are case insensitive, but may only include Latin characters, numbers, and underscores. Your bot's username must end in ‘bot’, e.g. ‘tetris_bot’ or ‘TetrisBot’.

The token is a string along the lines of 110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw that is required to authorize the bot and send requests to the Bot API. Keep your token secure and store it safely, it can be used by anyone to control your bot.
If your existing token is compromised or you lost it for some reason, use the /token command to generate a new one.

In order to make your Bot answering to requests from your Telegram users you can register a WebHook to automatically being called once updates are available.
The quickest and easiest way to set a WebHook for your Bot is to issue a GET request to the Bot API.
All you have to do is to call the setWebHook method in the Bot API via the following url write in your browser


my_bot_token is the token you got from BotFather when you created your Bot
url_to_send_updates_to is the url of the piece of code you wrote to implement your Bot behavior (in order to set a Webhook you need a server with HTTPS)
For instance


And you’ve got it.
Now if you go to the following url (you have to replace {my_bot_token} with your Bot Token)


you should see something like this


Now let's explain how to develop the bot PHP file.
In your favorite editor, create a my-telegram-bot.php file with the following content.

$botToken = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11";
$botAPI = "https://api.telegram.org/bot" . $botToken;
$update = file_get_contents('php://input');
$update = json_decode($update, TRUE);
if (!$update) {
$message = isset($update['message']) ? $update['message'] : "";

$botToken is the bot token, generated by BotFather for your bot and used to register the bot on the Webhook service
$botAPI is the URL used to send commands to the Telegram API
file_get_contents('php://input') handle the call incoming from Telegram server
json_decode($update, TRUE) decode communication message in a JSON structure
if (!$update) { exit; } if it's not a valid JSON command, it exits the script
$message if it's a valid command, it extracts the sent message

The script can already be published; it still does nothing but works already.
Now let's add some lines to extract useful data from the message incoming

$messageId = isset($message['message_id']) ? $message['message_id'] : "";

$messageText = isset($message['text']) ? $message['text'] : "";
$messageText = trim($messageText);
$messageText = strtolower($messageText);
$date = isset($message['date']) ? $message['date'] : "";
$chatId = isset($message['chat']['id']) ? $message['chat']['id'] : "";
$username = isset($message['chat']['username']) ? $message['chat']['username'] : "";
$firstname = isset($message['chat']['first_name']) ? $message['chat']['first_name'] : "";
$lastname = isset($message['chat']['last_name']) ? $message['chat']['last_name'] : "";

$messageId is the unique identification number of the chat message
$messageText if it is a text message, the text contained in the message sent
$date is the date the message was sent
$chatId is the unique id of the user who sent the message
$username is the username of the user who sent the message
$firstname is the firs tname of the user who sent the message
$lastname is the last name of the user who sent the message

Message is not necessarily a text, it is possible to managed the type of incoming message with the following lines

if (isset($message['text'])) {
    $response = "Received a text message: " . $message['text'];
} elseif (isset($message['audio'])) {
    $response = "Received an audio message";
} elseif (isset($message['document'])) {
    $response = "Received a document message";
} elseif (isset($message['photo'])) {
    $response = "Received a photo message";
} elseif (isset($message['sticker'])) {
    $response = "Received a sticker message";
} elseif (isset($message['video'])) {
    $response = "Received a video message";
} elseif (isset($message['voice'])) {
    $response = "Received a voice message";
} elseif (isset($message['contact'])) {
    $response = "Received a contact message";
} elseif (isset($message['location'])) {
    $response = "Received a location message";
} elseif (isset($message['venue'])) {
    $response = "Received a venue message";
} else {
    $response = "I received a message?";

When a photo is sent to the bot, you can retrieve the file and its info from Telegram API.

if (isset($message['photo'])) {
    $fileAPI = "https://api.telegram.org/file/bot" . $botToken;
    $url = $GLOBALS[botAPI] . '/getFile?file_id=' . $message['photo'][0]['file_id'];
    $fileinfo = file_get_contents($url);
    $fileinfo = json_decode($fileinfo, TRUE);                          
    $filePath = $fileinfo['result']['file_path'];
    $url = $GLOBALS[fileAPI] . '/' . $filePath;
    $imgData = "File size: " . $message['photo'][0]['file_size'] . "byte" . chr(10)
        . "Width: " . $message['photo'][0]['width'] . "px" . chr(10)
        . "Height: " . $message['photo'][0]['height'] . "px" . chr(10)
        . "URL: " . $url);

$fileAPI is the URL used to retrieve file info from Telegram API
$fileinfo the script performs an HTTP GET call to get file info in JSON format
$filePath the script get the URL path of file
$message['photo'][0]['file_size'] is the size of the first file in byte
$message['photo'][0]['width'] and $message['photo'][0]['height'] are the dimension of the first file in pixels

Bot can send several type of message to the chat

Text messages

$url = $GLOBALS[botAPI] . '/sendMessage?chat_id=' . $chatId . '&text=' . urlencode($message);

Photo messages

$url = $GLOBALS[botAPI] . '/sendPhoto?chat_id=' . $chatId . '&photo=' . urlencode("https://webnoos.altervista.org/noos.jpeg");

Location messages

$url = $GLOBALS[botAPI] . '/sendLocation?chat_id=' . $chatId . '&latitude=' . urlencode("45.1") . '&longitude=' . urlencode("11.3");

Telegram also features the ability to display keyboards in chat like this

header("Content-Type: application/json");
$parameters = array('chat_id' => $chatId, "text" => $messageText);
$parameters["method"] = "sendMessage";
$parameters["reply_markup"] = '{ "keyboard": [["uno", "due"], ["tre"], ["quattro", "5", "6"]], "one_time_keyboard": false}';
echo json_encode($parameters);

The current keyboard can be removed from the chat in this way

header("Content-Type: application/json");
$parameters = array('chat_id' => $chatId, "text" => $messageText);
$parameters["method"] = "sendMessage";
$parameters["reply_markup"] = '{ "remove_keyboard" : true}';
echo json_encode($parameters);

You can also display an inline keyboard

header("Content-Type: application/json");
$parameters = array('chat_id' => $chatId, "text" => $messageText);
$parameters["method"] = "sendMessage";
$keyboard = ['inline_keyboard' => [[
    ['text' =>  'Vai su Google', 'url' => 'https://www.google.com'],
    ['text' => 'Vai su Microsoft', 'url' => 'https://www.microsoft.com']
$parameters["reply_markup"] = json_encode($keyboard, true);
echo json_encode($parameters);

Finally, you have the ability to manage messages sent to the bot as a series of commands, to do different things, as in this example

switch ($messageText) {
    case "/hi":
        // TODO
        // TODO

This little starting tutorial ends here.