【2024年12月最新版】AWS SNS / End User Messagingで、送信者IDを指定してSMSを送る方法

# はじめに

### この記事で分かること

- AWS SNSを利用して、送信者IDを指定して日本国内でSMS送信する方法
  - マネジメントコンソールからSMS送信する方法
  - SDK for PHPでSMS送信する場合のコード例
- SNSでSMSを送信する際の注意点について（利用制限等）
- SMS配信ログの確認方法


### なぜこの記事を書くことにしたのか
AWS SNSを使ってSMSを送る方法を紹介した記事は既にいくつかありましたが、
2024年9月25日に発表されたSNSとEnd User Messagingの統合により手順が少し変更されました。
新しい手順について具体的に説明している記事を見つからなかったので、自分で調べた内容をまとめることにしました。

参考：
- [AWS公式ニュースリリース: Amazon SNSが、AWS End User Messaging経由でのSMSテキストメッセージの配信を開始](https://aws.amazon.com/jp/about-aws/whats-new/2024/09/amazon-sns-delivers-sms-text-messages-aws-end-user-messaging/
)
### AWS End User Messagingとは？
SNSとEnd User Messagingが統合されたと先に説明しましたが、このEnd User Messagingは、SMS,MMS,および音声通知（テキストから音声への変換）に関する機能を提供するサービスです。

元々AWSには、Amazon Pinpointというマーケティング向けのメッセージングサービスがありました。
このPinpointの機能のうち、上記の機能が新しくAWS End User Messagingという名称で呼ばれるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/c086cd3c-22c9-03be-2347-af3ec5cff910.png)

参考：
- [AWS公式ドキュメント：AWS End User Messaging](https://docs.aws.amazon.com/ja_jp/sms-voice/latest/userguide/what-is-service.html)
- [AWS公式ニュースリリース: AWS End User Messaging のご紹介](https://aws.amazon.com/jp/about-aws/whats-new/2024/07/aws-end-user-messaging/)


# SMS送信の手順

### 手順1. AWSコンソールにログインし、SNSの画面を開く

マネジメントコンソールにログインし、東京リージョン（ap-northeast-1）を選択します。
続いてSNSのサービス画面に移動します。
左側のサイドバーのメニューの「Mobole」>「テキストメッセージング（SMS）」をクリックすると以下のような画面に遷移します。

初期状態だと、SNSでのSMS送信機能はサンドボックス状態になっており
事前に登録した電話番号にしかSMSを配信できないようなっています。
（サンドボックスの解除方法は後述しています）

SMSをテスト配信するために、右下のオレンジ色の「電話番号を追加」ボタンをクリックして電話番号を登録していきましょう。

![スクリーンショット 2024-12-21 22.48.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/1f29d7a8-b6d8-a032-3671-f04e30d37cea.png)


### 手順2. SMS送信先の電話番号を登録する（サンドボックス）
今回は日本国内でSMS送信をするので、国と言語は日本を選択します。

なお、電話番号は国際通信に使用される標準の電話番号体系であるE.164形式で指定します。
例えば日本国内の電話番号`090-0000-0000`に送信したい場合は
最初の0を日本の国際電話コード`+81`に置き換えて
`+81 00 0000 0000`で指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/da0d5092-e957-4889-b160-40be127ed3f4.png)

右下の「電話番号を追加」ボタンをクリックすると、検証コードの入力を求められます。
指定した電話番号に検証メッセージのSMSが届くので、届いた検証コードを入力すればサンドボックスの電話番号の検証が完了します。

### 手順3. 送信者IDを登録する

SMSの受信者から見た送信者情報の表記として、日本では
- **送信者ID(Sender IDs)**：送信者を識別する英数字名
- **ロングコード**：受取人が居住する国または地域の番号形式を使用する11桁の電話番号
- **ショートコード**：5~6桁の通常の電話番号よりも短い数字列
等を選択できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/c46ded8c-9a25-62a1-6c51-ad7385ce7443.png)

ロングコードやショートコードは申請や料金がかかるため今回は`送信者ID`を登録していきます。
日本国内でのSMS送信の場合、送信者IDの登録には申請も料金も必要ありません。

※ ここで送信者IDを登録しておかないと、SMS送信後に受信者から見たら送信元が「NOTICE」と表示されます。

**参考：**
- [SMSでサポートされている国とリージョン](https://docs.aws.amazon.com/ja_jp/sms-voice/latest/userguide/phone-numbers-sms-by-country.html)
- [電話番号または送信者IDの選択](https://docs.aws.amazon.com/ja_jp/sms-voice/latest/userguide/phone-number-types.html)

まずSNSのコンソール画面から、「発信元ID」のボタンをクリックします。
![スクリーンショット 2024-12-22 11.11.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/a8b3a2c2-f31c-eb84-0569-5054d3a9190d.png)

するとEnd User Messagingのコンソールに移動するので、
左側のサイドバーから「設定」>「送信者ID」を選択し、右上の「リクエスト発信者」ボタンをクリックします。

![スクリーンショット 2024-12-22 11.13.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/1aa2a38d-c182-761d-8109-569d8bd09a8f.png)

#### ステップ1：国を選択
Japan(JP)を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/226040fd-6710-7b17-4b28-994818dc0434.png)

#### ステップ２：ユースケースを定義
今回は以下で選択
- 電話番号：テキストメッセージ（SMS）
- 1 か月あたりの推定メッセージ量 - オプション：5000件未満
- 会社の本社：ローカル
- 双方向SMSメッセージング：いいえ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/1c795819-691b-75a8-29b9-70a7f7abccd7.png)

