【SendGrid & Twilio】 ショートメッセージを利用してメールを送信してみよう

【SendGrid & Twilio】 ショートメッセージを利用してメールを送信してみよう

SendGridサポートチーム新人の佐々木です。

SendGridについて勉強の毎日ですが、時間を見つけてはTwilioも色々触って遊んでいます。

そこで見つけたのが、SendGridとTwilioを連携することで、ショートメッセージ(SMS)を利用したメール送信が可能になるという記事でした。

これが実現できれば、インターネット回線にアクセスできない環境でも、電話回線を使ってメールを送信できることになります!

今回はこの記事の内容を実際に試して紹介します。次のように、携帯電話からTwilioの電話番号にSMSを送信することで、SendGridが目的の宛先へメールを送ってくれる仕組みです。

ショートメッセージを利用してメールを送信してみよう

本記事では受信側から順番に、以下の流れで説明していきます。

  1. PHPアプリケーションの準備
  2. PHPアプリケーションとngrokの実行
  3. Twilio電話番号のWebhook設定
  4. SMSの送信

必要なものは以下のとおりです。

Twilioアカウントは無料トライアル版で問題ありません。無料トライアル版でもテスト用に無料の電話番号を購入することができます。

なお私は、macOS 10.15、PHP 7.3.11、Composer 2.0.7、ngrok 2.3.35の環境で動作を確認しました。

1: PHPアプリケーションの準備

まずは今回の実装システムの要である、PHPアプリケーションを準備しましょう!

作業フォルダ「sms_email」を作成し、その中に以下の空ファイルを用意してください。

  1. .env
  2. functions.php
  3. webhook.php

各ファイルを簡単に説明すると、1は認証情報などを格納する環境変数を記述するファイル、2はSMSをメールに変換して送信する関数を定義したプログラム、3はTwilioからのPOSTを受け取って2の関数を実行するプログラムとなります。

次に、パッケージ管理ツールのComposerを使ってphpdotenvをインストールします。phpdotenvは環境変数を簡単に扱えるようにするためのライブラリです。

「sms_email」フォルダ下で、次のコマンドを実行してください。

$ composer require vlucas/phpdotenv

同じくComposerを使って、TwilioのPHPライブラリもインストールしてください。

$ composer require twilio/sdk

これでPHPアプリケーションの枠組みができあがりました。

それでは、はじめに用意した3つのファイルの中身を記述していきます。

.envファイルを開いて、以下のようにTwilioやSendGridの認証情報を記述してください。

# TWILIO CREDENTIALS
TWILIO_ACCOUNT_SID="XXXXXX"
TWILIO_AUTH_TOKEN="XXXXXX"
TWILIO_PHONE_NUMBER="+XXXXXX"

# SENDGRID CREDENTIALS
SENDGRID_API_KEY="SG.XXXXXX"

FROM_EMAIL="koutasasaki_smstest@example.com"
FROM_NAME="Kouta Sasaki"

Account IDやAPIキーなどの認証情報をコード内に直接書き込むことはセキュリティ上好ましくないので、環境変数として.envファイル内に記述します。

差出人情報として”FROM_EMAIL”、”FROM_NAME”も忘れずに記載してください。

functions.phpには、次の内容を記述してください。

<?php
require __DIR__ . "/vendor/autoload.php";
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();


/**
 * Sendgrid Send email function
 * @param $subject
 * @param $body
 * @param $to
 * @return int
 * @throws \SendGrid\Mail\TypeException
 */
function sendEmail($subject, $body, $to)
{
    $email = new \SendGrid\Mail\Mail();
    $email->setFrom($_ENV['FROM_EMAIL'],$_ENV['FROM_NAME']);
    $email->setSubject($subject);
    $email->addTo($to);
    $email->addContent("text/plain", $body);
    $email->addContent(
        "text/html",
        $body
    );
    $sendgrid = new \SendGrid($_ENV['SENDGRID_API_KEY']);
    try {
        $response = $sendgrid->send($email);
        return $response->statusCode();
    } catch (Exception $e) {
        echo 'Caught exception: ' . $e->getMessage() . "\n";
    }
}

/**
 * Takes and processes the user's input, sends email.
 * @param $message
 * @return array|string[]
 * @throws \SendGrid\Mail\TypeException
 */
function processAndSendEmail($message)
{
    //TO:sam@mail.io+SUBJ:Hello+MSG: Im sending this email using SMS
    //we split the first input command
    $RawCommand = explode("+", $message);
    if (count($RawCommand) === 3) {
        //extract the useful data by splitting again using :
        $To = explode(":", $RawCommand[0])[1];
        $Subj = explode(":", $RawCommand[1])[1];
        $Msg = explode(":", $RawCommand[2])[1];
        //send email
        $sendEmail = sendEmail($Subj, $Msg, $To);
        //if email send success
        if ($sendEmail === 202) {
            $resp = ['status' => 'success', 'data' => [
                'to' => $To,
                'Subject' => $Subj,
                'Message' => $Msg
            ]];
        } else {
            //if email send fails
            $resp = ['status' => 'failed', 'message' => 'Message could\'nt be sent please try again'];
        }
    } else {
        //if user syntax is incorrect
        $resp = ['status' => 'failed', 'message' => 'Message could\'nt be sent please check your syntax'];
    }

    return $resp;
}

