https://d226lax1qjow5r.cloudfront.net/blog/blogposts/build-turkey-timer-laravel-facebook-messenger-dr/Blog_Timer-Lavavel-FB_1200x600.png

Laravel、Facebook Messenger、Vonageで七面鳥タイマーを作る

最終更新日 May 21, 2021

所要時間:1 分

今年は義母に頼まれて、家族のためにクリスマスディナーを作るのを手伝っている。とても楽しみなのだが、新しい子犬と幼い甥っ子がいるので、気が散ってポテトをオーブンに入れるタイミングを忘れてしまうのが目に見えている!

これを助けるために、レシピのコレクションを管理する小さなLaravelアプリケーションを書くことにした。WhatsApp、Facebook、Viber経由でレシピの名前をメッセージで送ると、各レシピに必要なステップのリストを取得し、実行時に次のステップを送信してくれる。各レシピに必要なステップのリストを取得し、実行時間になると次のステップを送信してくれる。キッチンのすべてが管理され、人の手が必要なときには通知されるので安心だ!

これがそのアプリケーションだ:

Turkey Timer DemoTurkey Timer Demo

この投稿ではFacebookを使いますが、WhatsAppやViberにも簡単に拡張できます。 Vonage laravel-notification パッケージ.

LaravelとVonageプロジェクトのセットアップ

このプロジェクトに必要なセットアップはかなり多いので、新年までこれを読むのに時間がかかるのを避けるために、この投稿ではVonage固有のコードに直接ジャンプした。もし興味があれば、アプリケーションをセットアップするために私が行ったプロセスを以下に示す(各項目は、作業についてのより長い説明を含むコミットにリンクしている):

ユーザー管理、レシピとそれに関連する時間を表示する機能を持つ、とてもシンプルなアプリケーションです。スタンドアロンのアプリケーションで、今のところVonageには依存していません。しかし、Facebookページへのメッセージを受信できるようにしたいので、もう少し設定が必要です。アプリケーションを動作させるには、次のことが必要です。 FacebookページをVonageアカウントにリンクする。, アプリケーションの作成と設定Vonageがウェブフック・リクエストの送信先を知っているようにする。 ngrokを使ってアプリケーションをインターネットに公開する。を使ってインターネットに公開する。

これを自分で作ってみたい方は VonageコミュニティSlackワークスペースに参加してください。

この投稿の続きでは、ユーザーがレシピ名でメッセージを送信し、アプリケーションが適切なタイミングで実行が必要なアクションを応答する機能を追加します。

Facebookのインバウンドメッセージへの対応

1つはユーザーからのメッセージを受信したときに呼び出されるもので、もう1つはVonageからのステータス更新を受信するものです。私は /webhooks/inbound-messageメッセージの受信には /webhooks/message-statusをステータスの更新用に選びました。Vonageはアプリケーションの外部からリクエストを送信するので、私は CSRFのチェックを無効にしなければなりません。 app/Http/Middleware/VerifyCsrfToken.php:

protected $except = [
    '/webhooks/*'
];

Vonageが私のウェブフックにアクセスできるようになったので、今度はそれらのインバウンドリクエストを処理する番だ。私は make:controllerを使って新しい WebhooksControllerを生成し routes/web.phpを生成して、上記のURLをこのコントローラに向けるようにしました:

Route::post('/webhooks/inbound-message', 'WebhooksController@inboundMessage')->name('webhooks.inbound');
Route::post('/webhooks/message-status', 'WebhooksController@messageStatus')->name('webhooks.status');

最後にすべきことは WebhooksController.今のところ、Vonageが送るリクエストのフォーマットを見ることができるように、インバウンドリクエストをロギングしている:

namespace App\Http\Controllers;
use Illuminate\Http\Request;

class WebhooksController extends Controller
{
    public function inboundMessage(Request $request) {
        \Log::debug('Inbound Message', $request->all());
    }

    public function messageStatus(Request $request) {
        \Log::debug('Message Status', $request->all());
    }
}

