Yandex.Alice and Telegram bot in PHP with a single functionality

Good afternoon.

There are a lot of articles on the topic of Telegram bots, but few write about skills for Alice, and I did not find any information on how to make a single bot, so I decided to share my experience on how to make a simple Telegram bot and Yandex.Alice skill for the site having a single functional.

So, I won’t tell you how to raise a web server and get an ssl certificate, enough has been written about it.

Creating a Telegram bot

First, create a Telegram bot, for this, go to Telegram and find the BotFather bot there.

Select / newbot Enter the

name of the bot by which it will respond, then enter the name of the bot, in return we get the token for controlling the bot, write this key, it will be useful to us in the future.

The next step is to tell the Telegram servers which server to send data from the bot to. To do this, make a link of the form:

https: //ТОКЕН___/setWebhook?url=https://____ПУТЬ_ДО_СКРПИТА___

___ TOKEN ___ replace with our token from the bot received earlier

____ PATH_DO_SCRIPT ___ replace with the address of the script on our server where the data will be processed (for example, ).

There is a problem, the server is under lock, but you can do this: rent the cheapest server where there are no restrictions and give the command from the console of this server


That's it, the Telegram bot is created and connected to your server.

Creating a skill for Yandex.Alice

Let's move on to creating the skill for Yandex.Alice.

To create a skill, you need to go to the Yandex.Dialogs developers page, Yandex.Dialogs developers page , click on "Create dialogue" and select "Skill in Alice."

The skill settings dialog opens.

We begin to enter the skill settings.

Enter the name of your skill.

The activation name should be selected very carefully so that Alice understands it correctly, from the nuances - a mobile application with Alice and columns like Yandex.Station or Irbis A can perceive words in different ways.

We enter the path to the script on our server in the same way as for Telegram, but it will be a script specifically for Alice, for example .

We choose the voice that the skill will speak, I prefer the voice of Alice.

If you plan to work only on mobile devices or in a browser, then select "Need a device with a screen."

Next, enter the settings for the Alice skills catalog. If you plan to use the word brand to activate, you need to go through the verification of the brand website in the service.

With the settings everything, go to the scripts.

Telegram bot script

Let's start with the script for Telegram.

We connect the library where messages from the bot and Alice will be processed:

include_once 'webhook_parse.php';

We set the token of our bot:

$tg_bot_token = "_____YOUR_BOT_TOKEN_____";

We get the data:

$request = file_get_contents('php://input');
$request = json_decode($request, TRUE);

We parse the data into variables:

if (!$request)
    // Some Error output (request is not valid JSON)
else if (!isset($request['update_id']) || !isset($request['message']))
    // Some Error output (request has not message)
  $user_id = $request['message']['from']['id'];
  $msg_user_name = $request['message']['from']['first_name'];
  $msg_user_last_name = $request['message']['from']['last_name'];
  $msg_user_nick_name = $request['message']['from']['username'];
  $msg_chat_id = $request['message']['chat']['id'];
  $msg_text = $request['message']['text'];
  $msg_text = mb_strtolower($msg_text, 'UTF-8');
  $tokens = explode(" ", $msg_text);

Now you can work with variables:

$ tokens - here now all the words that the user entered

$ user_id - here the user id

$ msg_chat_id - chat in which the bot received the command

$ msg_user_name - username

Next, we call the Parse_Tokens function for processing:

$Out_Str = Parse_Tokens($tokens);

And we send the answer:

Send_Out($user_id, $Out_Str);

the Send_Out function is simple and looks like this:

function Send_Out($user_id, $text, $is_end = true)
  global $tg_bot_token;
  if (strlen($user_id) < 1 || strlen($text) < 1) {return;}
  $json = file_get_contents('' . $tg_bot_token . '/sendMessage?chat_id=' . $user_id . '&text=' . $text);

Skill script for Yandex.Alice

Now let's move on to the script for Alice, it is almost the same as for Telegram.

We also connect the library where messages from the bot and Alice will be processed, plus a library with classes for Alice:

include_once 'classes_alice.php';
include_once 'webhook_parse.php';

We get the data:

$data = json_decode(trim(file_get_contents('php://input')), true);

We parse the data into variables:

if (isset($data['request']))
  if (isset($data['meta']))
    $data_meta = $data['meta'];
    if (isset($data_meta['client_id'])) {$client_id = $data_meta['client_id'];}
  if (isset($data['request']))
    $data_req = $data['request'];
    if (isset($data_req['original_utterance']))
      $original_utterance = $data_req['original_utterance'];
    if (isset($data_req['command'])) {$data_msg = $data_req['command'];}
    if (isset($data_req['nlu']))
      $data_nlu = $data_req['nlu'];
      if (isset($data_nlu['tokens'])) {$tokens = $data_nlu['tokens'];}
//      $data_token_count = count($data_tokens);
  if (isset($data['session']))
    $data_session = $data['session'];
    if (isset($data_session['new'])) {$data_msg_new = $data_session['new'];}
    if (isset($data_session['message_id'])) {$data_msg_id = $data_session['message_id'];}
    if (isset($data_session['session_id'])) {$data_msg_sess_id = $data_session['session_id'];}
    if (isset($data_session['skill_id'])) {$skill_id = $data_session['skill_id'];}
    if (isset($data_session['user_id'])) {$user_id = $data_session['user_id'];}

Here the necessary variables are slightly less:

$ tokens - now all the words that the user entered

$ user_id are here - here the user id

Yandex constantly pings the published skills, and I added a line to immediately exit the script without starting the full message processing:

  if (strpos($tokens[0], "ping") > -1)     {Send_Out("pong", "", true);}

We call the Parse_Tokens function for processing, it is the same as for Telegram:

$Out_Str = Parse_Tokens($tokens);

And we send the answer:

Send_Out($user_id, $Out_Str);

The Send_Out function is more complicated here:

function Send_Out($user_id, $out_text, $out_tts = "", $is_end = false)
  global $data_msg_sess_id, $user_id;
  ///// GENERATE BASE OF OUT //////
    $Data_Out = new Alice_Data_Out();
    $Data_Out->response = new Alice_Response();
    $Data_Out->session = new Alice_Session();
  ///// GENERATE BASE OF OUT End //////
  ///// OUT MSG GENERATE /////
  $Data_Out->session->session_id = $data_msg_sess_id;;
  $Data_Out->session->user_id = $user_id;
  $Data_Out->response->text = $out_text;
  $Data_Out->response->tts = $out_tts;
  if (strlen($out_tts) < 1) {$Data_Out->response->tts = $out_text;}
  $Data_Out->response->end_session = $is_end;
  header('Content-Type: application/json');
  print(json_encode($Data_Out, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT));

Finished the script for Alice.

The processing script Parse_Tokens itself was done purely as an example, you can do any checks and processing there.

function Parse_Tokens($tokens)
  $out = "";
  // do something with tokens //
  $out =  "Your eneter " . count($tokens) . " words: " . implode($tokens, " ");
  return $out;

If you need to communicate with a user of a more complex form than a question and answer, you will need to save in the database (for example mysql) $ user_id of the user and data already received from the user and analyze them in the Parse_Tokens function.

Actually, this is almost all, if everything is done correctly, then the Telegram bot is already available, Alice’s skill can be checked by , going to your new skill on the testing tab.

If everything works correctly, you can send the skill to moderation by clicking the "Moderation" button.

Now you have two bots for different platforms that work the same way.

Documentation on the Yandex.Dialog service here.

Complete scripts are available on github download .

Update: wrapped everything in classes and updated the repository on github

Also popular now: