Contents
X(旧Twitter)API の最新認証フロー
1‑1. OAuth 2.0 Authorization Code Flow with PKCE が必須
| 項目 | 説明 |
|---|---|
| Authorization Endpoint | https://x.com/i/oauth2/authorize (※旧 URL https://twitter.com/i/oauth2/authorize は非推奨) |
| Token Endpoint | https://api.x.com/2/oauth2/token |
| PKCE 必須要件 | ・Code verifier(ランダムな文字列) ・Code challenge(SHA‑256 ハッシュを Base64URL エンコードしたもの) ・ code_challenge_method=S256 を必ず付与 |
| 有効期限 | アクセストークンは最長 30 日、リフレッシュトークンは 90 日(アプリ設定により変動) |
実装手順(概要)
- Code verifier / challenge の生成(例:n8n の Function ノードで作成)。
- ユーザーを以下の URL にリダイレクトし、
code_challengeとstateを付与。
text
https://x.com/i/oauth2/authorize?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=YOUR_REDIRECT_URI&
scope=tweet.read%20tweet.write%20users.read&
state=RANDOM_STATE_STRING&
code_challenge=CODE_CHALLENGE&
code_challenge_method=S256
- リダイレクト先で取得した authorization_code と、1 で作成した code_verifier を使ってトークンエンドポイントへ
POST。
http
POST https://api.x.com/2/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
client_id=YOUR_CLIENT_ID&
redirect_uri=YOUR_REDIRECT_URI&
code=AUTHORIZATION_CODE&
code_verifier=CODE_VERIFIER
- 成功すると JSON に
access_token、refresh_tokenが返ります。 - n8n の HTTP Request ノードまたは Twitter (X) ノードの「Bearer Token」欄に
access_tokenを設定すれば認証完了です。
ポイント:PKCE はフロントエンド・サーバーレス環境でも安全に利用できるため、必ず実装してください。
メディアアップロード(V2)の正しいエンドポイントと手順
X の画像・動画添付は 2 段階の Chunked Upload が推奨されていますが、シングルファイルであれば下記エンドポイントで完結できます。
| 手順 | エンドポイント | HTTP メソッド | 主なパラメータ |
|---|---|---|---|
| 1. Media ID の取得(INIT) | https://upload.twitter.com/1.1/media/upload.json |
POST | command=INIT, total_bytes, media_type |
| 2. バイナリ送信(APPEND) | 同上 | POST | command=APPEND, media_id, segment_index, media_data(Base64) |
| 3. 完了通知(FINALIZE) | 同上 | POST | command=FINALIZE, media_id |
V2 の新エンドポイント(画像だけなら
https://upload.twitter.com/2/mediaが利用可能)
ただし、現時点(2026 年 4 月)では 公式ドキュメントは 1.1 系の/1.1/media/upload.jsonを最も安定して推奨しています。
実装例(n8n の HTTP Request ノードで流す)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# ① INIT - name: Media Init type: n8n-nodes-base.httpRequest parameters: url: https://upload.twitter.com/1.1/media/upload.json method: POST queryParameters: - name: command value: INIT - name: total_bytes value: {{$json["fileSize"]}} - name: media_type value: image/jpeg authentication: bearerToken token: YOUR_BEARER_TOKEN # ② APPEND(ファイルが 5 MB 以下なら 1 回で OK) - name: Media Append type: n8n-nodes-base.httpRequest parameters: url: https://upload.twitter.com/1.1/media/upload.json method: POST queryParameters: - name: command value: APPEND - name: media_id value: {{$node["Media Init"].json.media_id_string}} - name: segment_index value: 0 bodyContentType: multipart-form-data multipartFormData: - name: media_data filePath: /tmp/image.jpg # n8n が取得できるパス # ③ FINALIZE - name: Media Finalize type: n8n-nodes-base.httpRequest parameters: url: https://upload.twitter.com/1.1/media/upload.json method: POST queryParameters: - name: command value: FINALIZE - name: media_id value: {{$node["Media Init"].json.media_id_string}} authentication: bearerToken token: YOUR_BEARER_TOKEN |
FINALIZE のレスポンスに含まれる media_id_string を次の Twitter (X) ノードの「Media IDs」欄に渡せば、画像付きツイートが完了します。
レートリミットに関する注意点
- X API のレートリミットはエンドポイントごと・アプリのアクセスレベル(Essential, Elevated, Academic Research 等)で 異なる ことが公式ドキュメントでも明記されています。
- 例:
POST /2/tweetsは 15 分間に 300 件 が上限(Elevated Access 前提)。しかし、同一アカウントからのツイートはさらに 1 時間あたり 2,400 件 に制限される場合があります。 - 公式リファレンス: https://developer.x.com/en/docs/twitter-api/rate-limits
推奨対策
| 対策 | 実装例 |
|---|---|
| 指数バックオフ | n8n の「Error Trigger」+「Function」ノードで Math.pow(2, $json.attempt) * 1000 ミリ秒の遅延を算出し、最大 5 回再試行 |
| レートリミットヘッダー監視 | HTTP Response の x-rate-limit-remaining と x-rate-limit-reset を取得し、残数が少ない場合は「Delay」ノードで待機 |
| バッチ処理の分散 | 複数商品をまとめて投稿したいときは、1 件ずつキューイングし、一定時間ごとに 1 件だけ送信するフロー設計 |
Shopify の「カスタムアプリ」設定(旧プライベートアプリ)
2024 年以降、「プライベートアプリ」は廃止予定です。代わりに 「カスタムアプリ」(自社ストア専用)または 「パブリックアプリ」(複数店舗で利用)を作成します。
手順
- 管理画面 → アプリ > カスタムアプリの開発 に移動し、「新しいカスタムアプリを作成」 をクリック。
- アプリ名と開発者メールを入力し 「作成」。
- Configuration(設定)タブで必要なスコープを追加
| スコープ | 説明 |
|---|---|
read_products |
商品情報の取得 |
write_products |
商品情報の更新(画像添付等が必要な場合) |
read_orders |
注文情報の取得 |
write_script_tags (任意) |
Webhook 以外の外部スクリプト連携 |
- API credentials タブで Admin API access token(Bearer Token)を生成。
- トークンは 「Shopify の GraphQL / REST API」 両方で利用可能です。
注意:カスタムアプリのトークンは自動でローテーションしません。定期的に再発行し、n8n に更新する仕組み(例:Cron + HTTP Request)を用意してください。
Shopify Webhook の作成方法
商品が公開状態になるたびに通知を受け取るには products/update イベントの Webhook を設定します。
| 手順 | 操作 |
|---|---|
| 1 | 管理画面 → Settings → Notifications → Webhooks → 「Create webhook」 |
| 2 | Event: Product update を選択 |
| 3 | Format: JSON、URL: https://YOUR_N8N_INSTANCE/webhook/shopify-product-update(n8n の Webhook ノードのエンドポイント) |
| 4 | 「Save」後に表示される「Send test payload」で通信確認 |
セキュリティ推奨
- HMAC 検証:Shopify は
X-Shopify-Hmac-SHA256ヘッダーで署名を付与します。n8n の Function ノードで検証し、正当なペイロードか確認してください。 - 重複除外:同一商品が短時間に何度も更新されるケースがあります。
X-Shopify-Topicとidをキーにした データストア(n8n の「Set」→「Keep Only Latest」)で重複送信を防止します。
n8n のインストール・クラウド利用手順
1. Cloud(おすすめ初心者向け)
| 手順 | 操作 |
|---|---|
| a | https://n8n.io/ にアクセスし「Start for free」ボタンでアカウント作成 |
| b | メール認証後、ダッシュボードの Workflow 画面へ遷移 |
| c | 必要に応じて Execution Mode(Standard / Production)を選択 |
無料プランは月間 2,000 実行まで、Webhook は常時有効です。
2. ローカル Docker(本番運用・カスタムプラグイン向け)
|
1 2 3 4 5 6 7 8 |
docker run -d --name n8n \ -p 5678:5678 \ -e N8N_BASIC_AUTH_ACTIVE=true \ -e N8N_BASIC_AUTH_USER=admin \ -e N8N_BASIC_AUTH_PASSWORD=StrongPass!2026 \ -v ~/.n8n:/home/node/.n8n \ n8nio/n8n |
-vオプションで永続化ディレクトリをマウント- 本番環境は HTTPS 終端(例:NGINX + Let's Encrypt)を必ず導入
X API ノード(Twitter (X))の認証設定と基本パラメータ
| 項目 | 設定方法 |
|---|---|
| Authentication | Bearer Token を選択し、OAuth2 フローで取得した access_token を貼り付け |
| Operation | Create Tweet(POST /2/tweets)を選択 |
| Tweet Text | 前段の Set ノードやテンプレート変数(例:{{ $json["title"] }} - {{ $json["price"] }}円 #NewProduct)でマッピング |
| Media IDs | Media Upload フローで取得した media_id_string をカンマ区切りで入力 |
| Additional Options | Reply Settings, Poll, Place ID など必要に応じて設定可能 |
ポイント:n8n の X ノードは内部的に
Authorization: Bearer <token>ヘッダーを自動付与します。手動でヘッダーを書かなくても OKです。
商品公開時自動投稿フローの実装例
フローダイアグラム(テキスト版)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[Shopify Webhook (products/update)] │ [Function: HMAC Verify] ← 署名検証 │ [Set – テンプレート作成] │ ┌──────▼───────┐ │ HTTP Request│ ← Media Upload (INIT/APPEND/FINALIZE) │ (画像アップ)│ → media_id_string を取得 └──────▲───────┘ │ [Twitter (X) – Create Tweet] |
各ノードの設定概要
| ノード | 主な設定 |
|---|---|
| Webhook (Shopify) | URL: https://your-n8n-instance.com/webhook/shopify-product-update |
| Function(HMAC Verify) | js\nconst crypto = require('crypto');\nconst hmacHeader = $request.headers['x-shopify-hmac-sha256'];\nconst body = JSON.stringify($json);\nconst digest = crypto.createHmac('sha256', 'YOUR_SHOPIFY_SHARED_SECRET').update(body).digest('base64');\nif (digest !== hmacHeader) throw new Error('Invalid HMAC');\nreturn $json;\n |
| Set(本文テンプレート) | tweet_text = 新商品が登場! {{title}} – {{price}}円\n詳細はこちら → {{url}}\n#{{join(tags, " #")}} |
| HTTP Request(Media Upload) | 前述の 3 ステップを シーケンス(Execute Once per Execution)で実装。最終ステップの media_id_string を mediaId として出力 |
| Twitter (X) | Operation: Create Tweet、Tweet Text: {{$node["Set"].json.tweet_text}}、Media IDs: {{$node["HTTP Request"].json.mediaId}} |
画像が無い商品は Media Upload ステップをスキップする条件分岐(IF ノード)を追加すると、エラー回避できます。
エラーハンドリング・レートリミット対策
1. Error Trigger + Retry ロジック(指数バックオフ)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
- name: Error Trigger (429/5xx) type: n8n-nodes-base.errorTrigger parameters: errorTypes: - code: 429 - code: 500 - code: 502 - code: 503 - name: Calculate Delay type: n8n-nodes-base.function parameters: functionCode: | const attempt = $json.attempt ?? 1; return [{ json: { delay: Math.pow(2, attempt) * 1000, attempt: attempt + 1 } }]; - name: Delay type: n8n-nodes-base.wait parameters: waitTime: {{$node["Calculate Delay"].json.delay}} - name: Retry Tweet type: n8n-nodes-base.twitter # 同じ設定を再利用(X ノード) |
2. レートリミットヘッダーのモニタリング
| ヘッダー | 意味 |
|---|---|
x-rate-limit-remaining |
残り実行可能回数 |
x-rate-limit-reset |
UNIX タイムスタンプで次にリセットされる時刻 |
Function ノード例
|
1 2 3 4 5 6 7 |
const remaining = $response.headers['x-rate-limit-remaining']; if (parseInt(remaining) < 10) { // 残りが少ない場合は 60 秒待機 return [{ json: { wait: 60000 } }]; } return []; |
運用チェックリスト(日次 / 週次)
| 項目 | 実施頻度 | 確認ポイント |
|---|---|---|
| ツイート掲載確認 | 日次 | X アカウントで本日の自動投稿がすべて表示されているか |
| n8n Execution History | 日次 | エラー数 0、失敗したワークフローが無いか |
| トークン有効期限 | 週次 | X の access_token と Shopify の Admin API access token が期限切れでないか |
| レートリミット統計 | 週次 | Developer Dashboard → Usage で 429 エラー件数が増えていないか |
| Webhook 正常性 | 週次 | Shopify 管理画面の Webhook ステータスが「Active」か、最近送信されたテストペイロードが n8n に届いているか |
| バックアップ / バージョン管理 | 月次 | ワークフロー定義(JSON)を Git リポジトリへコミット |
n8n とカスタム実装の比較表
| 観点 | n8n(ノーコード) | カスタムアプリ / Shopify Functions |
|---|---|---|
| 導入スピード | 数時間で本番稼働可能 | 開発・テストに数日〜数週間 |
| 保守性 | UI 変更だけで対応、非エンジニアでも可 | コードレビュー・デプロイが必須 |
| 拡張性 | 標準ノードは限られる(外部 API は HTTP Request) | 任意のロジック・DB連携が自由 |
| コスト | Cloud 無料枠あり、上位プランは月額 $20 前後 | サーバー / Functions 実行時間に応じた従量課金+開発工数 |
| スケーラビリティ | ワークフロー単位で自動キューイング | Functions は Shopify が自動スケール、Node.js はインフラ管理が必要 |
| デバッグ | Execution History でステップごとに可視化 | ログは CloudWatch / Vercel 等外部へ委託 |
推奨ロードマップ
- フェーズ 1(PoC)
- n8n テンプレートをインポートし、商品公開時の自動ツイートを構築。
- フェーズ 2(安定化)
- エラーハンドリング、レートリミットバックオフ、トークン自動更新を n8n に実装。
- フェーズ 3(拡張)
- 在庫変動やキャンペーン情報など、複雑なロジックが必要になったら Node.js + Express または Shopify Functions に移行。
まとめ
- OAuth 2.0 PKCE を必ず使用し、最新の
https://x.com/i/oauth2/authorizeエンドポイントで認可を取得する。 - メディアアップロードは 1.1 系
/1.1/media/upload.jsonが安定版。V2 のエンドポイントも併記しておくと将来的な移行が楽になる。 - レートリミットは固定数値ではなく、公式ドキュメントを常に参照しつつ 指数バックオフ で対策する。
- Shopify 側は カスタムアプリ を作成し、必要スコープだけ付与してトークンを管理する。
- n8n のワークフローは Webhook → Set → Media Upload → Twitter (X) の4ステップで完結し、非エンジニアでも構築可能。
- 定期的な運用チェックとエラーハンドリングを組み込めば、長期安定稼働が実現できる。
これらの手順に沿って設定すれば、商品が公開されるたびに自動で X に投稿し、ブランド露出を最大化できます。質問や実装上の課題があれば、遠慮なくコメントしてください! 🚀