浜松のWEBシステム開発・スマートフォンアプリ開発・RTK-GNSS関連の開発はお任せください
株式会社シーポイントラボ
TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:静岡県浜松市中区富塚町1933-1 佐鳴湖パークタウンサウス2F

【Laravel】SMSを送ったり送らずにテストだけしたり

 SMSは二段階認証などでしばしば使われる電話番号を宛先にして送るメッセージです。もともとメッセージとして使う予定のなかった機能であったり、基本的に有料であったりとwebと少し違いがあります。送信者名が11文字までの英数字に限られる点は特に電話らしいです。
 SMSを送る時、なにかしら送る会社に登録してライブラリをダウンロードして、となります。ここでは例にNexmo(現 Vonage)を出します。
 Communications APIs | Vonage
 NexmoはGitHubに複数言語のライブラリを公開しているユーザフレンドリーなサービスです。いくつかフレームワークにも対応しており、Laravelも対応されています。
Nexmo/nexmo-laravel: Add Nexmo functionality such as SMS and voice calling to your Laravel app with this Laravel Service Provider.
 これを使うと次の様にするだけでパパっとSMSを送れます

# NEXMOに登録してキーを.envに設定
NEXMO_KEY=****
NEXMO_SECRET=*****
// /config/nexmo.phpにライブラリが読み込む設定を記述
return [
    'api_key'    => function_exists('env') ? env('NEXMO_KEY', '') : '',
    'api_secret' => function_exists('env') ? env('NEXMO_SECRET', '') : '',
];
// ファサードから実行
<?php

namespace App\Services\SMS;

use Nexmo;
use Nexmo\Message\Message;
use Nexmo\Message\Unicode;

class SmsClient
{
    /**
     * SMSメッセージを送信
     * @param  string                         $tel
     * @param  string                         $from
     * @param  string                         $msg
     * @throws Nexmo\Client\Exception\Request
     * @throws Nexmo\Client\Exception\Server
     * @return Message
     */
    public function send(string $tel, string $from, string $msg): Message
    {
        return Nexmo::message()->send(
            new Unicode(
                preg_replace('/^0/', '81', $tel),// 日本の携帯電話に海外からかける場合の番号に変換
                $from,
                $msg,
            )
        );
    }
}

 電話番号の変換が知らないとちょっとはまりますがそれくらいです。そしてこのコードが動くたびに10円弱かかります。SMSを送る必要のない時にお金を無用に払いたくない気持ちがわいてきます。Laravelでは比較的容易に切り替えができます。
 使うのはサービスコンテナです。Laravelにこのクラスを呼び出すときはこの呼び方で、と指定します。
 サービスコンテナ 6.x Laravel

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register(): void
    {
// 環境変数で明示しない限りは必ずモックのSMSで済ませる。SMSはお金がかかるのでこの形
// モッククラスの各メソッドでは実際に通信せずに通信結果の返り値らしいものを返すだけ
        $this->app->singleton(SmsClient::class, static function () {
            return config('sms.use_actual_sms') === true ? new SmsClient() : new SmsClientMock();
        });
    }
}

 

/**
 * 会員登録用コントローラ
 * Class SignUpController
 */
class SignUpController extends BaseController
{
    use ApiResponseTrait;
    protected $smsClient;

// 呼び出しはサービスコンテナによるクラス名指定のDI
// コントローラがルーティングで呼び出される際はサービスコンテナ経由なので他の指定は不要
    /**
     * RegisterController constructor.
     * @param $smsClientService
     */
    public function __construct(SmsClient $smsClientService)
    {
        $this->smsClient = $smsClientService;
    }
}
  • この記事いいね! (0)