OneSignal のドキュメントに、Web 解析 ツールとの連携方法について記載されたページがあります。
この中に、Google Analytics、Mixpanel に関するものがありましたので、試しに実装してみます。

[TOC]


参考 OneSingal のドキュメント

システム連携パートの、 以下の記事を参考にしました。
* Google Analytics
* Mixpanel


前提

バックエンド、フロントエンドには、それぞれ以下、ライブラリを使用しています。

バックエンド

Django 、 wagtail、 puput を使用しています。

  • Django (1.11.11)
  • wagtail (1.13.1)
  • puput (0.9.2.1)

フロントエンド

react と、 React Material Web Components、react-helmet を使用しています。

  • react@16.2.0
  • rmwc@1.1.2
  • react-helmet@5.2.0

実装にあたり意識すること

GTM から Google Analytics のタグ配信をしている場合、Tracker 名を指定する(または空欄する)をしないと、JavaScript 内で ga 関数を使って event 送付ができないようです。 また、Google Analytics だけでなく Mixpanel にも event を送付したいので、GTM でカスタムイベントを送付して、それをトリガーに GTM 経由で Google Analytics と Mixpanel に event を送付します。


実装

Google Analytics参考に、実装していきます。

UTM パラメータで、通知のクリックを取得する

UTM パラメータを使用して、通知クリックを計測します。
指定するパラメータは以下を設定します。

  • UTM パラメータ

    • utm_source
      Notification

    • utm_medium
      WebPush

    • utm_campaign
      EntryUpdate-yyyyMMddHHmmss

記事の更新通知は、python スクリプトで記載しています。WebPush の URL を、POST request の payload に追加します。キーは、"url"指定可能です。 python スクリプトは、 Django を使用しているので、Django Command として実装しています。

  • send_notifications.py
    # -*- coding: utf-8 -*-                                                                                                                                                             
    from __future__ import print_function
    from django.core.management.base import BaseCommand
    from requests.exceptions import HTTPError
    from puput.models import EntryPage
    from django.conf import settings
    import datetime
    import requests
    import json
    import urllib.parse
    
    
    class Command(BaseCommand):
    
        def handle(self, **options):
            now = datetime.datetime.now()
            entries = EntryPage.objects.filter(date__gte=now - datetime.timedelta(hours=1000))
            if entries:
                entry = entries.first()
                content = entry.title
                header = {"Content-Type": "application/json; charset=utf-8",
                          "Authorization": "Basic " + settings.ONESIGNAL_REST_API_KEY}
    
                # 記事URLを生成
                date_YYYYmmddHHMMSS = now.strftime("%Y%m%d%H%M%S")
                url_params = {"utm_source": "Notification", "utm_medium": "WebPush", "utm_campaign": "EntryUpdate-" + date_YYYYmmddHHMMSS }
                url = entry.full_url + "?" + urllib.parse.urlencode(url_params)
    
                payload = {"app_id": settings.ONESIGNAL_APP_ID,
                           "included_segments": ["All"],
                           "contents": {"en": content},
                           "headings": {"en": "New article"},
                           "url" : url }
    
                req = requests.post("https://onesignal.com/api/v1/notifications", headers=header, data=json.dumps(payload))
    

addListenerForNotificationOpened で、通知IDと OneSignal プレーヤー ID を記録する

