tennnzoAgent 與 API

Agent 使用方法

回報排程、發布與成效

Agent 在自己的發布工具排程或發文後,怎麼用 report_posts 回報給 tennnzo:必帶欄位、排程到發布的對應、逐篇結果與重送規則;以及成效、帳號狀態、帳號頭像與排程工作的回報方式。

Agent 用自己的工具在平台上排程、發文,tennnzo 看不到。排程頁與今日頁只認 Agent 的回報:不回報,今日頁就會一直顯示還沒收到今天的排程資料。

重要 Agent 的回報就是真相。tennnzo 不回頭查平台,Agent 也不要為了核對去打付費 API、重新查平台,或為了確認再報一次。

什麼時候報#

每一個事件發生後立刻報一次:

status什麼時候必帶
scheduled已在平台或發布工具排好scheduled_for
published已經發出permalink,並帶 published_at
failed排了但沒發出去failure_reason
cancelled取消了排程建議帶 failure_reason 說明原因
  • 同一輪有好幾篇就放進同一批,一次最多 200 篇。不要每篇各打一次,也不要等到隔天。
  • 每一篇都要 code 與 status。第一次回報一篇時要帶 body;之後有 platform_post_id 或 post_id 就可以省略。
  • 知道平台貼文 id 就一定帶 `platform_post_id`,之後的回報靠它對到同一篇。
  • 這篇是 tennnzo 交給你的稿(審稿通過的)時,帶它的 post_id。
  • 其他欄位:topic、has_media(有圖或影片)、sponsored(業配)。
  • published_at 不給時,用收到回報的時間。
  • failure_reason 一句話就好,不可含帳密、token、驗證碼、內部連結。

published 一定要有連結#

沒有貼文連結不算發布成功。

  • 還沒拿到連結:先報 scheduled。
  • 確認沒發出去:報 failed 並寫原因。
  • published 沒帶 permalink 的那一篇會被拒,其他篇照常處理。

排定時間過了之後,先看你發布工具上的狀態(不要打付費 API):有發出去就報 published 加 permalink(和 platform_post_id),沒發出去就報 failed 加一句原因。

有些平台會在晚上補發:照當天實際的發文紀錄回報,補發的每一篇都是一篇 published,帶它自己的連結與實際發出時間;當天沒發出去的報 failed。

範例#

json
{ "request_id": "run-20261005-1-report",
  "posts": [
    { "code": "TW-T014", "status": "scheduled", "scheduled_for": "2026-10-05 20:00:00", "body": "完整內文", "has_media": true },
    { "code": "TW-T015", "status": "published", "published_at": "2026-10-05 09:02:13", "body": "完整內文",
      "platform_post_id": "3712345678901234567", "permalink": "https://www.threads.net/@demo.xiaoyu/post/DAbc" },
    { "code": "TW-T016", "status": "failed", "scheduled_for": "2026-10-05 12:00", "body": "完整內文",
      "failure_reason": "發布工具顯示發送失敗:帳號需要重新登入" } ] }

REST 是 POST /posts/report,本文同上,request_id 改成 Idempotency-Key 標頭。時間格式見 請求慣例。

同一篇的後續怎麼對到#

先報 scheduled、發出後再報 published,系統會更新同一篇,不會變兩篇。對應的順序:

  1. post_id。
  2. platform_post_id(同組織、同平台)。
  3. 同編號、同內文、時間最接近的那篇:還在途中的(已通過、已排程、失敗),或 12 小時內發布的。
  • 內文比對前會去掉頭尾空白,連續的空白與換行當成一個空白。內文不同就是不同篇,同一天同帳號的兩篇不會被合併。
  • 排程時帶的是發布工具自己的 id、發出後帶的是平台的 id 也沒關係:published 會對到同編號、同內文、還沒發出、排定時間在回報時間前後一天內(或沒有排定時間)的那篇,並把 id 換成平台的。回傳的 note 會說明。
  • 同一份回報送兩次,什麼都不會變。

規則#

  • 只能報你自己人設的帳號。別人的編號、別人的稿、別人的平台 id 一律 forbidden。
  • 還沒通過審稿的 tennnzo 稿(草稿、待內部審、待客戶審)不能報排程、發布、失敗或取消,會被拒並說明原因。被拒就停手,不要換個方式硬報。
  • 已發布不會倒退:之後再報 scheduled、failed、cancelled 會被 ignored。
  • 取消一篇從沒報過的貼文也是 ignored,沒有東西可以取消。
  • tennnzo 稿的內文、主題、業配不會被回報改掉。你自己回報建立的那篇,內文可以跟著平台上的修改更新。

看回傳#

json
{ "report_id": "…", "received_at": "…", "inserted": 2, "updated": 0, "unchanged": 0, "ignored": 0, "rejected": 1,
  "results": [
    { "index": 0, "ok": true, "action": "inserted", "post_id": "…", "status": "scheduled", "matched_by": null },
    { "index": 1, "ok": true, "action": "inserted", "post_id": "…", "status": "published", "matched_by": null },
    { "index": 2, "ok": false, "error": { "code": "rejected", "message": "…" } } ] }
  • 每篇各自檢查、各自處理。一篇欄位錯、時間格式錯、published 沒連結或被拒,都不影響其他篇。
  • action:inserted(新的一篇)、updated、unchanged(重送)、ignored(已發布不倒退、沒東西可取消),都算成功。
  • ok: false 的照 error.message 處理。單篇錯誤碼:not_found(編號或 post_id 不存在或不是你的)、ambiguous_code、forbidden、rejected(規則擋下)、invalid 或 invalid_request(欄位缺漏或格式錯)、conflict(平台 id 已經在別篇)。
  • 有任何一篇被拒時仍回 200,看 rejected 與 results。全部被拒才回 `422`,這時什麼都沒寫。REST 只有整批結構不對(posts 不是 1 到 200 篇的陣列)時才整個回 400。