#### ステップ３：発信者タイプを選択
「発信者タイプ」は`送信者ID`にチェックを入れます。
「送信者ID」の欄は任意のものを入力してください。ここでは`TEST-SMS`で設定していきます。

なお、送信者IDには以下の指定があります。
> 送信者IDは、文字(A～Z)、数字(0～9)、またはハイフン (-) を含む 1～11 文字の英数字でなければなりません。送信者 ID は文字で始まる必要があります。

ここで小文字（a~z）でも入力できはしたのですが、大文字(A~Z)しか指定できないためか登録後は大文字の送信者IDに直されていました。

最後に、「リソースポリシー」の欄はデフォルト値のままにしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/92d33b16-1372-55da-803a-429aeee6a7ee.png)

#### ステップ４：確認とリクエスト 

最後に確認画面が表示されるので、問題なければ右下の「リクエスト」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/1867e306-95d0-19fd-4516-b335f2029519.png)

これで、送信者IDの登録は完了です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/00be3bec-5e35-c5ab-73ff-049cf12a2d9d.png)

### 手順4. コンソールからSMSを送信してみる

SNSのコンソールに戻り、右上の「テキストメッセージの発行」ボタンをクリックすると「SMSメッセージの発行」画面が開きます。
![スクリーンショット 2024-12-22 11.55.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/f23e36c5-25c5-7339-66c3-d597917750a0.png)

#### ステップ１：メッセージタイプの指定 
「メッセージのタイプ」には
- プロモーション（重要度が低いメッセージ用）
- トランザクション（重要度が高いメッセージ用）
の２つが選択できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/b19e4599-d2d7-c25e-4c70-5b2fcc7cb12a.png)

東京リージョンで送信者IDを指定してSMS送信する場合は
「トランザクション」を選択しないとエラーになるようであるため
ここでは「トランザクション」を選択します。
ちなみに、ログ設定をしている場合以下のようなエラーログがCloudWatch Logsに配信されます。
```json
{
    "notification": {
        "messageId": "9aec73fc-d328-545e-9364-2c2fab4b77af", # ダミーのID
        "timestamp": "2024-12-11 11:01:39.375"
    },
    "delivery": {
        "destination": "+819000000000", # ダミーの電話番号
        "smsType": "Promotional",
        "providerResponse": "Invalid parameters",
        "dwellTimeMs": 141
    },
    "status": "FAILURE"
}
```
※ AWSサポートによると、送信者IDを指定していてもUSリージョンなら「プロモーション」でも送信できたとのことでした。


ちなみに、日本国内でのSMS送信の場合、プロモーションもトランザクションも、
１通あたりの料金は2024年12月23日現在`$0.07451`で全く同じのようです。
それなら尚更トランザクションを指定しておいた方がよさそうですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/80d006fa-e2f8-9b0b-7e6e-c8d2c6068b67.png)

**参考：**
- [AWS End User Messaging Pricing](https://aws.amazon.com/jp/end-user-messaging/pricing/)


#### ステップ２：電話番号・メッセージ・送信者IDを入力してSMSを送信する

続いて、以下の情報を入力します。
- 送信先電話番号：
  - 手順2でサンドボックスに登録した電話番号を選択してください
- メッセージ：
  - 任意のメッセージを入力してください。ここでは「Hello World!」と入力します
- 発信元ID > 送信者ID：
  - 手順3で登録した送信者IDを入力してください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/d7e88802-65c5-8f35-0db8-49344ed85d5c.png)

右下の「メッセージの発行」ボタンをクリックすると指定した電話番号にSMSメッセージが送信されます。

送信者IDがちゃんと「TEST-SMS」で届いていますね。
![IMG_3981.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/dca28b77-4736-76fe-5e0f-7495a98dd0af.jpeg)

#### 補足
もし送信者IDが未指定だったり、登録されていない送信者IDを指定していたら以下のように「NOTICE」と表示されます。
![IMG_3982.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/808f1916-8df3-e213-9a4d-1af0e9f1f9c2.jpeg)

ちなみに「NOTICE」以外にも「253000」でSMSが届くこともありました。

### SDK for PHPでSMS送信する場合
上記の手順４では、マネジメントコンソールからSMS送信をしましたがSDK for PHPで送信するコード例もご紹介します。

