Бот Телеграм на PHP

Примеры как зарегистрировать бота в Telegram, описание и взаимодействие с основными методами API. Документация на core.telegram.org и tlgrm.ru (неофициальный, на русском).

Все запросы к API должны осуществляться по HTTPS, подойдет бесплатный сертификат «Let’s Encrypt».

1

Для регистрации нового бота нужно написать «папе ботов» @BotFather команду /newbot

Следующим сообщением отправляем название для бота, обязательно на конце имени должно быть слово «bot» или «_bot». Ответным сообщением получим токен:

Тут же можно настроить описание и аватарку:

/setname Имя
/setdescription Краткое описание
/setabouttext Описание бота
/setuserpic Юзерпик

Далее нужно поставить «Webhook» чтобы все сообщения из Telegram приходили на PHP скрипт (https://example.com/bot.php). Для этого нужно пройти по ссылке в которой подставлены полученный токен и адрес скрипта.

https://api.telegram.org/bot<token>/setWebhook?url=https://example.com/bot.php

В ответе будет

{"ok":true,"result":true,"description":"Webhook was set"}

При смене токена, установку вебхука нужно повторить.

2

Сообщения приходят POST-запросом, с типом application/json. Получить его в PHP можно следующим образом:

$data = file_get_contents('php://input');
$data = json_decode($data, true);
PHP

Чтобы посмотреть входящие данные, их придется дампить в файл:

file_put_contents(__DIR__ . '/message.txt', print_r($data, true));
PHP

Текстовое сообщение

Запрос от Телеграм:

Array (
	[update_id] => 17584194
	[message] => Array (
		[message_id] => 26
		[from] => Array (
			[id] => 123456789
				[is_bot] => 
				[first_name] => UserName
				[language_code] => ru-US
			)
		[chat] => Array (
			[id] => 123456789
			[first_name] => UserName
			[type] => private
		)
		[date] => 1541888068
		[text] => Привет бот!
	)
)

Получим текст сообщения:

if (!empty($data['message']['text'])) {
	$text = $data['message']['text'];
	echo $text;
}
PHP

Фотографии

При отправки фото боту, на скрипт приходит массив превьюшек, последним элементом будет оригинальное фото. Максимальный размер файла 20МБ.

Запрос от Телеграм:

Array (
	[update_id] => 17584194
	[message] => Array (
		[message_id] => 38
		[from] => Array (
			[id] => 123456789
			[is_bot] => 
			[first_name] => UserName
			[language_code] => ru-US
		)
		[chat] => Array (
			[id] => 123456789
			[first_name] => UserName
			[type] => private
		)
		[date] => 1541924962
		[photo] => Array (
			[0] => Array (
				[file_id] => AgADAgADUqexG7u8OEudBvlhgMzKC1agOQ8ABC6Bx26USA7Mw3gAAgI
				[file_size] => 1196
				[width] => 51
				[height] => 90
			)
			[1] => Array (
				[file_id] => AgttAgADUqoxG7u8OEudBvlhgMzKC1agOQ8ABKwp_3jDPrIlxHgAAgI
				[file_size] => 21146
				[width] => 180
				[height] => 320
			)
			[2] => Array (
				[file_id] => AgADAgADUqyxG7u8OEudBvlhgMzKC1agOQ8ABAN8gJWpUT1MxXgAAgI
				[file_size] => 90940
				[width] => 449
				[height] => 800
			)
			[3] => Array (
				[file_id] => AgADAgADUqouu7u8OEudBvlhgMzKC1agOQ8ABIqVC1nEpbLDwngAAgI
				[file_size] => 114363
				[width] => 719
				[height] => 1280
			)
		)
	)
)

Чтобы скачать файл нужно отправить POST или GET запрос на получение c параметром file_id изображения по URL:

https://api.telegram.org/bot<token>/getFile

В ответ придет информация о файле:

Array (
	[ok] => 1
	[result] => Array (
		[file_id] => AgADAgADUqoxG5u88E0dBvlhgMzKC1agOQ8ABIqVC1nEpbLDwngAAgI
		[file_size] => 114363
		[file_path] => photos/file_1.jpg
	)
)

Далее его можно скачать по ссылке:

https://api.telegram.org/file/bot<token>/<file_path>

В PHP сохранение файла на сервер можно реализовать следующим образом:

$token = '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11';

if (!empty($data['message']['photo'])) {
	$photo = array_pop($data['message']['photo']);
	
	$ch = curl_init('https://api.telegram.org/bot' . $token . '/getFile');  
	curl_setopt($ch, CURLOPT_POST, 1);  
	curl_setopt($ch, CURLOPT_POSTFIELDS, array('file_id' => $photo['file_id']));
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HEADER, false);
	$res = curl_exec($ch);
	curl_close($ch);
	
	$res = json_decode($res, true);
	if ($res['ok']) {
		$src  = 'https://api.telegram.org/file/bot' . $token . '/' . $res['result']['file_path'];
		$dest = __DIR__ . '/' . time() . '-' . basename($src);
		copy($src, $dest);
	}
}
PHP