最後にwebhook.phpを開いて、以下の内容を記述してください。

<?php
require __DIR__ . "/vendor/autoload.php";
require_once('functions.php');

use App\Clients;
use Twilio\Rest\Client;

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();


if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $message = $_REQUEST['Body'] ?? '';
    $from = $_REQUEST['From'] ?? '';
    if ($message !== '') {
        $account_sid = $_ENV['TWILIO_ACCOUNT_SID'];
        $auth_token = $_ENV['TWILIO_AUTH_TOKEN'];
        $twilio_number = $_ENV['TWILIO_PHONE_NUMBER'];
        $client = new Client($account_sid, $auth_token);
        $response = processAndSendEmail($message);
        $text = '';
        if ($response['status'] === 'success') {
            $text = 'Message was sent to ' . $response['data']['to'] . ' Successfully';
        } else {
            $text = $response['message'];
        }

        $client->messages->create(
            $from,
            array(
                'from' => $twilio_number,
                'body' => $text
            )
        );
    }
}

これで、PHPアプリケーションが完成です!

※オリジナル記事ではphpdotenvのgetenvを利用していますが、現在は推奨されていないため、以下のように書き換えました。
(参考:https://github.com/vlucas/phpdotenv#usage

$dotenv = Dotenv\Dotenv::create(__DIR__);
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__); に変更。
・環境変数を参照するメソッドは、getenv(‘’)でなく、$_ENV[‘’] に変更。

2: PHPアプリケーションとngrokの実行

今回準備したPHPアプリケーションはローカル環境で実行するので、Twilioと連携するためには外部ネットワークと接続する必要があります。

そこで、手軽にローカル環境を外部に公開できるngrokを使います。

まずは、ローカルホストのポート3000番を指定して、PHPのアプリケーションを実行します。

$ php -S localhost:3000

次に、ngrokで次のコマンドを実行して、ポート3000番を外部に公開します。

$ ngrok http 3000

以下のような画面が表示されれば成功です。

PHPアプリケーションとngrokの実行

これで、ngrokが作成したエンドポイント「http://xxxxxxx.ngrok.io」を介して、ローカルホストのポート3000番で待機するPHPアプリケーションにアクセスできる状態になりました!

3: Twilio電話番号のWebhook設定

最後に、Twilio電話番号で受信したSMSの内容をngrokで受け取れるようにするため、Webhookの設定を行いましょう。

まずはTwilioのダッシュボードから、電話番号の設定画面を開きます。

電話番号の設定画面

画面左の「・・・」が円で囲われたアイコンを選択するとメニューが展開されるので、「Phone Numbers」を選択してください。

「Phone Numbers」を選択

購入した電話番号が表示された画面に移動するので、電話番号「+X XXX XXX XXXX」をクリックしてください。

すると、電話番号の情報やイベントログの閲覧、各種設定を行う画面に遷移します。

各種設定

「Messaging」項目から「A MESSEAGE COMES IN」と書かれている箇所を探してください。

ここで、メッセージの受信をトリガーにどんなアクションを実行するか、選択できます。

画面のように「Webhook」を選び、WebhookのPOST先として、先ほど設定したngrokのアドレスを指定します。

「Webhook」を選択

このとき、ngrokのアドレス末尾に/webhook.phpをつけることを忘れないようにしましょう。(http://xxxxxxxx.ngrok.io/webhook.php のようになります。)

最後に「Save」を押下し、画面上部に「Number was successfully updated.」と表示されれば、設定終了です。

これで、Twilioの電話番号がSMSメッセージを受け付けると、HTTP POSTがngrok経由でwebhook.phpに送られるようになりました!

4: SMSを送信してみよう

それでは、いよいよ実際にSMSを送信してみましょう!

SMS画面を開いて、Twilioで用意した電話番号宛に、次のフォーマットでメッセージを送ってみてください!

TO:<宛先のアドレス>+SUBJ:<メールのタイトル>+MSG:<メールの本文>

SMS画面

SMSを送信したあと、ngrokとPHPアプリケーションを動作させているターミナル上でそれぞれ、「200 OK」「200」と表示されることを確認してください。

「200 OK」「200」と表示

「200」

このように表示されていれば、SMSを受信したTwilio電話番号からのWebhookを、ngrokで受信して、PHPアプリケーションによる処理が正しく完了しています。

SMSでも以下のように送信完了メッセージを受けとったら、メール送信成功です!

送信完了メッセージ

メールボックスを確認してみると…

メールボックス

確かにSMSで送ったメッセージが届いていました!

おわりに

今回は携帯電話からSMSを発信することで、目的の宛先へメールを送信する流れを体験してみました。記事では非常にシンプルな例を扱いましたが、アプリケーションを拡張すれば、複数宛先への一斉送信など、より発展的な活用をすることも可能です。

Twilioは、SendGridに限らず様々なコミュニケーションチャネルとの連携が、簡単に行えるのが魅力だと感じています。これからも色々な機能を触ってみて、興味深い活用例を見つけたらブログで紹介していきたいと思います!

SendGridとTwilioの連携例として、前回のブログ記事ではメールからSMSへ転送する方法についても取り上げているので、是非こちらも見てみてください。

メールを成功の原動力に

開発者にもマーケターにも信頼されているメールサービスを利用して、
時間の節約、スケーラビリティ、メール配信に関する専門知識を手に入れましょう。