Ingestly v1.0.0 について / もうJavaScriptでIDを読み書きしない

[Ingestly](https://qiita.com/hsano/items/dcb4be5bd210b54390be)プロジェクトに着手して1年ほど経ちました。
1年の間に、Fastly YAMAGOYA Meetupでお話しする機会を頂いたり、前職でAtlasプロジェクトに関わったメンバーからも支援を受けたりしました。
幸いなことに、いくつかの企業が本番環境で利用して下さるようになり、実績を蓄積しつつリアルなユースケースから改良のアイディアを得たりしています。

## ここ半年くらいの更新

ここ半年ほど、数名のコントリビューターを得て少しずつ改良を加えることができました。
当初はGoogle BigQueryだけを前提にしていましたが、今はデータベースの選択肢が広がりました。

### Elasticsearchに対応

- Elasticsearch Service ならびに 自前のElasticsearchクラスタにデータが投入できます。（Fastlyが対応したことによる）
- BigQueryではJSON文字列として1カラムに格納している情報を、Elasticsearchでは展開した状態で格納するので、スキーマレスの利便性を活用できます。
- マッピングテンプレートを用意しているので、重要なフィールドについては予め型を指定できます。

### Amazon Athenaに対応

- FastlyはもともとS3への書き出しに対応していましたが、[Takamichi Yanai](https://github.com/gigamori)さんがAthenaで扱うためのスキーマを作成してくれたことで対応できました。

### JS SDK で再帰イベントを無効にできるオプション
- [Ingestly Client JS](https://github.com/ingestly/ingestly-client-javascript)ではスクロールや読了計測で要素の可視性を観測するために再帰イベントを用います。
- この再帰イベントはSDKの初期化時に発火を開始し、requestAnimationFrameとスロットリングを組み合わせて軽量化しています。
- 一方で、最小限のデータ送信だけを行いたい場合には無駄な処理になるため、この再帰イベントそのものを発動しないオプションを追加しました。

### Ingestly O2O

- [Ingestly O2O](https://github.com/ingestly/ingestly-o2o)はHTMLとJavaScriptだけで構成したO2O的なユーザー識別を行うサンプル実装です。
- Ingestly O2Oは２つのHTMLで構成されており、1つはイベントや店舗への来場者がQRコードを生成する画面、もう一つはイベント主催者側が来場者のQRコードをスキャンした結果を記録するための画面です。
- この仕組みでは、来場者が自信のデバイスでQRコードを生成・表示（Ingestly IDが埋め込まれている）を表示し、主催者がそれを読み取ることで、そのIngestly IDのデバイスがその場にいたという事実を記録することができます。

### Ingestly Survey

- [Ingestly Survey](https://github.com/ingestly/ingestly-survey)を使うと、NPSや1問アンケートのような施策をIngestlyで行えます。
- 仕組みとしては、単にフォームをパースして内容をIngestlyに送るJavaScriptなので、どんなフォームでもIngestlyで回答を扱えます。（個人情報や決済情報を扱うセンシティブなフォームでの利用は避けましょう）
- Ingestly Surveyの結果はIngestly IDやUser IDで集計できるので、前後の行動や過去のエンゲージメント度合いとアンケート結果を紐づけた分析に利用できます。

### Ingestly Chrome Extension （デバッグ用）

- [Ingestly Chrome Extension](https://github.com/ingestly/ingestly-chrome-extension)も随時アップデートし、最新のカラムに対応させてきました。

## v1.0.0 での改良

1年ほど、v0.x ということで更新を続けてきましたが、以下の2つの改良を加えID管理体系を変え、また着手から1年くらいなので、メジャーバージョンを1に上げることにしました。
アップデートに際しては、必ずエンドポイント側の更新を先に適用して下さい。SDKのv1.0.0を利用するには、エンドポイントもv1.0.0である必要があります。逆に、エンドポイントがv1.0.0であれば、SDKはv1.0.0でもv0.6.xでも対応します。

### JavaScriptでCookieやlocalStorageを操作しない

- 従来のSDKではユニークIDをJSで生成し、Root ID、Session ID、Ingestly IDの3つに利用していました。
- エンドポイントはSDKから渡されたIngestly IDをCookieとして戻すことで、ブラウザ上でIDの永続化を行っていますが、一方で従来はブラウザ側でlocalStorageまたはCookieで別途キャッシュさせる処理をしていました。
- v1.0.0ではこのキャッシュ処理を削除し、IDの管理は全てエンドポイントで完結させています。また、これに伴い、HTTP200でIDを戻す必要がなくなるため、全てのリクエストはsendBeaconとHTTP204の組み合わせで完結するようになりました。

### GDPRやCCPA、個人情報保護法への対応に必要な同意管理

- これまで、あくまで「サイトと同じ環境で運用される」「自社で用意した内製ツール」の位置づけとして、サイトの1機能として振る舞うことを想定していました。
- しかし、CCPAや国内の個人情報保護に関する法規の改定、そして何よりもUXの観点から、同意管理と追跡からのオプトアウトが必要だと判断しました。
- v1.0.0では、SDKを初期化した時点のデフォルトはCookieを用いない＝個々のデバイスを識別しないモードとなります。オプション指定により初期化時点でデバイス識別を有効化（従来の動作）することもできます。
- また、個々のブラウザ上で同意管理を行うことで、個別にCookieを用いた識別を無効にしたり、計測そのものからオプトアウトすることも可能です。
- さらに、オプトアウト処理を行う `setConsent()` メソッドは、任意の同意情報を管理・記録できるようになっているため、「計測は許諾するが分析からはオプトアウトしたい」「サイト内の利用は許諾、しかしターゲティングには利用されたくない」といったデータの利用目的に応じた同意管理をサポートします。（正し、当然Ingestly単体で組織統制を行うわけではないため、クエリーの組み立てやデータの利用範囲は自社で業務フローを整備すべきです）

### Cookie

- SDKが `setConsent()` メソッドを利用して同意情報を保存する際、保存する処理はエンドポイントが行います。こうすることで、同意情報を記録するCookieの有効期限を適切に設定し、再同意の手間を削減します。
- また、 `setConsent()` を用いてCookieによる追跡からオプトアウトする場合、エンドポイントはCookieを抹消します。
- エンドポイントがデバイス識別を行うCookieは、従来から `Secure` 、 `httpOnly` 、そして `sameSite=LAX` 属性を持つファーストパーティCookieでしたが、v1.0.0ではさらにドメインをエンドポイントのホスト名まで含める形にし、Cookieを広範囲（gTLD+1 のような広さ）に送信せず、あくまでエンドポイントとのみやりとりするように変更しました。一般的に、サイト内の他のツールを含め "Ingestly以外" がIngestlyのCookieを読むことはできなくなりました。


## 今後の見通し

- バルク挿入の準備に着手しました。通信のオーバーヘッドを削減したり、JavaScriptにおいてもオフライン計測を実現することを視野に入れています。特にGoogle Cloud Pub/SubとDataflowを組み合わせ、リアルタイムなエンリッチメントパイプラインを構築することを検討しています。
- iOSならびにAndroidアプリのSDKを作ろうと考えています。これまではWebに割り切っていましたが、同じくらい簡単に、同じくらい自動化をしたアナリティクスを目指したいと思います。
- Firebase Analyticsがもう少し改良されたらIngestlyいらないのでは、とも思っています。（良いツールがあれば自分で作る必要はない！）