Документ

Запрос от Телеграм:

Array (
	[update_id] => 17474201
	[message] => Array (
		[message_id] => 44
		[from] => Array (
			[id] => 123456789
			[is_bot] => 
			[first_name] => UserName
			[language_code] => ru-US
		)
		[chat] => Array (
			[id] => 123456789
			[first_name] => UserName
			[type] => private
		)
		[date] => 1541925844
		[document] => Array (
			[file_name] => IMG_7947.JPG
			[mime_type] => image/jpeg
			[thumb] => Array (
					[file_id] => AAQCABMNv_QOAATwQugveIZBldZ3AAIC
					[file_size] => 2644
					[width] => 67
					[height] => 90
				)
			[file_id] => BQADAgADtQEAAqu9OEhzn2cEz8LpkgI
			[file_size] => 1976218
		)
	)
)

Скачивание файлов происходит по такой же схеме как у фотографий.

if (!empty($data['message']['document'])) {
	$file_id = $data['message']['document']['file_id'];
	
	$ch = curl_init('https://api.telegram.org/bot' . $token . '/getFile');  
	curl_setopt($ch, CURLOPT_POST, 1);  
	curl_setopt($ch, CURLOPT_POSTFIELDS, array('file_id' => $file_id));
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HEADER, false);
	$res = curl_exec($ch);
	curl_close($ch);
	
	$res = json_decode($res, true);
	if ($res['ok']) {
		$src  = 'https://api.telegram.org/file/bot' . $token . '/' . $res['result']['file_path'];
		$dest = __DIR__ . '/' . time() . '-' . basename($src);
		copy($src, $dest);
	}
}
PHP
3

Отправка текста

$response = array(
	'chat_id' => $data['message']['chat']['id'],
	'text' => 'Хай!'
);	
		
$ch = curl_init('https://api.telegram.org/bot' . $token . '/sendMessage');  
curl_setopt($ch, CURLOPT_POST, 1);  
curl_setopt($ch, CURLOPT_POSTFIELDS, $response);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
curl_close($ch);
PHP

Отправка картинки

$response = array(
	'chat_id' => $data['message']['chat']['id'],
	'photo' => curl_file_create(__DIR__ . '/image.png')
);	
		
$ch = curl_init('https://api.telegram.org/bot' . $token . '/sendPhoto');  
curl_setopt($ch, CURLOPT_POST, 1);  
curl_setopt($ch, CURLOPT_POSTFIELDS, $response);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
curl_close($ch);
PHP

Отправка файла

$response = array(
	'chat_id' => $data['message']['chat']['id'],
	'document' => curl_file_create(__DIR__ . '/file.xls')
);	
		
