X(Twitter)發佈
了解如何連結 X(Twitter)帳號,並發佈含文字、圖片與影片的推文。
⚠️ 僅限 Ultra 方案。 連結 X 帳號所有方案皆可使用,但 發佈到 X 需要 Ultra 方案(價格為 Pro 的 2 倍)。Ultra 每月可發佈最多 60 則 X 貼文。
連結 X 帳號
前置需求
- X(Twitter)帳號
- 已登入 Boring 控制台
連結步驟
- 在控制台按下 「Connect X (Twitter)」
- 於 X(Twitter)上 授權此應用程式
- 檢視並授予必要權限:
tweet.read:讀取推文tweet.write:發佈與刪除推文users.read:讀取個人資料media.write:上傳圖片與影片offline.access:維持長期存取
- 點擊 「Authorize app」 完成連結
完成後,帳號會顯示於「Authorized Accounts」列表:
- 使用者名稱(@username)
- 大頭貼
- 平台標籤(X)
- 唯一帳號 ID(可透過「Copy ID」複製)
- 解除連結選項
權杖資訊
- 權杖類型:OAuth 2.0 + PKCE
- Access Token:2 小時到期
- Refresh Token:6 個月到期
- 自動刷新:已啟用(發佈前自動刷新)
- 重新授權:僅在 6 個月後或手動撤銷時需要
支援的內容類型
X(Twitter)支援含多種媒體的推文:
| 功能 | 說明 | 是否必填 | 限制 |
|---|---|---|---|
| 文字 | 推文文字 | 否* | 最多 280 字元 |
| 圖片 | 附加照片 | 否 | 最多 4 張,每張 5MB |
| 影片 | 附加影片 | 否 | 最多 1 支,512MB |
*必須包含文字或媒體至少一種
發佈範例
1. 純文字推文
{
"post": {
"accountId": "your-x-account-id",
"content": {
"text": "Hello from Boring API! 🚀 This is a text-only tweet. #API #Automation",
"mediaUrls": [],
"platform": "x"
},
"target": {
"targetType": "x"
}
}
}
字數限制:文字超過 280 字元時會自動截斷。
2. 圖片推文(1-4 張)
{
"post": {
"accountId": "your-x-account-id",
"content": {
"text": "Check out these amazing photos! 📸\n\n#Photography #Travel",
"mediaUrls": [
"https://storage.example.com/photo1.jpg",
"https://storage.example.com/photo2.jpg",
"https://storage.example.com/photo3.jpg"
],
"platform": "x"
},
"target": {
"targetType": "x"
}
}
}
圖片規格:
- 格式:JPG、PNG、GIF、WEBP
- 大小限制:每張 5MB 以下
- 數量限制:每則推文最多 4 張
- 解析度:最高 8192x8192
- URL:需可公開存取
3. 影片推文
{
"post": {
"accountId": "your-x-account-id",
"content": {
"text": "New video tutorial! 🎥 Learn how to use our API in 5 minutes.\n\n#Tutorial #API #DevTools",
"mediaUrls": ["https://storage.example.com/tutorial.mp4"],
"platform": "x"
},
"target": {
"targetType": "x"
}
}
}
影片規格:
- 格式:MP4、MOV、AVI
- 檔案大小:最多 512MB
- 時長:最長 2 分 20 秒(140 秒)
- 解析度:最小 32x32,最大 1920x1200
- 影格率:最高 40 fps
- 長寬比:1:2.39 至 2.39:1
- URL:需可公開存取
注意:同一則推文只能有 1 支影片,無法與圖片混用。
API 請求範例
Python 範例
import requests
API_URL = "https://boring.aiagent-me.com/v2/posts"
API_KEY = "boring_xxxxxxxxxxxxx"
ACCOUNT_ID = "your-x-account-id"
post_data = {
"post": {
"accountId": ACCOUNT_ID,
"content": {
"text": "Automated tweet via Boring API! 🤖 #API #Automation",
"mediaUrls": [],
"platform": "x"
},
"target": {
"targetType": "x"
}
}
}
headers = {
"boring-api-key": API_KEY,
"Content-Type": "application/json"
}
response = requests.post(API_URL, headers=headers, json=post_data)
result = response.json()
if result.get("success"):
print("Tweet posted successfully!")
print(f"Tweet ID: {result['tweet_id']}")
print(f"Tweet URL: {result['tweet_url']}")
else:
print(f"Tweet failed: {result.get('error')}")
成功回應
{
"success": true,
"message": "Post published successfully",
"postSubmissionId": "uuid-here",
"platform": "x",
"post_type": "photo",
"tweet_id": "1234567890123456789",
"tweet_url": "https://x.com/i/status/1234567890123456789",
"media_count": 1
}
媒體上傳流程
媒體與推文都使用各連結帳號自己的 OAuth 2.0 token:
- 下載媒體:從提供的 URL 下載檔案
- OAuth 2.0 上傳:以連結帳號的 OAuth 2.0 token 透過 v2
/2/media/upload上傳(需media.writescope),媒體擁有者即為發文帳號 - 媒體處理:X 處理媒體(影片需較長時間)
- OAuth 2.0 發文:透過 v2
/2/tweets發佈推文並附上媒體
影片處理
影片需要額外的處理時間:
[X] Uploading video in chunks...
[X] Upload progress: 33%
[X] Upload progress: 67%
[X] Upload progress: 100%
[X] Video processing status: pending
[X] Video processing status: processing
[X] Video processing status: succeeded
[X] Tweet posted successfully!
常見處理時間:
- 小型影片(<10MB):5-10 秒
- 中型影片(10-50MB):10-30 秒
- 大型影片(50-512MB):30-90 秒
文字長度與計數
280 字元限制
X 嚴格限制 280 字元,Boring 會自動協助:
# 超過 280 字元的文字
text = "This is a very long tweet..." * 50 # 超過 1000 字
# Boring 會自動截斷至 280 字元
post_data = {
"post": {
"accountId": ACCOUNT_ID,
"content": {
"text": text,
"platform": "x"
},
"target": {"targetType": "x"}
}
}
結果:文字將被截斷並保留前 280 字。
Unicode 與 Emoji
Emoji 與特殊字元計數方式不同:
- ASCII 字元:1 字元
- Emoji:多數算 2 字元
- URL:會縮短為 23 字元(t.co)
範例:
"Hello 👋 World 🌍" = 14 字元(每個 emoji 2 字元)
"Check out https://example.com/very/long/url" ≈ 30 字元(URL 23 字元)
其他 API 範例
cURL
curl -X POST https://boring.aiagent-me.com/v2/posts \
-H "boring-api-key: boring_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"post": {
"accountId": "your-x-account-id",
"content": {
"text": "Testing the Boring API with X! 🚀 #API #Testing",
"mediaUrls": [],
"platform": "x"
},
"target": {
"targetType": "x"
}
}
}'
JavaScript / Node.js
const axios = require('axios');
const API_URL = 'https://boring.aiagent-me.com/v2/posts';
const API_KEY = 'boring_xxxxxxxxxxxxx';
const ACCOUNT_ID = 'your-x-account-id';
async function postTweet(text, mediaUrls = []) {
const postData = {
post: {
accountId: ACCOUNT_ID,
content: {
text: text,
mediaUrls: mediaUrls,
platform: 'x'
},
target: {
targetType: 'x'
}
}
};
try {
const response = await axios.post(API_URL, postData, {
headers: {
'boring-api-key': API_KEY,
'Content-Type': 'application/json'
}
});
console.log('Tweet posted:', response.data);
return response.data;
} catch (error) {
console.error('Error posting tweet:', error.response?.data || error.message);
throw error;
}
}
// 純文字推文
postTweet('Hello from Node.js! 👋 #NodeJS #API');
// 圖片推文
postTweet(
'Check out this beautiful sunset! 🌅 #Photography',
['https://storage.example.com/sunset.jpg']
);
疑難排解
常見錯誤
錯誤:「Account is not an X (Twitter) account」
- 原因:使用了錯誤的帳號 ID
- 解法:前往控制台,使用 X 帳號對應的帳號 ID
錯誤:「Too many media files」
- 原因:圖片超過 4 張
- 解法:最多僅能上傳 4 張圖片
錯誤:「Cannot mix images and videos」
- 原因:同時提供圖片與影片
- 解法:一則推文只能有 1 支影片 或 最多 4 張圖片
錯誤:「Failed to upload media」
- 原因:媒體 URL 無法存取或格式不支援
- 解法:
- 使用
curl -I https://your-media-url.jpg確認可公開存取 - 檢查檔案格式(圖片 JPG/PNG、影片 MP4/MOV)
- 確保檔案大小在限制內
- 使用
錯誤:「Video processing failed」
- 原因:X 無法處理影片
- 解法:
- 改用 MP4 並使用 H.264 編碼
- 確認長度在 140 秒以內
- 重新以標準設定轉檔
錯誤:「Token refresh failed」
- 原因:Refresh Token 逾期(6 個月)或已撤銷
- 解法:在控制台解除連結後重新授權
最佳實務
- 保持簡潔:280 字內傳達重點
- 善用 Hashtag:建議 2-3 個相關標籤
- 優化圖片:使用高品質 JPG/PNG
- 壓縮影片:盡量小於 50MB,加快上傳
- 先測試 URL:確認媒體可正常存取
- 注意速率限制:適度錯開發文時間
- 預覽推文:於控制台預覽後再發佈
速率限制
X API 速率限制(以每位使用者計):
- 發佈推文:3 小時內最多 300 則
- 上傳圖片:15 分鐘內最多 500 張
- 上傳影片:每日總量 512MB
Boring 會偵測速率限制並回傳對應錯誤。
Boring Ultra 方案上限: X 發佈每月每位使用者上限 60 則(每月初重置,跨你所有連結的 X 帳號合計)。超過會回傳 X_MONTHLY_LIMIT_EXCEEDED(HTTP 429)。
發佈歷史
在控制台查看所有推文:
- 登入 Boring 控制台
- 捲動至 「Publish History」 區塊
- 篩選平台為 X
每筆紀錄會顯示:
- 推文內容
- Tweet ID 與連結
- 媒體數量
- 時間戳記
- 發佈狀態(成功/失敗)
- 若失敗則顯示錯誤訊息
進階功能
多個 X 帳號
在同一個 Boring 帳戶連結多組 X 帳號:
# 帳號 1:個人 (@john_personal)
personal_account_id = "account-id-1"
# 帳號 2:商務 (@john_business)
business_account_id = "account-id-2"
# 發佈到個人帳號
post_to_account(personal_account_id, "Personal tweet! 👋")
# 發佈到商務帳號
post_to_account(business_account_id, "Business announcement! 📢")
批次發佈
程式化發佈多則推文:
tweets = [
{"text": "Tweet 1: Introduction 👋", "media": []},
{"text": "Tweet 2: Key features 🚀", "media": ["feature.jpg"]},
{"text": "Tweet 3: Final thoughts 💭", "media": []}
]
for tweet in tweets:
post_data = {
"post": {
"accountId": ACCOUNT_ID,
"content": {
"text": tweet["text"],
"mediaUrls": tweet["media"],
"platform": "x"
},
"target": {"targetType": "x"}
}
}
response = requests.post(API_URL, headers=headers, json=post_data)
print(f"Posted: {tweet['text']} - {response.json()}")
# 間隔發文避免速率限制
time.sleep(60)
安全性提醒
- OAuth 2.0 + PKCE:提升授權流程安全性
- 每帳號 token:媒體與推文皆使用連結帳號的 OAuth 2.0 token(X API v2)
- 權杖儲存:加密後存於 MongoDB
- 自動刷新:在到期前自動更新 Token
- 隨時撤銷:可於控制台隨時解除連結
速查表
純文字推文
{
"post": {
"accountId": "your-account-id",
"content": {
"text": "Hello World! 🌍",
"platform": "x"
},
"target": {"targetType": "x"}
}
}
圖片推文
{
"post": {
"accountId": "your-account-id",
"content": {
"text": "Check this out! 📸",
"mediaUrls": ["https://example.com/image.jpg"],
"platform": "x"
},
"target": {"targetType": "x"}
}
}
影片推文
{
"post": {
"accountId": "your-account-id",
"content": {
"text": "Watch this! 🎥",
"mediaUrls": ["https://example.com/video.mp4"],
"platform": "x"
},
"target": {"targetType": "x"}
}
}
下一步
- Facebook 發佈:了解 Facebook 平台
- Instagram 發佈:了解 Instagram 流程
- Threads 發佈:掌握 Threads 串文
- YouTube 發佈:延伸至 YouTube
- API 參考:完整 API 文件
- 程式範例:更多程式實作