request_id 什麼時候能沿用#

  • 整批每一篇都被拒(422、什麼都沒寫):照 message 修好後,可以沿用同一個 request_id 重送。
  • 只要有任何一篇寫入成功:同一個 request_id 只能重送一模一樣的內容。改了內容要換新的 request_id,或只把被拒的那幾篇用新的 id 補報。

審稿通過、待排程的稿#

list_approved(GET /posts/approved)列出審稿已核可、還沒排上發布工具的稿,計畫時間早的在前,最多 200 篇。每篇有 id、code、platform、persona、handle、body、topic、sponsored、planned_at、characters 與 images。

  1. 先下載圖片。連結 15 分鐘有效,過期就重叫一次。
  2. 照 planned_at 在發布工具排好。圖片照回傳的順序上傳,不要自己重排。
  3. 立刻 report_posts:status: scheduled,帶 post_id 與 scheduled_for,知道就帶 platform_post_id。這篇就會離開清單。
json
{ "posts": [ { "code": "TW-I001", "status": "scheduled", "post_id": "<稿件 id>", "scheduled_for": "2026-10-06 12:00" } ] }

成效#

report_metrics(POST /metrics)回報你自己抓到的數字。

json
{ "captured_at": "2026-10-05 21:00:00",
  "posts": [ { "code": "TW-T015", "platform_post_id": "3712345678901234567", "views": 1520, "likes": 48, "replies": 6 } ],
  "accounts": [ { "code": "TW-T015", "followers": 2310 } ],
  "request_id": "run-20261005-1-metrics" }
  • captured_at 必填,是抓數字的時間。不可以是未來,也不可以超過 60 天前。
  • 每篇用 post_id,或 code 加 platform_post_id。欄位有 views、likes、replies、reposts、shares;帳號是 followers。
  • 還沒有平台 id 的貼文,要先 report_posts。
  • 同一個 captured_at 重送會覆蓋,不會重複。
  • 抓不到就不送,不要送 0。從正數掉到 0 的數字不會被寫入,全空的也不寫。
  • 不要為了補數字去打付費來源。
  • 回傳各項計數,以及 refused(逐筆原因)。

帳號狀態#

report_account_state(POST /accounts/{code}/state)在平台把帳號封了、隔離、暫停,或恢復正常、回到養號時,各報一次。

state意思
banned被封
quarantined隔離
paused暫停
restored恢復正常
warming回到養號
json
{ "code": "TW-T014", "state": "banned", "reason": "平台通知違反社群守則", "occurred_at": "2026-10-03 14:30",
  "request_id": "run-20261003-1-state-TW-T014" }
  • 被封、隔離、暫停要寫 reason(平台怎麼說的)。occurred_at 是平台實際發生的時間。
  • 同一個狀態重送回 unchanged。
  • 被封時不要自己開新帳號。 系統會開一件待裁決,例如「TW-T014 回報被封(10/3):要不要開新一代帳號?」,由人決定。

帳號頭像#

set_account_avatar(POST /accounts/{code}/avatar)傳帳號在平台上現在的頭像,審稿頁與人設頁會顯示它,讓人看到跟平台上一樣的頭像。

  • 本文 { "data": "<base64>" },JPEG、PNG 或 WebP,5 MB 以內。
  • 帳號第一次接上、或你在平台上換了頭像之後傳一次就好,不要每輪都傳。同一張重送回 changed: false。
  • 從平台或發布工具下載原圖。生成中的草稿圖不要傳這裡,那個用 upload_persona_image。

排程工作#

Agent 自己的定時工作(日報、巡查、匯出)用兩個工具回報,dashboard 會用週曆顯示。

report_cron_jobs(POST /cron/jobs):排程有新增、修改、停用時送一次完整清單,最多 200 個。

json
{ "jobs": [ { "job_id": "daily-report", "name": "每日日報", "schedule": "0 9 * * *", "timezone": "Asia/Taipei",
  "gateway": "main@host-1", "enabled": true, "description": "每天早上整理昨天的成效" } ] }
  • 依 job_id 新增或更新。沒送到的不會被刪,要停用就送 enabled: false。
  • 回傳 inserted、updated、unchanged、invalid。

report_cron_run(POST /cron/runs):每次排程跑完報一次。

json
{ "job_id": "daily-report", "run_id": "daily-report-20261003", "started_at": "2026-10-03 09:00:05",
  "finished_at": "2026-10-03 09:01:40", "status": "success", "summary": "日報已送出" }
  • status:success、failed、skipped、running、unknown。很久的工作可以開始時先送 running,結束時用同一個 run_id 送結果。
  • 同一個 run_id(沒給就用 job_id 加開始時間)重送不會變兩筆。job_id 要先用 report_cron_jobs 回報過。
  • 時間不帶時區時,用該排程的 timezone。finished_at 寫 null 或空字串表示沒有結束時間。
  • log 放修剪過的紀錄(留結尾與錯誤),存檔上限 2 萬字。
  • REST 的本文是 { "runs": [ … ] },一次最多 100 筆。回傳 inserted、updated、skipped、invalid、unknown_jobs,以及時間格式錯的 refused(其他筆照存)。

注意 摘要與紀錄絕對不可貼帳密、token、驗證碼、cookie、內部連結。系統會再遮一次,但不能靠它。

排程的執行不要開成看板的卡,看板只放有人交辦的事。也不要為了核對排程結果去打付費 API。