Facebook Messenger用のチャットボットの開発

現在、チャットメッセンジャーには確かにブームがあります。 インスタントメッセージングプラットフォームは、ボット開発プラットフォームの発売を次々に発表します。

Facebookも例外ではありませんでした。 4月12日、F8会議で、Facebookはメッセンジャー用のボットを開発するためのプラットフォームを導入しました。

この記事では、PHPでFacebook用のチャットボットを開発した経験を共有したいと思います。



一般的な情報



Facebookチャットボットは、ユーザーに代わって公開ページを持つプライベートメッセージに基づいて構築されます。

したがって、ボットを作成するには、APIにアクセスするためのアプリケーション自体と、ユーザーが通信する公開ページを作成する必要があります。



ページ作成



この点について詳しくは述べません。

公開ページを作成し、ボットのメッセンジャーに表示する方法で呼び出して、アイコンをロードします。



アプリケーションを登録および構成する



開発者アカウントでアプリケーションを登録します。

developer.facebook.com/appsにアクセスしてください

[新しいアプリケーションの追加]をクリックし、別の設定を手動で選択します。







次に、フォームに入力します。







アプリケーションを作成したら、左側のメニューで[メッセンジャー]タブを選択してクリックします。

「開始」をクリックします。

まず、ボット用に作成されたページを選択し、トークンをコピーします。 どこかに保存しておくと、さらに便利になります。







次に、着信メッセージを処理するようにwebhookを構成します。

このステップでは、ボットが配置されるサーバーに次のスクリプトをアップロードする必要があります。



<?php $verify_token = ""; // Verify token if (!empty($_REQUEST['hub_mode']) && $_REQUEST['hub_mode'] == 'subscribe' && $_REQUEST['hub_verify_token'] == $verify_token) { echo $_REQUEST['hub_challenge']; }
      
      





$ verify_token変数にテキストを追加する必要があります。

スクリプトがサーバーにアップロードされます。 スクリプトがdomain.com/fbbotで利用できるとしましょう



FBアプリケーションの設定の[メッセンジャー]タブに戻ります。

ブロック「Webhooks」とボタン「Setup Webhooks」を探しています。 クリックしてください。



「逆URL」フィールドで、ボットのアドレスを指定します-domain.com/fbbot

SSL-証明書が必要です。 自己署名証明書は機能しません。



[マーカーの確認]フィールドで、スクリプトの$ verify_token変数で指定されたテキストを指定します。

[サブスクリプションフィールド]フィールドで、Webhookで受信する通知を選択します。



必要なものを選択し、「確認して保存」ボタンを押します。



アプリケーションとページをリンクする



コンソールに入力します:



 curl -ik -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=-token-"
      
      





-token-はページのトークンに置き換えます。



FB Messengerのメッセージタイプ



メッセージは、単なるテキストメッセージまたは構造化テキストのいずれかです。



ボタン(ボタン)



このタイプは、ユーザーの応答を必要とするメッセージの送信を目的としています。

これらは次のようになります。





ボタンには次の2つのタイプがあります。

  1. ボットに返信する
  2. インターネット上のアドレスに行く


重要なポイント:そのようなメッセージの1つには、最大3つのボタンがありますが、より多くのボタンでメッセージを送信しようとしても、受信者に届かないだけです。



要素(ジェネリック)



このタイプは、商品のカードまたは同様の構造を持つ他の要素を送信するためのものです。

各要素には、タイトル、サブタイトル、説明、画像、ボタンを含めることができます。





1つのメッセージには最大10個の要素を含めることができます。 複数のアイテムがある場合、水平スクロールが表示されます。

重要なポイント:そのようなメッセージの1つには、最大3つのボタンがありますが、より多くのボタンでメッセージを送信しようとしても、受信者に届かないだけです。



支払請求書



目的は名前から明らかです。

Facebookはメッセンジャーから完全なストアを作ることにしました。

支払い請求書には、商品、費用、支払い、配送先住所、割引に関する情報が含まれる場合があります。





重要なポイント:アカウント番号は一意でなければなりません。



コードを書く



ボットの作成時点では、GitHubにPHP APIの実装はなかったため、PHP SDKを自分で作成する必要がありました。



composerを使用してFB Messenger APIで動作するようにPHP SDKをインストールします。

 composer require "pimax/fb-messenger-php" "dev-master"
      
      





