Event Streamsを用いてTwilioのログをNode.jsとExpressサーバーアプリケーションで処理する方法

September 08, 2021
執筆者
レビュー担当者

event-streams-nodejs-express-jp

Event Streamsは執筆時点でPublic Betaとなるため、今後設定方法や仕様が変更される可能性があります。

Twilioは音声通話、SMS、ビデオなどさまざまなコミュニケーションAPIを提供しています。それぞれのAPIの実行結果はstatusCallback、あるいは類似したプロパティにコールバックURLを設定することでアプリケーション側にログを通知し、分析やエラー処理を行えるようになっています。

例 - Programmable SMS API(statusCallbackで検索)

このコールバックは簡単に利用できますが、複数のTwilioサービスを利用する場合はサービスごとあるいはリクエストごとに指定する必要があります。さらに、ログのフォーマットもサービスごとに異なる場合があります。

Event Streamsは各サービスのログをCloudEventsの仕様に沿って正規化、集約し、指定した宛先に配信します。そのためサービスごとに複数のコールバックを指定する必要がなく、またログの処理やエラーハンドリングをより簡単に実装できます。今回はこのEvent StreamsをNode.js/Expressサーバーアプリケーションで利用する方法を紹介します。また、Event Streamsの特長についてはこちらの記事で取り上げられていますのでぜひご覧ください。

FAQにも記載されていますが、Event Streamsは既存のステータスコールバックを置き換えるものではありません。今後も引き続き利用できます。

前提条件

このチュートリアルを試すには次の環境が必要になります。

イベントデータを受け取るExpressサーバーアプリケーションを構築

まず、イベントデータを受け取るExpressアプリケーションを作成します。

コンソールを開き、以下のコマンドをそれぞれ実行します。

mkdir event-stream-destination
cd event-stream-destination
npm init --y

続けてExpressパッケージをインストールします。

npm i express

この状態でindex.jsファイルを作成し、次のコードを追加します。

const express = require('express');

// expressサーバーアプリケーションを初期化
const app = new express();

// JSONリクエストを処理するためのミドルウェアを追加
app.use(express.json());

// /eventに対しての全てのリクエストをハンドル
app.all('/events', (req, res) => {
    const events = req.body;
    console.log(events);
    res.sendStatus(200);
});

// Expressサーバーアプリケーションとngrokを起動し、外部からアクセス可能にする

app.listen(3000, () => console.log('Listening Port 3000...'));

index.jsではExpressサーバーを初期化し、/eventsルートを実装しています。/eventsルートではリクエストのbodyをコンソールに出力し、ステータスコード200を返します。

そしてこのコードの最終行では、ローカルホストのポート3000番でリクエストを待つように実装しています。

続いてターミナルを開きExpressサーバーアプリケーションを起動します。

node index.js

この状態で http://localhost:3000/events をブラウザーで開き、OKと出力されることを確認します。

localshost-ok

Event StreamsからこのExpressサーバーアプリケーションにイベントを送信するには外部からアクセスできる必要があります。そのため別のターミナルを開き、下記のngrokコマンドを実行し3000番のポートを外部に公開します。

$ ngrok http 3000

ngrok

