Blog. Just Blog

Telegram-бот на PHP

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Telegram-бот на PHP
Telegram-бот на PHP

Несколько лет назад я сделал на своем сайте отправку сообщений в Telegram средствами серверного PHP. В конце статьи я упомянул, что кроме отправки данных можно организовать взаимодействие с сайтом через Telegram. Настало время это реализовать, то есть написать полноценного Telegram-бота на PHP.

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

Для того, чтобы серверный бот мог получать все сообщения и уведомления, первым делом надо зарегистрировать так называемый webhook, то есть указать ссылку на скрипт, куда Telegram будет отправлять все данные. Формируем ссылку вида:

https://api.telegram.org/bot[token]/setWebhook?url=https://вашсайт.ру/telebot.php
где [token] - это токен, полученный при регистрации бота. Например, для описанного ранее тестового бота ссылка будет вот такой:

https://api.telegram.org/bot629705209:AAFhFqFbhR3VHHrOgOM7R4OnQT-usqJwTBk/setWebhook?url=https://вашсайт.ру/telebot.php
Если все сделано правильно, то в браузере будет получен ответ:

{"ok":true,"result":true,"description":"Webhook was set"}
Telegram отправляет данные на указанный скрипт при помощи POST-запроса, формат передаваемых данных всегда JSON. Для удобства разбора полетов, особенно на первых этапах, лучше логировать все полученные данные куда-нибудь в файл. Каркас скрипта-приемника будет иметь следующий вид:
  1. $data=file_get_contents('php://input');
  2. if ($json=json_decode($datatrue)) {
  3.     if (isset($json['update_id'])) {
  4.         // $json - отправленные данные
  5.     }
  6.     else {
  7.         // Это точно не данные от Telegram
  8.         exit;
  9.     }
  10. }
  11. else {
  12.     // Получены некорректные данные
  13.     exit;
  14. }
Тут сразу же выполняется быстрая проверка на корректность полученных данных, после чего разобранный запрос помещается в массив $json. Обычно бот может получать текстовые данные, файлы или управляющие команды. Начнем с самого простого. Когда пользователь пишет в чат сообщение, то бот получит примерно такие данные:

Array (
  [update_id] => 434540657
  [message] => Array (
    [message_id] => 1702
    [from] => Array (
      [id] => 698237240
      [is_bot] =>
      [first_name] => Dmitry
      [language_code] => ru
    )
    [chat] => Array (
      [id] => 698237240
      [first_name] => Dmitry
      [type] => private
    )
    [date] => 1679039931
    [text] => Привет
  )
)

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

Бот может принимать управляющие команды, они начинаются с косой черты "/". Если Telegram распознает такую команду, то в этом случае в уведомлении будет присутствовать дополнительный блок, хотя в остальном оно ничем не отличается от обычного текстового сообщения.

Array (
  [update_id] => 434540657
  [message] => Array (
    [message_id] => 1702
    [from] => Array (
      [id] => 698237240
      [is_bot] =>
      [first_name] => Dmitry
      [language_code] => ru
    )
    [chat] => Array (
      [id] => 698237240
      [first_name] => Dmitry
      [type] => private
    )
    [date] => 1679039931
    [text] => /dosomething
    [entities] => Array (
      [0] => Array (
        [offset] => 0
        [length] => 12
        [type] => bot_command
      )
    )
  )
)

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

Array (
  [update_id] => 434540657
  [message] => Array (
    [message_id] => 1702
    [from] => Array (
      [id] => 698237240
      [is_bot] =>
      [first_name] => Dmitry
      [language_code] => ru
    )
    [chat] => Array (
      [id] => 698237240
      [first_name] => Dmitry
      [type] => private
    )
    [date] => 1679039931
    [text] => Yo, bota! /krush /kill and /destroy
    [entities] => Array (
      [0] => Array (
        [offset] => 10
        [length] => 6
        [type] => bot_command
      )
      [1] => Array (
        [offset] => 17
        [length] => 5
        [type] => bot_command
      )
      [2] => Array (
        [offset] => 27
        [length] => 8
        [type] => bot_command
      )
    )
  )
)

Когда пользователь отправляет боту картинку со своего устройства, то фактически боту никаких файлов не передается. Файл загружается на сервер Telegram, а боту приходит информация об этом файле.

