В новом уроке мы с вами рассмотрим отправку базовых запросов в Telegram. Я покажу вам как отправлять простые текстовые сообщения в Telegram, как отправлять кнопки и дополнительные клавиатуры.

Всю информацию по параметрам запросов мы будем брать из официальной документации Telegram.

Полный список всех записей курса находится на сайте или в публикациях на Хабр.

Все ответы от Telegram приходят в виде JSON строки. Для удобного отображения массива ответа в браузере, советую вам установить специальное расширение для браузера, которое называется JSON Viewer.

Отправка простых сообщений

Для отправки простых текстовых сообщений, нам необходимо воспользоваться методом sendMessage.

Ранее я показывал вам, как отправлять запросы с передачей параметров в URL, теперь для удобства я буду использовать запись параметров в массиве и с помощью функции http_build_query мы будем формировать строку с GET параметрами.

$token = "5340791844:AAEXXDduvInvQrlykV91USOQSevrPVU";

$getQuery = array(
    "chat_id" 	=> 1424625511,
    "text"  	=> "Новое сообщение из формы",
    "parse_mode" => "html"
);
$ch = curl_init("https://api.telegram.org/bot". $token ."/sendMessage?" . http_build_query($getQuery));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

$resultQuery = curl_exec($ch);
curl_close($ch);

echo $resultQuery;

Каждый запрос будет иметь переменную с записанным токеном, массив с параметрами запроса, код для создания запроса через Curl и вывод или запись полученной информации.

Отправка ответа на сообщение

Для отправки ответа на ранее созданное сообщения, вам необходимо в новом запросе sendMessage отправить дополнительный параметр reply_to_message_id, передав в него id сообщения, которое вы хотите прикрепить.

Полный запрос будет выглядеть так…

$token = "5340791844:AAEXXDduvInvQrlykV91USOQSevrPVU";

$getQuery = array(
     "chat_id" 	=> 1424625511,
     "text"  	=> "Новое сообщение из формы",
     "parse_mode" => "html",
     "reply_to_message_id" => 7
);
$ch = curl_init("https://api.telegram.org/bot". $token ."/sendMessage?" . http_build_query($getQuery));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

$resultQuery = curl_exec($ch);
curl_close($ch);

echo $resultQuery;

Удаление сообщений из чата

Для удаления сообщений, вам нужно воспользоваться методом deleteMessage и знать id сообщения которое вы хотите удалить.

Пример кода для удаления сообщений выглядит так:

$token = "5340791844:AAEXXDduvInvQrlykV91USOQSevrPVU";

$getQuery = array(
    "chat_id" 	=> 1424625511,
    "message_id"  => 32456,
);
$ch = curl_init("https://api.telegram.org/bot". $token ."/deleteMessage?" . http_build_query($getQuery));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);

$resultQuery = curl_exec($ch);
curl_close($ch);

echo $resultQuery;

Отправка кнопок в чат

На данный момент, существует 3 вида кнопок в чате, в Telegram.

  1. Кнопки которые прикреплены к сообщению (inline_keyboard).

  2. Кнопки которые располагаются под строкой ввода сообщения, они называются клавиатурой (keyboard).

  3. Кнопки меню команд, которые чаще всего располагаются слева от строки ввода сообщения.

Для начала давайте рассмотрим как нам добавить кнопки которые будут прикреплены к сообщению.

Для отправки таких кнопок, нам нужно воспользоваться методом sendMessage и передать ему в качестве параметра reply_markup — массив со свойствами клавиатуры.

Данный массив выглядит следующим образом…

...
'reply_markup' => json_encode(array(
    'inline_keyboard' => array(
	    array(
	        array(
		        'text' => 'Button 1',
		        'callback_data' => 'test_2',
	        ),

            array(
		        'text' => 'Button 2',
		        'callback_data' => 'test_2',
	        ),
	    )
    ),
)),
...

Разберём всё по порядку.