index.phpファイルを作成します。

 <?php $verify_token = ""; // Verify token $token = ""; // Page token if (file_exists(__DIR__.'/config.php')) { $config = include __DIR__.'/config.php'; $verify_token = $config['verify_token']; $token = $config['token']; } require_once(dirname(__FILE__) . '/vendor/autoload.php'); use pimax\FbBotApp; use pimax\Messages\Message; use pimax\Messages\MessageButton; use pimax\Messages\StructuredMessage; use pimax\Messages\MessageElement; use pimax\Messages\MessageReceiptElement; use pimax\Messages\Address; use pimax\Messages\Summary; use pimax\Messages\Adjustment; $bot = new FbBotApp($token); if (!empty($_REQUEST['hub_mode']) && $_REQUEST['hub_mode'] == 'subscribe' && $_REQUEST['hub_verify_token'] == $verify_token) { // Webhook setup request echo $_REQUEST['hub_challenge']; } else { $data = json_decode(file_get_contents("php://input"), true); if (!empty($data['entry'][0]['messaging'])) { foreach ($data['entry'][0]['messaging'] as $message) { //   //       // ... } } }
      
      





ユーザーからのメッセージの受信に応じて、ユーザーにメッセージを送信しようとしています。

これを行うには、メッセージ受信ブロックで次を追加します。

 $bot->send(new Message($message['sender']['id'], 'Hi there!'));
      
      







確認します。 ボットのメッセンジャーを見つけて、彼にメッセージを送ろうとします。

それに応じて、彼から「こんにちは!」を取得する必要があります。

重要:アプリケーションがモデレーションに合格するまで、ボットはアプリケーションの作成者に対してのみ機能します。



すべてが正常に機能する場合は、先に進みます。



メッセージ受信ブロックで、次を追加します。

 //       if (!empty($message['delivery'])) { continue; } $command = ""; //    ,    if (!empty($message['message'])) { $command = $message['message']['text']; //     ,    } else if (!empty($message['postback'])) { $command = $message['postback']['payload']; } //   switch ($command) { // When bot receive "text" case 'text': $bot->send(new Message($message['sender']['id'], 'This is a simple text message.')); break; // When bot receive "button" case 'button': $bot->send(new StructuredMessage($message['sender']['id'], StructuredMessage::TYPE_BUTTON, [ 'text' => 'Choose category', 'buttons' => [ new MessageButton(MessageButton::TYPE_POSTBACK, 'First button'), new MessageButton(MessageButton::TYPE_POSTBACK, 'Second button'), new MessageButton(MessageButton::TYPE_POSTBACK, 'Third button') ] ] )); break; // When bot receive "generic" case 'generic': $bot->send(new StructuredMessage($message['sender']['id'], StructuredMessage::TYPE_GENERIC, [ 'elements' => [ new MessageElement("First item", "Item description", "", [ new MessageButton(MessageButton::TYPE_POSTBACK, 'First button'), new MessageButton(MessageButton::TYPE_WEB, 'Web link', 'http://facebook.com') ]), new MessageElement("Second item", "Item description", "", [ new MessageButton(MessageButton::TYPE_POSTBACK, 'First button'), new MessageButton(MessageButton::TYPE_POSTBACK, 'Second button') ]), new MessageElement("Third item", "Item description", "", [ new MessageButton(MessageButton::TYPE_POSTBACK, 'First button'), new MessageButton(MessageButton::TYPE_POSTBACK, 'Second button') ]) ] ] )); break; // When bot receive "receipt" case 'receipt': $bot->send(new StructuredMessage($message['sender']['id'], StructuredMessage::TYPE_RECEIPT, [ 'recipient_name' => 'Fox Brown', 'order_number' => rand(10000, 99999), 'currency' => 'USD', 'payment_method' => 'VISA', 'order_url' => 'http://facebook.com', 'timestamp' => time(), 'elements' => [ new MessageReceiptElement("First item", "Item description", "", 1, 300, "USD"), new MessageReceiptElement("Second item", "Item description", "", 2, 200, "USD"), new MessageReceiptElement("Third item", "Item description", "", 3, 1800, "USD"), ], 'address' => new Address([ 'country' => 'US', 'state' => 'CA', 'postal_code' => 94025, 'city' => 'Menlo Park', 'street_1' => '1 Hacker Way', 'street_2' => '' ]), 'summary' => new Summary([ 'subtotal' => 2300, 'shipping_cost' => 150, 'total_tax' => 50, 'total_cost' => 2500, ]), 'adjustments' => [ new Adjustment([ 'name' => 'New Customer Discount', 'amount' => 20 ]), new Adjustment([ 'name' => '$10 Off Coupon', 'amount' => 10 ]) ] ] )); break; // Other message received default: $bot->send(new Message($message['sender']['id'], 'Sorry. I don't understand you.')); }
      
      