Array (
  [update_id] => 434540657
  [message] => Array (
    [message_id] => 1702
    [from] => Array (
      [id] => 698237240
      [is_bot] =>
      [first_name] => Dmitry
      [language_code] => ru
    )
    [chat] => Array (
      [id] => 698237240
      [first_name] => Dmitry
      [type] => private
    )
    [date] => 1679039931
    [photo] => Array (
      [0] => Array (
        [file_id] => AgAAAAAA1111111222222444zF-06666667777DDDDD
        [file_unique_id] => AQ111111111111h4
        [file_size] => 1575
        [width] => 55
        [height] => 90
      )
      [1] => Array (
        [file_id] => AgAAAAAA1111111222222444zF-06666667777CCCCC
        [file_unique_id] => AQ111111111111hy
        [file_size] => 23882
        [width] => 197
        [height] => 320
      )
      [2] => Array (
        [file_id] => AgAAAAAA1111111222222444zF-06666667777BBBBB
        [file_unique_id] => AQ111111111111h9
        [file_size] => 99568
        [width] => 493
        [height] => 800
      )
      [3] => Array (
        [file_id] => AgAAAAAA1111111222222444zF-06666667777AAAAA
        [file_unique_id] => AQ111111111111h-
        [file_size] => 175335
        [width] => 789
        [height] => 1280
      )
    )
  )
)

Как видите, Telegram и тут позаботился о web-мастере, передавая не только оригинальное изображение, но и подготовив аж три превьюшки разного размера. Сам файл получается в два этапа. Сперва надо определить, какой из четырех файлов нам нужен, они отличаются по полю file_id. Допустим, превьюшки нас не интересуют, поэтому просто берем последний элемент массива и получаем информацию о загруженном файле, используя его идентификатор.
  1. // Токен бота
  2. $token='629705209:AAFhFqFbhR3VHHrOgOM7R4OnQT-usqJwTBk'
  3.  
  4. $photo=array_pop($json['message']['photo']);
  5.  
  6. $ch=curl_init();
  7. curl_setopt($chCURLOPT_URL'https://api.telegram.org/bot'.$token.'/getFile');
  8. curl_setopt($chCURLOPT_POSTTRUE);
  9. curl_setopt($chCURLOPT_POSTFIELDS'file_id='.$photo['file_id']);
  10. curl_setopt($chCURLOPT_RETURNTRANSFERTRUE);
  11. curl_setopt($chCURLOPT_HEADERFALSE);
  12. curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);
  13. $result=curl_exec($ch);
  14. curl_close($ch);
  15.  
  16. $json=json_decode($result,true);
Если все сделано правильно, то будет получен ответ примерно такого содержания:

Array (
  [ok] => 1
  [result] => Array (
    [file_id] => AgAAAAAA1111111222222444zF-06666667777AAAAA
    [file_unique_id] => AQ111111111111h-
    [file_size] => 175335
    [file_path] => photos/file_0.jpg
  )
)

Только теперь, получив имя файла, можно загрузить его содержимое с сервера Telegram. Код будет примерно таким:
  1. $ch=curl_init();
  2. curl_setopt($chCURLOPT_URL,
  3.      'https://api.telegram.org/file/bot'.$token.'/'.$json['result']['file_path']);
  4. curl_setopt($chCURLOPT_POSTFALSE);
  5. curl_setopt($chCURLOPT_RETURNTRANSFERTRUE);
  6. curl_setopt($chCURLOPT_HEADERFALSE);
  7. curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);
  8. $source=curl_exec($ch);
  9. curl_close($ch);
  10.  
  11. // $source - содержимое файла
Есть большой соблазн вообще пропустить предыдущий шаг, так как массив изображений формируется только для файлов в формате JPEG, а оригинальная картинка всегда хранится по пути photos/file_0.jpg. Но стопроцентной гарантии у меня нет, поэтому оставлю это на ваше усмотрение.

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

