Blog. Just Blog

Анимация в Telegram через редактирование сообщений

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

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

Интересные динамические эффекты можно сделать при помощи редактирования сообщения. Для этого в официальном API Telegram есть несколько методов, нас интересуют только два из них - editMessageText и editMessageMedia. Но сперва немного освежим теорию. Когда пользователь запускает бота, в скрипте веб-хука мы можем узнать его идентификатор.

Array (  
  [update_id] => 216249334
  [message] => Array (
    [message_id] => 270
    [from] => Array (
      [id] => 600011111
      [is_bot] =>
      [first_name] => First
      [username] => Username
      [language_code] => ru
    )
    [chat] => Array (
      [id] => 600011111
      [first_name] => First
      [username] => Username
      [type] => private
    )
    [date] => 1010006010
    [text] => /start
    [entities] => Array (
      [0] => Array (
        [offset] => 0
        [length] => 6
        [type] => bot_command
      )
    )
  )
)

После успешной отправки текстового сообщения пользователю через метод sendMessage, бот получает ответ, в котором передаются данные об опубликованном сообщении. Нас интересует идентификатор (номер) сообщения в рамках этого чата.

Array (
  [ok] => 1
  [result] => Array (
    [message_id] => 272
    [from] => Array (
      [id] => 6222333444
      [is_bot] => 1
      [first_name] => Мой тестовый бот
      [username] => abcdef_bot
    )
    [chat] => Array (
      [id] => 600011111
      [first_name] => First
      [username] => Username
      [type] => private
    )
    [date] => 1010006010
    [text] => text
  )
)

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

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

Array (
  [ok] => 1
  [result] => Array (
    [0] => Array (
      [message_id] => 290
      [from] => Array (
        [id] => 6222333444
        [is_bot] => 1
        [first_name] => Мой тестовый бот
        [username] => abcdef_bot
      )
      [chat] => Array (
        [id] => 600011111
        [first_name] => First
        [username] => Username
        [type] => private
      )
      [date] => 1010006010
      [media_group_id] => 11111122222223333
      [photo] => Array (
        [0] => Array (
          [file_id] => AgACAgI
          [file_unique_id] => AQAD
          [file_size] => 1917
          [width] => 90
          [height] => 90
        )
        [1] => Array (
          [file_id] => AgACAgI
          [file_unique_id] => AQAD
          [file_size] => 32455
          [width] => 300
          [height] => 300
        )
      )
      [caption] => Калейдоскоп
    )
    [1] => Array (
      [message_id] => 291
      [from] => Array (
        [id] => 6222333444
        [is_bot] => 1
        [first_name] => Мой тестовый бот
        [username] => abcdef_bot
      )
      [chat] => Array (
        [id] => 600011111
        [first_name] => First
        [username] => Username
        [type] => private
      )
      [date] => 1010006010
      [media_group_id] => 11111122222223333
      [photo] => Array (
        [0] => Array (
          [file_id] => AgACAgI
          [file_unique_id] => AQAD7N
          [file_size] => 2080
          [width] => 90
          [height] => 90
        )
        [1] => Array (
          [file_id] => AgACAgI
          [file_unique_id] => AQAD7Ng
          [file_size] => 23274
          [width] => 300
          [height] => 300
        )
      )
    )
    [2] => Array (
      [message_id] => 292
      [from] => Array (
        [id] => 6222333444
        [is_bot] => 1
        [first_name] => Мой тестовый бот
        [username] => abcdef_bot
      )
      [chat] => Array (
        [id] => 600011111
        [first_name] => First
        [username] => Username
        [type] => private
      )
      [date] => 1010006010
      [media_group_id] => 11111122222223333
      [photo] => Array (
        [0] => Array (
          [file_id] => AgACAg
          [file_unique_id] => AQAD7
          [file_size] => 2177
          [width] => 90
          [height] => 90
        )
        [1] => Array (
          [file_id] => AgACAgI
          [file_unique_id] => AQAD7
          [file_size] => 24483
          [width] => 300
          [height] => 300
        )
      )
    )
  )
)

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

Полоса прогресса
Полоса прогресса

Отправляем пользователю текстовое сообщение, в котором будет полоска прогресс-бара с начальным значением. Получив message_id этого сообщения, в цикле меняем его текст с помощью метода editMessageText, корректируя прогресс-бар и процентовку. В виде кода это выглядит следующим образом:
  1. // Начальное сообщение
  2. $text='Работаем, ждите...'."\n";
  3. $text.=str_repeat(
  4.     chr(226).chr(172).chr(156).chr(239).chr(184).chr(143),
  5.     10
  6. );
  7. $text.=' 0%';
  8.  
  9. $query=array(
  10.     'chat_id'=>$chat_id,
  11.     'parse_mode'=>'HTML',
  12.     'disable_web_page_preview'=>'true',
  13.     'text'=>$text,
  14.     'disable_notification'=>'true',
  15. );
  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$query);
  25. curl_setopt($chCURLOPT_CONNECTTIMEOUT10);
  26. $result=curl_exec($ch);
  27. curl_close($ch);
  28.  
  29. $json=json_decode($result,true);
  30.  
  31. // Идентификатор сообщения
  32. $message_id=$json['result']['message_id'];
  33.  
  34. for($i=1$i<11$i++) {
  35.     sleep(2);
  36.  
  37.     // Новый текст сообщения
  38.     $text='Работаем, ждите...'."\n";
  39.     $text.=str_repeat(chr(240).chr(159).chr(148).chr(179), $i);
  40.     $text.=str_repeat(
  41.         chr(226).chr(172).chr(156).chr(239).chr(184).chr(143),
  42.         (10-$i)
  43.     );
  44.     $text.=' '.($i*10).'%';
  45.  
  46.     $query=array(
  47.         'chat_id'=>$chat_id,
  48.         'message_id'=>$message_id,
  49.         'parse_mode'=>'HTML',
  50.         'text'=>$text,
  51.     );
  52.  
  53.     // Заменить текст сообщения
  54.     $ch=curl_init();
  55.     curl_setopt($chCURLOPT_URL
  56.          'https://api.telegram.org/bot'.$token.'/editMessageText');
  57.     curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  58.     curl_setopt($chCURLOPT_HEADERfalse);
  59.     curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  60.     curl_setopt($chCURLOPT_POSTtrue);
  61.     curl_setopt($chCURLOPT_POSTFIELDS$query);
  62.     curl_setopt($chCURLOPT_CONNECTTIMEOUT10);
  63.     $result=curl_exec($ch);
  64.     curl_close($ch);
  65. }
