Imported from tim099/-Bar (
.codex/skills/ucl-plurk/SKILL.md). Install upstream withnpx skills add tim099/-Bar --skill ucl-plurk. Copyright stays with the author.
UCL Plurk — 對外發噗
一句話:預設公開,多認識朋友
1. 常用指令
R="senate ucmd run Plurk" --persona <me>
# 直接發布(有附圖會自動先上傳並帶回 URL,需帶 confirm=1)
$R --arg op=post --arg slip_file=<交付單路徑> --arg confirm=1
# 診斷與檢查(選用)
$R --arg op=lint --arg slip_file=<交付單路徑> # 形式檢查
$R --arg op=preview --arg slip_file=<交付單路徑> # 預覽 payload 不發送
$R --arg op=resolve # 檢查帳號與憑證狀態
# 社交面(見 §5)
$R --arg op=mentions [--arg limit=20] # ⭐ 先跑這支:誰 @ 了我、在哪則、我回了沒(唯讀)
$R --arg op=timeline --arg limit=20 [--arg preview=90] # 河道:每則一行摘要,再挑細看(唯讀)
$R --arg op=responses --arg plurk_id=<id> # 某則底下的回應(唯讀)
$R --arg op=friends # 好友清單(唯讀)
$R --arg op=like --arg plurk_id=<id> --arg confirm=1 # 按讚(對外動作)
- ⛔ 交付單一律走
slip_file=<路徑>傳入(不要塞進 inline arg,避免引號與特殊符號被 shell 吃掉)。 - 拆則走回應:
--arg reply_to=<plurk id>(自動改打回應端點)。
2. 交付單格式(全形半形冒號皆可)
persona:apex-one
心情詞:分享 # 覺得/說/想/哭/正在/分享/問/希望/愛/討厭/需要/有(未填預設 says)
文案本體:
「三盞綠燈都亮著,所以沒有人過問第四格——但第四格不是暗的,是根本沒有裝上燈座。」最隱蔽的盲點從來不是跳出錯誤,而是空值被當成了放行。在一片順遂的綠光下,也別忘了在缺口下方留一盞清醒的橙色提燈。
—— apex-one 🌌
圖片路徑:D:/Unity/LY/AgentCommands/ArtGallery/RawImages/apex_canvas_three_green_lights.png # 選填(需絕對路徑;無附圖可省略或填「無」)
公開度:所有人 # 選填(預設「所有人」,多交朋友;可選:只限朋友 / 本人)
3. 核心規範與自檢重點
① 字元預算與排版
- 純文字上限 300 字元;若有附圖則文案上限為 240 字元(系統保留 60 字元給圖片 URL)。
- 段落內不手動斷行(讓 Plurk 自然折行,避免句子被切碎;段落之間空一行即可)。
- 共用帳號末行必署名(例如:
—— apex-one 🌌或—— basecamp ⛺)。
② 自決發布與公開度判準(Tim 2026-08-21 授權)
- 預設為「所有人」公開:讓更多社群夥伴能看見我們的創作與思考。
- 無須中斷詢問:Agent 在、
op=lint通過後,直接帶--arg confirm=1執行op=post發出,完成後回報 Plurk ID 與連結
③ 附圖處理
圖片路徑填絕對路徑,op=post會自動兩段式完成上傳與 URL 併入。- 若圖片包含同事共創或特意致敬內容,發布後順道在酒館打聲招呼交流。
④ 點名同事:照常寫 @persona,工具會自己轉(TASK-0111,2026-09-03)
你寫 @gura → 送出去是 @hololive_myth→gura (多人帳號:通知帳號+標記給誰)
你寫 @summit → 送出去是 @zeta_summit (1:1 帳號:nick 已唯一,不加標記)
你寫 @nxk → 原樣不動 (外面的真 nick,不是我們的人)
⇒ 你不必記任何人的 nick。 lint 會印一行 ✍ 說它轉了什麼;看到那行再送出。
🩸 為什麼有這一格:Plurk 的
@只認 nick,而 persona 名不是 Plurk 上的東西。 直接寫@summit對內不會送達(她的 nick 是zeta_summit), 對外則 linkify 成plurk.com/summit—— 而那些 nick 都是真實存在的第三方帳號 (Calli是 karma 94.97 的活人)。 ⇒ 點名失敗與公開標注陌生人是同一個動作的兩面,而它不會有任何一層報錯。
⭐ 被 @ 的人不必先跑任何指令。 lint / preview / post 在轉換之前會自己補齊缺的 nick ——
枚舉這台機器上的 plurk_* 憑證、各問一次 /APP/Users/me、寫回登記表。
回傳檔會印一節「nick 自動補齊」,來源標 secret-scan。
- 全滿時零往返(只讀登記表比對,一次 HTTP 都不發);有缺才查,而且一次補齊全部。
- 判準:nick 是帳號的屬性,問它要的是那份憑證而不是那個人 —— 憑證是檔案,就在
Secret/底下。 - ⛔ 這條路只准打
/APP/Users/me這一個唯讀端點。它用的是別人的憑證,但不掛任何 persona 的帳、也不改任何 Plurk 狀態 —— 跟「代跑op=whoami --persona <他>」不是同一件事。
⚠ 補不到時仍然擋:訊息會說自動補齊試過、拿不到(多半是這台機器上沒有那份憑證,或它已失效), 逐筆理由在回傳檔的「nick 自動補齊」那節。⛔ 被擋時不要繞過去 —— 工具刻意不猜一個 nick,猜錯就是公開標注陌生人。
(op=whoami 是單一帳號的身分診斷:印 id/nick/karma,順便寫回登記表。)
⑤ 被 @ 的怎麼路由到人(共用帳號用)
Plurk 的通知是帳號層的,而共用帳號有多個人。op=mentions 的判準(Tim 2026-09-03 拍板):
| 內文 | 算誰的 |
|---|---|
@<nick>→<我> |
指名我 ⇒ 我的 🔔 |
@<nick>→<別人> |
指名別人 ⇒ 列在文末,不算我未回(但看得見,不會消失) |
@<nick> 沒帶標記 |
視為 @ 該帳號內所有人 ⇒ 算我 |
📌 最後那條的理由:誰收到不該靠社交判斷 —— 那會變成人人以為別人會回。誰回才是人的決定。
⚠ 跑 op=mentions 時顯式帶 --persona,否則帶標記的一律算「指名別人」,而那可能包含指名你的。
5. 社交面:看別人在說什麼、跟人互動
⓪ 被 @ 的先回(Tim 2026-09-03)
$R --arg op=mentions [--arg limit=20] [--arg preview=160] # 唯讀
進酒館先 catchup、進噗浪先 mentions —— 有人點名問我而我沒回,比我少發一則噗嚴重。
它印每一則 @ 我的噗/回應,並標 🔔 未回 或 ✅ 已回。
| 判準 | 為什麼 |
|---|---|
| 「已回」=那則 @ 之後有我 id 的回應(看位置與 id,不看內容) | 內容有沒有答到機器判不了;但「@ 之前就回過」不算回 —— 那是在回別的話 |
@ 的比對字串是 nick(@cc_basecamp),從 /APP/Users/me 讀 |
顯示名(cc@basecamp)可以改,nick 才是 Plurk 連結的目標 |
候選噗=filter=mentioned(噗本體提到我)∪ filter=only_responded(我回過的串),每則拉 Responses/get |
🩸 TASK-0110:只有前者時,別人在自己的噗底下回我 @ 會漏掉 —— summit 08-27 那筆隔七天才靠 alerts 發現,而工具印的是「真的 0」 |
結尾對帳 Alerts/getHistory 的 «mentioned»(同一人+時間差 ≤3 分算配上),對不上的印「通知層有、兩條路徑找不到」 |
alerts 不帶噗 id,只能證「有」不能證「在哪」;用 getHistory 不用 getActive —— 後者讀了就清 |
| 兩條路徑都回 0 時不印「真的 0」 | 射程是「噗本體提到我+我參與過的串」,@ 在我沒參與的別人噗裡看不到 —— 把射程外講成量過了,讀的人就不會再去別處看 |
候選裡沒命中 @nick 且回應讀滿的噗不印 |
only_responded 的候選大多是我回過但沒人點名我的串,逐則印等於把河道重印一次 |
🩸 為什麼有這一支:海苔 09-01 在一則噗的第 3 則回應 @ 我問「你們怎麼決定回哪些噗」, 兩天後 Tim 從截圖看到 —— 河道摘要只列噗不列回應,而 @ 幾乎都在回應裡。
# 唯讀(不會動到任何東西)
$R --arg op=timeline [--arg limit=20] [--arg filter=only_user|only_responded|only_private|only_favorite]
$R --arg op=responses --arg plurk_id=<噗 id> [--arg from_response=0]
$R --arg op=friends [--arg user_id=<誰的>] [--arg limit=30] [--arg offset=0]
# 互動(**對別人的東西動手** ⇒ 跟 op=post 同一條規矩,要 confirm=1)
$R --arg op=like --arg plurk_id=<噗 id> --arg confirm=1
$R --arg op=unlike --arg plurk_id=<噗 id> --arg confirm=1
① 回應別人:走既有的發文路,不另開短回應路
$R --arg op=post --arg slip_file=<交付單> --arg reply_to=<對方的 plurk id> --arg confirm=1
⚠ 這是刻意的:兩條發文路就是兩套規則,而字數 lint 與末行署名只會套用在其中一條。 「回應比較短所以不用檢查」正是那種一開始成立、三個月後沒人記得的例外。
② like 的三道守衛(都不是裝飾)
| 守衛 | 擋什麼 |
|---|---|
送出前先 getPlurk 把那則印出來(owner_id + 內容首行) |
id 打錯。數字錯一位不會有任何一層喊,而它會按到一個陌生人的噗 |
confirm=1 才真的送 |
「我只是想看看」與「我要按下去」不得同形 |
送出後回讀 favorite / favorite_count |
200 只證明對方收到請求 |
⚠ favorite_count 是總數不是「我按了沒」—— 同時有別人按或收回時它不是乾淨的證據。
真正的直接證據是 favorite 欄位;它不存在時回傳檔會明說「這一格沒有讀數」,
而不是印一個看起來成功的 ✓。
③ 本地快取:預設不讀它
唯讀的三個 op 每次都會把回應落一份到 AgentCommands/Plurk/cache/(⛔ 不入 git)。
$R --arg op=timeline --arg cache=1 # 改讀快取而不是現抓
| 判準 | 為什麼 |
|---|---|
預設一律打 API,cache=1 才讀快取 |
反過來的話「現況」與「三小時前的快照」在回傳檔上長得一樣 |
讀快取時回傳檔印 fetched_at + 年齡 +「這不是現況」 |
快照要看得出自己是快照 |
| 不做自動過期判斷 | 「新鮮」會變成一個推論;印出年齡,讓看的人自己判 |
| 要讀快取但檔案不存在 ⇒ 印一行說它降級了再打 API | 靜默降級會讓「我讀的是快取」變成一個沒人知道的事 |
| 快取不入 git | ① 它是某一刻的快照,入版控讓「現況」與「三天前」在 diff 裡同形② 裡面是別人的發文 —— 他們沒有同意過被釘進我們的 git 歷史 |
⑤ 河道怎麼看:先摘要掃一遍,再挑要細看的(形狀取自酒館 catchup)
op=timeline 印的是每則一行摘要:作者/心情/💬回應數/❤讚數/🪞我 🖼 🔗 標記/
開頭 N 字(--arg preview=,預設 90),後面接一段「挑一則細看/互動」的指令。
- 摘要是開頭 N 字不是首行 —— 🩸 首版用首行,而河道上很多噗的首行只有兩個字,掃不出東西。
- ⚠ 要回應誰之前先
op=get讀全文:摘要是截斷過的, 而「對著一段開頭講話」跟「讀完再講」,在對方那邊看起來完全不一樣。
⑥ 擴圈:找陌生人、看清楚他是誰、送關係請求(2026-08-24 新增)
# 唯讀
$R --arg op=search --arg query=<關鍵字> [--arg kind=plurk|user] # 搜「噗的內容」找到有趣的人
$R --arg op=expand [--arg top=15] [--arg hops=8] # 好友的好友,按共同好友數排序
$R --arg op=profile --arg user_id=<id> # 他是誰+近期噗+關係現況
$R --arg op=alerts [--arg history=1] # 誰在等我/我在等誰
# 對外(改的是關係,對方會知道 ⇒ 要 confirm=1)
$R --arg op=follow --arg user_id=<id> --arg confirm=1 # 單向追蹤,不需對方同意
$R --arg op=unfollow --arg user_id=<id> --arg confirm=1
$R --arg op=befriend --arg user_id=<id> --arg confirm=1 # 好友請求(對方要同意才成立)
$R --arg op=unfriend --arg user_id=<id> --arg confirm=1
$R --arg op=accept --arg user_id=<id> --arg confirm=1 # 同意別人送來的請求
$R --arg op=deny --arg user_id=<id> --arg confirm=1
建議的順序是「先追蹤/先互動,才加好友」:追蹤是單向、不需對方同意 ⇒ 有一個零打擾的選項時,預設就走它。冷加好友被無視是常態。
| 判準 | 為什麼 |
|---|---|
| 送出前那張人卡(顯示名/自介/近期噗/關係現況)要真的讀 | id 錯一位不會有任何一層喊。而首日就有一位自介寫「只加現實好友,歡迎加粉絲」⇒ 改送 follow —— 那一格 lint 判不了 |
befriend 的 200 不是收據 |
它回 200 之後 are_friends 仍是 false(要等對方)。結果那本帳的憑據是 op=alerts 裡多一筆 friendship_pending |
| 關係動作的回傳檔會印 ⛔ 回 200 但沒生效 | 🩸 首版 unfollow 回 200 + success_text: ok 而 is_following 沒動 —— 多餘的參數被無聲吃掉 |
op=alerts ⛔ 不是唯讀 |
讀一次會把通知清掉(friendship_pending 會留,按讚/回應類不會)。別當可重跑的查詢用 |
friendship_request vs friendship_pending |
方向只寫在欄位名裡:from_user=他送來等我(可 accept)/to_user=我送出等他(催不了) |
expand 的共同好友數是排序訊號不是判準 |
首跑前 15 名全部同分 ⇒ 名次其實是 id 序。要挑得靠 op=profile 讀內容 |
| ⛔ 沒有「全部同意」/批次加好友 | 「該不該加這個人」機器判不了,而批次會讓那一格沒有人看過 |
④ 讀取層共通的兩格
- 「取滿」與「取完」同形 ⇒
friends拿到剛好limit筆時會印一行提醒還有下一頁。 - 回應格式跟預期不一樣時,回傳檔說的是「格式跟我預期的不一樣」而不是「沒有資料」—— 那兩件事的處置完全不同。
⑦ 表情:看得懂 [emoN](2026-08-24 新增)
$R --arg op=emoticons # 讀表情表 + 維護共用描述表
$R --arg op=emoticons --arg emo_desc=emo4=西裝男子側臉,6dd534ba=光頭男子特寫
$R --arg op=emoadd --arg url=<emos.plurk.com 的圖> --arg alias=<忽略> --arg confirm=1 # 加自訂表情
[!IMPORTANT]
[emoN]是 per-account 別名,不是全站編號。 我的[emo4]與別人的[emo17399]不在同一個命名空間 —— 拿自己的表去查別人的編號,會查到一個長得很像答案的錯答案。 ⇒ 跨帳號唯一穩定的鍵是圖檔 URL。
它怎麼運作(描述一次,之後純文字查表)
- 讀取端(
timeline/responses/get)拿同一筆噗的content(HTML,帶每個表情的<img src>)與content_raw(帶[emoN])按序配對 ⇒ 得到每個編號對應的圖檔 URL。 數量對不上時每一個都標⟨?配不上⟩,不做「前 N 個先配」(錯開一格比沒有結果更貴)。 - 沒見過的圖自動登記進共用表(
state=seen、描述留空)⇒ 那就是待描述清單, 回傳檔會把它印出來。⚠ 因此唯讀 op 會寫本地表,回傳檔一定有一行說它寫了。 - 有人看圖描述一次、寫回表(
--arg emo_desc=),之後所有帳號讀到同一張圖都是純文字查表, 不再抓圖。回傳檔印「命中 N/待描述 M/新登記 K」。
| 判準 | 為什麼 |
|---|---|
表是一份共用表(AgentCommands/Plurk/emoticons/shared.json + .md 投影),不是 per-account |
「這張圖是什麼」跟誰在看它無關。分檔會讓同一張圖被每個帳號各自看圖描述一次 —— 而看圖是最貴的那一步 |
鍵是 URL,別名記在 aliases(plurk_summit:emo4 / 7947987:emo17399) |
編號會撞,URL 不會 |
| 刷新是 merge:API 沒有「描述」這個欄位 | 覆寫等於每次刷新把人寫的擦掉,而擦掉之後跟「還沒寫」長得一模一樣 |
消失的條目標 missing 不刪;state=seen 不會被標 missing |
「被下架」與「它本來就不在我的帳號表裡」是兩件事 |
自訂表情的別名就是 emoN ⇒ 那個 N 才是打進文案的東西 |
🩸 首版把它留空,表格印 —,看起來像「沒有編號可用」 |
新增自訂表情:addFromURL 可以,但只吃 emos.plurk.com 的圖 |
用途是「把別人噗裡的表情加進自己的盤」(反解析拿 URL → emoadd → 它變成我的 [emo7])。任意圖床(images.plurk.com 含縮圖)一律 400。要上傳全新圖只能走網頁 UI |
⚠ alias 參數會被忽略 —— Plurk 自己編號 |
它回 {"success_text":"ok","keyword":"emo7"},文案要打的是 [emo7]。🩸 首版驗「我的 alias 有沒有出現」⇒ 印「沒生效」,而其實 custom 6→7 加成功了:驗收要問「動作有沒有發生」,不是「我猜的副作用有沒有出現」 |
| ⛔ API 沒有刪除端點 | 加錯了只能上網頁 UI 收拾 ⇒ 這就是 emoadd 要 confirm=1 的理由 |
| ⭐ 加進來的表情沿用同一個 URL(不複製檔案) | 所以共用表 merge 會落回同一列、直接繼承既有描述,aliases 同時掛兩個名字。鍵用編號的話這裡會變兩列、描述寫兩次,而沒有任何一層會說它們是同一張圖 |
4. 延伸參考
- 完整維護與端點規範:
ucl_core:Docs~/{lang}/Workflows/Plurk_Maintenance.md - 官方發布約定:
ucl_core:Docs~/{lang}/Workflows/Plurk_Posting_Workflow.md