Array (
  [update_id] => 434540657
  [message] => Array (
    [message_id] => 1702
    [from] => Array (
      [id] => 698237240
      [is_bot] =>
      [first_name] => Dmitry
      [language_code] => ru
    )
    [chat] => Array (
      [id] => 698237240
      [first_name] => Dmitry
      [type] => private
    )
    [date] => 1679039931
    [document] => Array (
      [file_name] => my_image.png
      [mime_type] => image/png
      [thumbnail] => Array (
        [file_id] => AgAAAAAA1111111222222444zF-06666667777CCCCC
        [file_unique_id] => AQ111111111111hA
        [file_size] => 25093
        [width] => 320
        [height] => 282
      )
      [thumb] => Array (
        [file_id] => AgAAAAAA1111111222222444zF-06666667777BBBBB
        [file_unique_id] => AQ111111111111hB
        [file_size] => 25093
        [width] => 320
        [height] => 282
      )
      [file_id] => AgAAAAAA1111111222222444zF-06666667777AAAAA
      [file_unique_id] => AQ111111111111hC
      [file_size] => 33560
    )
  )
)

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

Array (
  [update_id] => 434540657
  [message] => Array (
    [message_id] => 1702
    [from] => Array (
      [id] => 698237240
      [is_bot] =>
      [first_name] => Dmitry
      [language_code] => ru
    )
    [chat] => Array (
      [id] => 698237240
      [first_name] => Dmitry
      [type] => private
    )
    [date] => 1679039931
    [document] => Array (
      [file_name] => my_book.fb2
      [mime_type] => application/octet-stream
      [file_id] => AgAAAAAA1111111222222444zF-06666667777AAAAA
      [file_unique_id] => AQ111111111111hC
      [file_size] => 1236900
    )
  )
)

Содержимое файла получается точно так же в два захода. И вот тут от получения информации о файле уже не отвертеться.
  1. // Токен бота
  2. $token='629705209:AAFhFqFbhR3VHHrOgOM7R4OnQT-usqJwTBk'
  3.  
  4. $ch=curl_init();
  5. curl_setopt($chCURLOPT_URL'https://api.telegram.org/bot'.$token.'/getFile');
  6. curl_setopt($chCURLOPT_POSTTRUE);
  7. curl_setopt($chCURLOPT_POSTFIELDS,
  8.     'file_id='.$json['message']['document']['file_id']);
  9. curl_setopt($chCURLOPT_RETURNTRANSFERTRUE);
  10. curl_setopt($chCURLOPT_HEADERFALSE);
  11. curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);
  12. $result=curl_exec($ch);
  13.  
  14. $json=json_decode($result,true);
  15.  
  16. curl_setopt($chCURLOPT_URL,
  17.     'https://api.telegram.org/file/bot'.$token.'/'.$json['result']['file_path']);
  18. curl_setopt($chCURLOPT_POSTFALSE);
  19. $source=curl_exec($ch);
  20. curl_close($ch);
  21.  
  22. // $source - содержимое файла
Дальше содержимое файла записывается на диск или используется по иному назначению. Хорошим тоном будет уведомить пользователя о факте успешного получения файла и о действии, которое с этим файлом было выполнено.

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

Отправка изображения
Отправка изображения
  1. // Подготовить локальный файл для отправки
  2. $file=__DIR__.'/original.jpg';
  3.  
  4. if (function_exists('curl_file_create')) {
  5.     $attachment=curl_file_create($file);
  6. }
  7. else {
  8.     $info=pathinfo($file);
  9.     $attachment='@'.realpath($file).';filename='.$info['basename'].
  10.              ';type='.mime_content_type($file);
  11. }
  12.  
  13. $query=array(
  14.     'chat_id'=>$chat_id,
  15.     'photo'=>$attachment,
  16.     'caption'=>'Тестовая картинка',
  17. );
  18.  
  19. $ch=curl_init();
  20. curl_setopt($chCURLOPT_URL,
  21.     'https://api.telegram.org/bot'.$token.'/sendPhoto');
  22. curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  23. curl_setopt($chCURLOPT_HEADERfalse);
  24. curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  25. curl_setopt($chCURLOPT_POSTtrue);
  26. curl_setopt($chCURLOPT_POSTFIELDS$query);
  27. $result=curl_exec($ch);
  28. curl_close($ch);
Для формирования объекта файла проверяется доступность функции cURL, так как функция curl_file_create отсутствует в старых версиях PHP. Для таких случаев создание объекта отправляемого файла выполняется в "ручном" режиме.

Отправка документа выполняется почти так же, только меняется название ключа массива и ссылка API.

Отправка документа
Отправка документа

