2026年にX (旧Twitter) で仕様変更があり,無料ではbotを作れなくなりました。(下記まとめを参照)
X(旧Twitter)上で,もう無料でbot作成できない。2026年2~3月にAPI完全有料化。価格は100ツイート1ドル。10ドル分クレジットを消費し次第botつぶやきを強制停止。有力な移行先・代替手段はBlueskyか
https://posfie.com/@ouen_suru_tan/p/iT3HTHp
そこでXからの移行先として,Blueskyを使ってみましょう。無料でbotを作れます。
Googleスプレッドシート上で「拡張機能」→「Apps Script」を選ぶと,JavaScriptに似た言語(GAS)でマクロを書くことができます。
下記に,なんと ぴったり100行で サンプルコードを掲載します。
ぴったり100行で理解できるサンプルコード
// 「Blueskyにテストメッセージを投稿するサンプルコード」のサンプルコード
//
// Googleスプレッドシート(GAS)から,Blueskyにbot投稿するコードの
// 動作原理やAPIの概念を「わずか100行で理解」する事が目的です。※実運用向けのコードではない
// 2026.3.31. @rwanda_go_tan
// ここに自分のBlueskyアカウント名とアプリパスワードを記述する。
const MY_BLUESKY_USERNAME = "~~~.bsky.social"; // 例: hoge.bsky.social
const MY_BLUESKY_PASSWORD = "~~~"; // Blueskyで「設定」→「プライバシーとセキュリティ」より
// Blueskyのセッションを作成する。
// 認証に使うアクセストークン文字列(accessJwt)を返す。
function bluesky_createSession() {
// セッション作成用のAPIにアクセスする
const api_response = UrlFetchApp.fetch("https://bsky.social/xrpc/com.atproto.server.createSession", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
payload: JSON.stringify({
identifier: MY_BLUESKY_USERNAME,
password: MY_BLUESKY_PASSWORD
})
});
// APIからのレスポンスは正常か
if (api_response.getResponseCode() === 200) {
// レスポンスをJSONとしてパース
const session_obj = JSON.parse(api_response.getContentText());
console.log("Blueskyセッション作成に成功。");
// 認証に使うアクセストークン文字列を返す
return session_obj.accessJwt;
// accessJwtとは,以降のAPIリクエスト中に認証に使う「短寿命のアクセストークン」を指す。
//
// ※参考文献 ATプロトコルでの認証方法について: HTTP API (XRPC)
// https://atproto.com/ja/specs/xrpc
// Authenticationの欄から引用:
// "Most requests should be authenticated using an access JWT,
// but the validity lifetime for these tokens is short.
// Every couple minutes, a new access JWT can be requested"
} else {
// 例外を投げ処理中断
throw new Error("Blueskyセッション作成に失敗。" + api_response.getContentText());
}
}
// Blueskyにbot API経由でメッセージを1つ投稿する。
function bluesky_postOneMessage( bs_post_message ) {
console.log("Blueskyにメッセージを投稿します。投稿内容: " + bs_post_message);
// まずセッションを作成し,認証トークンを取得
const bs_auth_token = bluesky_createSession();
// メッセージ投稿用のAPIにアクセスする
const api_response = UrlFetchApp.fetch("https://bsky.social/xrpc/com.atproto.repo.createRecord", {
method: "POST",
headers: {
"Authorization": "Bearer " + bs_auth_token, // 認証トークン(accessJwt)を渡す
"Content-Type": "application/json"
},
payload: JSON.stringify({
repo: MY_BLUESKY_USERNAME,
collection: "app.bsky.feed.post",
record: {
text: bs_post_message,
createdAt: new Date().toISOString()
}
})
});
// APIからのレスポンスは正常か
if (api_response.getResponseCode() === 200) {
console.log("Blueskyメッセージ投稿に成功。");
return true;
} else {
// 例外を投げ処理中断
throw new Error("Blueskyメッセージ投稿に失敗。" + api_response.getContentText());
}
}
// Blueskyにbot API経由でテストメッセージを1つ投稿する。
function bluesky_postTestMessage() {
// テスト用の文字列
const test_message = "テスト投稿用のメッセージです。" + (new Date().toLocaleString("ja-JP"));
// 投稿
bluesky_postOneMessage( test_message );
}
上述のコード冒頭「自分のBlueskyアカウント名とアプリパスワードを記述する」という2つの行に,ご自分のBlueskyアカウント情報を記載しておいてくださいね。
実行方法
実行方法は簡単で,GASのエディタをブラウザで開いていると上部に関数選択のプルダウンボックスがあるので,そこで bluesky_postTestMessage を選び「実行」を押すだけです。
すると,該当Blueskyアカウントにテストメッセージが投稿されます。
このサンプルコードは何に使えるの?
上記のコードは,BlueskyのAPIを使う「主な流れ」を理解するための学習用のコードです。
言わば「サンプルコードのサンプルコード」に過ぎません。その旨をコード内のコメントにも記載してあります。
実運用に不可欠なさまざまな処理をあえてごっそり省き,短く簡潔にしてあるのです。
「実運用に不可欠なさまざまな処理」とは,例えば下記のようなニーズを考慮したコードの事です。
- 「もしAPIにアクセス失敗したら,try-catch構文でエラー処理して…」
- 「万が一ソースコードに不正アクセスされた場合に備えてセキュリティを強化して…」
そのような実用的なコードを作り込んでゆくために,まず第一歩として上記のコードを「読んで理解する」というステップが役立つと思います。要点だけ抽出してあるわけです。
今回掲載のコードを実運用に役立つ・よりしっかりしたコードに書き換えてゆくためには,下記リンクの情報が役立つと思います。
【超初心者向け】5分でBluesky自動投稿Botを作る方法【2025年最新・完全無料】
https://note.com/unknowninterview/n/n902b956257ba
定期つぶやきさせるには?
botを安定稼働させるためには,1時間おきなどの時間間隔をあけて,SNSへのメッセージ自動投稿の処理を定期的に呼び出す必要があります。
Googleスプレッドシートには,GASで書いたコードの関数をタイマーのように定期的に呼び出す仕掛けが存在します(トリガー機能)。
その事については,また別の記事で設定方法・使い方などを記載する事にいたしましょう。
どうしてトリガ機能の説明を別の機会にゆずるのか?というと,「それはBlueskyのAPI利用方法とは別の話だから」です。
あくまでも「BlueskyでAPIにアクセスして,投稿したいメッセージを送信する」というのが中核であり,そこが分かってさえいれば,あとはもうBlueskyではなくGoogleスプレッドシート側の話ですよね。
実用的なbotを完成させるためには,全体の構成は下記のようになります。
- スプレッドシート上にbot投稿したいメッセージをたくさん(何百行も,何千行も)列挙して書いておき,
- 一定時間おきにそれらのメッセージをGASで上の行から1つずつスキャンして,どのメッセージを投稿したいかを選び,
- 今回投稿したいメッセージを1つだけ,API経由でBlueskyに送信する。
これら3つの処理のうち,3 に相当するのが今回の記事に掲載したサンプルコードです。
いっぽう 1,2 に相当する部分は,「シート内でたくさんある行の中から1つの行を選び,その行に書かれているデータを1行ずつ個別に処理してゆく」…という,Excel VBAなんかでよくある典型的なシートスキャン処理になります。
それを,いわばcronのようなタイマーで定期的に呼び出すバッチ処理として実現したいわけです。(この構成がわかれば,Googleスプレッドシートを使わなくてもGAS以外の方法でbotを実現する方法がたくさんある事にお気づきになるかと思います。)
そういう事ですので…。 今回は,BlueskyのAPIを無料で簡単に利用できる,という仕組み・流れが理解できればよし。そこまでで記述をとめておきます。
トリガー機能や,シート内の大量データをスキャンする仕組みを含めた実用的なbot構成については,また別の記事でお会いしましょう。
※後日,2026/4/7に追記:
トリガー機能の使い方等について,下記のQiita記事を執筆・公開しました。
「たった200行で,GASのトリガ重複実行を検出・回避し,シート末尾に定期的にログ記録するサンプルコード (排他制御しつつ,Googleスプレッドシート内でデータが存在する最終行に情報記録)」
https://qiita.com/rwanda_go_tan/items/e6a8bae04fdd2d1ba9a6