CloudFlare Worker 是一個很輕量的一個微服務提供平台,開發者可以使用 CF Worker 完成一些很小的服務,例如轉址、快取、代理、驗證等等。
CloudFlare Worker + 短連結?
一開始是突發奇想說,是不是可以用 CF Worker 去搭建一個自己的短連結服務?實際上是可以的。不過其實也有很多免費/付費平台,他們其實可以提供更多的功能。
所以如果單純只有把短網址,轉換到來源網址,似乎好像有點覺得太過簡單… 所以我決定加一個東西進去,Google Analytics。
其實加入 GA 也是有點小奇怪就是了… 因為 GA 更多時候是用在追蹤使用者與網頁上的互動,例如某些按鈕的事件,或是特別需要關注的某些訂單事件等等。在這裡只是追蹤誰從哪裡去了哪裡而已。
流程是這樣
短連結觸發 CF Worker。
CF Worker 向 KV Namespace 查詢有關短連結的 UTM 設定。
如果有,把剛剛的短連結,和UTM Tags 組合起來。以 301 返回給使用者。
如果沒有,則 fallback 回設定好的位置,可能是某個首頁或 404。使用者因為301再次見到 CF Worker,這次他帶了UTM Tags來。
CF Worker 再次按照短連結的設定,詢問來源網址的 OG Data 有哪些,然後回覆使用者
使用者因為看到了帶有 UTM Tags 的網頁,被網頁中的 GA 紀錄了時間,以及 UTM Campaign 的資訊
很快的使用者終於抵達來源網址
為什麼要去查詢來源網站的 OG Data ?
因為中間層的 GA 頁面,會導致社群分享的時候,看不到來源網址的 OG Data。
而在中間層的 GA 頁面加入來源網站的 OG Data 是一個方案,另外一個加速的方案則是檢查 User Agent。當 CF Worker 發現 User Agent 有關鍵字如 “bot”,基本上應該不是使用者的主流瀏覽器,這時候就直接轉向來源網址就好。
讓 Worker 可以追蹤和轉向短連結
Step 1. 將短連結加上設定好的 UTM Tags
當 CF Worker 看到請求網址的時候,去查詢存在 KV Namespace 的紀錄中設定。接著檢查 User Agent,是否帶有 bot 的字眼,如果有,直接轉向。
如果請求網址沒有帶有 UTM tags,將請求網址加上 UTM Tags 重新導向。
// Get short link data from KV
const metaData = await getMetaData(shortLink)
if (reqUserAgent.indexOf('bot') > -1) {
// If reqeust from a crawler bot
return makeResponse(301, metaData.origin)
}
if (reqURL.search.indexOf('utm_source=') == -1) {
return makeResponse(301, `${reqURL.origin}${reqURL.pathname}?${utmBilder(metaData)}`)
}
在重新導向的時候,如果 KV Namespace 沒有定義,這時候會被 fallback 導引到預先定義好的網頁。
const getMetaData = async (shortLink) => {
const fallback = {
'origin': ME_URL,
'utm_source': 'not-found-fallback',
'utm_medium': 'web',
'utm_campaign': 'about.me'
}
const metaData = await WORKERS_KV_LINKS.get(shortLink)
if (!metaData) {
return fallback
}
return JSON.parse(metaData)
}
Step 2. 帶有 UTM Tags 回到 Worker,取得來源網址的 OG Data
CF Worker 再次見到了使用者,這次使用者帶了 UTM Tags 來。CF Worker 接著查詢來源網址的 OG Data,然後再次回覆給使用者。
async function fetchOGData(requestURL) {
const fetchOpts = {
redirect: 'follow',
follow: 20,
cf: {
cacheTtl: 10,
cacheEverything: true
}
}
const response = await fetch(new URL(requestURL), fetchOpts)
const body = await ((result) => result.text())(response)
const $ = cheerio.load(body)
const title = $('title').toString()
const metadata = $('meta').toString()
return { title, metadata }
}
const renderRedirectPage = async (requestURL) => {
const { title, metadata } = await fetchOGData(requestURL)
let results = TEMPLATE_REDIRECT.toString()
results = results.replaceAll('${title}', `${title}`)
results = results.replaceAll('${metadata}', `${metadata}`)
results = results.replaceAll('${requestURL}', `${requestURL}`)
results = results.replaceAll('${cachedAt}', `${(new Date).toISOString()}`)
return makeResponse(200, null, results)
}
Step 3. 輸出帶有 OG Data 的 HTML,並且延遲重新導向
最後,使用者看到了一個跳轉畫面,同時 GA 也紀錄了這次的重新導向。
後記
使用起來其實算是沒有太大問題,都能夠作到導向的功能,以及 OG Data 的顯示。這部份其實可以額外做出一個變化:加入設定頁面,以及 Google 登入。如此一來就可以有界面增刪查改。
Firebase 能不能用呢?以 Firebase Cloud Function 來實做應該是可以作到相同的目的,但要注意的就是 Cloud Function 免費方案(Spark Plan) 已經不能使用,在 Pay as you go (Blaze Plan) 就要小心額度上限。
另外類似的工具,例如 Heroku, netlify 等等,應該也都能做到。想要使用 CF Worker 單純是想是用看看他的功能。
但結論上來說,因為對 GA 了解還不夠… 所以還沒辦法在 GA 上獲得進一步解釋。但在這之前,還是可以先把資料累積起來,之後回頭去看數據,應該能夠看懂吧?
連結
CloudFlare Worker Document
https://developers.cloudflare.com/workers/
關於這份程式原始碼
https://github.com/dubistowch/cloudflare-worker-shortlink
OG Data
https://ogp.me/
GA4: 認識新一代的 Google Analytics (分析)
https://support.google.com/analytics/answer/10089681?hl=zh-Hant&ref_topic=9143232
邊寫邊直播的當下