GASとTwitter APIでX(旧Twitter)へブログ記事を自動ツイートする仕組みを構築した話

ウェブやブログ

本ページはアフィリエイトプログラムを利用しています

色々自動化したい。
そんなお年頃のわたくし。

今回はGoogleスプレッドシートとGAS(Google Apps Script)、それにTwitter API(X API)を使って、X(旧Twitter)へ自動ツイートする仕組みを作ってみたというお話。

Xを再開することにしたのでブログ過去記事を自動ツイートしたい

TwitterがXになって久しいですが。

イーロン・マスク氏の雰囲気そのままに、Xはゴタゴタしていたので、なんだかもう使いたくなくなってBlueskyに移行。
そのままBlueskyでブログの更新通知などやったりもしていたものの、結局イマイチだなーとXに戻ることに。

XにはTwitter時代のアカウントがあるわけですが、なんとなく、心機一転新規アカウントでやろう、と。
そこで、1000記事以上あるブログの記事を、自動で日々ツイートしたくなった、というのが経緯。

XになってからAPI周りも色々変わった。
そんなこんなで、お勉強も兼ねて、構築してみたわけです。

Xへの自動投稿:GAS × スプレッドシート × Twitter API

まずは全体像から。

• 投稿文の管理はGoogleスプレッドシート
• GASでランダムに投稿文を抽出してツイート
• Twitter(X)APIのOAuth 1.0aで投稿
• 投稿は朝10時と夜7時の1日2回、時間トリガーで実行

Twitter APIの認証まわりはOAuth 1.0aで対応

最近のX APIでは、OAuth 2.0のApp-onlyではツイートできず。
そのため、古き良きOAuth 1.0a(アクセストークンによるユーザー認証)で実装。

ま、これもまた時期に使えなくなる気がしてる。
※2025年10月現在、動作確認はできております。

X(旧Twitter)へ自動投稿するには、APIの認証が必須。
今回は OAuth 1.0a(ユーザーコンテキスト) を使って、投稿権限付きのトークンを取得する。

1. X Developer Portal にアクセスする

まずは開発者ポータルに自動ツイートをするXアカウントでログイン。

Use Cases, Tutorials, & Documentation
Publish & analyze posts, optimize ads, & create unique customer experiences with the X API, X Ads API, & X Embeds.

2. アプリを作成する

1. 「Projects & Apps」→「Overview」に移動
2. 「+ Create App」または「+ Add App」ボタンをクリック
3. アプリ名(例:AutoBlogPoster)を入力して作成

自分の場合課金なしのfreeなのでプロジェクトはすでに存在。
課金しているユーザはプロジェクト自体も作れるのかも。

3. 認証設定(Authentication Settings)を変更する

OAuth 1.0aを使って投稿するには、アプリの権限設定が必要です。

1. 「Projects & Apps」から作ったアプリを選択し、User authentication settingsをEdit
2. 以下のように設定する

