前面說了那麼多理論,最後幾天來寫一下開發實務吧!今天要介紹的是怎麼收集 App 使用者行為資料。
追蹤事件是需要成本的,這些成本包括開發、蒐集、除錯、分析等。因此一開始思考的點是「哪些事件對於商業來說是最重要的」。
由於當時的 App 的商業模式是以廣告為主,最重要的就是說服我們的 App 能幫廣告主帶來流量,因此最重要的資料應用就是每日活躍使用者數報表,用這個報表向廣告主說明每天會有多少人看過他們的廣告,並以此來收費。從一開始就很明確要追蹤的資料以及應用上的目的。
最一開始的設計當然是以簡單為主,幸好市面上有很多工具可以協助我們做到這件事。其中最有名也最普遍的就是 GA 了(Google Analytics)只要在網站或是 App 裡埋上對應的追蹤碼,GA 就能蒐集很多使用者的行為資料。如果要紀錄比較複雜的行為,可以使用自定義的事件,在應對的使用者行為發生時送給 GA。
GA 的開發真滴簡單,只要在網站裡埋對應的追蹤碼就可以了。
同上,埋好之後就可以在 GA 的後台確認有沒有部署成功,成功的話就能看到流量進來了。
雖然大家對於 GA 的數字還是有爭議,但畢竟是 Google 的產品,所以也算是一般業界很常用來參考的數值。初期需要評估的大概就是兩個點:
小的迭代像是增加追蹤事件,或是調整 GA 報表之類。
用 GA 就是如此的方便,但之後就越來越難了。當滿足基本商務需求後,接著就會有更複雜的商務需求,像是:「想知道不同年齡、性別的使用者會看什麼影片來更了解使用者以及找到合適的廣告主」、「想知道哪部片最受歡迎來做排名推薦」、「想知道使用者留存率來優化使用者體驗」等等。因為 GA 僅提供統計資料、沒有辦法知道特定的使用者行為,當 GA 無法滿足這些需求時,就只好開始刻自己的事件追蹤器了。
為了追蹤個別使用者行為,在自製事件追蹤便納入了使用者辨識碼。以 App 來說,對於登入的使用者就會用登入帳號(Email 或個人 ID 之類),對於未登入的使用者之前可以用 Device ID 來做使用者識別。
第一個自製的事件追蹤,我們先用了一個很簡單的 JSON 來定義與傳送資料。
{
"device_id": "u123141",
"email": "xxxx@gmail.com",
"user_id": "u123123",
"timestamp": "2021-09-29 00:00:00",
"event": "login",
"content1": "email",
"content2": "",
"content3": "",
"content4": ""
}
除了資料定義之外,也要考慮到後續怎麼收集。
我們初步選擇 AWS Kineis 來做資料的收集以及 Lambda 來做後續的處理,並將處理完的資料放到 S3
App -> Kinesis -> Firehose -> SQS-> Lambda -> S3
在選擇資料收集方法上的時候,要考量到價錢、可擴張性、易維護性以及穩定性。真的是幸好現在有 AWS 這樣的雲端服務才讓這件事情變得容易許多(但 Kinesis 上次也是死了...)。
由於這次是自製事件追蹤,在設計上就牽扯到很多單位。
前端
前端需要實作追蹤事件,在特定的行為發生後將事件傳送出來。
後端
由於剛開始沒有人力開發後端,所以就採用上述的方式,將資料直接從前端拋到 Kinesis 上。
Data
Data Team 初期會負責檢核資料以及做資料的前處理。
由於自己開發的元件和牽扯到的團隊變多,部署時也開始複雜起來。前端、後端、Data 都有各自的部署週期,在團隊間溝通上特別需要溝通好,以免就是前端上線、但是後端還沒準備好的情況。這種時候上線建議先從 Data 開始上線,確保處理資料程式上線後,前端再讓資料上線,以避免寶貴資料丟失的狀況。
評估的時候除了前面提到的商務需求外,也需要評估自己開發的部分有沒有問題,包括系統穩定度、負載量等等。因為 GA 的程式還沒拔掉,所以也可以交叉比對一下自己收下來的資料與 GA 的差異(通常都會有差異)是否穩定。
上線之後除了修 bug 之外,當然也會依照實際需求來調整追蹤的事件,前後端和資料團隊都需要頻繁的溝通和調整。
隨著 App 逐漸複雜,使用者事件也會開始變得複雜。這時候原本的事件系統也變得越來越難維護,所以我們又痛定思痛做了一次大改版 QQ...
由於每個事件都有對應的資料要傳,所以這次乾脆就獨立一個欄位將事件內容放在裡面方便整理。
{
"device_id": "u123141",
"user_id": "u123123",
"timestamp": "2021-09-29 00:00:00",
"event": "login",
"data": {
"method": "email",
"email": "xxxx@gmail.com"
}
}
{
"device_id": "u123141",
"user_id": "u123123",
"timestamp": "2021-09-29 00:00:00",
"event": "itemview",
"data": {
"item_type": "recommendation"
"item_id": [1, 2, 3, 4],
"item_url": ["www.qq.com/1", "www.qq.com/2", "www.qq.com/3", "www.qq.com/4"]
}
}
這樣設計的用意是想讓紀錄事件的內容文件看起來清楚一點,但事實證明當事件一多之後還是很恐怖...抱歉了我的前同事們...
在新事件上,我們因為一些原因屏除了直接打到 Kinesis 的方法,改用 RESTFul API 來接事件,這樣以可以讓後端做初步的資料格式檢查。但溝通上就更複雜,需要前端+後端+資料三個團隊一起涉入開發,開發複雜度也直接上天。當初最難的做的應該是實作自己的 session(https://support.google.com/analytics/answer/6086069?hl=zh-Hant&ref_topic=6083659) 機制吧...抱歉了我的前同事,但是我們真的需要這個酷東西。
整體開發來說,事件定義是最難的。除了 Session 以外,當初還想知道使用者實際上有看到哪些版位,IOS、Android、Web 對相同定義的實作方式都完全不同。
除了複雜度增加外,跟之前的差不多就跳過。
當事件越來越多,有幾件事變得特別複雜
每個都有一段血淚史這邊我就先不挖了。
好的事件是分析的第一步,千萬不能覺得這些事件都是前端的事情,實作上前端真的有很多問題需要一起克服解決,才能維持事件的品質。