■AmazonSNS: PHPプログラムの作成
AWSのSDKを使ってプッシュを送信できる
Composerを使う場合、以下でインストールできる
kreait/firebase-php をインストール済みなら、同じ場所で追加インストールすればいい
$ php composer.phar require aws/aws-sdk-php
環境によっては以下のコマンドになる
$ composer require aws/aws-sdk-php
以下からSDKを入手して、手動で配置することもできる
https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_installation.html
以降のフォルダ名は pushtest1-dev としているが、これは開発版想定
証明書などが異なるので、本番用を作るなら pushtest1 フォルダなどに、検収版を作るなら pushtest1-stg フォルダなどに、別途作ると良さそう
アプリからPHPプログラムを呼び出す場合、SSL経由にする必要があるので注意
(この例では一方的に送信するだけなので問題ないが、本番用のアプリなら端末からPHPにアクセスしてデバイストークンを渡したり…が必要)
■pushtest1-dev\index.php
※ファイルの文字コードは UTF-8N にする
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>AmazonSNS</title>
</head>
<body>
<h1>AmazonSNS</h1>
<h2>CreatePlatformEndpoint</h2>
<p>アプリケーションに端末を追加。</p>
<form action="exec.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="exec.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="exec.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="exec.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="exec.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="exec.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="exec.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="exec.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>
■pushtest1-dev\exec.php
※ファイルの文字コードは UTF-8N にする
<?php
require __DIR__ . '/vendor/autoload.php';
use Aws\Sns\SnsClient;
/* アクセスキー */
$aws_access_key = 'XXXXX';
$aws_secret_access_key = 'YYYYY';
/* AmazonSNS */
$snsClient = new SnsClient([
'version' => 'latest',
'credentials' => [
'key' => $aws_access_key,
'secret' => $aws_secret_access_key,
],
'region' => 'ap-northeast-1',
]);
$result = null;
$code = null;
$data = null;
try {
switch ($_POST['api']) {
case 'createPlatformEndpoint':
/**
* アプリケーションに端末を追加
*
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#createplatformendpoint
*/
$result = $snsClient->createPlatformEndpoint([
'PlatformApplicationArn' => $_POST['applicationArn'],
'Token' => $_POST['deviceToken'],
]);
$code = $result->get('@metadata')['statusCode'];
$data = $result['EndpointArn'];
break;
case 'listEndpointsByPlatformApplication':
/**
* アプリケーションに対するエンドポイントの一覧を取得
*
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#listendpointsbyplatformapplic...
*/
$result = $snsClient->listEndpointsByPlatformApplication([
'NextToken' => $_POST['nextToken'],
'PlatformApplicationArn' => $_POST['applicationArn'],
]);
$code = $result->get('@metadata')['statusCode'];
$data = $result['Endpoints'];
break;
case 'getEndpointAttributes':
/**
* アプリケーションに対するエンドポイントの状態を取得
*
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#getendpointattributes
*/
$result = $snsClient->getEndpointAttributes([
'EndpointArn' => $_POST['endpointArn'],
]);
$code = $result->get('@metadata')['statusCode'];
$data = $result['Attributes'];
break;
case 'setEndpointAttributes':
/**
* アプリケーションに対するエンドポイントの状態を変更
*
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#setendpointattributes
*/
$result = $snsClient->setEndpointAttributes([
'Attributes' => [
'Enabled' => $_POST['enabled']
],
'EndpointArn' => $_POST['endpointArn'],
]);
$code = $result->get('@metadata')['statusCode'];
$data = [];
break;
case 'createTopic':
/**
* トピックを追加
*
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#createtopic
*/
$result = $snsClient->createTopic([
'Name' => $_POST['name'],
]);
$code = $result->get('@metadata')['statusCode'];
$data = $result['TopicArn'];
break;
case 'subscribe':
/**
* トピックにエンドポイントを追加
*
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#subscribe
*/
$result = $snsClient->subscribe([
'Endpoint' => $_POST['endpoint'],
'Protocol' => 'application',
'ReturnSubscriptionArn' => false,
'TopicArn' => $_POST['topicArn'],
]);
$code = $result->get('@metadata')['statusCode'];
$data = $result['SubscriptionArn'];
break;
case 'listTopics':
/**
* トピック一覧を取得
*
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#listtopics
*/
$result = $snsClient->listTopics([
'NextToken' => $_POST['nextToken'],
]);
$code = $result->get('@metadata')['statusCode'];
$data = $result['Topics'];
break;
case 'publish':
/**
* 指定した端末もしくはトピックに対してプッシュを送信
*
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html#publish
*/
$parameter = [
'Message' => $_POST['message'],
];
if ($_POST['targetArn'] != '') {
$parameter['TargetArn'] = $_POST['targetArn'];
} elseif ($_POST['topicArn'] != '') {
$parameter['TopicArn'] = $_POST['topicArn'];
}
$result = $snsClient->publish($parameter);
$code = $result->get('@metadata')['statusCode'];
$data = $result['MessageId'];
break;
default:
break;
}
} catch (Exception $e) {
$result = $e->getMessage();
}
/* 実行結果を表示 */
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>AmazonSNS</title>
</head>
<body>
<h1>AmazonSNS</h1>
<pre><?php print_r(['code' => $code, 'data' => $data, 'result' => $result]) ?></pre>
</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"))
}