1
0

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 3 years have passed since last update.

Amazon SNSを利用してモバイルプッシュ通知を送信するやり方ー HMS対応(実装)

Last updated at Posted at 2021-03-11

ソリューション概要

Amazon SNSを利用してモバイルプッシュ通知を送信するやり方ー HMS対応(ソリューション)をご参照ください。

AWS Lambdaの実装

サブスクリプションからのデータを取得する

プッシュデータはevent.Records[0].Sns.Messageに入っています。

index.js
...

exports.handler = function (event, context, callback) {
    ...

    // プッシュデータ
    let pushData = null;
    if (event
        && event.hasOwnProperty("Records")
        && Array.isArray(event.Records) 
        && event.Records.length > 0
        && event.Records[0].hasOwnProperty("Sns")
        && event.Records[0].Sns.hasOwnProperty("Message")
    ) {
        pushData = event.Records[0].Sns.Message;
    }

    ...
}

HMSプッシュサーバーとのやり取り

アクセストークンのAPIを呼び出すメソッドcreateGetAccessTokenPromise()と、プッシュ通知配信のAPIを呼び出すメソッドcreatePushNotificationPromise()を用意します。

util.js
const https = require('https');
const querystring = require('querystring');

module.exports = class Util {
    constructor() {}

    createRequestPromise_json(hostname, path, method, headers, data) {
        return new Promise((resolve, reject) => {
            try {
                const stringData = JSON.stringify(data);

                headers["Content-Type"] = "application/json";

                const options = {
                    hostname: hostname,
                    path: path,
                    method: method,
                    rejectUnauthorized: false,
                    headers: headers
                };
        
                const request = https.request(options, (response) => {
                    let data = '';
                    response.on('data', (chunk) => {
                        data += chunk;
                    });
        
                    response.on('end', () => {
                        resolve(data);
                    });
                }).on("error", (error) => {
                    reject(error);
                });
        
                request.write(stringData);
                request.end();
            } catch (exception) {
                reject(exception);
            }
        });
    }

    createRequestPromise_x_www_form_urlencoded(hostname, path, method, headers, data) {
        return new Promise((resolve, reject) => {
            try {
                const postData = querystring.stringify(data);

                headers["Content-Type"] = "application/x-www-form-urlencoded";
                headers["Content-Length"] = postData.length;

                const options = {
                    hostname: hostname,
                    path: path,
                    method: method,
                    headers: headers
                };
        
                const request = https.request(options, (response) => {
                    let data = '';
                    response.on('data', (chunk) => {
                        data += chunk;
                    });
        
                    response.on('end', () => {
                        resolve(data);
                    });
                }).on("error", (error) => {
                    reject(error);
                });
        
                request.write(postData);
                request.end();
            } catch (exception) {
                reject(exception);
            }
        });
    }
}
pushUtil.js
const Util = require("./util.js");

const CLIENT_ID = "HMSのAppGallery Connectに登録したプロジェクトのクライアントID";
const CLIENT_SECRET = "HMSのAppGallery Connectに登録したプロジェクトのクライアントシークレット";

module.exports = class MenuContent {

    constructor() {
        this.util = new Util();
    }

    createGetAccessTokenPromise() {
        const hostname = "oauth-login.cloud.huawei.com";
        const path = "/oauth2/v3/token";
        const method = "POST";
        const headers = {};
        const data = {
            grant_type: "client_credentials",
            client_id: CLIENT_ID,
            client_secret: CLIENT_SECRET
        };

        return this.util.createRequestPromise_x_www_form_urlencoded(hostname, path, method, headers, data);
    }

    // このサンプルでは通知メッセージ(データメッセージではない)のみに焦点を当てます
    createPushNotificationPromise(accessToken, title, body, token) {
        const hostname = "push-api.cloud.huawei.com";
        const path = "/v2/736430079244623135/messages:send";
        const method = "POST";
        const headers = {
            Authorization: "Bearer " + accessToken
        };

        // リクエストパラメータの詳細は
        // https://developer.huawei.com/consumer/jp/doc/development/HMSCore-References-V5/https-send-api-0000001050986197-V5
        // をご参照ください
        const data = {
            validate_only: false,
            message: {
                notification: {
                    title: title,
                    body: body
                },
                android: {
                    notification: {
                        title: title,
                        body: body,
                        click_action: {
                            "type": 1,
                            "intent": "#Intent;compo=com.rvr/.Activity;S.W=U;end"
                        }
                    }
                },
                // 配信対象のトークンの配列
                token: token
            }
        };

        return this.util.createRequestPromise_json(hostname, path, method, headers, data);
    }

}

HMSプッシュデータを配信する

アクセストークンを取得してから、プッシュデータを配信します。
ここで気を付けなければならないのは、配信先のトークン数の上限です。
現時点では配信先のトークン数の上限は1000個までなので、1000個以上の場合、分割して送る必要があります。

index.js
const Util = require("./util.js");
const PushUtil = require("./pushUtil.js");

exports.handler = function (event, context, callback) {
    const util = new Util();
    const pushUtil = new PushUtil();

    let pushData = event.Records[0].Sns.Message;

    // タイトル=pushData.titleと仮定する
    const pushTitle = pushData.title;
    // 本文=pushData.bodyと仮定する
    const pushBody = pushData.body;
    // 送信対象=pushData.tokenと仮定する
    const pushToken = pushData.token;

    // プッシュサーバーにアクセスするためのプッシュトークンを認証サーバーから取得する
    const getAccessTokenPromise = pushUtil.createGetAccessTokenPromise();
    getAccessTokenPromise.then((result) => {        
        let accessTokenJson = null;
        try {
            accessTokenJson = JSON.parse(result);
        } catch (exception) {
            const response = {
                'statusCode': 500,
                'headers': {
                    'Content-type': 'application/json'
                },
                'body': JSON.stringify(error)
            }
            callback(null, response);
        }
        
        // アクセストークン
        const accessToken = accessTokenJson.access_token;
        
        // プッシュ通知を送る
        const pushNotificationPromise = pushUtil.createPushNotificationPromise(accessToken, pushTitle, pushBody, pushToken);
        pushNotificationPromise.then((result) => {
            const response = {
                'statusCode': 200,
                'headers': {
                    'Content-type': 'application/json'
                },
                'body': JSON.stringify(result)
            }
            callback(null, response);
        }).catch((error) => {
            const response = {
                'statusCode': 500,
                'headers': {
                    'Content-type': 'application/json'
                },
                'body': JSON.stringify(error)
            }
            callback(null, response);
        });
    }
}

Amazon SNSのサブスクリプション作成

Lambdaを作成したら、関数のARNが生成されます。

image.png

このARNを使って、Amazon SNSのサブスクリプションを作ります。

サブスクリプションを作成するときに、プロトコルAWS Lambdaにし、エンドポイントにLambdaの関数のARNを入れればよいです。

image.png

これでHMSに対応したAmazon SNSのモバイルプッシュ通知が完成です!

サンプル

https://github.com/Rei2020GitHub/MyPublicProject/tree/master/AWS/hms-push-demo-send-push-notification

参考

Amazon SNSを利用してモバイルプッシュ通知を送信するやり方ーコンソール利用
Amazon SNSを利用してモバイルプッシュ通知を送信するやり方ー Node.js
Amazon SNSを利用してモバイルプッシュ通知を送信するやり方ー HMS対応(ソリューション)
Amazon SNSを利用してモバイルプッシュ通知を送信するやり方ー HMS対応(実装)

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?