LoginSignup
3
0

はじめに

Vonage は CPaaS(Communications Platform as a Service)のプロバイダーで、SMS送信や音声通話などのコミュニケーション機能をAPI連携で実装できるサービスを提供されています。

本記事では Vonage から提供されている API を用いて SMS送信とパスワードなし認証を実装してみました。

開発環境

Vonage では様々なプログラミング言語の SDK が用意されています。

今回は PHP のフレームワークである Laravel を用いて実装します。

  • PHP v8.2
  • Laravel v10.x

Vonage API を用いた実装方法を確認することが目的であるため、本記事では画面を作成せずに Artisan コマンドを作成し、簡略化を図っております。

Laravel で Vonage を使用するためのパッケージとして、Vonage のサイトで紹介されている vonage/vonage-laravel と Laravelの公式マニュアルで紹介されている laravel/vonage-notification-channel があります。

今回は Laravel の公式マニュアルに記載されている laravel/vonage-notification-channel を使用して進めていきます。

ちなみに、どちらを用いても SMS 送信やパスワードなし認証は実装可能です。

使用準備

Laravel の公式マニュアルに従って、Vonage を使用するための準備を進めていきます。

まずは以下のコマンドを実行して、composer でパッケージをインストールします。

composer require laravel/vonage-notification-channel guzzlehttp/guzzle

インストールが完了したら、.env に Vonage を使用するために必要な情報を記述します。

.env
VONAGE_KEY=[VonageのDashboardで取得したAPI key]
VONAGE_SECRET=[VonageのDashboardで取得したAPI Secret]

これだけで準備完了です。

SMS送信

入力されたメッセージを送信する Artisan コマンドを作成して、SMS送信の動作を確認してみます。

こちらの実装では、Vonage の SMS API を使用しています。

Notifications を使用して送信する方法

Laravel の公式マニュアルには Notifications(通知)の機能を活用してSMS送信を行う方法が記載されています。

まずは VonageNotification.php を作成します。

app\Notifications\VonageNotification.php
class VonageNotification extends Notification
{
    use Queueable;

    private string $message;

    public function __construct(string $message = '')
    {
        $this->message = $message;
    }

    public function via(object $notifiable): array
    {
        return ['vonage'];
    }

    public function toVonage(object $notifiable): VonageMessage
    {
        $from = 'Laravel App';  // 送信先で表示される送信者ID
        return (new VonageMessage)->from($from)->content($this->message);
    }
}

次に、作成した VonageNotification.php を用いてSMS送信を行う Artisan コマンドを作成します。

app\Console\Commands\SendSms.php
class SendSms extends Command
{
    protected $signature = 'send:sms';

    public function handle()
    {
        $message = $this->ask('What message do you want to send?');

        $to = '送信先の電話番号';
        Notification::route('vonage', $to)->notify(new VonageNotification($message));
    }
}

それでは実際にコマンドを実行して、動作確認を行ってみます。$to の値を自分の電話番号に置き換えてから実行してください。

php artisan send:sms

What message do you want to send?:
> Hello world!

スマホで確認したところ、入力したメッセージが届いていました。

また、標準のままだと日本語が文字化けしてしまうため、日本語を送信するためには unicode() を実行する必要があります。

app\Notifications\VonageNotification.php
    public function toVonage(object $notifiable): VonageMessage
    {
-       return (new VonageMessage)->from($from)->content($this->message);
+       return (new VonageMessage)->from($from)->content($this->message)->unicode();       
    }

Vonage ファサードを用いて送信する方法

vonage/vonage-laravelREADME に記載されている方法で、シンプルな記述でSMS送信を行うことができます。

class SendSms extends Command
{
    protected $signature = 'send:sms';

    public function handle()
    {
        $message = $this->ask('What message do you want to send?');

        $to = '送信先の電話番号';
        $from = 'Laravel App';  // 送信先で表示される送信者ID
        Vonage::sms()->send(new SMS($to, $from, $message));
    }
}

パスワードなし認証

SMS/音声/メールを用いたパスワードなし認証を行う Artisan コマンドを作成して、動作を確認してみます。

こちらの機能では、Vonage の Verify API を使用しています。

マニュアルによると、旧バージョンの Verify V1 と現バージョンの Verify V2 が提供されているようです。

Verify V1

まずは旧バージョンを用いて実装してみます。V1 では、SMSと音声(読み上げ)による組み合わせで認証を行うことが可能です。デフォルトのワークフロー(workflow_id = 1)では SMS → 音声 → 音声の流れで認証が行われます。

  1. ワークフロー開始
  2. SMS で PIN コードを送信
    ~ 数分間経過 ~
  3. 電話が掛かってきて PIN コードを読み上げ
    ~ 数分間経過 ~
  4. 電話が掛かってきて PIN コードを読み上げ
    ~ 数分間経過 ~
  5. ワークフロー終了

ちなみにワークフローは 7 種類あり、workflow_id を指定すれば選択可能です。

選択可能なワークフロー
public const WORKFLOW_SMS_TTS_TSS = 1;  // SMS → 音声 → 音声(デフォルト)
public const WORKFLOW_SMS_SMS_TSS = 2;  // SMS → SMS → 音声
public const WORKFLOW_TTS_TSS = 3;      // 音声 → 音声
public const WORKFLOW_SMS_SMS = 4;      // SMS → SMS
public const WORKFLOW_SMS_TTS = 5;      // SMS → 音声
public const WORKFLOW_SMS = 6;          // SMS
public const WORKFLOW_TTS = 7;          // 音声

