Threads API 已經推出一段時間,各路大神也都分享過很多串接經驗
甚至有一些對應的分析產品推出
像是 Threadslytics
除了有資料分析外,還有排程貼文的服務
有需要的朋友如果想要穩定好用,可以參考看看
最近比較有點空閒的時間,就想利用 Cursor 來嘗試看看利用 AI 的助力開發
個人用的類似分析工具,簡單的把資料撈回來並且搭配熟悉的 Looker Studio 視覺化
Threads API 的準備
Threads API 的申請和文件 Threads API 官方文件
由於網路上蠻多類似的中文資源了,這邊就不想重新贅述一次
但可以提供一些詳細的資訊:
- Threads - Alfonso 的 10 篇連載
- 利用發佈不久的 ChatGPT search 功能查詢:
對話連結
- 使用 Perplexity Pro 的查詢:
對話連結
上面的搜尋對話都可以接著繼續往下查詢
如果有遇到問題或是卡住的地方
歡迎到 IG 這邊私訊聊聊
darrell_tw_
Google App Script 串 Threads API
主要 main function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| function updateAllThreadsData() { if (DEV_MODE) { Logger.log('=== 開始全部數據更新流程 ==='); Logger.log('時間:' + new Date().toISOString()); } try { // 1. 更新所有貼文的數據 if (DEV_MODE) Logger.log('1. 開始更新貼文數據'); getAllPostStats(); // 2. 更新每日用戶數據 if (DEV_MODE) Logger.log('2. 開始更新每日用戶數據'); getUserInsights(); // 3. 更新追蹤者數據 if (DEV_MODE) Logger.log('3. 開始更新追蹤者數據'); updateFollowersCount(); if (DEV_MODE) { Logger.log('=== 全部更新流程完成 ==='); Logger.log('完成時間:' + new Date().toISOString()); } } catch (error) { Logger.log('更新過程發生錯誤:', error); throw error; } }
|
程式碼大部分都是請 Cursor AI 幫忙,我自己只有做點調整
但我有特別說明的 prompt 有:
- 加上 DEV_MODE,讓我在執行除錯時可以顯示盡量詳細的 log,如果有預期外的錯誤或是停住,至少可以知道目前執行到哪裡
- 加上 try catch,未來有需要可以對錯誤做其他處理
主要執行的邏輯有三段:
- 更新所有貼文的數據
- 更新每日用戶數據
- 更新追蹤者數據
更新貼文數據
取得所有貼文
1 2 3 4 5
| const url = `https://graph.threads.net/v1.0/me/threads?fields=id,shortcode,timestamp,text,is_quote_post,media_type,permalink&access_token=${ACCESS_TOKEN}`;
const response = UrlFetchApp.fetch(url, { method: "GET" });
|
取得所有貼文的回傳資料
要使用 Threads API 表示我們需要能夠發送一個 request 過去
Google App Script 不像一般的 JavaScript 有內建的 fetch API,所以需要使用 UrlFetchApp
其實用法非常接近,只是就記得需要使用 UrlFetchApp
就好
後續就是處理 Response
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const contentText = response.getContentText(); const data = JSON.parse(contentText);
const postsWithInsights = data.data.map(post => { Logger.log(`正在獲取貼文 ${post.id} 的指標數據`); const insights = fetchPostInsights(post.id); // 這邊是取得單一貼文的表現數據,下面會提及 // 取得數據後會再跟原本的貼文資料做合併
const postWithInsights = { ...post, insights }; return postWithInsights; });
|
再取得單一貼文數據
這邊有個邏輯是上面的 API 要先取得所有的貼文 id, text
但沒有數據,
數據需要使用另外一個 {postId}/insights
API 去取得
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| const METRICS = ['views', 'likes', 'replies', 'reposts', 'quotes', 'shares']; const postStatsUrl = `https://graph.threads.net/v1.0/${postId}/insights?metric=${METRICS.join(',')}&access_token=${ACCESS_TOKEN}`;
const response = UrlFetchApp.fetch(postStatsUrl, { method: "GET" });
const data = JSON.parse(response.getContentText()); if (!data || !data.data) { throw new Error('API 回應格式錯誤'); }
const insights = { views: 0, likes: 0, replies: 0, reposts: 0, quotes: 0, shares: 0 };
data.data.forEach(metric => { if (metric.values && metric.values.length > 0) { insights[metric.name] = metric.values[0].value || 0; } else if (metric.total_value) { insights[metric.name] = metric.total_value.value || 0; } });
|
取得單一貼文的回傳資料
如果對上面的概念有點模糊,可以參考這個示意圖
到這邊為止,就處理貼文的數據部分
算是完成了三分之一
接下來要繼續處理用戶數據
更新每日用戶數據
取得用戶數據 API 文件
用戶數據部分的指標有一些不直覺的地方
瀏覽數 Views 會是一天一天的資料
其他的都是時間區間內的總數
另外 followers_count 和 follower_demographics 不支援 since & until 的參數
代表無法取得以前的資料,只會拿到目前最新的數據
這邊用兩張圖來呈現概念
腦中如果有這些資料代表什麼意思,那後續就會更知道要怎麼處理和整理資料了
1 2 3 4 5 6 7 8
| // 取得日期範圍(今天往前30天) const days = DEV_MODE ? 10 : 30; const dates = []; for (let i = 0; i <= days; i++) { const date = new Date(); date.setDate(date.getDate() - i); dates.push(date); }
|
首先,要決定往前處理幾天的資料
DEV_MODE 是為了快速除錯測試,只會處理 10 天
正式環境就處理 30 天
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| // 處理每一天的數據 dates.forEach((date, index) => { const dateStr = Utilities.formatDate(date, 'GMT+8', 'yyyy-MM-dd'); const startTime = Math.floor(date.setHours(0, 0, 0, 0) / 1000); const endTime = startTime + (24 * 60 * 60) - 1; const url = `https://graph.threads.net/v1.0/me/threads_insights?metric=views,likes,replies,reposts,quotes,followers_count&since=${startTime}&until=${endTime}&access_token=${ACCESS_TOKEN}`; const response = UrlFetchApp.fetch(url, { method: "GET", redirect: "follow", muteHttpExceptions: true }); const data = JSON.parse(response.getContentText()); const metrics = { views: 0, likes: 0, replies: 0, reposts: 0, quotes: 0 };
data.data.forEach(metric => { if (metric.values && metric.values.length > 0) { metrics[metric.name] = metric.values[0].value || 0; } else if (metric.total_value) { metrics[metric.name] = metric.total_value.value || 0; } }); //... // 避免 API 請求過於頻繁 Utilities.sleep(200); })
|
取得每一天的 start time 和 end time 的 timestamp
帶入 API 並取得資料,並注意 API 請求的速率,這邊降低為 200ms,也就是一秒鐘 5 次
雖然文件沒有提及 Meta 有限制,但友善的 call API 從你我做起
取得資料後整理為 Google Sheet 需要的格式存入即可
更新每日追蹤者數的成長
如上面概念圖片提到,追蹤者數的成長是無法溯及以往的資料
只能從開始撈的當下開始記錄
例如從 11/01 開始撈,當天的追蹤者數是 1500
那就是從 1500 開始累積紀錄了
可能到 12/01 會是 3000
邏輯就跟使用者數據一樣,處理上簡單很多,就只要處理 followers_count 即可
1 2 3 4 5 6 7 8 9
| const followersUrl = `https://graph.threads.net/v1.0/me/threads_insights?metric=followers_count&access_token=${ACCESS_TOKEN}`; const followersResponse = UrlFetchApp.fetch(followersUrl, { muteHttpExceptions: true }); const followersData = JSON.parse(followersResponse.getContentText());
followersData.data.forEach(metric => { if (metric.name === 'followers_count' && metric.total_value) { followersCount = metric.total_value.value || 0; } });
|
Looker Studio 視覺化 Threads API 資料
Looker Studio 視覺化,只需要使用 Google Sheet 就好
另外這份報表也沒有用到太多進階的功能
我是把資料存成三個 tab:
一個存貼文資料
一個存用戶數據
一個存追蹤者數據
目前 Looker Studio 的資料只有呈現用戶數據和追蹤者數量
貼文數據未來會放入,但不想單純放上 table 而已
現階段的小目標是想把這份 Looker Studio 整理一下並且讓它可以被重複使用
預想是大家複製過去後,在接上自己的 Google Sheet 就完成
用一個簡短的範例介紹如何拉其中一張圖表