ServiceWorker を使用している場合、WebPush は サイト を閲覧していない状態でも受け取ることができます。
この状態だと、サイト上の JavaScript に実装しているリスナで event の受信ができません。
OneSignal の場合、 WebHook URL の設定があり、URL を設定すると event 発生時、OneSignal の JavaScript が POST
リクエストを送信してくれます。
サーバ側に POST の受け皿となるプログラムを配置し、このプログラム経由で、Google Analytics に Measurement Protocol で event を送信できるか試してみました。結果を以下に記載します。
参考
Webhook の設定方法は以下に記載があります。
以下は、CORS に関するリンクになります。
前提
バックエンド、フロントエンドには、それぞれ以下、ライブラリを使用しています。
バックエンド
Django 、 wagtail、 puput、 djangorestframework を使用しています。
- Django (1.11.11)
- wagtail (1.13.1)
- puput (0.9.2.1)
- djangorestframework (3.6.4)
フロントエンド
react と、 React Material Web Components、react-helmet を使用しています。
- react@16.2.0
- rmwc@1.1.2
- react-helmet@5.2.0
実装
OneSignal で Webhooks URL を設定する
OneSinal の init に webhooks 属性を追加します。
cors を true にすると、X-OneSignal-Event
という Request Header を付与されて、Webhooks URL に POST 送信 が行われます。
var OneSignal = window.OneSignal || [];
OneSignal.push(["init", {
appId: "${config.oneSignalAppId}",
autoRegister: false,
allowLocalhostAsSecureOrigin: true,
notifyButton: {
enable: false /* Set to false to hide */
},
webhooks: {
cors: true, // Defaults to false if omitted
"notification.displayed": "https://mutter.monotalk.xyz/notification/collect/",
"notification.clicked": "https://mutter.monotalk.xyz/notification/collect/",
"notification.dismissed": "https://mutter.monotalk.xyz/notification/collect/"
}
}]);
サーバ側の実装
サーバ側は、 Django REST framework を使って実装しました。
-
rest_framework.py
api_view
デコレータで POST のみを受け付けるようにしました。
Header の設定有無で、HTTP_400_BAD_REQUEST
を返すようにしましたが、referrer のチェック等の実装しておいたほうがいいかもしれません。
Header のチェックで問題がなければ、POST されたデータを、Measurement Protocol の形式に変換して送信します。
content-type は、x-www-form-urlencoded なので、辞書をデータとして直接送信します。
from django.http import Http404 from rest_framework import status from rest_framework.decorators import api_view import json import requests @api_view(['POST']) def collect_notification_event(request): """ List all code snippets, or create a new snippet. """ event = request.META.get('HTTP_X_ONESIGNAL_EVENT', None) if event not in ["notification.clicked","notification.displayed","notification.dismissed"]: return Response(status=status.HTTP_400_BAD_REQUEST) if request.method == 'POST': json_data = request.data payload = {"v": "1", "t": "event", "tid": "UA-xxxxxxxx-x", "cid": json_data.get("userId", ""), "hl": "ja", "ni": "1", "ec": "Notification", "ea": json_data.get("event", ""), "el": json_data.get("heading", "") } r = requests.post("https://www.google-analytics.com/collect", data=payload) return Response(status=r.status_code) else: return Response(status=status.HTTP_400_BAD_REQUEST)
-
urls.py
from home.api.rest_framework import collect_notification_event urlpatterns = [ url(r'^notification/collect/$', collect_notification_event, name='collect_notification_event') ]
動作確認 OneSingal から、WebPush を送信する
ブラウザを閉じた状態で OneSingnal から、WebPush を送信しないと動作確認できないのかと思いましたが、開いた状態でもブラウザの Network タブを確認すると、Webhook URl に POST リクエストが送信されていることが確認できます。
OneSingal の Webhook を使用して、 イベントを送信してみました。
POST データの受信ができれば、データ形式を変換して Google Analytics 以外の解析基盤にも送付できます。
MixPanel も導入したので、そちらに送付するコードもそのうち書いてみたいと思いました。
以上です。
コメント