AWS Lambda, SQS, HTTP/S, Email, SMS, モバイルデバイスなどに対して PUSH 通知を送ることができる Amazon SNS を AWS SDK for PHP を用いて操作する方法についてざっくりと見ていきます。なお、雰囲気をつかんだのちに、実装する際にはドキュメントを見ることを強くお勧めします。
SNSクライアントのインスタンス化
Amazon SNS の操作をするためのクライアントクラスは、以下のように直感的にインスタンス化できます。
<?php
require_once('./vendor/autoload.php');
use Aws\Sns\SnsClient;
$client = new SnsClient([
'version' => 'latest',
'region' => 'us-east-1', # 各自の利用しているregionを指定
'profile' => 'default', # ~/.aws/credentials 下に credential を置く
]);
デバイストークンの登録
APNSやGCMなどから発行されたデバイストークンは SnsClient#createPlatformEndpoint
を用いて対応するアプリケーションへエンドポイント登録ができます。戻り値の 'EndpointArn'
にデバイスに紐づく EndpointArn が格納されているので、個別のデバイスへの通知が必要な場合は、これを永続化する必要があります。
try {
$platformApplicationArn = '<applicationのarn>';
$token = '<デバイスから受け取ったデバイストークン>'
$params = [
'PlatformApplicationArn' => $platformApplicationArn,
'Token' => $token,
];
$result = $client->createPlatformEndpoint($params);
$endpointArn = $result['EndpointArn']; // 必要に応じて永続化
} catch (Aws\Sns\Exception\SnsException $e) {
// 例外処理
}
なお、すでに登録されているデバイストークンを何度登録しても、正常に動作します(べき等性がある)。ただし、すでに登録されているデバイストークンが、異なる attribute(具体的にはUser Data)を持っている場合は例外が発生するので注意が必要です。こういったことは、AWSコンソールとコード両方からデバッグテストなどをしているときに発生しやすいと思います。
また、エンドポイントの Enabled が false になっていることをチェックしたければ、以下のように Attributes を指定してあげれば例外のほうに流れてくれます。
$params = [
'PlatformApplicationArn' => $platformApplicationArn,
'Token' => $token,
'Attributes' => ['Enabled' => 'true'],
];
try {
$result = $client->createPlatformEndpoint($params);
$endpointArn = $result['EndpointArn']; // 必要に応じて永続化
} catch (SnsException $e) {
// トークンが登録済みで Enabled が false のときに例外に流れるようになる
}
トピックの作成・購読
デバイストークンをアプリケーションに登録するとエンドポイントが発行されます。エンドポイントへ個別に通知を送るのも良いですが、一斉におなじ内容の通知を送りたいこともあると思います。そんなときにはトピックというものが便利です。トピックにエンドポイントを紐付けておけば、トピック宛に通知を送るだけで、紐付いているエンドポイントに一斉にメッセージを送ることができます。トピックを作る場合は SnsClient#createTopic
を使います。
$params = ['Name' => '<Topic名>'];
$result = $client->createTopic($params);
$topicArn = $result['TopicArn'];
続いてエンドポイントが TopicArn
を購読するように処理を走らせます。
$params = [
'Endpoint' => $endpointArn,
'Protocol' => 'Application',
'TopicArn' => $topicArn,
];
$result = $client->subscribe($params);
$subscriptionArn = $result['SubscriptionArn'];
このようにして、エンドポイントにトピックを購読させることができます。すでに無効になっているエンドポイントについても購読処理は正常に行うことができます。
プッシュ通知の送信
Amazon SNSを利用すれば、トピックや各デバイスなど様々な粒度でPUSH通知を送ることができます。通知には SnsClient#publish
を使います。
$msg = [
'Message' => 'hogehoge',
'TargetArn' => '<TopicArn | EndpointArn>',
];
無効なエンドポイントに通知を行った場合、例外が発生します。ただし、トピックへ送った場合で、サブスクライバーの中に無効なエンドポイントがあっても正常に処理が行われます。JSONでメッセージを送る際には MessageStructure => 'json'
をパラメタに追加してください。
$msg = array(
'MessageStructure' => 'json',
'TargetArn' => $topicArn,
'Message' => json_encode(array(
'default' => '<string>...',
'APNS_SANDBOX' => json_encode(array(
'aps' => array(
'key' => 'value'
)
))
))
);