これらの変更を行った後、個人アカウントからFacebookページにメッセージを送ると、Laravelのログファイルに以下のようなエントリーが表示されました:

{
  "message_uuid": "f4fcc665-7b71-4291-a079-505154e28c36",
  "to": {
    "id": "987654210987654",
    "type": "messenger"
  },
  "from": {
    "id": "123456789012345",
    "type": "messenger"
  },
  "timestamp": "2018-12-12T11:36:44.663Z",
  "direction": "inbound",
  "message": {
    "content": {
      "type": "text",
      "text": "Christmas Dinner"
    }
  }
}

素晴らしい!ユーザーは私にメッセージを送り、私のアプリケーションはそれを意図したとおりに受け取った。メッセージを受け取れるようになったので、次は返事を送り返す番です。

このセクションで行われた変更は このコミット

Laravel通知の作成

正しい時間にユーザーに更新を送り返すために、Laravelのキューシステムの delay機能を使います。その前に、Laravelの queue機能を有効にする必要があります。ここでは databaseドライバを使用することにします。特に高スループットになるわけではありませんし、データベースを使用することで、Redisなどの依存関係を追加する必要がなくなります。この設定は .envファイルで設定できます:

QUEUE_CONNECTION=database

これが完了したら、ジョブを保存するテーブルを作成した。 php artisan queue:table && php artisan migrate.

すべての管理作業が終わったので、いよいよ通知を作り始めよう。条件がトリガーされるたびに簡単な文章を送る必要がある。メッセージごとに1つのnotificationを作成することもできましたが、スピードのために、次の内容の文字列を app/Notifications/FreeText.phpに以下の内容の文字列を受け取ります:

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;

class FreeText extends Notification implements ShouldQueue
{
    use Queueable, ShouldQueue;

    protected $text;
    protected $channel;

    public function __construct($text, $channel)
    {
        $this->text = $text;
        $this->channel = $channel;
    }

    public function via($notifiable)
    {
        return [];
    }
}

これは通知を定義するものですが、私たちのアプリケーションはまだそれを送信する方法を知りません。私たちは viaメソッドを実装し to*メソッドを実装する必要があります。これらの通知を送信するために パッケージを使うことにします。パッケージを使うことにします:

  • toNexmoWhatsApp

  • toNexmoFacebook

  • toNexmoViberServiceMessage

  • toNexmoSms

を実装し toNexmoFacebookを実装します:

public function toNexmoFacebook($notifiable)
{
    return (new \Nexmo\Notifications\Message\Text)
        ->content($this->text);
}

これらのメソッドを実装するだけでなく、メッセージをどのようにルーティングするかをLaravelに伝える必要があります。通常は $notifiableエンティティを使用します。今回は、メッセージを受信したチャンネルで返信することにします。このチャンネルはnotificationのコンストラクタに渡されます。これが私の viaメソッドはこのようになります:

public function via($notifiable)
{
    return [$this->channel];
}

Messengerで送信するために、Vonageの認証情報と設定を提供することです。同じことをしたい場合は アプリケーションを作成するを作成し、以下を .envファイルに追加します:

NEXMO_APPLICATION_ID="YOUR_APPLICATION_ID"
NEXMO_PRIVATE_KEY=./private.key
NEXMO_FROM_MESSENGER="FACEBOOK_PAGE_ID"

このセクションで行われた変更は このコミット

フェイスブックにアップデートを送信する

さて、すべての大変な作業を終えたので、最後にすることは、レシピを調理するために実行する必要があるアクションを送信することである。

ユーザーからメッセージを受信したら、そのメッセージが送信されたチャンネルと、メッセージを送信したユーザーのIDを抽出する必要がある。これができたら、新しい オンデマンド通知を作成することができます:

// The incoming message contains the platform + contact details that
// we need to reply with, so configure a notification route with those
// details
$from = $request->input('from');

// The Vonage Messages API returns messenger, but our channel names are all prefixed with nexmo-
$channel = 'nexmo-' . $from['type'];
$sender = Notification::route($channel, $from['id']);

