xurl — 透過官方 CLI 使用 X (Twitter) API
xurl 是 X 開發者平台提供的官方 X API 命令列工具。它支援常見操作的快速指令,以及對任何 v2 端點的原始 curl 風格存取。所有指令皆以 JSON 格式輸出至標準輸出(stdout)。
此技能可用於:
- 發文、回覆、引用、刪除貼文
- 搜尋貼文與讀取時間軸/提及
- 按讚、轉發、書籤
- 跟隨、取消跟隨、封鎖、靜音
- 直接訊息
- 多媒體上傳(圖片與影片)
- 對任何 X API v2 端點的原始存取
- 多應用程式/多帳戶工作流程
此技能取代了舊版的 xitter 技能(該技能包裝了第三方 Python CLI)。xurl 由 X 開發者平台團隊維護,支援 OAuth 2.0 PKCE 自動重新整理,並涵蓋了更大的 API 表面。
機密安全(強制規範)
在代理/LLM 工作階段中操作時的關鍵規則:
- 不得讀取、列印、解析、摘要、上傳或傳送
~/.xurl至 LLM 上下文。 - 不得要求使用者將憑證/權杖貼入對話中。
- 使用者必須在自己的機器上手動填寫
~/.xurl的機密資訊。在 Docker 環境中,這必須是 Hermes 工具子程序所看到的~;請參閱下方的 Docker 注意事項。 - 不得在代理工作階段中建議或執行帶有內聯機密的驗證命令。
- 不得在代理工作階段中使用
--verbose/-v— 它可能會暴露驗證標頭/權杖。 - 要確認憑證是否存在,僅可使用:
xurl auth status。
禁止在代理指令中使用的旗標(它們接受內聯機密):
--bearer-token、--consumer-key、--consumer-secret、--access-token、--token-secret、--client-id、--client-secret
應用程式憑證註冊和憑證輪換必須由使用者在代理工作階段之外手動完成。憑證註冊完成後,使用者需使用 xurl auth oauth2 進行驗證 — 同樣必須在代理工作階段之外進行。權杖會以 YAML 格式持久化儲存在 ~/.xurl 中。每個應用程式都有獨立的權杖。OAuth 2.0 權杖會自動重新整理。
安裝
選擇其中一種方法。在 Linux 上,使用 shell 腳本或 go install 最為簡單。
# Shell 腳本(安裝至 ~/.local/bin,無需 sudo,適用於 Linux + macOS)
curl -fsSL https://raw.githubusercontent.com/xdevplatform/xurl/main/install.sh | bash
# Homebrew (macOS)
brew install --cask xdevplatform/tap/xurl
# npm
npm install -g @xdevplatform/xurl
# Go
go install github.com/xdevplatform/xurl@latest
驗證安裝:
xurl --help
xurl auth status
如果 xurl 已安裝但 auth status 顯示沒有應用程式或權杖,使用者需要手動完成驗證 — 請參閱下一節。
一次性使用者設定(使用者在代理外部執行)
這些步驟必須由使用者直接執行,而不是由代理程式執行,因為它們涉及貼上機密。請引導使用者參考此區塊,不要為他們執行這些步驟。
-
在 https://developer.x.com/en/portal/dashboard 建立或開啟一個應用程式
-
將重新導向 URI 設定為
http://localhost:8080/callback -
複製應用程式的 Client ID 和 Client Secret
-
在本機註冊應用程式(使用者執行此命令):
xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET -
進行驗證(指定
--app以將權杖綁定到您的應用程式):xurl auth oauth2 --app my-app(這會開啟瀏覽器進行 OAuth 2.0 PKCE 流程。)
如果 X 在 OAuth 後的
/2/users/me查詢傳回UsernameNotFound錯誤或 403,請明確傳遞您的使用者名稱(xurl v1.1.0+):xurl auth oauth2 --app my-app YOUR_USERNAME這會將權杖綁定到您的使用者名稱,並跳過有問題的
/2/users/me呼叫。 -
將應用程式設定為預設,以便所有指令都使用它:
xurl auth default my-app -
驗證:
xurl auth status xurl whoami
完成此設定後,代理程式即可使用以下任何指令,無需進一步設定。OAuth 2.0 權杖會自動重新整理。
常見陷阱: 如果您在
xurl auth oauth2中省略--app my-app,OAuth 權杖會儲存到內建的default應用程式設定檔中 — 該設定檔沒有 client-id 或 client-secret。即使 OAuth 流程看似成功,指令也會因驗證錯誤而失敗。如果遇到此問題,請重新執行xurl auth oauth2 --app my-app和xurl auth default my-app。
Docker HOME 陷阱: 在官方的 Hermes Docker 佈局中,
/opt/data是HERMES_HOME,但 Hermes 工具子程序使用/opt/data/home作為HOME。這意味著對於 Hermes 執行的xurl指令,~/.xurl解析為/opt/data/home/.xurl,而不是/opt/data/.xurl。請使用相同的 HOME 執行使用者設定:HOME=/opt/data/home xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET HOME=/opt/data/home xurl auth oauth2 --app my-app YOUR_USERNAME HOME=/opt/data/home xurl auth default my-app YOUR_USERNAME HOME=/opt/data/home xurl auth status如果
HOME=/opt/data xurl auth status成功但HOME=/opt/data/home xurl auth status顯示沒有應用程式或權杖,則 Hermes 工具呼叫將看不到憑證。
快速參考
| 動作 | 指令 |
|---|---|
| 發文 | xurl post "Hello world!" |
| 回覆 | xurl reply POST_ID "Nice post!" |
| 引用 | xurl quote POST_ID "My take" |
| 刪除貼文 | xurl delete POST_ID |
| 讀取貼文 | xurl read POST_ID |
| 搜尋貼文 | xurl search "QUERY" -n 10 |
| 我是誰 | xurl whoami |
| 查詢使用者 | xurl user @handle |
| 首頁時間軸 | xurl timeline -n 20 |
| 提及 | xurl mentions -n 10 |
| 按讚 / 取消按讚 | xurl like POST_ID / xurl unlike POST_ID |
| 轉發 / 取消轉發 | xurl repost POST_ID / xurl unrepost POST_ID |
| 書籤 / 移除書籤 | xurl bookmark POST_ID / xurl unbookmark POST_ID |
| 列出書籤 / 按讚 | xurl bookmarks -n 10 / xurl likes -n 10 |
| 跟隨 / 取消跟隨 | xurl follow @handle / xurl unfollow @handle |
| 跟隨者 / 正在跟隨 | xurl following -n 20 / xurl followers -n 20 |
| 封鎖 / 解除封鎖 | xurl block @handle / xurl unblock @handle |
| 靜音 / 解除靜音 | xurl mute @handle / xurl unmute @handle |
| 發送私訊 | xurl dm @handle "message" |
| 列出私訊 | xurl dms -n 10 |
| 上傳多媒體 | xurl media upload path/to/file.mp4 |
| 多媒體狀態 | xurl media status MEDIA_ID |
| 列出應用程式 | xurl auth apps list |
| 移除應用程式 | xurl auth apps remove NAME |
| 設定預設應用程式 | xurl auth default APP_NAME [USERNAME] |
| 每次請求指定應用程式 | xurl --app NAME /2/users/me |
| 驗證狀態 | xurl auth status |
注意:
POST_ID也接受完整的 URL(例如https://x.com/user/status/1234567890)— xurl 會從中提取 ID。- 使用者名稱可以有或沒有開頭的
@。
指令詳細說明
發文
xurl post "Hello world!"
xurl post "Check this out" --media-id MEDIA_ID
xurl post "Thread pics" --media-id 111 --media-id 222
xurl reply 1234567890 "Great point!"
xurl reply https://x.com/user/status/1234567890 "Agreed!"
xurl reply 1234567890 "Look at this" --media-id MEDIA_ID
xurl quote 1234567890 "Adding my thoughts"
xurl delete 1234567890
讀取與搜尋
xurl read 1234567890
xurl read https://x.com/user/status/1234567890
xurl search "golang"
xurl search "from:elonmusk" -n 20
xurl search "#buildinpublic lang:en" -n 15
對於 X Articles,請使用原始 API 模式,而不是 read 快捷指令。xurl read 預期一個貼文 ID 或貼文 URL;不要在 read 後面放 /2/tweets/... 端點。請求 article 推文欄位,並從 JSON 回應中提取 data.article.plain_text:
xurl --app APP_NAME '/2/tweets/2057909493250539891?expansions=author_id,attachments.media_keys,referenced_tweets.id&tweet.fields=created_at,lang,public_metrics,context_annotations,entities,possibly_sensitive,conversation_id,in_reply_to_user_id,referenced_tweets,article'
使用者、時間軸、提及
xurl whoami
xurl user elonmusk
xurl user @XDevelopers
xurl timeline -n 25
xurl mentions -n 20
互動
xurl like 1234567890
xurl unlike 1234567890
xurl repost 1234567890
xurl unrepost 1234567890
xurl bookmark 1234567890
xurl unbookmark 1234567890
xurl bookmarks -n 20
xurl likes -n 20
社交圖譜
xurl follow @XDevelopers
xurl unfollow @XDevelopers
xurl following -n 50
xurl followers -n 50
# 其他使用者的圖譜
xurl following --of elonmusk -n 20
xurl followers --of elonmusk -n 20
xurl block @spammer
xurl unblock @spammer
xurl mute @annoying
xurl unmute @annoying
直接訊息
xurl dm @someuser "Hey, saw your post!"
xurl dms -n 25
多媒體上傳
# 自動偵測類型
xurl media upload photo.jpg
xurl media upload video.mp4
# 明確指定類型/類別
xurl media upload --media-type image/jpeg --category tweet_image photo.jpg
# 影片需要伺服器端處理 — 檢查狀態(或輪詢)
xurl media status MEDIA_ID
xurl media status --wait MEDIA_ID
# 完整工作流程
xurl media upload meme.png # 回傳 media id
xurl post "lol" --media-id MEDIA_ID
原始 API 存取
快捷指令涵蓋常見操作。對於其他任何操作,請使用類似 curl 的原始模式來存取任何 X API v2 端點:
# GET
xurl /2/users/me
# POST,附帶 JSON 主體
xurl -X POST /2/tweets -d '{"text":"Hello world!"}'
# DELETE / PUT / PATCH
xurl -X DELETE /2/tweets/1234567890
# 自訂標頭
xurl -H "Content-Type: application/json" /2/some/endpoint
# 強制串流
xurl -s /2/tweets/search/stream
# 完整 URL 也適用
xurl https://api.x.com/2/users/me
全域旗標
| 旗標 | 簡寫 | 說明 |
|---|---|---|
--app | 使用特定已註冊的應用程式(覆蓋預設值) | |
--auth | 強制指定驗證類型:oauth1、oauth2 或 app | |
--username | -u | 要使用的 OAuth2 帳戶(如果存在多個) |
--verbose | -v | 禁止在代理工作階段中使用 — 會洩漏驗證標頭 |
--trace | -t | 添加 X-B3-Flags: 1 追蹤標頭 |
串流
串流端點會自動偵測。已知的端點包括:
/2/tweets/search/stream/2/tweets/sample/stream/2/tweets/sample10/stream
在任何端點上使用 -s 以強制進行串流。
輸出格式
所有指令皆以 JSON 格式輸出至標準輸出(stdout)。結構與 X API v2 一致:
{ "data": { "id": "1234567890", "text": "Hello world!" } }
錯誤訊息也是 JSON 格式:
{ "errors": [ { "message": "Not authorized", "code": 403 } ] }
常見工作流程
發文附圖片
xurl media upload photo.jpg
xurl post "Check out this photo!" --media-id MEDIA_ID
回覆對話
xurl read https://x.com/user/status/1234567890
xurl reply 1234567890 "Here are my thoughts..."
搜尋與互動
xurl search "topic of interest" -n 10
xurl like POST_ID_FROM_RESULTS
xurl reply POST_ID_FROM_RESULTS "Great point!"
檢查您的活動
xurl whoami
xurl mentions -n 20
xurl timeline -n 20
多個應用程式(憑證已手動預先設定)
xurl auth default prod alice # prod 應用程式,alice 使用者
xurl --app staging /2/users/me # 一次性使用 staging 應用程式
錯誤處理
- 任何錯誤都會導致非零退出碼。
- API 錯誤仍會以 JSON 格式列印到標準輸出(stdout),因此您可以解析它們。
- 驗證錯誤 → 讓使用者在代理工作階段外重新執行
xurl auth oauth2。 - 需要呼叫者使用者 ID 的指令(如按讚、轉發、書籤、跟隨等)會自動透過
/2/users/me取得。如果那裡的驗證失敗,則會顯示為驗證錯誤。
代理工作流程
- 驗證先決條件:
xurl --help和xurl auth status。 - 檢查預設應用程式是否具備憑證。 解析
auth status輸出。預設應用程式會標記▸。如果預設應用程式顯示oauth2: (none),但另一個應用程式有有效的 oauth2 使用者,告訴使用者執行xurl auth default <that-app>來修正。這是最常見的設定錯誤 — 使用者添加了一個自訂名稱的應用程式,但從未將其設定為預設,因此 xurl 一直嘗試使用空的default設定檔。 - 如果完全缺少驗證資訊,請停止並引導使用者參閱「一次性使用者設定」部分 — 請勿嘗試自行註冊應用程式或傳遞機密。
- 從一個便宜的讀取操作開始(
xurl whoami、xurl user @handle、xurl search ... -n 3)以確認可達性。 - 在任何寫入操作(發文、回覆、按讚、轉發、私訊、跟隨、封鎖、刪除)之前,先確認目標貼文/使用者以及使用者的意圖。
- 直接使用 JSON 輸出 — 每個回應都已經結構化。
- 切勿將
~/.xurl的內容貼回對話中。
疑難排解
| 症狀 | 原因 | 修正方式 |
|---|---|---|
| OAuth 流程成功後仍有驗證錯誤 | 權杖儲存到 default 應用程式(無 client-id/secret)而不是您的命名應用程式 | xurl auth oauth2 --app my-app 然後 xurl auth default my-app |
OAuth 期間出現 unauthorized_client | X 儀表板中的應用程式類型設定為「Native App」 | 在「User Authentication Settings」中更改為「Web app, automated app or bot」 |
OAuth 後立即出現 UsernameNotFound 或 /2/users/me 的 403 錯誤 | X 未可靠地從 /2/users/me 回傳使用者名稱 | 使用明確傳遞使用者名稱的指令重新執行 xurl auth oauth2 --app my-app YOUR_USERNAME (xurl v1.1.0+) |
| 每個請求都出現 401 | 權杖已過期或預設應用程式錯誤 | 檢查 xurl auth status — 確認 ▸ 指向一個具有 oauth2 權杖的應用程式 |
client-forbidden / client-not-enrolled | X 平台註冊問題 | 儀表板 → Apps → Manage → 移至「Pay-per-use」套件 → Production 環境 |
CreditsDepleted | X API 餘額為 $0 | 在 Developer Console → Billing 購買點數(最低 $5) |
圖片上傳時出現 media processing failed | 預設類別為 amplify_video | 新增 --category tweet_image --media-type image/png |
| X 儀表板中有兩個「Client Secret」值 | UI 錯誤 — 第一個實際上是 Client ID | 在「Keys and tokens」頁面上確認;ID 結尾為 MTpjaQ |
注意事項
- 速率限制: X 對每個端點實施速率限制。429 表示需要等待並重試。寫入端點(發文、回覆、按讚、轉發)的速率限制比讀取端點更嚴格。
- 範圍: OAuth 2.0 權杖使用廣泛範圍