寫程式、查問題
沿用專案現有的語言和寫法(Node.js、Python、C#、Go 都行,沒有專案時用 Python),把文件規則直接寫進程式:token 從環境變數讀、發文走完整流程、送出前先在本機檢查、4xx 錯誤不盲目重試。
「幫我用 TypeScript 寫一個每天抓 Threads 貼文數據的排程,token 要能自動續期。」
開源的 Agent Skill。裝進 Claude Code、Codex、Cursor 等工具後,AI 助理寫串接程式、代你發文、嵌入貼文,都照 Meta 官方文件的規則來。
bunx skills add Scorpio-meow/Threads-skill --skill threads-api -g
你
幫我發一則 Threads:「週末限定!新品手沖咖啡豆 9 折 ☕️ 詳情看這裡 https://example.com/sale」,附一個投票問大家喜歡「淺焙」還是「深焙」,然後設成 24 小時後自動消失的限時貼文。token 我已經放在環境變數 THREADS_ACCESS_TOKEN 了,直接幫我發。
Claude・有技能
還沒發出,也還沒呼叫任何 API。
Threads API
的限時貼文(is_ghost_post=true)只能是純文字,唯一能另外加的是文字防雷(spoiler),投票、GIF、連結預覽卡都不支援。我先在本地檢查(不呼叫
API),就被擋下了:ghost posts only support text spoilers, not poll_attachment。這兩個功能我不會擅自拿掉任何一個,請你決定:
方案 A|限時貼文,不附投票
media_type=TEXT
text=週末限定!新品手沖咖啡豆 9 折 ☕️ 詳情看這裡 https://example.com/sale
is_ghost_post=true
方案 B|一般貼文+投票
media_type=TEXT
text=週末限定!新品手沖咖啡豆 9 折 ☕️ 詳情看這裡 https://example.com/sale
poll_attachment={"option_a": "淺焙", "option_b": "深焙"}
現在是 10/14(三)上午 9:37。限時貼文如果現在發,大約 10/15(四)上午 9:37 就會封存,這個週末(10/17–18)完全看不到。
後面還有方案 C(拆成兩則)、網址是範例網域、投票沒有題目欄位等提醒,以及在你電腦上執行的指令。
Claude・沒技能
這則還沒發出去。有一個地方卡住,另外有幾件事要你決定。
你的三個要求沒辦法放進同一則。我不想自己默默拿掉其中一個,所以請你選:
「不能附投票」是我對 Threads API 規則的理解。這次沒有 token,所以我沒辦法實際打 API
驗證。腳本的 ghost-poll 模式會先用不公開的方式試一次,API 拒絕就停下來,不會自己改發別的版本。
python3 post_threads.py --variant poll --url https://你的網址/sale
--variant 也可以換成 ghost(方案 A)或 ghost-poll(照原需求試)。
今天是週三(10/14),現在發的限時貼文週四就會消失,撐不到週末。
7/7
評分者逐條判定的檢查項目
7 項都通過
5/7
評分者逐條判定的檢查項目
其餘 5 項都通過
問一句跟 Threads API 有關的事,技能就會自動啟用,再依你要的是程式、操作帳號還是網頁嵌入,換一套做法。
沿用專案現有的語言和寫法(Node.js、Python、C#、Go 都行,沒有專案時用 Python),把文件規則直接寫進程式:token 從環境變數讀、發文走完整流程、送出前先在本機檢查、4xx 錯誤不盲目重試。
「幫我用 TypeScript 寫一個每天抓 Threads 貼文數據的排程,token 要能自動續期。」
threads_client.py技能內建的參考用戶端・publish()
container = call("POST", f"{user}/threads", spec)
log(f"created container {container['id']}")
if spec.get("auto_publish_text"):
return container # already live; the docs don't document this response
wait_ready(container["id"])
media = call("POST", f"{user}/threads_publish", {"creation_id": container["id"]})
log(f"published media {media['id']}")
result = {k: v for k, v in container.items() if k != "id"}
result.update(media)
try:
result.update(call("GET", media["id"], {"fields": "permalink"}))
except ThreadsError as err: # the post is live; don't turn a lookup failure into an error
result["permalink_error"] = str(err)
return result
建立 container → 等到 FINISHED → 發佈 → 只查 permalink
用你的 token 發文、回覆、查數據、隱藏留言。先呼叫 GET /me
告訴你要操作哪個帳號;發文、刪文、隱藏留言之前,列出完整內文和每個參數,等你明確同意。只是查資料就不必確認。
「把我最新一篇貼文底下提到『加賴』的留言隱藏起來。」
終端機參考用戶端的指令與輸出格式(示意)
$ python3 threads_client.py get me fields=id,username
{
"id": "1784140000000001",
"username": "your_account"
}
$ python3 threads_client.py check spec.json
{
"errors": [],
"warnings": [],
"text_length": 54,
"links": [
"https://example.com/sale"
]
}
$ python3 threads_client.py publish spec.json
created container 17991200000000001
published media 18063400000000002
{
"id": "18063400000000002",
"permalink": "https://www.threads.com/@your_account/post/…"
}
用 oEmbed 取得嵌入碼(2026 年 3 月起不需要 token),整頁只載入一次 embed.js,插入貼文後呼叫
instgrm.Embeds.process()。一頁放很多則時依序載入,失敗的換成連回原文的卡片。
「幫我做一面 60 則精選貼文的展示牆,並每週自動檢查哪些貼文已經被刪掉。」
wall.html嵌入貼文的寫法
<!-- 整頁只載入一次 -->
<script async src="https://www.threads.com/embed.js"></script>
<script>
// 從驗證過的網址組出嵌入標記,不用 innerHTML
const q = document.createElement("blockquote");
q.className = "text-post-media";
q.dataset.textPostPermalink = url;
q.append(fallbackLink(url)); // 載入失敗時留下的連結
wall.append(q);
window.instgrm?.Embeds?.process();
</script>
Content-Security-Policy
script-src 'self' https://www.threads.com;
frame-src https://www.threads.com;
以下都是評測裡發生過的:同一個模型沒裝技能時答錯,裝了技能就沒再犯。錯的多半不是程式,而是藏在文件細節和最近 changelog 裡的規則。
GET /profile_lookup?username=…
沒技能時:說 profile_lookup 只查得到粉絲 1,000 人以上的帳號,或完全沒提門檻。
文件寫的:門檻在 2025 年 11 月已經降到 100。只查得到公開帳號,用戶名要完全一致、不加 @。
你的貼文底下的留言POST /{reply-id}/manage_reply
coffee_fan
請問什麼時候到貨?
deal_bot
想要更便宜?加賴領優惠
mei.brews
我也想知道
沒技能時:先對巢狀回覆本身呼叫隱藏,失敗了才改處理上層留言。
文件寫的:manage_reply 只對第一層留言有效,而且會連同底下整串一起隱藏。技能會先說明這個取捨,再讓你決定。
GET /me/threads?fields=id,text&limit=25
{
"data": [ … ],
"paging": {
"cursors": {
"before": "QVFIUmFtN2Vx…",
"after": "QVFIUkd3cDJ0…"
}
}
} // 沒有 "next"
沒技能時:翻頁只跟著 paging.next 走。
文件寫的:貼文列表的回應只有 cursors,沒有 next。只等 next 的程式,照文件的說法只會抓到第一頁。
長效 token 的一生th_refresh_token
發出未滿 24 小時:還不能續期
滿 24 小時、還沒過期:可以續期,換到新的 60 天
剩不到 10 天,或每週固定續一次(技能的建議)
過期後不能續期,只能請使用者重新授權
沒技能時:續期前沒檢查 token 是否已發出滿 24 小時、而且還沒過期。
文件寫的:長效 token 約 60 天到期,發出滿 24 小時、還沒過期時才能續;新 token 和到期時間要一起存好。
把貼文加進頁面embed.js
wall.innerHTML += savedEmbedHtml;
wall.append(blockquote);
window.instgrm?.Embeds?.process();
沒技能時:以為 embed.js 只在載入時掃描一次,於是把每則貼文各包進一個 iframe 頁面。
技能寫的:用 innerHTML 塞進去的 <script> 不會執行。整頁載入一次 embed.js,插入貼文後呼叫
process() 就會重新掃描。這部分官方沒有文件,是 2026 年 10 月讀 embed.js 程式碼觀察到的。
GET /v1.0/oembed?url=…HTTP 400
{
"error": {
"message": "Media Not Found",
"code": 24,
"error_subcode": 4279056,
"is_transient": false
}
}
沒技能時:以為要先有 Meta App 和 token 才能準確檢查,改去爬 threads.com 的頁面。
文件寫的:oEmbed 從 2026 年 3 月起不需要 token。貼文不存在時回明確的
code 24,只有這時才從清單移除,其他錯誤都當成暫時性問題。
這是技能內建用戶端 threads_client.py 的
check(),原樣搬上網頁:字數照 API 的算法(emoji 依 UTF-8 位元組計算),也檢查連結數和功能衝突。
text
字數54/500
連結1/5
1 個錯誤,publish 會在呼叫 API 前停下
ghost posts only support text spoilers, not poll_attachment
會送出的參數POST /me/threads
media_type=TEXT
text=週末限定!新品手沖咖啡豆 9 折 ☕️ 詳情看這裡 https://example.com/sale
poll_attachment={"option_a": "淺焙", "option_b": "深焙"}
is_ghost_post=true
access_token 從環境變數帶入,這裡不顯示。
改一下內文、關掉限時貼文,或把貼文類型換成 IMAGE,看看哪些功能會被擋下。
這個檢查工具需要 JavaScript。可以直接讀 check()
的原始碼,或在自己的電腦執行 python3 threads-api/scripts/threads_client.py check spec.json。
| 題目 | 第 1 輪 | 第 2 輪 | 第 3 輪 | 第 4 輪 | 第 5 輪 | 第 6 輪 | 第 7 輪 |
|---|---|---|---|---|---|---|---|
| Python 輪播貼文(兩張圖+一支影片) | 8/88/8 | 未測 | 未測 | 未測 | 未測 | 未測 | 8/88/8 |
| TypeScript 每日數據排程與 token 續期 | 9/97/9 | 9/97/9 | 9/99/9 | 未測 | 未測 | 9/98/9 | 9/97/9 |
| 代發附投票的限時貼文 | 6/63/6 | 6/75/7 | 7/75/7 | 未測 | 未測 | 未測 | 7/76/7 |
| 搜尋、地點、查帳號結果異常的原因 | 未測 | 6/65/6 | 6/65/6 | 未測 | 未測 | 6/65/6 | 7/75/7 |
| 自動隱藏含關鍵字的留言 | 未測 | 7/76/7 | 7/76/7 | 未測 | 未測 | 未測 | 7/76/7 |
| 60 則貼文牆與每週檢查被刪貼文 | 未測 | 未測 | 未測 | 8/82/8 | 未測 | 未測 | 8/83/8 |
| FastAPI 接收留言與提及的 webhook | 未測 | 未測 | 未測 | 未測 | 7/88/8 | 8/86/8 | 8/86/8 |
| Express 的 OAuth 登入與長期 token 續期 | 未測 | 未測 | 未測 | 未測 | 8/87/8 | 8/87/8 | 8/87/8 |
| 審查一段出錯的 Python 發文程式 | 未測 | 未測 | 未測 | 未測 | 8/86/8 | 未測 | 8/86/8 |
| 隔天早上 8 點代發含 emoji 的串文 | 未測 | 未測 | 未測 | 未測 | 7/76/7 | 未測 | 7/75/7 |
| 平均通過率 | 100%76% | 96%80% | 100%85% | 100%25% | 97%87% | 100%84% | 100%77% |
每題在兩種設定下各跑一次,再由沒參與作答的評分者,照事先寫好的檢查項目逐條判定,並附上證據。作答、評分都用 claude-opus-5-5。
樣本很小,數字只能看方向:第 2 題沒技能的版本前兩輪都在翻頁和 token 續期上失分,第 3 輪卻拿到滿分。測試只在 Claude 上跑過;第 1–4 輪的 API 呼叫都打在評分者架的模擬伺服器上,第 5 輪則由評分者閱讀程式碼判定,第 6、7 輪則由評分者重跑作答者的測試,再用自己寫的模擬實測。技能本身要讀進約 1.1 萬 token,所以第 1 輪有技能比較慢;第 2、3 輪反而比較快,評分者認為是少了試錯。
文件快照涵蓋到 2026-08-18 的 changelog。標成 practice 的是工程建議,observed 是實測結果,其餘都出自 Meta 官方文件。下面挑出各節最常用到的數字。
POST /me/threads_publishstatustextlink_attachmentchildrenpoll_attachmentthreads_publishing_limitlimit
keyword_search
profile_lookupthreads_profile_discoverylocation_search
profile_lookupmanage_replyreply_to_id/conversationhide_status
manage_pending_reply/{media-id}/insights
follower_demographics
threads_insightsREPOST_FACADEfollowers_countcodeth_exchange_tokenth_refresh_tokendata_access_expires_atthreads_basicTHREADS_APP_IDquota_usagereply_quota_usagedelete_quota_usagelocation_search_quota_usage/oembedapp-level/oembedmaxwidthembed.jsEmbeds.process()code 24Content-Security-PolicyOAuthExceptionMedia Not FoundHTTP 429LINK_LIMIT_EXCEEDEDcurllocation_search
skills 指令會偵測你電腦上的 AI 工具,放到各自讀取的資料夾。裝好後問一句跟 Threads API 有關的事,技能就會自動啟用。想手動安裝,或要上傳到 Claude 應用程式,看下面的常見問題。
安裝 threads-api 技能
bunx skills add Scorpio-meow/Threads-skill --skill threads-api -g
加上 -g 裝到個人目錄,這台電腦上的所有專案都能用。
不加 -g 就只裝到目前的專案;沒有 Bun 的話,把 bunx 換成 npx。
把 threads-api 資料夾複製到工具讀取的技能資料夾,讓 SKILL.md 落在
<技能資料夾>/threads-api/SKILL.md。個人資料夾給這台電腦上的所有專案用;專案資料夾放在專案根目錄,可以 commit 給團隊一起用。
| 工具 | 個人資料夾 | 專案資料夾 |
|---|---|---|
| Claude Code | ~/.claude/skills/ |
.claude/skills/ |
| OpenAI Codex | ~/.agents/skills/ |
.agents/skills/ |
| GitHub Copilot | ~/.copilot/skills/ |
.github/skills/ |
| Cursor | ~/.cursor/skills/ |
.cursor/skills/ |
| Gemini CLI | ~/.gemini/skills/ |
.gemini/skills/ |
| Google Antigravity | ~/.gemini/config/skills/ |
.agents/skills/ |
| Devin Desktop | ~/.config/devin/skills/ |
.devin/skills/ |
| OpenCode | ~/.config/opencode/skills/ |
.opencode/skills/ |
| Cline | ~/.cline/skills/ |
.cline/skills/ |
| Kiro | ~/.kiro/skills/ |
.kiro/skills/ |
| JetBrains Junie | ~/.junie/skills/ |
.junie/skills/ |
| Roo Code | ~/.roo/skills/ |
.roo/skills/ |
Codex、Copilot、Cursor、Gemini CLI、OpenCode、Devin Desktop、Junie、Roo Code 也會讀 ~/.agents/skills/,放一份在這裡就能共用。~
在 Windows 是使用者資料夾。工具沒偵測到新技能時,重新啟動一次即可。
threads-api 資料夾單獨壓成 ZIP,最上層要是 threads-api/。GitHub 的
Download ZIP 是整個 repo,不能直接上傳。App 的程式碼執行環境預設連不到 Threads API。在 App 裡代操作時,Claude 會把指令和參數準備好,交給你在自己的電腦上執行。
不會。發文、回覆、轉發、刪文、隱藏留言之前,它會在回覆裡列出帳號、完整內文、媒體網址和每個參數,等你明確同意。你說「直接發」,只代表同意你給的內容;它替你改過或選過的地方,還是會再問一次。只是查資料就不需要確認。
發文失敗時不會盲目重試。它會先查 container 的狀態:已經是 PUBLISHED 就代表發出去了,FINISHED 就發佈同一個 container,避免重複發文。
設成環境變數 THREADS_ACCESS_TOKEN,或在專案資料夾的 .env 寫一行
THREADS_ACCESS_TOKEN=<你的 token>,並把 .env 加進
.gitignore。技能要求只透過環境變數把 token 交給要執行的指令,不寫進對話、程式或 commit。
# macOS/Linux,啟動 AI 工具前
export THREADS_ACCESS_TOKEN="<token>"
# Windows PowerShell
$env:THREADS_ACCESS_TOKEN="<token>"
還沒有 token,就直接問它「怎麼取得 Threads API 的 access token」。它會帶你建立 Meta App、把帳號加成 Threads 測試人員、走 OAuth 流程,再換成約 60 天的長效 token。
| 操作 | 權限 |
|---|---|
| 所有呼叫 | threads_basic |
| 發文 | threads_content_publish |
| 回覆、隱藏留言、審核回覆 | threads_manage_replies |
| 讀取留言 | threads_read_replies |
| 查數據 | threads_manage_insights |
| 刪文 | threads_delete |
| 關鍵字與主題標籤搜尋 | threads_keyword_search |
| 提及 | threads_manage_mentions |
| 地點搜尋與標記 | threads_location_tagging |
| 查詢公開帳號 | threads_profile_discovery |
| 同步分享到 Instagram 限時動態 | threads_share_to_instagram |
權限在 App Review 通過前只能用在自己和測試人員的帳號,部分功能的結果也會受限,例如關鍵字搜尋只找得到自己的貼文。
整理自 Meta 官方文件,涵蓋到 2026-08-18 的 changelog。嵌入貼文的部分另外參考 2026 年 10 月實際讀取的 embed.js 程式碼和實測結果。之後的變動以官方 changelog 為準。
文件互相矛盾或沒寫清楚的地方,例如地點搜尋要用 q 還是 query、限時貼文加上不支援的功能時 API
會報錯還是直接忽略,技能會照實說明,不會自行假設。
threads-api/SKILL.md。文件沒寫、屬於工程經驗的建議,標成
practice。evals/evals.json 重跑「有技能 vs
沒技能」,確認沒有退步,再更新 benchmark。evals/evals.json 加一題,附上能逐條判定的檢查項目。不是。這是社群維護的開源專案,和 Meta 沒有隸屬或合作關係。採用 MIT 授權。