```php
// 送信先の電話番号
//（日本の国際電話コード `+81` を連結した国際形式の電話番号）
$phoneNumber = '+81' . "0900000000";
// 送信者ID
$senderId = 'TEST-SMS';
// 送信メッセージ
$message = 'Hello World!';

// IAM Identity Center(AWS SSO)認証プロバイダーを使用する場合
// 公式ドキュメント：https://docs.aws.amazon.com/ja_jp/sdk-for-php/v3/developer-guide/guide_configuration.html#config_credentials
$credentials = \Aws\Credentials\CredentialProvider::sso('profile default'); // profile名を指定
$sns = new \Aws\Sns\SnsClient([
    'region' => 'ap-northeast-1',
    'version' => 'latest',
    'credentials' => $credentials
]);

try {
    // SMS送信処理をSNSにリクエスト
    // NOTE: AWS SNSに対してSMS送信をリクエストするだけの処理（非同期）なので、SMS送信が成功したかどうかまではアプリ側で検知できない
    $result = $sns->publish([
        'Message' => $message,
        'PhoneNumber' => $phoneNumber,
        'MessageAttributes' => [
            'AWS.SNS.SMS.SMSType' => [
                'DataType' => 'String',
                'StringValue' => 'Transactional', // ※ 送信者IDを指定する場合、東京リージョンのの場合Transactionalを指定しないとエラーになる
            ],
            'AWS.SNS.SMS.SenderID' => [
                'DataType' => 'String',
                'StringValue' => $senderId,
            ],
        ],
    ]);
    return response()->json(['result' => 'SMS sent successfully', 'messageId' => $result->get('MessageId')]);
} catch (\Exception $e) {
    return response()->json(['result' => 'SMS sent failed', 'message' => $e->getMessage()]);
}
```

# SNSでのSMS送信の注意点

### サンドボックス
初期状態では悪用のリスク等を軽減するためにサンドボックスに設定されており、
検証済みの送信先電話番号(最大10個まで)にしかSMSメッセージを送信できないようになっています。

もしサンドボックスを解除したい場合は、[こちらの手順](https://docs.aws.amazon.com/ja_jp/sns/latest/dg/sns-sms-sandbox-moving-to-production.html)に従ってAWSサポートセンターに「サービスクォータの引き上げ」をリクエストする必要があります。

### SMS送信の利用制限
サンドボックスに加えて、初期状態では1.00USD/月までしかSMS送信できない利用制限があります。
この制限を解除するには、同じくAWSサポートセンターに「サービスクォータの引き上げ」をリクエストする必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/333f32b9-1ec8-73cd-df4d-60167a8d0a5d.png)

**参考：**
- [毎月のAmazon SNS SMS支出クォータの引き上げをリクエストする](https://docs.aws.amazon.com/ja_jp/sns/latest/dg/channels-sms-awssupport-spend-threshold.html)

AWSサポートにリクエストして24時間以内に、最初の返答があります。
もし申請内容に不備等があれば追加で質問に答える必要があります。

実際に利用制限の引き上げをAWSサポートにリクエストしてみたところ、利用制限の解除に加えて
サンドボックスの解除もまとめて行われました。
なお、その時は月1.00USDの利用制限は解除したいもののサンドボックスは解除したくなかったので、
利用制限の解除のみをしてもらうよう調整してもらうことも可能でした。

### AWS SNS等でのSMS送信には国際網が利用される
AWS SNS (End User Messaging) や Amazon Pinpoint を利用して国内にSMSを配信する場合、国内キャリアとの直接接続ではなく国際SMSメッセージとして送られる点に注意が必要です。

そのため、要件として「国内キャリア直接接続」を求められているケースでは、AWS のサービスを利用したSMS送信が要件に合致しない場合があります。

AWSサポートからいただいた回答：
> SNS, Pinpoint を使用した SMS メッセージ配信は、複数の SMS プロバイダーを利用し冗長化を図っている国際 SMS メッセージでございます。
日本国内の電話番号へのメッセージ配信において経路が日本国内に限定されることを保証しておらず、一般的には SMS メッセージの受信端末において国際 SMS メッセージ受信拒否設定が解除されている必要がございます。

> SMS メッセージは、サードパーティーのダウンストリームアグリゲータ、SMS サプライヤー、およびモバイル通信事業者を介してモバイルデバイスに配信されます。

このように国際網を使用する以上、日本国内だけに配信経路を限定できるわけではないという点を理解しておくことが大切です。

# SMS配信ステータスのログについて

SNSでSMS送信をした際に、 SNS > テキストメッセージング(SMS)の
コンソールから配信の成功 or 失敗をグラフで確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613419/8e845a3a-b649-8bce-34f3-71a04bd02caf.png)

しかし、SMS配信に失敗した場合の詳しいログまでは知ることができません。
なので、配信ステータスのログ記録を有効にしてCloudWatch Logsに配信成功 or 失敗の詳細ログを出すようにしておくとエラーの原因分析などに役立ちます。

ログ記録の有効化の手順については、以下の記事をご参考ください。（そんなに難しくありませんでした）

**ログ記録有効化の手順**
- [re:Post SMSメッセージのAmazon SNSトピック配信ログにアクセスする方法を教えてください。](https://repost.aws/ja/knowledge-center/monitor-sns-texts-cloudwatch)


# 終わりに
本記事では、AWS SNS/End User Messagingを使ったSMS配信の手順や注意点をご紹介しました。
皆様の導入・運用の一助となれば幸いです。