Sending structured message and keyboard menu in Viber chat bot
After having an overwhelming response to our earlier post on building Viber Chat bot, we are here again with another Viber chat bot article. In that post, we provided you with set of code for receiving message from users and deliver normal text messages. Rather than just replying text, we can also send complex messages. So we came up with this article to fulfill this gap. This time, we will be sending structured message to the user including keyboard menu, pictures and links as well.
We will develop a Viber chat bot similar to that of chat bot of LetzCricket.
Finding Chat bot
First of all, we are going to find how the chat bot of LetzCricket looks like. For this, we need to search for a public account named LetzCricket on Viber.
You will get the screen similar the following screenshot if you enter the public chat and subscribe to the public account.
Now click on the message icon in top right side of the screen to start 1-on-1 chat. Then message “Hi” to start the conversation. As a result, you will see the following message with keyboard menu.
Now that we have a preview of what we are going to make, lets start coding. Here’s the PHP code:
<?php $request = file_get_contents("php://input"); $input = json_decode($request, true); if($input['event'] == 'webhook') { $webhook_response['status']=0; $webhook_response['status_message']="ok"; $webhook_response['event_types']='delivered'; echo json_encode($webhook_response); die; } else if($input['event'] == "subscribed") { // when a user subscribes to the public account } else if($input['event'] == "conversation_started"){ // when a conversation is started } elseif($input['event'] == "message") { /* when a user message is received */ $type = $input['message']['type']; //type of message received (text/picture) $text = $input['message']['text']; //actual message the user has sent $sender_id = $input['sender']['id']; //unique viber id of user who sent the message $sender_name = $input['sender']['name']; //name of the user who sent the message // here goes the data to send message back to the user if($text == 'LCNews'){ //if user presses News option $data = getNewsList($sender_id); } elseif($text=='LCArticles'){ //if user presses Articles option $data = getArticleList($sender_id); } elseif($text==' LCInterviews'){ //if user presses Interview option $data = getInterviewList($sender_id); } elseif($text==' LCGallery'){ //if user presses Gallery option $data = getGalleryList($sender_id); } elseif($text==' LCPoll'){ //if user presses Poll option $data = getPollList($sender_id); } elseif($text==' LCPOTM'){ //if user presses Player of the month option $data = getPOTM($sender_id); } elseif($text==' LCQuote'){ //if user presses Quote option $data = getQuote($sender_id); } else{ $data = getMainMenu($sender_id); } //here goes the curl to send data to user $ch = curl_init("https://chatapi.viber.com/pa/send_message "); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); $result = curl_exec($ch); curl_close($ch); } ?>
Creating Keyboard menu
We sent normal text in the previous article. In this article, we are sending keyboard menu along with message. Keyboards can be attached to any message type and be sent and displayed together. To attach a keyboard to a message simply add the keyboard’s parameters to the message JSON. Please refer to previous article to see keyboard’s parameter.
The keyboards are fully customizable. We can create and design according to our requirement. The client will always display the last keyboard that was sent to it.
We have created a function getMainMenu() to create keyboard menu. It will be called at the same place where we had prepared content to deliver to the user.
The getMainMenu() function that delivers the main menu to the user would look like this:
<?php function getMainMenu($user_id){ $data['auth_token']='your_auth_token'; $data['receiver']=$user_id; $data['BgColor']="#ffffff"; $data['type']='text'; $data['text']="Please select one of the options below:"; $keyboard_array['Type']='keyboard'; $keyboard_array['DefaultHeight']=false; $keyboard_array['BgColor']="#FFFFFF"; $keyboard['keyboard']=$keyboard_array; $news['Columns']=2; $news['Rows']=2; $news['TextVAlign']="bottom"; $news['TextHAlign']="center"; $news['TextOpacity']="100"; $news['Text']='NEWS'; $news['TextSize']="regular"; $news['ActionType']="reply"; $news['ActionBody']="LCNews"; $keyboard['keyboard']['Buttons'][]=$news; $articles['Columns']=2; $articles['Rows']=2; $articles['TextVAlign']="bottom"; $articles['TextHAlign']="center"; $articles['TextOpacity']="100"; $articles['Text']='ARTICLES'; $articles['TextSize']="regular"; $articles['ActionType']="reply"; $articles['ActionBody']="LCArticles"; $keyboard['keyboard']['Buttons'][]=$articles; $interviews['Columns']=2; $interviews['Rows']=2; $interviews['TextVAlign']="bottom"; $interviews['TextHAlign']="center"; $interviews['TextOpacity']="100"; $interviews['Text']='INTERVIEWS'; $interviews['TextSize']="regular"; $interviews['ActionType']="reply"; $interviews['ActionBody']="LCInterviews"; $keyboard['keyboard']['Buttons'][]=$interviews; $gallery['Columns']=2; $gallery['Rows']=2; $gallery['TextVAlign']="bottom"; $gallery['TextHAlign']="center"; $gallery['TextOpacity']="100"; $gallery['Text']='GALLERY'; $gallery['TextSize']="regular"; $gallery['ActionType']="reply"; $gallery['ActionBody']="LCGallery"; $keyboard['keyboard']['Buttons'][]=$gallery; $poll['Columns']=2; $poll['Rows']=2; $poll['TextVAlign']="bottom"; $poll['TextHAlign']="center"; $poll['TextOpacity']="100"; $poll['Text']='POLL'; $poll['TextSize']="regular"; $poll['ActionType']="reply"; $poll['ActionBody']="LCPoll"; $keyboard['keyboard']['Buttons'][]=$poll; $potm['Columns']=2; $potm['Rows']=2; $potm['TextVAlign']="bottom"; $potm['TextHAlign']="center"; $potm['TextOpacity']="100"; $potm['Text']='PLAYER OF THE MONTH'; $potm['TextSize']="regular"; $potm['ActionType']="reply"; $potm['ActionBody']="LCPOTM"; $keyboard['keyboard']['Buttons'][]=$potm; $quote['Columns']=2; $quote['Rows']=2; $quote['TextVAlign']="bottom"; $quote['TextHAlign']="center"; $quote['TextOpacity']="100"; $quote['Text']='QUOTE OF THE DAY'; $quote['TextSize']="regular"; $quote['ActionType']="reply"; $quote['ActionBody']="LCQuote"; $keyboard['keyboard']['Buttons'][]=$quote; $website['Columns']=4; $website['Rows']=2; $website['TextVAlign']="bottom"; $website['TextHAlign']="center"; $website['TextOpacity']="100"; $website['Text']='VISITE OUR WEBSITE'; $website['TextSize']="regular"; $website['ActionType']="open-url"; $website['ActionBody']="http://www.letzcricket.com"; $keyboard['keyboard']['Buttons'][]=$website; $data['keyboard']=$keyboard['keyboard']; } ?>
This will show the keyboard menu with custom design.
Now if you tap the News option from the keyboard menu, a message “LCNews” is sent to the webhook. We can easily detect if a user has tapped the News option and fetch the news to send it to the user.
The function to send news list to the user is as follows:
function getNewsList($user_id){ //fetch news array from wherever you like from your database or by calling any api // your news list will be something like this: $newsArray = array( 'title'=>'The Title', 'date'=>'2017-01-29', 'link'=>'http://www.letzcricket.com', 'image'=>' https://pbs.twimg.com/profile_images/776331737538371584/6y1GnWLP.jpg' ); $keyboard_array['Type']='keyboard'; $keyboard_array['BgColor']='#dddddd'; for($i=0;$i<count($newsArray);$i++){ $left['Columns']=2; $left['Rows']=2; $left['ActionType']="open-url"; $left['ActionBody']=$newsArray[$i]['link']; $left['BgColor']="#ffffff"; $left['Image']=$newsArray[$i]['image']; $keyboard_array['Buttons'][]=$left; $right['Columns']=4; $right['Rows']=2; $right['Type']="url"; $right['TextSize']="regular"; $right['TextHAlign']="left"; $right['TextVAlign']="top"; $right['ActionType']="open-url"; $right['ActionBody']=$newsArray[$i]['link']; $right['BgColor']="#f5f5f5"; $keyboard_array['Buttons'][]=$right; } $data['auth_token']='your_auth_token'; $data['receiver']=$user_id; $data['BgColor']="#ffffff"; $data['type']='text'; $data['text']="Here are some news from LetzCricket:"; $data['keyboard']=$keyboard_array; }
This will display list of news back to the user like:
Similarly you can send list of articles, gallery or interviews in the format you like.
Hope you enjoy this complete tutorial. Please do write to us if you face any problem. We might as well continue with the other features if you want. Don’t forget to provide feedback on what you would like us to deliver to you in the continuity of this tutorial.
Can you please share the github repository for the code if possible?
Thanks.