Отправка документа
Отправка документа
  1. // Подготовить локальный файл для отправки
  2. $file=__DIR__.'/example.xls';
  3.  
  4. if (function_exists('curl_file_create')) {
  5.     $attachment=curl_file_create($file);
  6. }
  7. else {
  8.     $info=pathinfo($file);
  9.     $attachment='@'.realpath($file).';filename='.$info['basename'].
  10.              ';type='.mime_content_type($file);
  11. }
  12.  
  13. $query=array(
  14.     'chat_id'=>$chat_id,
  15.     'document'=>$attachment,
  16.     'caption'=>'Тестовый документ',
  17. );
  18.  
  19. $ch=curl_init();
  20. curl_setopt($chCURLOPT_URL,
  21.     'https://api.telegram.org/bot'.$token.'/sendDocument');
  22. curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  23. curl_setopt($chCURLOPT_HEADERfalse);
  24. curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  25. curl_setopt($chCURLOPT_POSTtrue);
  26. curl_setopt($chCURLOPT_POSTFIELDS$query);
  27. $result=curl_exec($ch);
  28. curl_close($ch);
По аналогии отправляются аудиофайлы, вынесенные от документов в отдельную категорию.

Отправка аудио
Отправка аудио
  1. // Подготовить локальный файл для отправки
  2. $file=__DIR__.'/example.mp3';
  3.  
  4. if (function_exists('curl_file_create')) {
  5.     $attachment=curl_file_create($file);
  6. }
  7. else {
  8.     $info=pathinfo($file);
  9.     $attachment='@'.realpath($file).';filename='.$info['basename'].
  10.              ';type='.mime_content_type($file);
  11. }
  12.  
  13. $query=array(
  14.     'chat_id'=>$chat_id,
  15.     'audio'=>$attachment,
  16.     'caption'=>'Тестовая песенка',
  17. );
  18.  
  19. $ch=curl_init();
  20. curl_setopt($chCURLOPT_URL,
  21.     'https://api.telegram.org/bot'.$token.'/sendAudio');
  22. curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  23. curl_setopt($chCURLOPT_HEADERfalse);
  24. curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  25. curl_setopt($chCURLOPT_POSTtrue);
  26. curl_setopt($chCURLOPT_POSTFIELDS$query);
  27. $result=curl_exec($ch);
  28. curl_close($ch);
Отправку всяких стикеров, контактов и прочего смотрите в официальной документации, там ничего сложного.

Отдельно хочется остановиться на взаимодействии пользователя с ботом. Конечно, можно сколько угодно набирать вручную текстовые сообщения и команды управления, но это быстро надоедает, к тому же повышается риск ошибки. Гораздо удобнее сразу же предоставлять пользователю список возможных действий в привычном ему формате, например, в виде кнопок.

Первый тип клавиатуры - inline-клавиатура, которая прикрепляется к конкретному сообщению. Как правило в ней содержится список действий, которые связаны с этим сообщением, например, переход по ссылке или открытие конкретной карточки товара. Для отправки такой клавиатуры надо сперва сформировать массив с кнопками, которые будут прикреплены к сообщению, а затем передать его в параметре reply_markup.

Пример inline-клавиатуры
Пример inline-клавиатуры
  1. $keyboard=array(
  2.     "resize_keyboard"=>true,
  3.     "inline_keyboard"=>array(
  4.         // Первая строка кнопок
  5.         array(
  6.             array(
  7.                 'text' => 'Перейти на сайт www.manhunter.ru',
  8.                 'url'=>'https://www.manhunter.ru',
  9.             ),
  10.         ),
  11.         // Вторая строка кнопок
  12.         array(
  13.             array(
  14.                 'text' => 'Привет!',
  15.                 'callback_data'=>'Нажата внопка 1'
  16.             ),
  17.             array(
  18.                 'text' => 'До свидания!',
  19.                 'callback_data'=>'Нажата внопка 2'
  20.             ),
  21.         ),
  22.     ),
  23. );
  24.  
  25. $text='Вот такие кнопки. Попробуй их все!';
  26.  
  27. $ch=curl_init();
  28. curl_setopt($chCURLOPT_URL,
  29.     'https://api.telegram.org/bot'.$token.'/sendMessage');
  30. curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  31. curl_setopt($chCURLOPT_HEADERfalse);
  32. curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  33. curl_setopt($chCURLOPT_POSTtrue);
  34. curl_setopt($chCURLOPT_POSTFIELDS,
  35.     'chat_id='.$chat_id.'&text='.rawurlencode($text).
  36.     '&reply_markup='.json_encode($keyboard));
  37. curl_setopt($chCURLOPT_CONNECTTIMEOUT10);
  38. $result=curl_exec($ch);