Первое важное правило - reply_markup принимает json, поэтому для создания кнопок, вам нужно конвертировать массив в JSON с помощью функции json_encode.

В массиве с параметрами кнопок, есть особые параметры. Эти параметры, так же, указаны в документации.

  • С помощью параметра text вы можете передать текст кнопки.

  • параметр url указывает ссылку, если вам нужно сделать кнопку для перехода на внешний ресурс.

  • параметр callback_data указывает строку которая будет возвращена после нажатия на кнопку. Данную строку используют как команду.

Массив для кнопок имеет сложную многоуровневую систему. Первый уровень отвечает за общую запись параметров, второй уровень отвечает за ряд кнопок, третий уровень отвечает за параметры кнопки.

Таким образом, для создания 2 кнопок в одном ряду, мы будем использовать следующий код

...
'reply_markup' => json_encode(array(
    'inline_keyboard' => array(
	    array(
	        array(
		        'text' => 'Button 1',
		        'callback_data' => 'test_2',
	        ),

            array(
		        'text' => 'Button 2',
		        'callback_data' => 'test_2',
	        ),
	    )
    ),
)),
...

Для создания 2 рядов по 2 кнопки используйте код ...

...
'reply_markup' => json_encode(array(
    'inline_keyboard' => array(
	     array(
	        array(
  		        'text' => 'Button 1',
		        'callback_data' => 'test_2',
	        ),

            array(
		        'text' => 'Button 2',
		        'callback_data' => 'test_2',
	        ),
	    ),
        array(
	        array(
		        'text' => 'Button 3',
		        'callback_data' => 'test_3',
	        ),

            array(
		        'text' => 'Button 4',
		        'callback_data' => 'test_4',
	        ),
	    )
    ),
)),
...

И для создания одной кнопки в первом ряду и 2 — во втором, используйте следующий код.

...
'reply_markup' => json_encode(array(
    'inline_keyboard' => array(
	    array(
            array(
		        'text' => 'Button 2',
		        'callback_data' => 'test_2',
	        ),
	    ),
        array(
	        array(
		        'text' => 'Button 3',
		        'callback_data' => 'test_3',
	        ),

            array(
		        'text' => 'Button 4',
		        'callback_data' => 'test_4',
	        ),
	    )
    ),
)),
...

Надеюсь, я смог объяснить данную тему доступно, если у вас будут вопросы, пишите их в нашем Telegram канале.

Отправка клавиатуры в чат

Аналогичные параметры имеет и массив для отправки клавиатуры в чат. Для создания клавиатуры пропишем следующий код.

...
'reply_markup' => json_encode(array(
    'keyboard' => array(
        array(
	        array(
		        'text' => 'Тестовая кнопка 1',
		        'url' => 'YOUR BUTTON URL',
	        ),
	        array(
		        'text' => 'Тестовая кнопка 2',
		        'url' => 'YOUR BUTTON URL',
	        ),
        )
    ),
    'one_time_keyboard' => TRUE,
    'resize_keyboard' => TRUE,
)),
...

Структура массивом для кнопок та же, но только есть отличие в названиях и количестве параметров.

Ключ inline_keyboard заменяется на keyboard.

А так же для клавиатуры добавляются 2 дополнительных параметра:

  • one_time_keyboard — скрыть клавиатуру, как только она была использована. Клавиатура по-прежнему будет доступна, но клиенты будут автоматически отображать обычную, буквенную клавиатуру в чате — пользователь может нажать специальную кнопку в поле ввода, чтобы снова увидеть пользовательскую клавиатуру. Значение по умолчанию равно false.

  • resize_keyboard — изменяет размер клавиатуры по вертикали для оптимальной подгонки (например, уменьшить клавиатуру, если есть только два ряда кнопок). По умолчанию установлено значение false, и в этом случае пользовательская клавиатура всегда имеет ту же высоту, что и стандартная клавиатура приложения.

