Amazon Pinpointを使ってLINE公式アカウントからユーザーへプッシュメッセージを送ってみた

2021.12.28

いわさです。

Amazon Pinpointでは標準でEメール、SMS、モバイルプッシュ通知(APNs/FCM)、アプリ内メッセージの送信チャネルが用意されていますが、"カスタムチャネル"という機能もあります。
この機能は実体としてはPinpointからLambda関数を呼び出すだけの機能なので、実装次第でなんでも出来ます。

本日はカスタムチャネルを使って、LINE公式アカウントから登録ユーザーへのプッシュメッセージを送ってみました。

LINE公式アカウントの用意

今はフリープランでプッシュメッセージ使えるんですね。
Mr.Moさんの記事を参考に、セットアップさせて頂きました。

ユーザー情報の取得

上記記事を参考に、テストメッセージの送信も行うことが出来ます。

プッシュメッセージはLINE IDでは送信できなくて、個別のユーザーに送信する場合はUser IDが必要になります。
そのため、公式アカウントに友だち登録したユーザーのUser IDを取得しましょう。

まず、LINE公式アカウントを友だち追加したユーザーのリストを取得するには認証済みアカウントまたはプレミアムアカウントのみ利用が可能です。
Messaging APIリファレンス | LINE Developers

今回は未認証アカウントなので、この方法は使えませんが、友だち登録を行った際にWebhookイベントで登録ユーザーの情報を確認することが出来ます。
今回はWebhook.siteを使ってWebhookを設定し、リクエストからUser IDを取得しました。

以下は、公式アカウントへの友だち登録/ブロック解除をしたタイミングで送信されるイベントレコードです。

{
  "destination": "U0f111111111122222222223333333333",
  "events": [
    {
      "type": "follow",
      "timestamp": 1640656234713,
      "source": {
        "type": "user",
        "userId": "U0e444444444455555555556666666666"
      },
      "mode": "active"
    }
  ]
}

実際にPinpointでセグメントを構築する際には公式アカウントの友だちとターゲットシステム間での連携が実質必須かなと思います。
そしてWebhookの処理からPinpointのエンドポイント作成を行うとかになるかなと。

Pinpointでの動的セグメント作成については以下を参考にしてください。
Amplifyを使った記事ですが、エンドポイント更新はHTTPでアクセス出来ます。

カスタムチャネルを準備する

カスタムチャネルはLambda関数もしくはHTTPエンドポイントを指定することが出来ます。
今回はLambda関数を指定します。

Lambdaからプッシュメッセージを送信する方法は、リサリサさんの以下の記事が大変参考になりました。

LINE SDK用のLambdaレイヤーを用意する方法と、メッセージ送信の大枠を真似させてもらいました。

そして、カスタムチャネルに送信されるイベントデータは以下の構造です。

50件のエンドポイントごとに1回関数が呼び出されます。
キャンペーンのターゲットが80名の場合だと、2回関数が実行されます。
また、カスタムチャネルの場合メッセージ設定は出来ないので、イベントデータに含まれる属性を使って関数側でのメッセージ構築が必要です。

今回はシンプルに以下のようにしました。

import json
import os
from linebot import (LineBotApi, WebhookHandler)
from linebot.models import (MessageEvent, TextMessage, TextSendMessage)

def lambda_handler(event, context):
    
    line_bot_api = LineBotApi(channel_access_token=os.environ['LINE_CHANNEL_ACCESS_TOKEN'])
    
    for key in event['Endpoints'].keys():
        user_id = event['Endpoints'][key]['Address']
        line_bot_api.push_message(user_id, TextSendMessage(text='hoge from Pinpoint'))

    return {
        'statusCode': 200,
        'body': json.dumps('ok', ensure_ascii=False)
    }

作成した関数のリソースベースポリシーで、Pinpointからの関数実行を許可する必要があります。

静的セグメントとキャンペーンの実行

ではPinpointからキャンペーンで送信してみましょう。
まずは送信者のリスト(セグメント)を作成します。

今回はWebhookで事前入手したUser IDを使ってCSVファイルを用意し、静的セグメントへインポートします。

iwasa.takahito@HL00780 20211228line % cat segment.csv 
Address,ChannelType,User.UserAttributes.hoge
U0e444444444455555555556666666666,CUSTOM,いわさ1

セグメントインポートについては以下を参考にしてください。

キャンペーンを作成し、メッセージを送信しましょう。
チャネルにカスタムを選択し、チャネルタイプにLambda関数を指定するだけです。
後はセグメントの内容に応じてLambda関数が実行されます。

アプリ内メッセージだと15分以降後じゃないとキャンペーン開始が出来なかったですが、カスタムチャネルの場合は即時実行出来るようでした。
今回は即時実行しました。

送信されました!良いですね。

さいごに

本日はAmazon Pinpointのカスタムチャネルを使って、LINE公式アカウントの友だちにプッシュメッセージを送信してみました。

今回は宛先が1件ということでプッシュメッセージ機能を使いましたが、LINEのMessaging APIにはマルチキャストやナローキャストなど柔軟なメッセージ配信APIが提供されています。Pinpointのカスタムチャネルだとマルチキャストで50人づつ送信するのが良いかもしれないですね。
そのあたりや、冒頭のUser IDの取得方法についてはアレンジしてみてください。

Messaging APIリファレンス | LINE Developers

カスタムチャネル使えば何でも出来そうですね。何でも出来る反面、当然ながらPinpointコンソール上で利用できる便利な機能(メッセージテンプレートなど)は利用出来ないのでそのあたりの作り込みは必要になります。
あと、外部APIを実行する場合はレート制限にも気をつけてください。

LINE公式アカウントがそもそもメッセージ送信機能が充実しているので、このチャネル単体だとPinpoint使う理由としては弱い感じがしますが、マルチチャネルだったり外部サービスで管理する属性でセグメントを構築するなどを行う場合はPinpointの強みが出ると思います。