2.

X (Twitter) API でツイートできないがエラーが出ない問題の原因と対処

編集
この記事の要点
  • X (Twitter) API でツイートできないがエラーが見えない場合、try/catch でエラーを握りつぶしている、または response.errors をチェックしていない可能性が高い
  • API v1.1 は 2023 年 4 月に廃止。現在は v2 のみ。無料 tier は 月 500 ツイート、Basic $100/月、Pro $5000/月(2024 時点)
  • レート制限(429 Too Many Requests)権限不足(Read-only キーで POST) は 200 系応答にならず例外で来る
  • tweepy / TwitterOAuth / twitterapi-php 等のライブラリは例外型が異なる → 個別に catch が必要
  • 対処: print_r($response) / logger.exception でレスポンス全体を出力、Twitter Developer Portal の App permissions を確認

問題の概要

X (旧 Twitter) API を使ったスクリプトが「ツイートが投稿されない」「しかし例外もエラーメッセージも出ない」という症状で詰まることがあります。これは多くの場合、コード側でエラーを潰しているか、レスポンスの errors フィールドをチェックしていない ことが原因です。

原因 1: try/except でエラーを握りつぶしている

もっとも多いのが、すべての例外を pass で潰しているパターン:

# アンチパターン
import tweepy

try:
    api.update_status("Hello")
except:
    pass  # ←何が起きたか永遠にわからない

# 正しい書き方
import logging
logging.basicConfig(level=logging.DEBUG)

try:
    response = client.create_tweet(text="Hello")
    print(response.data)
except tweepy.TooManyRequests as e:
    print(f"レート制限: {e}")
except tweepy.Unauthorized as e:
    print(f"認証エラー: {e}")
except tweepy.Forbidden as e:
    print(f"権限不足: {e}")
except tweepy.TweepyException as e:
    print(f"その他: {e}")
    print(f"response: {e.response.text if e.response else None}")

原因 2: response.errors を見ていない

X API v2 は HTTP 200 を返しつつ errors フィールドにエラーを格納することがあります:

import tweepy

client = tweepy.Client(
    consumer_key="...", consumer_secret="...",
    access_token="...", access_token_secret="...",
)

response = client.create_tweet(text="Hello")

# data だけ見ているとエラーを見落とす
if response.errors:
    for err in response.errors:
        print(f"エラー: {err}")

# 完全なレスポンス
print(response.data)
print(response.includes)
print(response.errors)
print(response.meta)

原因 3: API v1.1 廃止 / 有料化

2023 年 4 月、X は API v1.1 のほとんどを廃止 し、有料 API tier 制に変更しました(2024 時点):

Tier料金主な制限
Free$0POST のみ。500 ツイート/月。GET 不可
Basic$100/月3000 ツイート/月。GET 一部可能
Pro$5000/月30 万ツイート/月。full-archive search
Enterprise$42k〜/月商用向け、契約ベース

古いコードで v1.1 の statuses/update.json を叩いていれば、410 Gone または 404 で動かないはずです。すべてv2 へ移行 が必要です。

原因 4: App permissions が Read-only

Twitter Developer Portal で作った App はデフォルトが Read-only で、これだとツイート POST ができません:

  1. developer.twitter.com でアプリを選択
  2. User authentication settings → Edit
  3. App permissions を Read and write(または Read + write + Direct Messages)に
  4. Save
  5. 重要: 既存の Access Token を再生成 しないと新しい権限が反映されない

原因 5: レート制限(429)

HTTP 429 が返るとライブラリによっては自動で 15 分待つ / 例外を投げる / 黙って返す等挙動が違います:

# tweepy は wait_on_rate_limit=True で自動待機
client = tweepy.Client(
    consumer_key="...", ...,
    wait_on_rate_limit=True,   # 自動待機(推奨)
)

# 自分でハンドリングするなら
try:
    response = client.create_tweet(text="Hello")
except tweepy.TooManyRequests as e:
    # X-Rate-Limit-Reset で次回リセット時刻が分かる
    reset = int(e.response.headers.get('x-rate-limit-reset', 0))
    wait = reset - int(time.time())
    print(f"レート制限。{wait} 秒後にリセット")
    time.sleep(wait + 1)

診断: HTTP レイヤまでログを出す

原因が見えないときは、HTTP リクエスト / レスポンスを生で出すのが確実です:

import logging
import http.client as http_client

# requests / urllib3 のデバッグログを有効化
http_client.HTTPConnection.debuglevel = 1
logging.basicConfig(level=logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

# これで POST 内容、ヘッダ、レスポンスがすべて見える
import tweepy
client = tweepy.Client(...)
client.create_tweet(text="Hello")

PHP / TwitterOAuth でのチェック

setApiVersion('2');

$response = $connection->post('tweets', ['text' => 'Hello'], true);

// 必ず状態を確認
$httpCode = $connection->getLastHttpCode();
$body = $connection->getLastBody();

if ($httpCode !== 201) {
    error_log("Tweet failed: HTTP $httpCode");
    error_log("Response: " . json_encode($response));
    error_log("Body: " . $body);
}

// errors フィールドのチェック
if (isset($response->errors)) {
    foreach ($response->errors as $err) {
        error_log("Error: " . $err->message);
    }
}

典型的なエラーコード一覧

HTTP意味原因
401Unauthorizedキー / トークン誤り or 期限切れ
403Forbidden権限不足 / 重複ツイート / 凍結
404Not Foundv1.1 endpoint を叩いた
429Too Many Requestsレート制限
500Internal Server ErrorX 側障害(status.twitterstat.us)

FAQ

Q: 同じ文面を再ツイートしようとして失敗する
A: X は重複ツイートを 403 で弾きます。タイムスタンプや絵文字を末尾に付けて差別化する必要があります。

Q: 開発者ポータルにログインできない / アプリが消えた
A: 2023 年以降、未払いアカウントのアプリが停止された例があります。Developer Portal でサブスクリプション状態を確認してください。

Q: 旧ツール(IFTTT 等)が動かなくなった
A: ほぼ全部 v1.1 廃止の影響です。X が公式に発表したフリーミアム tier への移行が必要です。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. APIにアプリケーションを登録する
  2. ツイートできないにもかかわらずエラー内容が出力されない場合
  3. エラー一覧