オープンソースのCDP:RudderStackを試してみた

# はじめ
みなさん、こんにちはM&Aクラウドの尾村です。私は一応、データエンジニアというのを名乗っているのですが、これまでCustomer Data Platformと呼ばれる製品（有名どころは、Treasure DataやKARTE）を扱ってきませんでした（そのような環境にいませんでした）。そこで今回はOSSでセルフホスト版もあるRudderStackという製品を試してみようと思います。

# 環境について
今回は簡単のために、無料で利用できるRudderStack Cloudを利用しました。試す上で、自社のサービスのログデータが必要になります。もちろん、今回はお試しのため、自社のアプリなんかは利用できません。そこで今回は簡単なサンプルアプリを使います。簡単に用意できる環境としてdockersamplesの[voting-app](https://github.com/dockersamples/example-voting-app/tree/main)を使いました。

# RudderStack cloudへのサインイン
下記のようなサインイン画面です。Googleアカウントでサインインできるのはいいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091446/63294c91-5b15-7703-a513-3b9129a74568.png)
サインインすると、下記のような画面になります。
![無題のプレゼンテーション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091446/1ee781c0-17a0-614a-245b-457d45a51093.png)


# SDKのインストール
公式ドキュメントの[Quickstart](https://www.rudderstack.com/docs/get-started/quickstart/)にあるようにjavascriptのSDKをインストールする必要があります。
add　sourceを押して、JavaScriptを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091446/7df69e65-5f1e-ba1f-272d-6149cae3d98e.png)
Name This Sourceと出てくるので適当な名前を入れましょう。
![スクリーンショット 2023-11-26 21.19.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091446/95ba1a1b-971e-1b64-8b8e-eb094f76960d.png)
コードのスニペットが表示されるので、コピーしましょう。
result/viewsのindex.htmlファイルのheadにスニペットを貼りましょう。

# page呼び出しの埋め込み

下記のスニペットをindex.htmlのheadに埋め込みました。
```html
    <script type="text/javascript">
      !function(){var e=window.rudderanalytics=window.rudderanalytics||[];e.methods=["load","page","track","identify","alias","group","ready","reset","getAnonymousId","setAnonymousId","getUserId","getUserTraits","getGroupId","getGroupTraits","startSession","endSession"],e.factory=function(t){return function(){e.push([t].concat(Array.prototype.slice.call(arguments)))}};for(var t=0;t<e.methods.length;t++){var r=e.methods[t];e[r]=e.factory(r)}e.loadJS=function(e,t){var r=document.createElement("script");r.type="text/javascript",r.async=!0,r.src="https://cdn.rudderlabs.com/v1.1/rudder-analytics.min.js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(r,a)},e.loadJS(),
      e.load("API_KEY","DATA_PLANE_URL"),
      e.page()}();
    </script>
```
そのあと、http://localhost:5000/ にアクセスしたあと、RudderStackのEventsページにアクセスすると、下記のようにイベントを受け取っている確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091446/c5faa204-c5b9-906b-a7d4-47449c99b7d8.png)

# live events
live Eventsの機能を使うとリアルタイムに送信されたデータを確認することができます。今回は、ローカルホストからアクセスしているため、全然データがありませんが、特に面白く見えませんが、referrerやscreenの情報を得得られることがわかります。

![スクリーンショット 2023-11-26 22.24.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091446/77dde400-2441-e45f-8443-715a3546802a.png)

# Data Extractの利用
CDPのレベルを上げたいと考えると、さまざまなデータソースからデータを取れないといけません。そこで、ETLの機能を試してみようと思いましたが、下記のようにfreeのプランだとSalesforceやHubSpot、その他のシステムにアクセスしようとするとupgradeを求められたので諦めました。
![スクリーンショット 2023-11-26 22.30.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091446/3518f4ba-990a-dcdd-613f-c698e01d3fe2.png)

# BigQueryへの書き込み
データを読み込めたので、今度はデータの書き込みを行います。サイドバーのcollectからDestinationsを選択し、New DestinationからBigQueryを選択します。Name Destinationに名前を選択し、データの取得元として、JavaScriptTestを選択します。次のページで必要項目を入力します。BigQueryに入れる前の段階でGCSを利用するため、連携用のサービスアカウントは、GCSとBigQueryの２つのロールを追加してあげる必要があります。
接続が成功すると、下記のように画面で接続できていることが確認できました。
![スクリーンショット 2023-11-26 23.12.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091446/4e9d8ea8-7597-21ba-d56c-fce92ce52629.png)


# データの変換
サイドバーのCollectにあるtransformationからデータの変換を定義できます。事前に定義されたものがあるので、今回はAllowlistを試してみました。allowlistは、eventがpageであるもののみを許可しています。Test Payloadも事前に定義されているものがあるので、importしました。（scriptの方はともかく、Payloadはどうしても複雑になるので、これはありがたいですね。）save transformationsをして保存しました。transformationsはfreeのプランだと、5つまで定義することが可能です。


![スクリーンショット 2023-11-26 22.44.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091446/d05a1bb0-548f-d328-6a03-ccfba0ce776f.png)
```javascript
/***
 * This transformation allows events to reach a downstream destination only if a specific property
 * contains certain values, e.g., allow only Product Added, or Order Completed events, or send
 * certain event types to a particular destination, or only send events that do not have
 * tracking plan to a specific destination
***/

export function transformEvent(event, metadata) {
    const property = event.event; // Edit event name
    const allowlist = ["page"]; // Edit allowlist contents
    if (!property || !allowlist.includes(property)) return;
    return event;
}
```

この変換を先ほどのBigQueryのDestinationに追加することができます。
![スクリーンショット 2023-11-26 23.15.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091446/21e2e248-8419-ac8a-8249-14cd4cb9560e.png)
Allowlistを選び、chooseを押せば追加できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091446/5a5d3d12-fb62-24e1-3478-00af90ecfc1d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091446/7c0db2ac-1f41-bc43-09b9-306a049ce5c4.png)

# 最後に
今回はOSSのRudderStackを試してみて、CDPに入門してみました。今までCDPを使ったことがなかったため、CDPに対してイメージがわかなかったのですが、今回入門することで、ある程度、イメージが湧いてよかったかなと思います。今回利用したものは、free版であるためにどうしても制限がありましたが、うまく使えれば強力なツールになりそうだとも感じたので、中長期的に弊社のデータ基盤としてCDPがどのような役割を持てそうかを考えていければと思いました。