Memo

メモ > 技術 > サービス: AmazonSNS > AmazonSNS: PHPプログラムの作成

AmazonSNS: PHPプログラムの作成
■ライブラリの準備 AWSのSDKを使ってプッシュ通知を送信できる。 Composerを使う場合、以下でインストールできる。
$ composer require aws/aws-sdk-php
もしくは以下からSDKを入手して、手動で配置することもできる。 https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_installation.html ■プログラムの作成 AmazonSNSを扱うためのPHPプログラムを作成する。(ファイルの文字コードは UTF-8N にする。) アクセスキーは、先ほど作成したものを使用する。 ※いったん pushtest1-dev などのフォルダを作って、その中に開発版用として作成するといい。 証明書などが異なるので、本番用を作るなら pushtest1 フォルダなどに、検収版を作るなら pushtest1-stg フォルダなどに、別途作ると良さそう。 (実案件なら、そもそも配置するサーバ自体が異なると思われるが。) アプリからPHPプログラムを呼び出す場合、SSL経由にする必要があるので注意。 (このプログラムはブラウザから操作する前提なので問題ないが、本番用のアプリなら端末からPHPにアクセスしてデバイストークンを渡したり…が必要。)
<?php require 'vendor/autoload.php'; use Aws\Sns\SnsClient; use Aws\Sns\Exception\SnsException; $result_code = null; $result_data = null; try { // AmazonSNSに接続 $client = new SnsClient([ 'credentials' => [ 'key' => 'XXXXXXXXXX', 'secret' => 'YYYYYYYYYY', ], 'region' => 'ap-northeast-1', 'version' => 'latest', ]); if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['api'])) { if ($_POST['api'] === 'createPlatformEndpoint') { // アプリケーションに端末を追加 // https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#createplatformendpoint $result = $client->createPlatformEndpoint([ 'PlatformApplicationArn' => $_POST['applicationArn'], 'Token' => $_POST['deviceToken'], ]); $result_code = $result->get('@metadata')['statusCode']; $result_data = $result['EndpointArn']; } elseif ($_POST['api'] === 'listEndpointsByPlatformApplication') { // アプリケーションに対するエンドポイントの一覧を取得 // https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#listendpointsbyplatformapplic... $result = $client->listEndpointsByPlatformApplication([ 'NextToken' => $_POST['nextToken'], 'PlatformApplicationArn' => $_POST['applicationArn'], ]); $result_code = $result->get('@metadata')['statusCode']; $result_data = $result['Endpoints']; } elseif ($_POST['api'] === 'getEndpointAttributes') { // アプリケーションに対するエンドポイントの状態を取得 // https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#getendpointattributes $result = $client->getEndpointAttributes([ 'EndpointArn' => $_POST['endpointArn'], ]); $result_code = $result->get('@metadata')['statusCode']; $result_data = $result['Attributes']; } elseif ($_POST['api'] === 'setEndpointAttributes') { // アプリケーションに対するエンドポイントの状態を変更 // https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#setendpointattributes $result = $client->setEndpointAttributes([ 'Attributes' => [ 'Enabled' => $_POST['enabled'] ], 'EndpointArn' => $_POST['endpointArn'], ]); $result_code = $result->get('@metadata')['statusCode']; $result_data = []; } elseif ($_POST['api'] === 'createTopic') { // トピックを追加 // https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#createtopic $result = $client->createTopic([ 'Name' => $_POST['name'], ]); $result_code = $result->get('@metadata')['statusCode']; $result_data = $result['TopicArn']; } elseif ($_POST['api'] === 'subscribe') { // トピックにエンドポイントを追加 // https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#subscribe $result = $client->subscribe([ 'Endpoint' => $_POST['endpoint'], 'Protocol' => 'application', 'ReturnSubscriptionArn' => false, 'TopicArn' => $_POST['topicArn'], ]); $result_code = $result->get('@metadata')['statusCode']; $result_data = $result['SubscriptionArn']; } elseif ($_POST['api'] === 'listTopics') { // トピック一覧を取得 // https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#listtopics $result = $client->listTopics([ 'NextToken' => $_POST['nextToken'], ]); $result_code = $result->get('@metadata')['statusCode']; $result_data = $result['Topics']; } elseif ($_POST['api'] === 'publish') { // 指定した端末もしくはトピックに対してプッシュ通知を送信 // https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#publish $gcm = json_encode([ 'data' => [ 'title' => $_POST['message'], 'body' => $_POST['message'], 'url' => null, ], // 通知タップ時にアプリを開くために必要な追加のフィールド 'notification' => [ 'title' => $_POST['message'], 'body' => $_POST['message'], ], ]); $apns = json_encode([ 'aps' => [ 'alert' => [ 'title' => $_POST['message'], 'body' => $_POST['message'], ], 'badge' => 1, 'sound' => 'default' ], 'url' => null ]); $message = [ 'default' => $_POST['message'], 'GCM' => $gcm, 'APNS' => $apns, 'APNS_SANDBOX' => $apns, ]; $parameter = [ 'Message' => json_encode($message), 'MessageStructure' => 'json', ]; /* $parameter = [ 'Message' => $_POST['message'], ]; */ if ($_POST['targetArn'] != '') { $parameter['TargetArn'] = $_POST['targetArn']; } elseif ($_POST['topicArn'] != '') { $parameter['TopicArn'] = $_POST['topicArn']; } $result = $client->publish($parameter); $result_code = $result->get('@metadata')['statusCode']; $result_data = $result['MessageId']; } } } catch (SnsException $e) { exit('SnsException: ' . $e->getMessage()); } catch (Exception $e) { exit('Exception: ' . $e->getMessage()); } ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>AmazonSNS</title> </head> <body> <h1>AmazonSNS</h1> <?php if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['api'])) : ?> <h2>Result</h2> <pre><?php print_r(['result_code' => $result_code, 'result_data' => $result_data]) ?></pre> <?php endif ?> <h2>CreatePlatformEndpoint</h2> <p>アプリケーションに端末を追加。</p> <form action="sns.php" method="post"> <input type="hidden" name="api" value="createPlatformEndpoint"> <dl> <dt>applicationArn(必須)</dt> <dd><input type="text" size="60" name="applicationArn"></dd> <dt>deviceToken(必須)</dt> <dd><input type="text" size="60" name="deviceToken"></dd> </dl> <p><input type="submit" value="実行"></p> </form> <h2>ListEndpointsByPlatformApplication</h2> <p>アプリケーションに対するエンドポイントの一覧を取得。(1回のリクエストで100件まで。1秒間に30トランザクションまで。)</p> <form action="sns.php" method="post"> <input type="hidden" name="api" value="listEndpointsByPlatformApplication"> <dl> <dt>nextToken</dt> <dd><input type="text" size="60" name="nextToken" value=""></dd> <dt>applicationArn(必須)</dt> <dd><input type="text" size="60" name="applicationArn" value=""></dd> </dl> <p><input type="submit" value="実行"></p> </form> <h2>GetEndpointAttributes</h2> <p>アプリケーションに対するエンドポイントの状態を取得。</p> <form action="sns.php" method="post"> <input type="hidden" name="api" value="getEndpointAttributes"> <dl> <dt>endpointArn(必須)</dt> <dd><input type="text" size="60" name="endpointArn"></dd> </dl> <p><input type="submit" value="実行"></p> </form> <h2>SetEndpointAttributes</h2> <p>アプリケーションに対するエンドポイントの状態を変更。</p> <form action="sns.php" method="post"> <input type="hidden" name="api" value="setEndpointAttributes"> <dl> <dt>enabled(必須)</dt> <dd> <select name="enabled"> <option value=""></option> <option value="true">true</option> <option value="false">false</option> </select> </dd> <dt>endpointArn(必須)</dt> <dd><input type="text" size="60" name="endpointArn"></dd> </dl> <p><input type="submit" value="実行"></p> </form> <h2>CreateTopic</h2> <p>トピックを追加。</p> <form action="sns.php" method="post"> <input type="hidden" name="api" value="createTopic"> <dl> <dt>name(必須)</dt> <dd><input type="text" size="60" name="name"></dd> </dl> <p><input type="submit" value="実行"></p> </form> <h2>Subscribe</h2> <p>トピックにエンドポイントを追加。</p> <form action="sns.php" method="post"> <input type="hidden" name="api" value="subscribe"> <dl> <dt>endpoint(必須)</dt> <dd><input type="text" size="60" name="endpoint" value=""></dd> <dt>topicArn(必須)</dt> <dd><input type="text" size="60" name="topicArn" value=""></dd> </dl> <p><input type="submit" value="実行"></p> </form> <h2>ListTopics</h2> <p>トピック一覧を取得。(1回のリクエストで100件まで。1秒間に30トランザクションまで。)</p> <form action="sns.php" method="post"> <input type="hidden" name="api" value="listTopics"> <dl> <dt>nextToken</dt> <dd><input type="text" size="60" name="nextToken" value=""></dd> </dl> <p><input type="submit" value="実行"></p> </form> <h2>Publish</h2> <p>指定した端末もしくはトピックに対してプッシュ通知を送信。</p> <form action="sns.php" method="post"> <input type="hidden" name="api" value="publish"> <dl> <dt>message(必須)</dt> <dd><input type="text" size="60" name="message" value=""></dd> <dt>targetArn</dt> <dd><input type="text" size="60" name="targetArn" value=""></dd> <dt>topicArn</dt> <dd><input type="text" size="60" name="topicArn" value=""></dd> </dl> <p><input type="submit" value="実行"></p> </form> </body> </html>
■補足 プッシュ通知送信部分の $parameter を組み立てる部分を以下のように変更すると、単純なメッセージ以外も送信できる。 ただしAndroidではプッシュ通知の本文が表示されなくなるので、Androidアプリ側で受け取り処理の調整が必要になるみたい。(要検証。)
$fcm = json_encode([ 'data' => [ 'message' => $_POST['message'], 'param1' => 'xxx', 'param2' => 'yyy' ], ]); $apns = json_encode([ 'aps' => [ //'alert' => $_POST['message'], 'alert' => [ //'title' => 'タイトル', //'subtitle' => 'サブタイトル', 'body' => $_POST['message'], ], 'badge' => 0, 'sound' => 'default' ], 'param1' => 'xxx', 'param2' => 'yyy' ]); $message = [ 'default' => $_POST['message'], 'FCM' => $fcm, 'APNS' => $apns, 'APNS_SANDBOX' => $apns, ]; $parameter = [ 'Message' => json_encode($message), 'MessageStructure' => 'json', ]; /* $parameter = [ 'Message' => $_POST['message'], ]; */
Androidアプリ側では MyFirebaseMessagingService.kt の以下の部分の調整で取得できるかも。(要検証。)
override fun onMessageReceived(remoteMessage: RemoteMessage?) { Log.d(TAG, "From: " + remoteMessage!!.from!!) // Check if message contains a data payload. if (remoteMessage.getData().isNotEmpty()) { Log.d(TAG, "Message data payload: " + remoteMessage.getData().get("default")) // 10秒以上処理にかかる場合は、Firebase Job Dispatcherを使用する sendNotification(this, remoteMessage.getData().get("default")) } // Check if message contains a notification payload. if (remoteMessage.notification != null) { Log.d(TAG, "Message Notification Body: " + remoteMessage.notification!!.body!!) sendNotification(this, remoteMessage.notification!!.body!!) } }
以下のようにdefaultをmessageに変更すると、メッセージを受け取ることができるかも。(要検証。) プッシュ通知一覧でもテキストが表示されるかも。(要検証。)
if (remoteMessage.getData().isNotEmpty()) { Log.d(TAG, "Message data payload1: " + remoteMessage.getData().toString()) Log.d(TAG, "Message data payload2: " + remoteMessage.getData().get("message")) // 10秒以上処理にかかる場合は、Firebase Job Dispatcherを使用する sendNotification(this, remoteMessage.getData().get("message")) }

Advertisement