Кнопки могут быть расположены в несколько строчек, а в качестве параметров указывается ссылка или строка с описанием действия, которое будет передано на ваш обработчик. При нажатии на кнопку-ссылку Telegram спросит подтверждение на переход, а при нажатии на кнопку-действие ваш обработчик получит примерно такие уведомление:

Array (
  [update_id] => 434540657
  [callback_query] => Array (
    [id] => 1111222223333344444
    [from] => Array (
      [id] => 698237240
      [is_bot] =>
      [first_name] => Dmitry
      [language_code] => ru
    )
    [message] => Array (
      [message_id] => 74
      [from] => Array (
        [id] => 1112223445
        [is_bot] => 1
        [first_name] => MySupaTestBot
        [username] => MySupaTestBot_bot
      )
      [chat] => Array (
        [id] => 698237240
        [first_name] => Dmitry
        [type] => private
      )
      [date] => 1679227556
      [text] => Вот такие кнопки. Попробуй их все!
      [reply_markup] => Array (
        [inline_keyboard] => Array (
          [0] => Array (
            [0] => Array (
              [text] => Перейти на сайт
              [url] => https://www.manhunter.ru/
            )
          )
          [1] => Array (
            [0] => Array (
              [text] => Привет
              [callback_data] => Нажата внопка 1
            )
            [1] => Array (
              [text] => До свидания
              [callback_data] => Нажата внопка 2
            )
          )
        )
      )
    )
    [chat_instance] => -123456789081123230
    [data] => Нажата внопка 1
  )
)

После отправки callback-сообщения клиент Telegram переходит в режим ожидания ответа, при этом на нажатой кнопке появляется значок часиков. Если в течение определенного времени ответ от серверного обработчика не получен, то значок часиков пропадает. Но хорошей практикой будет отправлять из обработчика ответ на callback-сообщения с помощью метода answerCallbackQuery. В этом случае для идентификации получателя используется ['callback_query']['id'].
  1. $callback_id=$json['callback_query']['id'];
  2.  
  3. $text='';
  4.  
  5. $ch=curl_init();
  6. curl_setopt($chCURLOPT_URL,
  7.     'https://api.telegram.org/bot'.$token.'/answerCallbackQuery');
  8. curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  9. curl_setopt($chCURLOPT_HEADERfalse);
  10. curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  11. curl_setopt($chCURLOPT_POSTtrue);
  12. curl_setopt($chCURLOPT_POSTFIELDS,
  13.     'callback_query_id='.$callback_id.'&text='.rawurlencode($text));
  14. curl_setopt($chCURLOPT_CONNECTTIMEOUT10);
  15. $result=curl_exec($ch);
Текст ответа появится в виде всплывающего сообщения, если текст пустой, то клиент просто вернется из режима ожидания ответа в обычный режим работы. Показ сообщения также регулируется параметром show_alert. В зависимости от задачи, вместо показа сообщения можно передать параметр url, в этом случае клиент выполнит команду "открыть сылку".

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

Пример обычной клавиатуры
Пример обычной клавиатуры
  1. $keyboard=array(
  2.     "resize_keyboard"=>true,
  3.     "keyboard"=>array(
  4.         array(
  5.             array(
  6.                 'text' => 'Всем привет!',
  7.             ),
  8.             array(
  9.                 'text' => 'До свидания!',
  10.             ),
  11.         ),
  12.     ),
  13. );
  14.  
  15. $text='Вот такие кнопки. Попробуй их все!';
  16.  
  17. $ch=curl_init();
  18. curl_setopt($chCURLOPT_URL,
  19.     'https://api.telegram.org/bot'.$token.'/sendMessage');
  20. curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  21. curl_setopt($chCURLOPT_HEADERfalse);
  22. curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  23. curl_setopt($chCURLOPT_POSTtrue);
  24. curl_setopt($chCURLOPT_POSTFIELDS,
  25.     'chat_id='.$chat_id.'&text='.rawurlencode($text).
  26.     '&reply_markup='.json_encode($keyboard));
  27. curl_setopt($chCURLOPT_CONNECTTIMEOUT10);
  28. $result=curl_exec($ch);