addListenerForNotificationOpened実装することで、通知ID (WebPush通知に付与されるユニークな番号) と、OneSignal プレーヤー ID (ユーザーID) を記録することができます。
サンプルコードは、ga 関数で、event を送付していますが、Mixpanel にも event を送付したいため gtm で カスタムイベントを送付して、タグ配信でイベントを記録します。

  • React コンポーネントの componentDidMount function
    addListenerForNotificationOpened追加します。

        OneSignal.on("addListenerForNotificationOpened", function(data) {
            OneSignal.getUserId(function(userId) {
                window.dataLayer = window.dataLayer || [];
                window.dataLayer.push({
                    event: "sendEvent",
                    eventName: "NotificationOpened",
                    eventData:{ category : "Notification", 
                        action : "Opened",
                        label : userId,
                        value : data.id,
                        nonInteraction : true
                    },
                    eventCustomData : {
                        userId: userId,
                        notificationId: data.id 
                    }
                });
            });
        });
    

  • GTMの設定
    トリガー、カスタムHTMLタグ、JavaScript変数を作成しました。以下説明します。

    • トリガー
      イベント名は、JavaScript から送付している event 属性のsendEvent設定しています。

      • 名称
        event.sendEvent
      • トリガーの種類
        カスタムイベント
      • イベント名
        sendEvent
      • このトリガーの発生場所
        すべてのカスタムイベント
    • ユーザー定義変数1
      ユーザー定義変数は、dataLayter 変数に 設定している、カスタム属性の受け皿になります。

      • 名前
        eventData.action
      • 変数の種類
        データレイヤーの変数
      • 変数名
        eventData.action
    • ユーザー定義変数2

      • 名前
        eventData.category
      • 変数の種類
        データレイヤーの変数
      • 変数名
        eventData.category
    • ユーザー定義変数3

      • 名前
        eventData.label
      • 変数の種類
        データレイヤーの変数
      • 変数名
        eventData.label
    • ユーザー定義変数4

      • 名前
        eventData.nonInteraction
      • 変数の種類
        データレイヤーの変数
      • 変数名
        eventData.nonInteraction
    • ユーザー定義変数5

      • 名前
        eventData.value
      • 変数の種類
        データレイヤーの変数
      • 変数名
        eventData.value
    • ユーザー定義変数6
      以下は、Mixpanel に連携する データレイヤー変数になります。
      Mixpanel に送信するデータの event 名 として使用します。

      • 名前
        eventName
      • 変数の種類
        データレイヤーの変数
      • 変数名
        eventName
    • ユーザー定義変数7
      以下は、Mixpanel に連携する データレイヤー変数になります。
      Mixpanel に送信するデータの カスタム属性として設定します。

      • 名前
        eventCustomData
      • 変数の種類 データレイヤーの変数
      • 変数名 eventCustomData
    • ユニバーサルアナリティクスタグ
      Google Analytics への イベント送付用にしようするタグです。

      • タグタイプ
        ユニバーサル アナリティクス
      • トラッキング タイプ
        イベント
      • カテゴリ
        {{eventData.category}}
      • アクション
        {{eventData.action}}
      • ラベル
        {{eventData.label}}

      • {{eventData.value}}
      • 非インタラクション ヒット
        {{eventData.noInteraction}}
      • Google アナリティクス設定
        別途定義している、アナリティクス設定変数になります。
        {{GAID}}
      • 詳細設定-タグ呼び出しオプション
        1回のイベントにつき1度
      • 配信トリガー
        event.sendEvent
    • Mixpanel のイベント送付 カスタムHTMLタグ
      Mixpanel のイベント送付用のカスタムHTMLタグです。

      • タグタイプ カスタムHTMLタグ
      • HTML
        <script>
            var customData = {{eventCustomData}};
            var eventName = {{eventName}};
            if (typeof customData === "undefined" || typeof eventName === "undefined") {
              // mixpanelは定義されている前提で処理する。
              mixpanel.track(eventName, customData);
            }
        </script>
        
      • 詳細設定-タグ呼び出しオプション
        1回のイベントにつき1度
      • 詳細設定-タグの順序付け
        タグが発効する前にタグを配信
      • 設定タグ
        ここには Mixpanel の初期化カスタムHTMLタグを設定します。
        GTM を使って、Mixpanel のタグを設定する | Monotalk に、初期化タグの設定方法は記載しましたので、そちらをご確認ください。
      • 配信トリガー
        event.sendEvent
  • イベント送信タグの使いまわし
    GTM で設定した、イベント送信用のタグは、その他のイベント送信時にも使いまわします。
    カスタムイベント、sendEvent を設定した際は、Google Analytics 、 Mixpanel に イベントが送信されます。

購読のトラッキング

notificationPermissionChange イベントを使用して、WebPush 通知の許可、不許可 の状態を送信することができます。

  • notificationPermissionChange GTMにカスタムイベントを送付するスクリプト notificationPermissionChange は、event 記録用の関数と、状態変更用の関数を作成しています。
    2つ登録しても上書きされることなく、eventのタイミングで、

    OneSignal.on("notificationPermissionChange", function(permissionChange) {
        var currentPermission = permissionChange.to;
        window.dataLayer = window.dataLayer || [];
        window.dataLayer.push({
            event: "sendEvent",
            eventName: "NotificationOpened",
            eventData:{ category : "Notification", 
                action : "PermissionChange",
                label : currentPermission,
                value : 0,
                nonInteraction : true
            },
            eventCustomData : {
                currentPermission : currentPermission
            }
        });
    });

通知パーミション表示をトリガーに event を送信する

permissionPromptDisplay使用することで、通知パーミション表示をトリガー に event を送信することができます。
正直、このタイミングで event 送信だと、粒度細かすぎるのではと思いますが、ドキュメントに従って試しに実装してみました。

  • permissionPromptDisplay GTMにカスタムイベントを送付するスクリプト
        OneSignal.on("permissionPromptDisplay", function(permissionChange) {
            window.dataLayer = window.dataLayer || [];
            window.dataLayer.push({
                event: "sendEvent",
                eventName: "NotificationDisplayed",
                eventData:{ category : "Notification", 
                    action : "Displayed",
                    label : "",
                    value : "",
                    nonInteraction : true
                },
                eventCustomData : { permissionChange : permissionChange }
            });
        });
    

設定後の感想

以下、設定後の感想となります。

  • ドキュメントに記載されている イベントリスナー で イベント送信を実行するようにしたが、正直全部に設定する必要はない。
    Webhooks の送信タイミングと、addListenerForNotificationOpened重複していそうです。
    個人的には、Measurement Protocol だと、ブラウザを開いていない状態でも送信ができるため、このタイミングでのみ送付すればよいかと思います。

  • permissionPromptDisplay で送信する意義
    通知パーミッションイベントダイアログが開かれたタイミングで、イベント送付するのは、ユーザ自身に選択させないケースで、有用に思います。
    ダイアログ開いたが、許可する割合が少ない等の場合は、表示タイミングのチューニングの余地があるかどうかがわかると思われます。

  • できることなら、GTM経由でeventは記録したい
    event 送付のためのスクリプトで、それなりの実装量になりました。クリックイベント等は、GTMからのevent 送付 で記録して、userId を記録する等、OneSignal のリスナーを使わないと、取得しにくい情報に絞って event送付するのかよいかと思います。

OneSignal には、Web Push Webhooksいう機能もあり、これを使うと、ブラウザが閉じた状態でも、通知ダイアログのイベントを記録することができます。
後日この機能も使用してみようかと思います。
以上です。

コメント