DroidScript
DroidScript
учимся и разрабатываем

Настраиваемые боты

Ботостроительство  
22.12.2024

Могут ли пользователи изменять функциональность бота и настраивать её для своей работы? На этом занятии мы рассмотрим возможности пользовательской настройки ботов

Для разогрева рассмотрим пример простого интерпретатора PHP.

Интерпретатор 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);
Ботостроительство  
© 2016-2025 
actech