ボットにメッセージを送信しようとしています。



すべてが指示に従って完了したら、メッセンジャーですべてのタイプのメッセージを受信する必要があります。



Job4Joyフリーランス交換ボットの実際の例



そのため、私たちの目標は、適切なカテゴリで新しいプロジェクトを発行するボットを実装することです。

picoFeedを使用してRSS経由でデータを受信します-github.com/fguillot/picoFeed



私たちは実施します:

 composer require fguillot/picofeed @stable composer require "pimax/fb-messenger-php" "dev-master"
      
      





次の内容のindex.phpファイルを作成します(コメントはコードに記載されています)。

 <?php $verify_token = ""; // Verify token $token = ""; // Page token $config = []; // config if (file_exists(__DIR__.'/config.php')) { $config = include __DIR__.'/config.php'; $verify_token = $config['verify_token']; $token = $config['token']; } require_once(dirname(__FILE__) . '/vendor/autoload.php'); use PicoFeed\Reader\Reader; use pimax\FbBotApp; use pimax\Messages\Message; use pimax\Messages\MessageButton; use pimax\Messages\StructuredMessage; use pimax\Messages\MessageElement; $bot = new FbBotApp($token); if (!empty($_REQUEST['hub_mode']) && $_REQUEST['hub_mode'] == 'subscribe' && $_REQUEST['hub_verify_token'] == $verify_token) { // Webhook setup request echo $_REQUEST['hub_challenge']; } else { $data = json_decode(file_get_contents("php://input"), true); if (!empty($data['entry'][0]['messaging'])) { foreach ($data['entry'][0]['messaging'] as $message) { if (!empty($data['entry'][0])) { if (!empty($data['entry'][0]['messaging'])) { foreach ($data['entry'][0]['messaging'] as $message) { if (!empty($message['delivery'])) { continue; } $command = ""; if (!empty($message['message'])) { $command = $message['message']['text']; } else if (!empty($message['postback'])) { $command = $message['postback']['payload']; } if (!empty($config['feeds'][$command])) { getFeed($config['feeds'][$command], $bot, $message); } else { sendHelpMessage($bot, $message); } } } } } } } /** * Send Help Message * * @param $bot Bot instance * @param array $message Received message * @return bool */ function sendHelpMessage($bot, $message) { $bot->send(new StructuredMessage($message['sender']['id'], StructuredMessage::TYPE_BUTTON, [ 'text' => 'Choose category', 'buttons' => [ new MessageButton(MessageButton::TYPE_POSTBACK, 'All jobs'), new MessageButton(MessageButton::TYPE_POSTBACK, 'Web Development'), new MessageButton(MessageButton::TYPE_POSTBACK, 'Software Development & IT') ] ] )); $bot->send(new StructuredMessage($message['sender']['id'], StructuredMessage::TYPE_BUTTON, [ 'text' => ' ', 'buttons' => [ new MessageButton(MessageButton::TYPE_POSTBACK, 'Design & Multimedia'), new MessageButton(MessageButton::TYPE_POSTBACK, 'Mobile Application'), new MessageButton(MessageButton::TYPE_POSTBACK, 'Host & Server Management') ] ] )); $bot->send(new StructuredMessage($message['sender']['id'], StructuredMessage::TYPE_BUTTON, [ 'text' => ' ', 'buttons' => [ new MessageButton(MessageButton::TYPE_POSTBACK, 'Writing'), new MessageButton(MessageButton::TYPE_POSTBACK, 'Mobile Application'), new MessageButton(MessageButton::TYPE_POSTBACK, 'Marketing') ] ] )); $bot->send(new StructuredMessage($message['sender']['id'], StructuredMessage::TYPE_BUTTON, [ 'text' => ' ', 'buttons' => [ new MessageButton(MessageButton::TYPE_POSTBACK, 'Business Services'), new MessageButton(MessageButton::TYPE_POSTBACK, 'Translation & Languages') ] ] )); return true; } /** * Get Feed Data * * @param $url Feed url * @param $bot Bot instance * @param $message Received message * @return bool */ function getFeed($url, $bot, $message) { try { $reader = new Reader; $resource = $reader->download($url); $parser = $reader->getParser( $resource->getUrl(), $resource->getContent(), $resource->getEncoding() ); $feed = $parser->execute(); $items = array_reverse($feed->getItems()); if (count($items)) { foreach ($items as $itm) { $url = $itm->getUrl(); $message_text = substr(strip_tags($itm->getContent()), 0, 80); $bot->send(new StructuredMessage($message['sender']['id'], StructuredMessage::TYPE_GENERIC, [ 'elements' => [ new MessageElement($itm->getTitle(), $message_text, '', [ new MessageButton(MessageButton::TYPE_WEB, 'Read more', $url) ]), ] ] )); } } else { $bot->send(new Message($message['sender']['id'], 'Not found a new projects in this section.')); } } catch (Exception $e) { writeToLog($e->getMessage(), 'Exception'); } return true; } /** * Log * * @param mixed $data Data * @param string $title Title * @return bool */ function writeToLog($data, $title = '') { $log = "\n------------------------\n"; $log .= date("Ymd G:i:s") . "\n"; $log .= (strlen($title) > 0 ? $title : 'DEBUG') . "\n"; $log .= print_r($data, 1); $log .= "\n------------------------\n"; file_put_contents(__DIR__ . '/imbot.log', $log, FILE_APPEND); return true; }
      
      







