4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Lambda (Node.js) から SNS 経由で IOSデバイス にプッシュ通知

Posted at

はじめに

LambdaからSNS経由でアプリをインストールしたIOSデバイスにプッシュ通知する方法についてまとめました。

事前構築

SNS作成

SNSでプッシュ通知の設定をします。

プラットフォームアプリケーションの作成

プラットフォームアプリケーションの作成をクリックします。
スクリーンショット 2022-10-14 16.00.24.png

  • アプリケーション名:適切な名前
  • プッシュ通知プラットフォーム:Apple iOS/VoIP/MacOS
  • プッシュサービス:IOS
  • 証明書:作成済みのファイルをアップロード
    • アップロード後、認証情報をファイルから読み込みをクリックする
      スクリーンショット 2022-10-14 16.08.43.png
  • 配信ステータスのログ記録のIAMロールは、新しいサービスロールの作成を選択し、新しいロールの作成をクリックする
    スクリーンショット 2022-10-14 16.01.21.png
    • 許可をクリックすると自動で作成される
      スクリーンショット 2022-10-14 16.02.00.png
    • IAMロールが作成されたことを確認し、作成をクリックする
      スクリーンショット 2022-10-14 16.02.15.png

SNSでプッシュ通知テスト

デバイストークンを元に、SNSからIOSデバイスにプッシュ通知できるか確認します。
デバイストークンは、取得しているものとします。

アプリケーションエンドポイントの作成をクリックします。
スクリーンショット 2022-10-14 16.14.42.png
デバイストークンを入力し、作成をクリックします。
スクリーンショット 2022-10-14 16.15.46.png

メッセージの発行をクリックします。
スクリーンショット 2022-10-14 16.16.31.png
配信プロトコルごとにカスタムペイロード。を選択し、メッセージの発行をクリックすると、アプリを入れているデバイスにプッシュ通知が送られます。
スクリーンショット 2022-10-14 16.16.58.png

このSNSのプラットフォームアプリケーションのARNは、Lambdaで必要なため、メモしておきましょう。
スクリーンショット 2022-10-14 16.22.37.png

プッシュ通知がデバイス側に来ない場合

以下の原因が考えられますので、もう一度設定を確認しましょう。

  • デバイストークンが異なる
  • プッシュ通知の証明書の設定ミス
  • デバイス側でプッシュ通知の表示がオフの設定になっている
  • SNSのエンドポイントのステータスが無効になっている

配信失敗時、CloudWatch Logsのsns/ap-northeast-1/アカウントID/app/APNS/test/Failureにエラーログが出力されていますので、そちらも参考になります。

ちなみに、SNSのエンドポイントのステータスが無効になっているに関して、エンドポイントの編集で設定変更が可能です。
スクリーンショット 2022-10-14 16.20.49.png

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つのメソッドの役割について、以下の記事が参考になりました。

参考

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?