При нажатиии таких кнопок серверному обработчику, соответственно, приходят самые обычные уведомления, как будто пользователь набрал их на клавиатуре.

Через @BotFather можно задавать список команд бота. Он появится в меню команд при нажатии кнопки рядом с полем ввода. Но можно сделать это и программно, например, сразу после старта бота.

Меню команд бота
Меню команд бота
  1. $commands=array(
  2.     array(
  3.         'command'=>'start',
  4.         'description'=>'Запуск бота'
  5.     ),
  6.     array(
  7.         'command'=>'monster',
  8.         'description'=>'Монстр дня'
  9.     ),
  10.     array(
  11.         'command'=>'crossword',
  12.         'description'=>'Кроссворд'
  13.     ),
  14.     array(
  15.         'command'=>'coupon',
  16.         'description'=>'Купон'
  17.     ),
  18. );
  19.  
  20. $query=array(
  21.     'commands'=>json_encode($commands),
  22. );
  23.  
  24. $ch=curl_init();
  25. curl_setopt($chCURLOPT_URL,
  26.     'https://api.telegram.org/bot'.$token.'/setMyCommands');
  27. curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  28. curl_setopt($chCURLOPT_HEADERfalse);
  29. curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  30. curl_setopt($chCURLOPT_POSTtrue);
  31. curl_setopt($chCURLOPT_POSTFIELDS$query);
  32. curl_setopt($chCURLOPT_CONNECTTIMEOUT10);
  33. $result=curl_exec($ch);
  34. curl_close($ch);
Как и в предыдущем случае, на сервер отправится управляющая команда, как будто ее набрали с клавиатуры. Количество команд в списке не должно быть больше 100.

И напоследок буквально пару слов об оформлении сообщений, которые бот отправляет пользователю. Чтобы определенный фрагмент текста можно было скопировать одним нажатием, его надо оформить тегами <code> и дополнить список полей отправки параметром parse_mode=HTML.
  1. $text='Длинный текст, <code>а этот фрагмент можно копировать</code>, и еще текст';
  2. $ch=curl_init();
  3. curl_setopt($chCURLOPT_URL,
  4.     'https://api.telegram.org/bot'.$token.'/sendMessage');
  5. curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  6. curl_setopt($chCURLOPT_HEADERfalse);
  7. curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  8. curl_setopt($chCURLOPT_POSTtrue);
  9. curl_setopt($chCURLOPT_POSTFIELDS,
  10.     'chat_id='.$chat_id.'&text='.rawurlencode($text).'&parse_mode=HTML');
  11. curl_setopt($chCURLOPT_CONNECTTIMEOUT10);
  12. $result=curl_exec($ch);
  13. curl_close($ch);
По умолчанию Telegram не позволяет вставлять изображения в текст сообщений. Это частично можно обойти, сформировав сообщение особым образом, указав ссылку на картинку с пустым текстом ссылки и добавив еще один параметр disable_web_page_preview=false в отправляемые данные.

Изображение в сообщении
Изображение в сообщении

В этом случае превью изображения будет расположено сразу под текстом, независимо, где оно находилось в оригинале. И такая превьюшка в сообщении может быть только одна. Что ж, это лучше, чем ничего.
  1. $text='Посмотрите, какая картинка есть у нас ';
  2. $text.='<a href="https://вашсайт.ру/image.jpg">&#8205;</a>';
  3. $text.='Вам нравится?';
  4.  
  5. $ch=curl_init();
  6. curl_setopt($chCURLOPT_URL,
  7.     'https://api.telegram.org/bot'.$token.'/sendMessage');
  8. curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  9. curl_setopt($chCURLOPT_HEADERfalse);
  10. curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  11. curl_setopt($chCURLOPT_POSTtrue);
  12. curl_setopt($chCURLOPT_POSTFIELDS,
  13.     'chat_id='.$chat_id.'&text='.rawurlencode($text).
  14.     '&disable_web_page_preview=false&parse_mode=HTML');
  15. curl_setopt($chCURLOPT_CONNECTTIMEOUT10);
  16. $result=curl_exec($ch);
  17. curl_close($ch);