そして、次のようなconfig.phpファイル:

 <?php return [ 'token' => '', //   'verify_token' => '', //   'feeds' => [ 'All jobs' => 'https://job4joy.com/marketplace/rss/', 'Web Development' => 'https://job4joy.com/marketplace/rss/?id=3', 'Software Development & IT' => 'https://job4joy.com/marketplace/rss/?id=5', 'Design & Multimedia' => 'https://job4joy.com/marketplace/rss/?id=2', 'Mobile Application' => 'https://job4joy.com/marketplace/rss/?id=7', 'Host & Server Management' => 'https://job4joy.com/marketplace/rss/?id=6', 'Writing' => 'https://job4joy.com/marketplace/rss/?id=8', 'Customer Service' => 'https://job4joy.com/marketplace/rss/?id=10', 'Marketing' => 'https://job4joy.com/marketplace/rss/?id=11', 'Business Services' => 'https://job4joy.com/marketplace/rss/?id=12', 'Translation & Languages' => 'https://job4joy.com/marketplace/rss/?id=14', ] ];
      
      







すべてのカタログでの公開



ボットはアカウント所有者のみが利用できます。 すべての人がボットにアクセスできるようにするには、App Reviewページでアプリケーションを公開する必要があります。







その後、メッセンジャーのモデレートを要求する必要があります。 これを行うには、タブ-メッセンジャーに移動します。

[メッセンジャーのアプリレビュー]ブロックで、[アクセス許可のリクエスト]ボタンをクリックします。

表示されるウィンドウで、「pages_messaging」を選択し、「アイテムを追加」をクリックします。



今では、節度を待つだけです。



この記事の執筆時点では、最初のボットのモデレートは完了していませんが、申請が提出されてから2営業日以上経過しています。



おわりに



この記事では、Facebook用のチャットボットを作成する基本的な側面を検討しました。

トピックが人気のあることが判明した場合、他の人気のあるインスタントメッセンジャー用のボットを開発した経験について話をする準備ができています。



便利なリンク



  1. FBチャットボット入門-developers.facebook.com/docs/messenger-platform/quickstart
  2. Webフックリファレンス-developers.facebook.com/docs/messenger-platform/webhook-reference
  3. FB Messenger PHP API-github.com/pimax/fb-messenger-php
  4. PHP APIの例-github.com/pimax/fb-messenger-php-example
  5. Job4Joy FBボット-github.com/pimax/job4joy_fb



All Articles