[Twilio] SMS送信状況を監視する #twilio

2019.06.20

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんにちは、中村です。

Twilioを使ったSMS送信は、statusCallbackプロパティにURLを指定することでステータスモニタリングができます。これを利用することで、配信を最適化できます。例えば送信先番号側が受け取れない設定をしていたりする場合に、今後送信をしても同様に送信エラーになってしまう可能性があります。常にモニタリングしておきデータを蓄積する、またエラーが発生していることを管理者に通知するといった機能を実現できるかと思います。

今回は、

  • 送信状況をSlackへ通知

を実装します。

SMS送信状況を監視する

StatusCallback Overview

StatusCallbackを指定した時、Twilioはメッセージ送信のステータスが変わるたびにHTTP POSTでリクエストを送信します。statusには下記が用意されています。

  • queued
  • failed
  • sent
  • delivered
  • undelivered

こちらがStatusCallback URLへのリクエストパラメータ(送信完了)のサンプルです。

{
    "SmsSid": "SMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "SmsStatus": "delivered",
    "MessageStatus": "delivered",
    "To": "+15558675310",
    "MessageSid": "SMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "AccountSid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "From": "+15017122661",
    "ApiVersion": "2010-04-01"
}

これらの情報を元に、機能を実装していきます。

構成

今回はこのような仕組みをCloudformationで作成します。

作ってみた

Slack App

今回は、Slack AppのIncoming Webhookを利用します。下記のpostを参考にWebhookのURLを作成しメモしておいてください。

SNSでSlackにメッセージ送信する #slack

ソースコード

request-promiseでHTTP POSTを利用しています。npmやyarnでインストールしてください。 環境変数はCloudformation作成時に入力するので無視しておいてください。

index.js

  • HTTP POSTでSlackへメッセージを送信
const rp = require('request-promise');

exports.handler = async (event) => {
    console.log(JSON.stringify(event));
    let array = event.body.split('&');
    console.log(array);
    
    let message = 'SMS Information \n\n';
    for (let i=0; i<array.length; i++) {
        message += array[i] + '\n';
    }
    
    console.log(message);

    let result = await notifySlack(message);
    console.log('[Notify Slack]' + result);

    return {
        statusCode: 200
    }
}

async function notifySlack(message) {
    let option = {
        'url': process.env.WEBHOOK_URL,
        'header': {
            'Content-Type': 'application/json'
        },
        'method': 'POST',
        'json': true,
        'body': {
            'text': message
        }
    };

    let result = await rp(option).promise();
    console.log(JSON.stringify(result));

    return true;
}

Cloudformation

githubにYAMLを置いておきました。こちらから参照してください。 今回は、Zip化したソースをLambdaに置いていますが、ご自身で利用するときは下記を編集してください。

56 Code:
57  S3Bucket: "sample-lambda-code-for-blog"
58  S3Key: "twilio-statuscallback.zip"

Cloudformationのダッシュボードでスタックを作成しましょう。DynamoDBのテーブル名とSlack AppでメモしたWebhook URLを入力してください。

IAMリソースの作成について確認が出ますので、チェックして進めてください。

全てのデプロイが終わったら、ローカルからテストしましょう。

const accountSid = 'xxxxxxxxxx'; //Twilioのコンソールにて取得
const authToken = 'xxxxxxxxxx'; //Twilioのコンソールにて取得
const client = require('twilio')(accountSid, authToken);

client.messages
      .create({
         body: 'Hello, World!',
         from: 'xxxxxxxxx', //Twilioで取得した電話番号
         statusCallback: 'https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prd/callback', //先ほど作成したAPI GatewayのURL
         to: 'xxxxxxxx' //送信先電話番号
       })
      .then(message => console.log(message.sid));

Slackでインテグレーションしたチャネルにメッセージがpostされてきます。

まとめ

TwilioのSMS送信のステータス管理をすることでより効率的に送信ができます。このような形でLambdaが呼べるので、他の外部システム呼び出しなど自由に行えます。今回のパターンでは送信がうまくいかなかったユーザーへ電話などSMS以外のアプローチでコンタクトを取るなどをすることでより顧客へのリーチ率を向上できると思います。