Подведём итоги!

  • В новом уроке мы с вами разобрали самый популярный метод для работы с Телеграм ботами — sendMessage. Данный метод позволяет отправлять текстовые сообщения с привязанными кнопками и клавиатурами.

  • Научились удалять сообщения

  • Разобрали какие бывают типы кнопок и научились создавать массивы для гибкой структуры вывода дополнительных клавиатур и кнопок.

В следующем уроке, я вам покажу как отправлять файлы и изображения в чат.

Оригинал статьи на сайте Prog-Time.

Новый урок уже на Habr - https://habr.com/ru/post/697010/

Комментарии (5)


  1. FanatPHP
    03.11.2022 15:57
    +2

    Поучаствую в написании статьи.
    Лично я весь начинаю чесаться, когда вижу все эти кучи curlopt в количестве. И отдельно бесит, когда в примерах кода появляется горизонтальный скроллинг. Особенно если предполагается, что это у нас "более удобочитаемый код" ;-)


    Поэтому после пары примеров с сырым курлом, я все-таки предлагаю написать небольшую функцию-хелпер, и дальше уже обращаться к ней


    function curl($url, $data = [], $method = 'GET', $options = [])
    {
        $default_options = [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADER => false,
            CURLOPT_SSL_VERIFYPEER => false,
        ];
    
        if ($method === 'GET') {
            $url .= (strpos($url, '?') === false) ? '?' : '&';
            $url .= http_build_query($data);
        } 
        if ($method === 'POST') {
            $options[CURLOPT_POSTFIELDS] = http_build_query($data);
        } 
        if ($method === 'JSON') {
            $options[CURLOPT_POSTFIELDS] = json_encode($data);
            $options[CURLOPT_HTTPHEADER][] = 'Content-Type:application/json';
        }
    
        $ch = curl_init($url);
        curl_setopt_array($ch, array_replace($default_options, $options));
    
        $result = curl_exec($ch);
        if ($result === false) {
            throw new ErrorException("Curl error: ".curl_error($ch), curl_errno($ch));
        }
        curl_close($ch);
        return $result;
    }

    Понятно что внутри ее можно облагородить, сделать CURLOPT_SSL_VERIFYPEER подключаемой, допилить обработку ошибок НТТР, добавить еще всякой красоты — но чисто функционально она свою задачу решает. Чтобы в итоге мы видели только нужный для понимания статьи код, а детали реализации не болтались у нас все время перед носом:


    $token = "5340791844:AAEXXDduvInvQrlykV91USOQSevrPVU";
    $url = "https://api.telegram.org/bot$token/sendMessage";
    
    $getQuery = array(
        "chat_id"   => 1424625511,
        "text"      => "Новое сообщение из формы",
        "parse_mode" => "html"
    );
    echo curl($url, $getQuery);


    1. Prog-Time Автор
      04.11.2022 09:36

      Спасибо за участие в написание материала. Я добавил твой код в свою статью на сайте Prog-Time с ссылкой на профиль на Habr. Функция добавлена в 3 урок


      1. FanatPHP
        05.11.2022 09:53

        Ну, в таком-то виде, "шоб було" добавлять не стоило. Это был пример того, как можно сократить количество кода при минимальном пороге обучения. А если уж просто упоминать, то не этот самопал, а нормальные библиотеки.


    1. KGeist
      05.11.2022 00:15

      Если curl_exec вернёт false, не будет вызван curl_close. Не приведёт ли это к утечке ресурсов?


      1. FanatPHP
        05.11.2022 09:52

        О, кстати, хороший вопрос. Теоретически может, но по факту скорее всего не приведет. Но всё равно получилось неаккуратненько. Писал на коленке, причем так старался всё учесть, а тут такая мелочь обидная. Всего-то перенести парой строчек выше.


        К счастью, как я тут узнал из коммента под другой статьёй, начиная с 8 версии curl_close() — уже не нужна. Курл сам все закроет по окончании работы функции.