$ch = curl_init('https://api.telegram.org/bot' . $token . '/sendDocument');  
curl_setopt($ch, CURLOPT_POST, 1);  
curl_setopt($ch, CURLOPT_POSTFIELDS, $response);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
curl_close($ch);
PHP
4

Скрипт простейшего бота @SnippRu. Он отвечает на вопросы и сохраняет файлы и изображение на сервере.

<?php

$data = file_get_contents('php://input');
$data = json_decode($data, true);

if (empty($data['message']['chat']['id'])) {
	exit();
}

define('TOKEN', '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11');

// Функция вызова методов API.
function sendTelegram($method, $response)
{
	$ch = curl_init('https://api.telegram.org/bot' . TOKEN . '/' . $method);  
	curl_setopt($ch, CURLOPT_POST, 1);  
	curl_setopt($ch, CURLOPT_POSTFIELDS, $response);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HEADER, false);
	$res = curl_exec($ch);
	curl_close($ch);

	return $res;
}

// Прислали фото.
if (!empty($data['message']['photo'])) {
	$photo = array_pop($data['message']['photo']);
	$res = sendTelegram(
		'getFile', 
		array(
			'file_id' => $photo['file_id']
		)
	);
	
	$res = json_decode($res, true);
	if ($res['ok']) {
		$src = 'https://api.telegram.org/file/bot' . TOKEN . '/' . $res['result']['file_path'];
		$dest = __DIR__ . '/' . time() . '-' . basename($src);

		if (copy($src, $dest)) {
			sendTelegram(
				'sendMessage', 
				array(
					'chat_id' => $data['message']['chat']['id'],
					'text' => 'Фото сохранено'
				)
			);
			
		}
	}
	
	exit();	
}

// Прислали файл.
if (!empty($data['message']['document'])) {
	$res = sendTelegram(
		'getFile', 
		array(
			'file_id' => $data['message']['document']['file_id']
		)
	);
	
	$res = json_decode($res, true);
	if ($res['ok']) {
		$src = 'https://api.telegram.org/file/bot' . TOKEN . '/' . $res['result']['file_path'];
		$dest = __DIR__ . '/' . time() . '-' . $data['message']['document']['file_name'];

		if (copy($src, $dest)) {
			sendTelegram(
				'sendMessage', 
				array(
					'chat_id' => $data['message']['chat']['id'],
					'text' => 'Файл сохранён'
				)
			);	
		}
	}
	
	exit();	
}

// Ответ на текстовые сообщения.
if (!empty($data['message']['text'])) {
	$text = $data['message']['text'];

	if (mb_stripos($text, 'привет') !== false) {
		sendTelegram(
			'sendMessage', 
			array(
				'chat_id' => $data['message']['chat']['id'],
				'text' => 'Хай!'
			)
		);

		exit();	
	} 

	// Отправка фото.
	if (mb_stripos($text, 'фото') !== false) {
		sendTelegram(
			'sendPhoto', 
			array(
				'chat_id' => $data['message']['chat']['id'],
				'photo' => curl_file_create(__DIR__ . '/torin.jpg')
			)
		);
		
		exit();	
	}

	// Отправка файла.
	if (mb_stripos($text, 'файл') !== false) {
		sendTelegram(
			'sendDocument', 
			array(
				'chat_id' => $data['message']['chat']['id'],
				'document' => curl_file_create(__DIR__ . '/example.xls')
			)
		);

		exit();	
	}
}
PHP
17.11.2018, обновлено 03.02.2021
141585
Предыдущая запись Вход на сайт через Вконтакте
Следующая запись Получение котировок PHP

Комментарии 21