・App permissions → Read and Write
・Type of App → Web App, Automated App or Bot
・Callback URI / Redirect URL → https://example.com/callback(ダミーでOK)
・Website URL → 自分のブログなど(https://yourblog.comなど)

3. 「Save」ボタンで保存

4. Access Token / Access Token Secret を取得する

User Auth 設定が完了したら、アクセストークンを発行する。

1. 「Projects & Apps」から作ったアプリを選択し、上部タブの Keys and tokens を開く
2. 「API Key and Secret」「Access Token and Secret」で「Generate」もしくは「Regenerate」ボタンを押して、情報を取得する

後ほどGASで使うので、情報はメモしておく

補足:トークン再発行のタイミング

App Permissions(Read Only → Read and Writeなど)を変更した場合は、Access Token / Secret を再発行する必要がある。
以前のトークンはそのままでは権限が不足していてエラーでハマる原因に。

スプレッドシートにツイート内容をまとめる

投稿する内容は、スプレッドシートの1列目に書くだけ。

ブログの過去記事です!

タイトルタイトルタイトルタイトルタイトル

https://aaa.com/xxx/

#タグ1 #タグ2

こんな感じで内容は自由に。

また、シート名は「tweets」に設定。

GAS(Google Apps Script)で自動ツイート実行

スプレッドシートの拡張機能からApps Scriptへ。

// == 概要 ==
// スプレッドシートのランダムな行から投稿文を選び、
// 毎日2回(朝10時/夜7時)自動でX(旧Twitter)へ投稿

// == 設定項目 ==
const consumerKey = "YOUR_API_KEY"; // Twitter API Key
const consumerSecret = "YOUR_API_SECRET"; // Twitter API Secret
const accessToken = "YOUR_ACCESS_TOKEN"; // Twitter Access Token
const accessSecret = "YOUR_ACCESS_SECRET"; // Twitter Access Token Secret
const SPREADSHEET_ID = "YOUR_SPREADSHEET_ID"; // スプレッドシートID
const SHEET_NAME = "tweets"; // シート名(例:"tweets")

// == CryptoJSの読み込み(OAuth署名用) ==
eval(UrlFetchApp.fetch("https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js").getContentText());

// == メイン関数(ランダム投稿) ==
function postRandomTweet() {
  const sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
  const data = sheet.getDataRange().getValues().flat().filter(row => row && row !== "");

  if (data.length === 0) {
    Logger.log("📭 投稿できるデータがありません。");
    return;
  }

  const randomIndex = Math.floor(Math.random() * data.length);
  const tweetText = data[randomIndex];
  postToTwitter(tweetText);
}

// == X(旧Twitter)へ投稿 ==
function postToTwitter(tweetText) {
  const apiUrl = "https://api.twitter.com/2/tweets";
  const method = "POST";

  const nonce = Utilities.getUuid().replace(/-/g, "");
  const timestamp = Math.floor(Date.now() / 1000).toString();

  const oauthParams = {
    oauth_consumer_key: consumerKey,
    oauth_nonce: nonce,
    oauth_signature_method: "HMAC-SHA1",
    oauth_timestamp: timestamp,
    oauth_token: accessToken,
    oauth_version: "1.0",
  };

  const baseParams = Object.keys(oauthParams)
    .sort()
    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(oauthParams[key])}`)
    .join("&");

  const baseString = [
    method,
    encodeURIComponent(apiUrl),
    encodeURIComponent(baseParams)
  ].join("&");

  const signingKey = `${encodeURIComponent(consumerSecret)}&${encodeURIComponent(accessSecret)}`;
  const signature = CryptoJS.HmacSHA1(baseString, signingKey).toString(CryptoJS.enc.Base64);
  oauthParams.oauth_signature = signature;

  const authHeader = "OAuth " + Object.keys(oauthParams)
    .sort()
    .map(key => `${encodeURIComponent(key)}="${encodeURIComponent(oauthParams[key])}"`)
    .join(", ");

  const payload = JSON.stringify({ text: tweetText });
  const res = UrlFetchApp.fetch(apiUrl, {
    method: "POST",
    contentType: "application/json",
    payload: payload,
    muteHttpExceptions: true,
    headers: {
      Authorization: authHeader,
    },
  });

  const code = res.getResponseCode();
  const body = res.getContentText();

  if (code === 201 || code === 200) {
    Logger.log("✅ 投稿成功: " + tweetText);
  } else {
    Logger.log("❌ 投稿失敗 (" + code + "): " + body);
  }
}

// == テスト投稿用 ==
function testTweet() {
  postToTwitter("テスト投稿!🧪 #自動投稿テスト");
}

こちらがスクリプト。

const consumerKey = "YOUR_API_KEY";
const consumerSecret = "YOUR_API_SECRET";
const accessToken = "YOUR_ACCESS_TOKEN";
const accessSecret = "YOUR_ACCESS_SECRET";

ここにはX Developer Portalで作ったアプリから取得した情報を入れる。

const SPREADSHEET_ID = "YOUR_SPREADSHEET_ID";
const SHEET_NAME = "tweets";

ここにはスプレッドシートの情報を入れる。

https://docs.google.com/spreadsheets/d/ここがSPREADSHEET_ID/edit?gid=0#gid=0

SPREADSHEET_IDは、スプレッドシートのURLの上記箇所。

スプレッドシートの任意の行の1列目からランダムにツイート文を取得し、Xへ投稿する。
OAuth 1.0aによる署名処理にはCryptoJSをCDNから読み込み、API認証と投稿処理をGASだけで完結。
スプレッドシートに投稿文を1行ずつ並べておくだけでOK。

トリガー設定:朝10時と夜7時に自動実行

GASの「時間主導型トリガー」を使えば、定時投稿も簡単。

• 10:00 → 朝のツイート
• 19:00 → 夜のツイート

それぞれ postRandomTweet() 関数を実行するようトリガーを設定しておくだけ。

自分の場合は上記設定としているが、こちらも好みの設定でOK。

まとめ

「ブログを自動でXに投稿したい」
そんな思いから始めた今回の仕組み作りですが、GASとX APIを使えば、意外と簡単に構築できます。

GASは無料でもかなり使えるし、Twitter APIも書き込み上限は500件/月なので大量に投稿するでもしなければ無料枠でいけちゃいます。

スプレッドシート × GAS × X API。
なかなか便利だな、と。

タイトルとURLをコピーしました