この時点でユーザーに好きなテキストを送ることができます。最初にチェックしなければならないのは、送られてきたメッセージにレシピ名が含まれているかどうかです。もし含まれていなければ、レシピが見つからなかったというメッセージを送ります。

// Try and find the recipe name that was sent to us
$recipeName = $request->input('message.content.text');
$recipe = \App\Recipe::where('name', $recipeName)->first();
if (!$recipe) {
    $sender->notify(new FreeText(
        "I couldn't find that recipe",
        $channel
    ));
    return;
}

このコードのブロックを乗り越えれば、有効なレシピとなり、通知をスケジュールする時が来たのです!レシピの各タイミングセットには actionstart_timeがあります。幸いなことに、Laravelでは通知を今から何秒遅らせるかを指定することができます。

メソッドの最後の部分は inboundMessageメソッドの最後の部分は timingを繰り返し、新しい通知をスケジュールする必要があります:

foreach ($recipe->timings()->get() as $t) {
    $sender->notify((new FreeText(
        $t->action,
        $channel
    ))->delay($t->start_time));
}

これをまとめると inboundMessageメソッドは次のようになる:

public function inboundMessage(Request $request) {
    \Log::debug('Inbound Message', $request->all());

    $from = $request->input('from');

    // The Vonage API returns messenger, but our channel names are all prefixed with nexmo-
    $channel = 'nexmo-' . $from['type'];
    $sender = Notification::route($channel, $from['id']);

    // Try and find the recipe name that was sent to us
    $recipeName = $request->input('message.content.text');
    $recipe = \App\Recipe::where('name', $recipeName)->first();
    if (!$recipe) {
        $sender->notify(new FreeText(
            "I couldn't find that recipe",
            $channel
        ));
        return;
    }

    // If we get this far, we have a recipe! Time to schedule some notifications
    foreach ($recipe->timings()->get() as $t) {
        $sender->notify((new FreeText(
            $t->action,
            $channel
        ))->delay($t->start_time));
    }
}

このセクションで行われた変更は このコミット

アプリケーションの実行

すべてのビルドが終わったので、いよいよ最終的なアプリケーションを実行する!動作させるために必要なことの簡単なチェックリストです:

  1. 走る php artisan serve

  2. 確認 ngrok http 8000Vonageが私のアプリケーションに電話をかけることができるようにする。

  3. 実行 php artisan queue:workデータベースに挿入されるジョブを監視するため

  4. 私のフェイスブックページにアクセスして、レシピを送ってください(この場合は! Christmas Dinner!)

  5. やるべきことがあればメッセージが届くと思いながら、座ってリラックスする。

この記事のプロジェクト全体をご覧になりたい方は Githubにあります。.もし自分で実行したいのであれば、次のことが必要だ:

  1. FacebookページをVonageにリンクする

  2. 新しいVonageアプリケーションを作成し、ページをそのアプリケーションに関連付けます。

  3. ウェブフックの設定

  4. リポジトリをクローンする

  5. 更新する .envあなたのVonage認証情報で

  6. 走る composer install

  7. 走る php artisan migrate && php artisan db:seed

  8. 走る php artisan servephp artisan queue:workを別々の端末で実行する

  9. Facebookページにメッセージを送る

次はどこだ?

いやあ、楽しかった!を試せただけでなく Vonage Messages APIを試すことができただけでなく、Laravelの通知について多くのことを学ぶことができました。 新しいチャンネル).おまけに、クリスマスに必要なことをリマインドしてくれる小さなヘルパーまでついてくる!

シェア:

https://a.storyblok.com/f/270183/384x384/1c8825919c/mheap.png
Michael Heapヴォネージの卒業生

マイケルはポリグロット・ソフトウェア・エンジニアであり、システムの複雑性を軽減し、より予測可能なものにすることに尽力している。さまざまな言語やツールを使いこなし、ユーザーグループやカンファレンスで世界中の聴衆と技術的な専門知識を共有している。日々、マイケルはVonageの元開発者支持者であり、あらゆるテクノロジーについて学び、教え、書くことに時間を費やしている。