Андрей Михайленко Андрей Михайленко
25 апреля 2020 в 20:24
Как сделать, что бы бот отправлял рандомыне файлы с папки, по ключевому слову.
Например,пользователь в чате пишет gif , а бот отправляет случайную гифку с папки.
Daniel Lanfort Daniel Lanfort
26 декабря 2020 в 14:57
а в чем проблема?
Роман Гринько Роман Гринько
12 марта 2022 в 12:06
банально просто, на сервер в папку, например, gifs, кидаем гифки с именами 1.gif 2.gif 3.gif ... 99.gif
и при получении команды рандомно выбираем гифку
$random = rand(1, 99);
далее отправляем гифку пользователю
sendTelegram('sendDocument', 
array(
'chat_id' => $data['message']['chat']['id'],
'document' => curl_file_create(__DIR__ . '/gifs/' . $random . '.gif')
)
);
и все, профит
Артем Бурлака Артем Бурлака
3 февраля 2021 в 04:24
Во втором разделе почему-то используете сложную конструкцию. print_r может возвращает результат, а не выводить. За это отвечает второй параметр
Snipp.ru Snipp.ru
3 февраля 2021 в 15:58
Да, действительно) Спасибо за комментарий.
Lexa Dv Lexa Dv
14 марта 2021 в 00:22
Сделаю или помогу сделать вам бота. Не бесплатно, обращайтесь в телеграм: @dvoinikov
Meizu Rin Meizu Rin
15 марта 2021 в 07:02
А как сделать, что бы бот из сайта, отправлял добавленную новость. Автоматический
Nokian Nokian
10 июня 2021 в 01:18
Привет! А какой платформой на сайте пользуешься?
Тестировщик Тестировщик
23 июня 2021 в 19:49
Как кнопки добавить можете код написать?
Пробую так, но не выходит ничего:
$keyboard = [
  [ "Кнопка 1" ],
  [ "Кнопка 2" ],
  [ "Кнопка 3" ]
];

 // Команда /start.
  if ( mb_stripos( $text, '/start' ) !== false ) {
    sendTelegram(
      'sendMessage',
      array(
        'chat_id' => $data[ 'message' ][ 'chat' ][ 'id' ],
				'keyboard' => $keyboard,
				'resize_keyboard' => true,
				'reply_markup' => $reply_markup,
				'text' => 'Добро пожаловать в бота!',
      )
    );
    exit();
  }
Muhammaddiyor Tohirov Muhammaddiyor Tohirov
30 июля 2021 в 15:07
$keyboard = [
	[ "Кнопка 1" ],
	[ "Кнопка 2" ],
	[ "Кнопка 3" ]
];

$reply_markup = json_encode([
	"keyboard"=>$keyboard,
	"resize_keyboard"=>true
]);

// Команда /start.
if ( mb_stripos( $text, '/start' ) !== false ) {
	sendTelegram('sendMessage',[
		'chat_id'=> $data[ 'message' ][ 'chat' ][ 'id' ],
		'text'=>'Добро пожаловать в бота!',
		'reply_markup'=>$reply-markup
	]);
	exit();
}
Дмитрий Ушаков Дмитрий Ушаков
11 октября 2021 в 23:57
$keyboard = [
	[ "Кнопка 1" ],
	[ "Кнопка 2" ],
	[ "Кнопка 3" ]
];
$reply_markup = json_encode([
	"keyboard"=>$keyboard,
	"resize_keyboard"=>true
]);
// Команда /start.
if ( mb_stripos( $text, '/start' ) !== false ) {
	sendTelegram('sendMessage',[
		'chat_id'=> $data[ 'message' ][ 'chat' ][ 'id' ],
		'text'=>'Добро пожаловать в бота!',
		'reply_markup'=>$reply_markup
	]);
	exit();
}
Kamron Zamirov Kamron Zamirov
27 ноября 2021 в 12:52
$keyboard = json_encode([
"resize_keyboard" => true,
"keyboard" => [
[["text" => "blablabla"],["text" => "blablabla"]],],
]);
Дмитрий Ушаков Дмитрий Ушаков
11 октября 2021 в 23:53
Здравствуйте, подскажите, пожалуйста !
Не работает sendVideo и sendDocument !!!
 sendTelegram(
	'sendVideo', 
            array(
                'chat_id' => $data['message']['chat']['id'],
                'video' => $link
            )
        );
