メモ > 技術 > サービス: 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"))
}