Еще один часто используемый вариант оформления постов - большой текст в качестве подписи к изображению. В этом случае картинка будет сверху, а под ней, например, рекламный текст. Длина подписи к картинке, а, следовательно, и текста поста, не должна превышать 1024 символа. Обычный текст сообщения к фото добавлять нельзя.

Текст в подписи и inline-клавиатура
Текст в подписи и inline-клавиатура

Пост можно дополнить инлайновыми кнопками-ссылками, украсить иконками эмодзи, главное во всем знать меру. Код для отправки будет следующим:
  1. $keyboard=array(
  2.     "resize_keyboard"=>true,
  3.     "inline_keyboard"=>array(
  4.         array(
  5.             array(
  6.                 'text' => 'Перейти на сайт www.manhunter.ru',
  7.                 'url'=>'https://www.manhunter.ru',
  8.             ),
  9.         ),
  10.     ),
  11. );
  12.  
  13. // Подготовить локальный файл для отправки
  14. $file=__DIR__.'/example.jpg';
  15.  
  16. if (function_exists('curl_file_create')) {
  17.     $attachment=curl_file_create($file);
  18. }
  19. else {
  20.     $info=pathinfo($file);
  21.     $attachment='@'.realpath($file).';filename='.$info['basename'].
  22.              ';type='.mime_content_type($file);
  23. }
  24.  
  25. $query=array(
  26.     'chat_id'=>$chat_id,
  27.     'photo'=>$attachment,
  28.     'caption'=>'Новинка! Распродажа!'."\n".
  29.                'Только сейчас и только у нас!'."\n".
  30.                'Налетай, торопись, покупай живопись!',
  31.     'reply_markup'=>json_encode($keyboard),
  32. );
  33.  
  34. $ch=curl_init();
  35. curl_setopt($chCURLOPT_URL,
  36.     'https://api.telegram.org/bot'.$token.'/sendPhoto');
  37. curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  38. curl_setopt($chCURLOPT_HEADERfalse);
  39. curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  40. curl_setopt($chCURLOPT_POSTtrue);
  41. curl_setopt($chCURLOPT_POSTFIELDS$query);
  42. $result=curl_exec($ch);
  43. curl_close($ch);
Комбинируя описанные тут методы приема и отправки сообщений разного типа, вы можете написать собственного Telegram-бота с нужным функционалом. В очередной раз скажу, что перечисленными функциями возможности Telegram-ботов не ограничиваются. Изучайте документацию, смотрите примеры, пробуйте и у вас все получится.

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 1512 | Комментариев: 6

Метки: PHP

Комментарии

Отзывы посетителей сайта о статье
ManHunter (04.05.2023 в 13:08):
Добавил в статью информацию про answerCallbackQuery, про список команд, подкорректировал код создания объектов отправляемых файлов.
ManHunter (22.03.2023 в 21:35):
С чего вдруг такая забота?
Petya (22.03.2023 в 19:24):
Я надеюсь, токены бота в статье липовые приведены?
ManHunter (20.03.2023 в 09:53):
ЦитатаЕсли не секрет, какую мобилу юзаете?

У меня их две: Huawei P30 и Huawei P30 Pro

master-ufa, разместить скрипт-приемник можно на любом ресурсе, который доступен извне по https. Оптимально это свой сайт или сервер, зависит от задачи. У меня скрипт залит на этот сайт, по уведомлениям о разных событиях я одним нажатием нужной кнопки мгновенно выполняю нужное действие. И не важно, где я нахожусь, не надо лезть в комп, открывать браузер, заходить в админку и все такое.
Скрипт для отправки может работать вообще хоть откуда, лишь бы был исходящий интернет.
nordpoint (20.03.2023 в 09:46):
Спасибо за труды! Если не секрет, какую мобилу юзаете?
master-ufa (20.03.2023 в 08:56):
Вчера только решил изучить телеграм-бота, а тут уже все расписано. СПАСИБО. Один только вопрос: где можно разместить Скрипт?
1. На домашнем компьютере который постоянно включен?
2. Если на "мойсайт.ру", то в каком месте?
3. В самом Телеграмм есть возможность?
4. Какие надежные сторонние сервисы для размещения Вы используете?

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2023
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0045 сек.) / Память: 4.5 Mb
Наверх