ランダムに生成されたURL/events(画像の例ではhttps://49149f5418d7.ngrok.io/events)をブラウザーで開き、先ほどと同じ結果が得られることを確認しましょう。このURLはEvent Streamsの設定に必要になります。ngrokを再起動するとURLが変更されてしまうため、以後、チュートリアルを完了するまで ngrokを起動したまま にしておいてください。

新しいコンソールでEvent Streamsを設定

Event Streamsを利用するためにはSinkと呼ばれるイベントの配信先を作成する必要があります。これまではTwilio CLIを用いて各種設定を行う必要がありましたが、先日、新しいコンソールから直感的に設定できるようになりました。

Event Streamsコンソールは新しいコンソールのみで利用できます。既存コンソールを利用している場合は、こちらのドキュメントを参考に引き続きTwilio CLIを用いて設定してください。

Twilioコンソールから、Event Streamsを選択します。

new console - event streams

管理画面でCreate new sinkボタンをクリックし、新しいSinkを作成します。

Sink - Create

新規作成画面では、Sinkの説明とSink Typeを指定します。今回のチュートリアルではそれぞれSink tutorialWebhookを設定・選択します。

sink type

Next stepボタンをクリックするとWebhook Sinkの設定画面に遷移します。この画面ではそれぞれ次の設定を行えます。

項目名

説明

設定値

Destination

イベントの配信先

先ほどngrokによって生成されたURL/events

Method

Destinationにイベントを送信する際のリクエストメソッド

POST

Batch

イベントをまとめて (Batchで) 送信するかどうか

True

sink - destination

項目を入力し、FinishボタンをクリックするとSinkが作成されます。ここでダイアログが表示され、Validate sink connectionをクリックするとSinkへの接続をテストできます。

sink has been created

配信先との接続を確認

接続確認ページではテストイベントを発行し、指定したDestinationにイベントが送信されているかどうかを確認できます。

sink validation

Send test eventボタンをクリックするとテストイベントが発行されます。実行中のExpressサーバーアプリケーションでテストイベントが出力されていることを確認してください。

test event

dataに含まれるtest_idの値を先ほどの接続確認ページのTest event IDフィールドに入力し、Validate connectionボタンをクリックすると検証が行われます。test_idが正しいものである場合は接続確認が完了します。

validated connection

webhookを利用する場合、この接続確認は必須ではありませんが、確認しておくに越したことはないでしょう。

続けてCreate subscriptionボタンをクリックしイベントの購読設定を行います。

イベントの購読

Subscription descriptionフィールドに任意の名前を入力し、次にどのイベントを購読するかを設定します。

2021年9月時点でEvent Streamsはこちらのイベントに対応しています。今回はSMSを送信するイベントを取得してみましょう。MessagingMessageについてApply schema version to all項目を1と設定します。

apply all

Create Subscriptionボタンを押して設定を反映します。

これでコンソール側の設定が完了しました。

SMSを送信し、Event Streamsをテスト!

ここからはSMSを送信しイベントが正しくExpressサーバーアプリケーションに配信されていることを確認します。

まずは、電話番号コンソールからSMS送信が可能な米国電話番号を購入します。すでに電話番号を持っている場合は一覧が表示されます

Phone numbers

現在コンソールから購入できる日本の番号からはSMSを送信できません。日本の電話番号でSMSを送信したい場合は営業部まで問い合わせてください。

SMS送信可能な番号を保有していない場合は、Buy a numberボタンをクリックします。

米国を選択し、番号一覧からSMSを提供している番号を一つ購入します。

US numbers

購入した番号を控えておきます。

Webアプリケーションの開発環境へと戻り、twilio-nodeヘルパーライブラリーをプロジェクトに追加します。

npm i twilio

パッケージのインストール後、sendSMS.jsファイルを作成し次のコードを追加します。

const twilio = require('twilio');

// Twilioコンソールから資格情報を取得
const account_sid = '<Account Sid>';
const auth_token = '<Auth Token>';

// 購入したTwilio番号 E.164フォーマット
const twilio_number = '+1xxxxxxxxxxx';

// SMS送信先の電話番号 E.164フォーマット
const my_number = '+81xxxxxxxxxx';

//Twilioクライアントを初期化
const client = new twilio(account_sid, auth_token);

//SMSを送信
client.messages.create({
    from: twilio_number,
    to: my_number,
    body: 'Event Streamsのテストメッセージです。'
}).then(message => console.log(message.sid));

account_sidauth_tokenに入力する値はTwilioコンソールで確認できます。

credentials

サンプルコードでは変数に直接Account SIDとAuth Tokenを記載していますが、実開発では直接指定せず環境変数を利用してください。Node.jsで環境変数を利用する方法についてはこちらの記事を参照してください。

続けてtwilio_numberには先ほど購入したSMS送信可能なTwilio番号を、my_numberには検証済みの送信先電話番号をそれぞれE.164フォーマットで入力します。

それぞれの変数に値を入力した後、新しいターミナルを開き次のコマンドを実行します。

node sendSMS.js

SMSの送信に合わせてExpressサーバーアプリケーションに各種イベントが通知されます。出力を確認しましょう。下記の画像はいくつかの情報を白塗りしていますが、com.twilio.messaging.message.sentcom.twilio.messaging.message.delivered イベントが配信されていることを確認できます。

sms events

まとめ

今回はSMSでEvent Streamsの動作を確認しましたが、StudioやTaskRouterなどのイベント購読を有効化すると同じエンドポイントで複数のTwilioサービスのイベントを処理できます。このようにEvent Streamsを利用すると複数のTwilioサービスのイベントログを一ヵ所に集約でき、より簡単に分析やアラートの発報が可能となります。ぜひ、お試しください。

この記事への質問についてはこちらまでお願いします。

  • dikehara [@] twilio.com
  • Twitter:@Neri78