sendTelegram(
	'sendDocument', 
		array(
			chat_id' => $data['message']['chat']['id'],
			'document' => curl_file_create($link)
		)
	);

в $link лежит полный путь до файла.
Помогите, пожалуйста, вообще не понимаю в чем проблема.
Причем аналогичный код с sendPhoto работает !
sendTelegram(
	'sendPhoto', 
            array(
                'chat_id' => $data['message']['chat']['id'],
                'photo' => $link
            )
        );
Snipp.ru Snipp.ru
12 октября 2021 в 15:16
Посмотрите что возвращает API, скинув ответ в лог-файл:
$res = sendTelegram(
	'sendVideo', 
	array(
		'chat_id' => $data['message']['chat']['id'],
		'video' => $link
	)
);

file_put_contents(__DIR__ . '/log.txt', $res . PHP_EOL, FILE_APPEND);
Дмитрий Ушаков Дмитрий Ушаков
12 октября 2021 в 21:22
Спасибо за ответ!
{"ok":false,"error_code":400,"description":"Bad Request: wrong file identifier/HTTP URL specified"}
{"ok":false,"error_code":400,"description":"Bad Request: failed to get HTTP URL content"}
Проблема оказалась в сервере и в правах доступа к файлам (
Дмитрий Ушаков Дмитрий Ушаков
12 октября 2021 в 21:24
Спасибо за Статью !!!
Ольга Соловьёва Ольга Соловьёва
18 ноября 2021 в 18:32
Я перевел своих клиентов на webjack, делает все то же самое, минимальный тариф дешевле.
Можно получить месяц бесплатно по промокоду semen21, напишите его в чат техподдержки на сайте
anatoliyrnd anatoliyrnd
13 января 2023 в 21:46
Так ты ольга и перевел!!! Или все же перевелА , а может ты не ольга!???
Борис Спирин Борис Спирин
28 января 2022 в 14:14
Спасибо, очень интересно!
Как быть, когда сохранить нужно не оригинальное фото, которое прислано боту, а сжатое.
А давайте платные курсы по написанию бота организуем?
anatoliyrnd anatoliyrnd
13 января 2023 в 21:52
А как можно реализовать текстовый ответ по кнопке, ну т.е что бы текст отправленный боту был привязан к определенным данным. Ну например пользователь запросил у бота список , в ответ получил список допустим из трех позиций и нажав на кнопку возле одной из позиций написал текст, и отправил, и бот смог распознать к какой позиции относиться этот текст? У каждой позиции будет свой уникальный id. бот на PHP.
Алексей Ефремов Алексей Ефремов
3 марта 2023 в 16:30
Добрый день подскажите пожалуйста. Как передавать формат текста? Типа есть текст курсивом, как получить курсивный текст и вывести его на сайт ?

, чтобы добавить комментарий.

Другие публикации

Публикация записей на стену сообщества VK
Для начала вы должны быть авторизированы в VK и являться администратором группы или страницы. Далее нужно создать...
31470
+9
Получить фото из Instagram без API
Так как Instagram и Fasebook ограничили доступ к API, а фото с открытого аккаунта всё же нужно периодически получать и...
24718
+7
Подключение к платежной системе Сбербанка
После регистрации в системе эквайринга Сбербанка и получив доступ к тестовой среде, можно приступить к интеграции с...
67064
+25
Список MIME типов
Ниже приведён список MIME-заголовков и расширений файлов.
25045
+7
Работа с JSON в PHP
JSON (JavaScript Object Notation) – текстовый формат обмена данными, основанный на JavaScript, который представляет собой набор пар {ключ: значение}. Значение может быть массивом, числом, строкой и...
114503
+15
Отправка sms через «SMS Aero» в PHP
Для отправки SMS-сообщений со своего сайта можно воспользоваться сервисом SMS Aero.
6966
+3