また、発行する PIN コードの長さは 4桁 または 6桁 を選択可能です。

選択可能な PIN コード桁数
public const PIN_LENGTH_4 = 4;
public const PIN_LENGTH_6 = 6;

それではデフォルトのワークフロー(SMS → 音声 → 音声)でパスワードなし認証を行う Artisan コマンドを作成して実行してみます。ちなみに、PINコードは 6桁 を指定しています。

発行した PIN コードに対しては 3 回までチェックが可能です。3 回失敗すると PIN コードが無効となり、ワークフローが終了します。

app\Console\Commands\VerifyV1.php
class VerifyV1 extends Command
{
    protected $signature = 'verify:v1';

    public function handle()
    {
        $to = '送信先の電話番号';
        $from = 'Sender ID';
        $brand = 'Brand Name';

        // 認証開始
        $workflowId = \Vonage\Verify\Request::WORKFLOW_SMS_TTS_TSS;
        $request = new \Vonage\Verify\Request($to, $brand, $workflowId);
        $request->setCodeLength(\Vonage\Verify\Request::PIN_LENGTH_6);
        $request->setLocale('ja-jp');
        $request->setSenderId($from);
        $response = Vonage::verify()->start($request);

        $failedCount = 0;
        while ($failedCount < 3) {
            $code = $this->ask('Please enter the verification code');
            try {
                // PIN コードのチェック
                $result = Vonage::verify()->check($response->getRequestId(), $code);
                $responseData = $result->getResponseData();
                if ($responseData['status'] === "0") {
                    break;
                }
            } catch (\Vonage\Client\Exception\Exception $e) {
                $failedCount++;
                $this->error($e->getMessage());
            }
        }
        // 結果メッセージの表示
        if ($failedCount < 3) {
            $this->info('Successfully authenticated');
        } else {
            $this->error('Authentication has failed');
        }
    }
}

認証成功の場合

Artisan コマンドを実行すると、スマホに SMS が送信されました。

受信した PIN コードを入力すると、認証成功のメッセージが表示されました。

認証失敗の場合

誤った PIN コードを3回入力して失敗すると、ワークフローが終了となり、認証失敗のメッセージが表示されました。

Verify V2

次に現バージョンを用いて実装してみます。V2 では独自のワークフローを柔軟に組み上げることが可能です。使用できるチャンネルは以下の通りです。

  • SMS
  • 音声
  • WhatsApp
  • WhatsApp Interactive / WhatsApp Codeless
  • 電子メール
  • サイレント認証(SIM を用いた認証)

今回は、SMS → 電子メール → 音声 のワークフローでパスワードなし認証を行う Artisan コマンドを作成して実行してみます。ちなみに、PINコードの桁数も 4桁 ~ 10桁 で柔軟に選択可能となりました。

記事投稿時点では Verify V2 は日本語に対応しておりません。

app\Console\Commands\VerifyV2.php
class VerifyV2 extends Command
{
    protected $signature = 'verify:v2';

    public function handle()
    {
        $toPhoneNumber = '送信先の電話番号';
        $toEmail = '送信先のメールアドレス';
        $brand = 'Laravel App';

        // 認証開始
        $request = new SMSRequest($toPhoneNumber, $brand);
        $request->setLength(10);    // PIN コードの桁数を指定
        $request->setTimeout(60);   // PIN コードの有効期限を指定
        $emailWorkflow = new VerificationWorkflow(VerificationWorkflow::WORKFLOW_EMAIL, $toEmail);
        $request->addWorkflow($emailWorkflow);
        $voiceWorkflow = new VerificationWorkflow(VerificationWorkflow::WORKFLOW_VOICE, $toPhoneNumber);
        $request->addWorkflow($voiceWorkflow);
        $response = Vonage::verify2()->startVerification($request);

        $isAuthenticated = false;
        while (true) {
            $code = $this->ask('Please enter the verification code (Enter "no" to exit)');
            if ($code === 'no') {
                try {
                    // ワークフローのキャンセル
                    Vonage::verify2()->cancelRequest($response['request_id']);
                } catch (\Exception $e) {
                    $this->error($e->getMessage());
                }
                break;
            }
            // PIN コードのチェック
            try {
                $result = Vonage::verify2()->check($response['request_id'], $code);
                if ($result === true) {
                    $isAuthenticated = true;
                    break;
                }
            } catch (\Exception $e) {
                $this->error($e->getMessage());
            }
        }
        // 結果メッセージの表示
        if ($isAuthenticated) {
            $this->info('Successfully authenticated');
        } else {
            $this->error('Authentication has failed');
        }
    }
}

認証成功の場合

Artisan コマンドを実行すると、スマホに SMS が送信されました。

そのまま何もしないで SMS に記載された PIN コードの有効期限が過ぎると、メールが届きました。

そのまま何もしないでメールに記載された PIN コードの有効期限が過ぎると、スマホに着信がありました。読み上げられた PIN コードを入力すると、認証成功のメッセージが表示されました。

認証失敗の場合

誤った PIN コードを入力するとエラーが表示されました。また、"no" と入力するとワークフローが終了となり、認証失敗のメッセージが表示されました。

おわりに

Vonage の SMS API と Verify API を用いて、SMS 送信とパスワードなし認証を実装してみました。

割と簡単に実装することができるので、こういった機能を求められた場合は CPaaS の選択肢の1つとして Vonage を検討してみてはいかがでしょうか?

また、本記事では紹介しきれなかった音声通話(Voice API)などを Laravel(PHP)で実装する場合は、vonage/vonage-php-sdk-coreREADME を参考にされると良いと思います。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0