用 Claude Code 串接 Cloudflare Web Analytics API:自動產生每日流量報告

Claude Code

AI 文章延伸

AI 幫你讀這篇文章

選擇平台後可直接帶入閱讀脈絡,快速整理重點、補齊盲點,並延伸到同站相關文章。

我們團隊的官網 codotx.com 部署在 Cloudflare Pages 上,流量分析用的是 Cloudflare Web Analytics——輕量、不需要 cookie、隱私友善,而且網站本來就掛在 Cloudflare 上,在 Dashboard 開啟就能用。

但每次要看數據都得登入 Dashboard 點來點去,不太方便。我們想在 Claude Code 裡直接查流量,甚至每天自動產生報告。這篇記錄整個串接過程,包括中間踩到的幾個坑。

Cloudflare Web Analytics Dashboard,顯示 codotx.com 的流量數據和 Core Web Vitals

建立 API Token

Dashboard 看數據當然可以,但我們想在 Claude Code 裡直接查詢。Cloudflare Web Analytics 的數據可以透過 GraphQL API 取得,不過需要一組有適當權限的 API Token。

第一個嘗試是用 wrangler CLI 的 OAuth token。結果不行——wrangler 的 token scope 不包含 analytics 相關權限。

需要另外建立一組 API Token。到 Cloudflare Dashboard → My Profile → API Tokens,選擇「查看分析與記錄」範本。

API Token 建立頁面,選擇「查看分析與記錄」範本

建立時有幾個重點:

  • 權限需要:區域 Analytics 讀取帳戶 Account Analytics 讀取
  • 區域資源建議限定為特定網域,不需要開放整個帳戶的存取

API Token 權限設定,區域資源限定為 codotx.com

建立完成後,用 verify endpoint 確認 token 有效:

curl -s "https://api.cloudflare.com/client/v4/user/tokens/verify" \
  -H "Authorization: Bearer YOUR_API_TOKEN" | jq '.success'

回傳 true 就表示可以用了。

用 GraphQL API 查詢流量數據

Cloudflare Web Analytics 的 API endpoint 是 https://api.cloudflare.com/client/v4/graphql。查詢需要三個參數:

  • Account ID:在 Cloudflare Dashboard 首頁或 wrangler whoami 可以找到
  • siteTag:用來識別網站的唯一標籤
  • 日期範圍:ISO 8601 格式

siteTag 的坑

這裡我們卡了一陣子。直覺上會以為 siteTag 就是 Dashboard 上給的 beacon token,但如果你用的是自動注入模式,Cloudflare 會分配一組不同的 siteTag。

用 beacon token 查詢,回傳空陣列。資料明明在 Dashboard 上看得到,API 卻拿不到。

解法是先不帶 siteTag 篩選,改用 requestHost 來找:

curl -s -X POST "https://api.cloudflare.com/client/v4/graphql" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{ viewer { accounts(filter: {accountTag: \"YOUR_ACCOUNT_ID\"}) { rumPageloadEventsAdaptiveGroups(filter: {datetime_geq: \"2026-03-09T00:00:00Z\", datetime_leq: \"2026-03-10T23:59:59Z\", requestHost: \"codotx.com\"}, limit: 10, orderBy: [count_DESC]) { count dimensions { requestPath siteTag } } } } }"
  }'

這樣就能從回傳結果裡拿到實際的 siteTag。拿到之後,後續查詢就能直接用 siteTag 篩選了。

欄位名稱的坑

GraphQL schema 裡的欄位命名不太直覺。一開始我們用 path 查詢頁面路徑,結果噴 unknown field 錯誤。正確的欄位名稱是 requestPath

類似的情況還有國家欄位要用 countryName、瀏覽器要用 userAgentBrowser。效能數據更是要用完全不同的 dataset——rumPerformanceEventsAdaptiveGroups 而不是 rumPageloadEventsAdaptiveGroups

完整的查詢範例

以下是我們實際在用的查詢,一次拉回熱門頁面和國家分布:

{
  viewer {
    accounts(filter: {accountTag: "YOUR_ACCOUNT_ID"}) {
      topPages: rumPageloadEventsAdaptiveGroups(
        filter: {
          datetime_geq: "2026-03-09T00:00:00Z"
          datetime_leq: "2026-03-10T23:59:59Z"
          requestHost: "codotx.com"
        }
        limit: 20
        orderBy: [count_DESC]
      ) {
        count
        dimensions { requestPath }
      }
      topCountries: rumPageloadEventsAdaptiveGroups(
        filter: {
          datetime_geq: "2026-03-09T00:00:00Z"
          datetime_leq: "2026-03-10T23:59:59Z"
          requestHost: "codotx.com"
        }
        limit: 10
        orderBy: [count_DESC]
      ) {
        count
        dimensions { countryName }
      }
    }
  }
}

效能數據的查詢長這樣:

{
  viewer {
    accounts(filter: {accountTag: "YOUR_ACCOUNT_ID"}) {
      performance: rumPerformanceEventsAdaptiveGroups(
        filter: {
          datetime_geq: "2026-03-09T00:00:00Z"
          datetime_leq: "2026-03-10T23:59:59Z"
          siteTag: "YOUR_SITE_TAG"
        }
        limit: 1
      ) {
        count
        quantiles {
          pageLoadTimeP50
          pageLoadTimeP75
          pageLoadTimeP90
          pageLoadTimeP99
        }
      }
    }
  }
}

注意效能數據的單位是微秒,需要除以 1000 才是毫秒。

自動化每日報告

能從 API 拿到數據之後,下一步是自動化。我們寫了一個 shell script,每天早上用 cron job 執行,產生 markdown 格式的流量報告。

核心邏輯:

  1. date -v-1d 取得昨天的日期作為查詢範圍
  2. 送出三個 GraphQL 查詢:總覽 + 來源 + 裝置 + 瀏覽器、頁面 + 國家、效能
  3. jq 解析 JSON 回傳值,組合成 markdown 表格
  4. 儲存到 reports/YYYY-MM-DD.md

產生出來的報告長這樣:

# codotx.com 每日流量報告

**日期:** 2026-03-09

## 總覽

| 指標 | 數值 |
|------|------|
| 瀏覽量 (Pageviews) | 25 |
| 造訪數 (Visits) | 15 |

## 熱門頁面

| 頁面 | 瀏覽量 |
|------|--------|
| `/` | 18 |
| `/about/` | 2 |
| `/news/2026-03-09-claude-code-lsp-setup/` | 2 |

一開始我們用 Claude Code 的 /loop 指令來排程,設定每天早上 10 點自動跑報告。用起來很方便,但有個根本問題:/loop 的排程只存在於當前 session,Claude Code 關掉就沒了。對於每天要跑的任務來說不太實際,最後還是回到 cron job。

設定 cron job 的指令:

# 每天早上 10:03 執行
3 10 * * * /path/to/scripts/daily-report.sh >> /path/to/reports/cron.log 2>&1

reports/scripts/ 資料夾都加到 .gitignore,不進版控。

踩坑總結

整個串接過程遇到三個問題:

  1. wrangler OAuth token 權限不足 — 需要另外建立有 Analytics 讀取權限的 API Token
  2. siteTag 跟 beacon token 不同 — 自動注入模式下,Cloudflare 會分配不同的 siteTag,需要用 requestHost 反查
  3. GraphQL 欄位名稱不直覺path 要用 requestPath,效能數據要用不同的 dataset

從建立 API Token 到 cron job 跑出第一份報告,整個過程大約一個小時。大部分時間花在找 siteTag 和摸索 GraphQL schema 上。一旦搞清楚 API 的結構,後面的自動化就很順了。

作品案例

看看我們打造的產品與專案。從 WordPress 外掛到 AI 客服方案,每一個作品都是實戰經驗的累積。

瀏覽作品案例

服務項目

WordPress 開發、WooCommerce 電商、LINE 整合、AI 解決方案,依據你的需求提供最適合的技術服務。

瀏覽服務項目

Contact

聯絡我們

若你有任何技術需求、專案諮詢或合作想法,歡迎隨時與我們聊聊(首次諮詢免費)。

  • 想打造 WordPress 網站或 WooCommerce 電商
  • 需要 LINE 整合或 AI 功能導入
  • 有產品點子想找技術合夥人一起實現
  • 既有網站需要改版升級或效能優化
  • 尋找長期穩定的技術顧問合作夥伴