После завершения сообщение можно вообще удалить, выдав вместо него готовый результат. Ну или заменив текст сообщения с прогресс-баром, если результат подразумевается в текстовом виде.

Метод editMessageMedia позволяет заменить одну картинку в одном сообщении. В интернетах я часто встречал вопрос, как можно заменить несколько картинок в сообщении. Так вот, если вы внимательно читали теоретическую часть, то понимаете, что нет никаких нескольких картинок в одном сообщении. Есть несколько объединенных в группу самостоятельных сообщений, каждое с одной картинкой. Именно поэтому в качестве параметра медиафайла у метода editMessageMedia всегда передаются данные только одной картинки. Соответственно, замена картинки в сообщении выполняется примерно следующим образом:
  1. // Отправить фото
  2. $query=array(
  3.     'chat_id'=>$chat_id,
  4.     'disable_web_page_preview'=>'true',
  5.     'caption'=>'Картинка',
  6.     'photo'=>curl_file_create('image_1.jpg'),
  7. );
  8.  
  9. $ch=curl_init();
  10. curl_setopt($chCURLOPT_URL,
  11.      'https://api.telegram.org/bot'.$token.'/sendPhoto');
  12. curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  13. curl_setopt($chCURLOPT_HEADERfalse);
  14. curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  15. curl_setopt($chCURLOPT_POSTtrue);
  16. curl_setopt($chCURLOPT_POSTFIELDS$query);
  17. curl_setopt($chCURLOPT_CONNECTTIMEOUT10);
  18. $result=curl_exec($ch);
  19. curl_close($ch);
  20.  
  21. $json=json_decode($result,true);
  22.  
  23. // Идентификатор сообщения
  24. $message_id=$json['result']['message_id'];
  25.  
  26. // Пауза
  27. sleep(2);
  28.  
  29. // Заменить фото
  30. $query=array(
  31.     'chat_id'=>$chat_id,
  32.     'message_id'=>$message_id,
  33. );
  34.  
  35. $query['new_attach']=curl_file_create('image_2.jpg');
  36.  
  37. $media=array(
  38.     'type'=>'photo',
  39.     'media'=>'attach://new_attach',
  40.     'caption'=>'Новая картинка',
  41. );
  42. $query['media']=json_encode($media);
  43.  
  44. $ch=curl_init();
  45. curl_setopt($chCURLOPT_URL,
  46.      'https://api.telegram.org/bot'.$token.'/editMessageMedia');
  47. curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  48. curl_setopt($chCURLOPT_HEADERfalse);
  49. curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  50. curl_setopt($chCURLOPT_POSTtrue);
  51. curl_setopt($chCURLOPT_POSTFIELDS$query);
  52. curl_setopt($chCURLOPT_CONNECTTIMEOUT10);
  53. $result=curl_exec($ch);
  54. curl_close($ch);
Если требуется редактировать несколько фотографий, то после отправки группы картинок через метод sendMediaGroup надо извлечь из ответа список всех message_id и редактировать нужные по одиночке, как написано выше. Никаких групповых операций для этого не предусмотрено. Также надо учитывать, что редактировать можно только имеющиеся изображения. Нельзя, например, добавить в уже отправленную группу новые изображения. При этом удалять изображения из группы можно, для этого имеется метод deleteMessage. Но даже такими методами можно организовать некое подобие анимации или внести динамику в приложение Telegram.

Поделиться ссылкой ВКонтакте
Просмотров: 247 | Комментариев: 2

Метки: PHP, Telegram

Комментарии

Отзывы посетителей сайта о статье
ManHunter (13.06.2024 в 17:02):
Давно уже добрались :(( Минималистичный чисто информационный фронтенд уже не канет, подавай личный кабинет с графиками, с вкладочками, с рюшечками и оборочками. Иначе, цитата, "вроде все понятно, но выглядит несолидно".

Опечатку поправил, спасибо.
Petya (13.06.2024 в 16:57):
Цитатаа может быть просто добавляющая важности свистоперделка "для форсу бандитского".

Что, и до Вас добрались заказчики, не принимающие слишком быструю и слишком маленькую программу :( ?

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

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

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