Могут ли пользователи изменять функциональность бота и настраивать её для своей работы? На этом занятии мы рассмотрим возможности пользовательской настройки ботов
Для разогрева рассмотрим пример простого интерпретатора PHP.
На основе встроенного запроса можно реализовать интерпретатор PHP.
В функцию message_inline добавьте код и сделайте вывод результата в поле title
$query = $data['inline_query']['query']; $firstChar = substr($query, 0, 1); if( $firstChar == '='){ $query = substr($query, 1); eval("\$result = $query;"); } $mResult = []; array_push($mResult,[ "type" => "article", "id" => 1, "title" => $result, "input_message_content" => [ "message_text" => $result, "parse_mode"=>'HTML' ] ]);
После этого в строку чата можно ввести, например, такой текст:
@Имя бота = test(); function test(){ $object = new stdClass(); $object->name = 'GeeksforGeeks'; $object->address = 'Noida'; return $object->name; }
Или можно сделать простейший отладчик с выводом значения переменной. Введите в поле чата любую доступную переменную, например:
@Имя бота =$inline_query_id;
Кнопка меню доступна в персональном чате и её также можно запрограммировать на открытие внешних ресурсов или отображения меню команд. Но эту кнопку можно использовать и для вывода отладочной информации в процессе тестирования бота.
$cmb = [ "chat_id"=> $chat_id, "menu_button"=> [ "type"=> "web_app", "text"=> $result, "web_app"=>[ "url"=>"https://test.ru" ] ] ]; $cmb = json_encode($cmb); call('setChatMenuButton',$cmb);
В предыдущем примере вывод результата интерпретации PHP-кода производился в меню автозагрузки, но его можно вывести и на как текст на кнопке меню.
Можно ли сделать программируемого из чата бота? Можно, но здесь на первый план выходит вопрос безопасности. Доверять что-то выполнять в eval можно только себе, да и то не всегда.
Вспомнился один случай по этому поводу. Как-то один товарищ решил сжать диск для высвобождения места. В те времена жесткие диски стоили очень дорого, а места всегда не хватало. Прошло какое-то время и места опять стало не хватать. Тогда он решил провести чистку файлов и видит, что корне находится какой-то непонятный файл огромного размера. Он обрадовался и удалил его, а вместе с ним и всю операционную систему, которая ранее была сжата в этот файл.
В приведённом выше примере пользовательский запрос не сохраняется и никакого изменения функциональности не происходит. Но у встроенного запроса есть возможность вывести кнопку в верхней части меню автозагрузки. Эту кнопку можно использовать, например, для сохранения запроса. Это можно использовать для создания сообщения "Избранное", в клавиатуру которого пользователи смогут добавлять ссылки на ранее созданные запросы. Преимущество этого решения состоит в простоте добавления ссылок в кнопки. Недостаток - сложный механизм обновления ссылок и невозможность выйти за рамки встроенных кнопок.
В персональном чате пользователь может редактировать свои сообщения. Это наталкивает на мысль реализовать такой механизм: в пользовательском сообщении создаётся код для текста и клавиатуры, который затем интерпретируется и реализуется в следующем сообщении от бота. Проще говоря, при помощи своего сообщения пользователь изменят следующее за ним сообщение от бота - добавляет в него клавиатуру, тест и т.п.
Преимущество способа - функциональность, недостаток - сложность редактирования на мобильных устройствах. На десктопе использование редактора json упрощает создание нужного кода.
Суть идеи состоит в объединении двух массивов - предопределенного и того, который формируется из пользовательских данных.
$text = (Array)json_decode($text); $data = [ "chat_id" => $chat_id, "message_id"=>$message_id, "parse_mode"=>'HTML' ]; $data = array_merge($data,$text);
После этого пользователи смогут изменять и текст, и клавиатуру так, как им нужно:
{ "text":"Привет\nСсылка", "reply_markup": { "inline_keyboard":[ [ { "text": "Копировать", "callback_data":"добавить" } ] ] } }
Сообщения в чатах сами по себе хранят информацию. Это можно использовать для создания поста с настройками. Единственное, необходимо где-то хранить номер сообщения с настройками для доступа к нему или каким-то образом его получать.
Для взаимодействия с интерфейсом используются элементы управления - кнопки, флажки, списки и т.д. В ТГ всё крайне скудно в этом плане и приходится что-то придумывать нестандартное. Например, выбор из списка можно реализовать так: рядом с каждой опцией создать командную ссылку с числом /index. При нажатии на ссылку создать исчезающее сообщение, индекс команды которого использовать для изменения выбранного элемента списка в сообщении. Другой вариант - выбор опций производить при помощи кнопок встроенной клавиатуры. Ещё вариант - ввод исчезающего сообщения с номером опции.
Ниже показан фрагмент примера имитации работы флажка при нажатии на встроенную кнопку.
if(preg_match('/настройка/ui', $text) === 1){ if($messageText=='☐'){ $messageText='🗹'; } else{ $messageText='☐'; } $data = [ "chat_id" => $chatId, "message_id"=>505, "text" => $messageText, "reply_markup"=> [ "inline_keyboard"=> [ [ [ "text"=> "Настройка", "callback_data" => "настройка".$timestamp ] ] ] ] ]; $data = json_encode($data); call("editMessageText",$data); }
Если символов опций несколько, то им сопоставляется массив, а сами опции можно получить из текста при помощи регулярного выражения, например:
$re = '/☒|☐/m'; $str = '☐ изображение ☒ музыка'; preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);