前の記事では、AntigravityでX自動投稿を作るための準備を行いました。
この記事では、実際にPythonでXへ投稿するコードを作ります。
今回の目標は、CSVに保存した投稿文の中からreadyの投稿を1件だけ選び、X APIを使って投稿することです。
投稿が成功したら、CSVのstatusをpostedに変更し、投稿日時を記録します。
今回作る処理の流れ
今回作る処理は、次の流れです。
1. .envからX APIキーを読み込む
2. posts.csvを開く
3. statusがreadyの投稿を1件探す
4. X APIへ投稿する
5. 成功したらstatusをpostedに変更する
6. posted_atに投稿日時を入れる
7. CSVを保存する
この流れが理解できれば、X自動投稿の基本はほぼ完成です。
posts.csvの確認
まず、posts.csvを次の形にします。
id,text,status,posted_at
1,Antigravityを使えば、X自動投稿の仕組みもAIと一緒に作れます。,ready,
2,X自動投稿はブラウザ操作ではなく、公式APIを使うのが安全です。,ready,
3,投稿文はCSVで管理すると、初心者でも仕組みを理解しやすくなります。,ready,
重要なのは、status列です。
readyは未投稿、postedは投稿済みという意味にします。
post_to_x.pyを作る
次に、post_to_x.pyを作ります。
import csv
import os
from datetime import datetime
from dotenv import load_dotenv
from requests_oauthlib import OAuth1SessionPOSTS_CSV = "posts.csv"def load_env():
load_dotenv() api_key = os.getenv("X_API_KEY")
api_secret = os.getenv("X_API_SECRET")
access_token = os.getenv("X_ACCESS_TOKEN")
access_token_secret = os.getenv("X_ACCESS_TOKEN_SECRET") if not all([api_key, api_secret, access_token, access_token_secret]):
raise ValueError(".envに必要なX APIキーが設定されていません。") return api_key, api_secret, access_token, access_token_secretdef get_next_post():
with open(POSTS_CSV, mode="r", encoding="utf-8-sig", newline="") as file:
reader = csv.DictReader(file)
rows = list(reader) for row in rows:
if row["status"] == "ready":
return row, rows return None, rowsdef save_posts(rows):
fieldnames = ["id", "text", "status", "posted_at"] with open(POSTS_CSV, mode="w", encoding="utf-8-sig", newline="") as file:
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(rows)def post_to_x(text):
api_key, api_secret, access_token, access_token_secret = load_env() oauth = OAuth1Session(
api_key,
client_secret=api_secret,
resource_owner_key=access_token,
resource_owner_secret=access_token_secret,
) url = "https://api.x.com/2/tweets" response = oauth.post(
url,
json={"text": text}
) if response.status_code not in [200, 201]:
raise Exception(f"投稿に失敗しました: {response.status_code} {response.text}") return response.json()def main():
post, rows = get_next_post() if post is None:
print("投稿待ちのデータがありません。")
return text = post["text"]
print(f"投稿します: {text}") result = post_to_x(text)
print("投稿成功:", result) for row in rows:
if row["id"] == post["id"]:
row["status"] = "posted"
row["posted_at"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
break save_posts(rows)
print("CSVを更新しました。")if __name__ == "__main__":
main()
コードの意味を初心者向けに解説
このコードでは、まず.envからX APIの認証情報を読み込んでいます。
load_dotenv()
これにより、.envに書いたAPIキーをPythonから使えるようになります。
次に、posts.csvを読み込みます。
reader = csv.DictReader(file)
rows = list(reader)
DictReaderを使うことで、CSVの各行を辞書のように扱えます。
たとえば、投稿文は次のように取り出せます。
row["text"]
投稿対象は、statusがreadyのものだけです。
if row["status"] == "ready":
return row, rows
これで、未投稿の投稿文を1件だけ取得できます。
X APIへ投稿する部分
Xへ投稿しているのは、この部分です。
response = oauth.post(
url,
json={"text": text}
)
urlには、X APIの投稿用エンドポイントを指定しています。
url = "https://api.x.com/2/tweets"
X公式ドキュメントでも、投稿作成のエンドポイントはPOST /2/tweetsとして案内されています。
投稿本文は、JSON形式で送ります。
json={"text": text}
つまり、CSVから読み込んだ投稿文を、X APIへ送信しているということです。
実行方法
ターミナルで次のコマンドを実行します。
python post_to_x.py
Macなどの場合は、次のコマンドです。
python3 post_to_x.py
成功すると、ターミナルに次のような表示が出ます。
投稿します: Antigravityを使えば、X自動投稿の仕組みもAIと一緒に作れます。
投稿成功: {...}
CSVを更新しました。
その後、posts.csvを確認すると、1行目のstatusがpostedに変わります。
id,text,status,posted_at
1,Antigravityを使えば、X自動投稿の仕組みもAIと一緒に作れます。,posted,2026-04-27 10:00:00
2,X自動投稿はブラウザ操作ではなく、公式APIを使うのが安全です。,ready,
3,投稿文はCSVで管理すると、初心者でも仕組みを理解しやすくなります。,ready,
これで、同じ投稿が何度も投稿されるのを防げます。
Antigravityに修正を依頼するプロンプト
コードを書いたあと、Antigravityに次のように依頼すると改善しやすいです。
このpost_to_x.pyを確認してください。目的は、posts.csvからstatusがreadyの投稿を1件取得し、X APIで投稿し、成功後にstatusをpostedへ変更することです。以下を確認してください。
・APIキーがコードに直接書かれていないか
・同じ投稿が二重投稿されないか
・エラー時にCSVが更新されないか
・初心者にもわかるコメントになっているか
・改善点があれば修正してください
Antigravityは、単にコードを作るだけでなく、確認や改善にも使えます。
エラーが出たときの見方
投稿に失敗した場合、次のようなエラーが出ることがあります。
投稿に失敗しました: 401
これは認証エラーの可能性があります。
確認することは次の通りです。
・API Keyが正しいか
・API Secretが正しいか
・Access Tokenが正しいか
・Access Token Secretが正しいか
・アプリ権限がRead and writeになっているか
・権限変更後にトークンを再生成したか
次のようなエラーもあります。
投稿に失敗しました: 403
これは権限不足やAPI利用プランの問題で発生することがあります。
また、同じ内容を何度も投稿しようとすると、スパムや重複投稿の扱いになる可能性があります。
Xの自動化ルールでは、重複または実質的に同じ投稿を複数回行うことに注意が必要とされています。
初心者がやりがちな失敗
初心者がよく失敗するのは、次のパターンです。
.envのファイル名が間違っている
.envを.env.txtで保存している
CSVの列名が違う
statusに余計な空白が入っている
Pythonの実行場所が違う
X APIの権限が足りない
特にWindowsでは、.envが実際には.env.txtになっていることがあります。
拡張子を表示して確認してください。
この記事のまとめ
この記事では、PythonでXへ自動投稿する基本コードを作りました。
重要なポイントは次の通りです。
- 投稿文はCSVで管理する
- statusがreadyの投稿だけを投稿する
- X APIのPOST /2/tweetsを使う
- 投稿成功後にstatusをpostedへ変更する
- APIキーは.envで管理する
これで、手動実行によるX自動投稿の基本は完成です。
次の記事では、この仕組みに「予約投稿」と「定期実行」を追加して、毎日決まった時間に投稿できる形へ発展させます。

