はじめに
LambdaからSNS経由でアプリをインストールしたIOSデバイスにプッシュ通知する方法についてまとめました。
事前構築
- プッシュ通知用証明書(p12)は、発行済とする
- IOSデバイスのデバイストークンは、取得済みとする
SNS作成
SNSでプッシュ通知の設定をします。
プラットフォームアプリケーションの作成
- アプリケーション名:
適切な名前
- プッシュ通知プラットフォーム:
Apple iOS/VoIP/MacOS
- プッシュサービス:
IOS
- 証明書:
作成済みのファイルをアップロード
- 配信ステータスのログ記録のIAMロールは、
新しいサービスロールの作成
を選択し、新しいロールの作成
をクリックする
SNSでプッシュ通知テスト
デバイストークンを元に、SNSからIOSデバイスにプッシュ通知できるか確認します。
デバイストークンは、取得しているものとします。
アプリケーションエンドポイントの作成
をクリックします。
デバイストークンを入力し、作成をクリックします。
メッセージの発行をクリックします。
配信プロトコルごとにカスタムペイロード。
を選択し、メッセージの発行
をクリックすると、アプリを入れているデバイスにプッシュ通知が送られます。
このSNSのプラットフォームアプリケーションのARNは、Lambdaで必要なため、メモしておきましょう。
プッシュ通知がデバイス側に来ない場合
以下の原因が考えられますので、もう一度設定を確認しましょう。
- デバイストークンが異なる
- プッシュ通知の証明書の設定ミス
- デバイス側でプッシュ通知の表示がオフの設定になっている
- SNSのエンドポイントのステータスが無効になっている
配信失敗時、CloudWatch Logsのsns/ap-northeast-1/アカウントID/app/APNS/test/Failure
にエラーログが出力されていますので、そちらも参考になります。
ちなみに、SNSのエンドポイントのステータスが無効になっている
に関して、エンドポイントの編集で設定変更が可能です。
Lambda作成
Lambdaを作成します。ランタイムをNode.jsにし、他はデフォルトのままにします。
IAMロール
AmazonSNSFullAccess
をアタッチします。
コード
環境変数
- PLATFORM_APPLICATION_ARN:
先程作成したSNSのARN
(arn:aws:sns:ap-northeast-1:アカウントID:app/APNS/test) - APN_TYPE:
APNS
(サンドボックスの場合、APNS_SANDBOX
)
const AWS = require('aws-sdk');
const sns = new AWS.SNS();
const platformApplicationArn = process.env.PLATFORM_APPLICATION_ARN;
const apnType = process.env.APN_TYPE;
const pushParams = (endPointArn) => {
const params = {
TargetArn: endPointArn,
Message: JSON.stringify({
[apnType]: JSON.stringify({
aps: {
alert: {
title: 'タイトルです',
body: '本文です',
},
sound: 'default',
// アプリ側に渡したい値がある場合、以下などを記載してもよい
value: {
status: 'ok',
},
},
}),
}),
MessageStructure: 'json',
};
console.log('Received pushParams:', JSON.stringify(params, null, 2));
return params;
};
const pushNotification = async (deviceTokens) => {
for (const deviceToken of deviceTokens) {
const platformApplicationArnParams = {
PlatformApplicationArn: platformApplicationArn,
Token: deviceToken,
};
// PlatformEndpointを作成。作成済みの場合、新たに作成せず、PlatformEndpointのARNを返す
const createEndpoint = await sns.createPlatformEndpoint(platformApplicationArnParams).promise();
const endPointArn = createEndpoint.EndpointArn;
console.log('Received endPointArn:', JSON.stringify(endPointArn, null, 2));
const enableEndpointParams = {
EndpointArn: endPointArn,
Attributes: {
Enabled: 'true',
},
};
// PlatformEndpointのARNを元に、PlatformEndpoint を Enabled の状態にする。元々Enabledの状態でも問題なし。
await sns.setEndpointAttributes(enableEndpointParams).promise();
// プッシュ通知する
await sns.publish(pushParams(endPointArn)).promise();
}
};
exports.handler = async (event, context, callback) => {
const deviceTokens = ['deviceToken-1', 'deviceToken-2', 'deviceToken-3'];
await pushNotification(deviceTokens);
};
- setEndpointAttributes
- createPlatformEndpoint
- publishメソッド
今回使用した上記の3つのメソッドの役割について、以下の記事が参考になりました。
参考