1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Podcast の文字起こしから、X に 1 日 5 回自動投稿してみた(GitHub Actions・月約 $3)

1
Posted at

はじめに

「信州プルリクエスト」という Podcast をやっています。長野で働くエンジニア 2 人が、ゆるく雑談する番組です。

X への投稿は、以前は手動でしていましたが、反応もなく、だんだん面倒になってきました。一方で、エピソードは 19 話になり、話した内容も少しずつ溜まってきました。その文字起こしから文章を抜粋すれば、投稿を作れるのではと思いました。

そこで、X へ 1 日 5 回、GitHub Actions で自動投稿する仕組みを作り、2026 年 10 月 25 日に動かし始めました。

  • 費用は月約 $3(X API の従量課金)です
  • フォロワーは 11 人です(10 月 31 日時点)。認知度への効果は、まだ出ていません
  • 続けるかどうかの基準は、先に決めました。3 か月後に「フォロワー +5」「配信日(火曜)以外の再生数が増えた」「長野系のアカウントから反応があった」のどれもなければ、頻度を下げるか止めます

この記事では、その仕組みと費用、6 日間の途中経過を書きます。成功談ではありません。

1. 構成

手元で作るファイルと、ボット(GitHub Actions)が書くファイルを分けました。queue.json の文面は、抜粋した文章に、Claude Code で自分が話しているっぽさを加えたものです。

// queue.json(手元で作る)
{"id": 212, "type": "b", "episode": null,
 "text": "10月31日、松川渓谷に紅葉を見に行ってきました。…\n\n#長野 #紅葉",
 "priority": true, "image": "images/matsukawa-20261031.jpg"}
// state.json(ボットだけが書く)
{"announcements": [{"id": 62, "type": "a", "episode": "ep019", "text": "今週のPR:…", "priority": true}],
 "status": {"212": {"posted_at": "2026-10-31T21:08:25+09:00"}}}

新しいエピソードの告知(announcements)は、別のワークフローが配信日の火曜の朝に RSS を確認して追加します。

最初は queue.json に投稿時刻も書いていました。手元で編集している間にボットが commit すると、マージが衝突しました。ファイルを分けてからは、衝突していません。

切り替えの途中で、ボットが旧形式(queue.json)に記録した投稿済みが 10 件あり、手で state.json に移しました。

post_next.py は、実行のたびに次の 1 件を選んで投稿します。選び方は次のとおりです。

  • 新しいエピソードの告知が最優先
  • それ以外は、まだ投稿していないもの → 投稿が古いものの順。30 日は再投稿しない。季節ものは、その月だけ
  • URL 付きの投稿は料金が高いので、週に 1 回まで(「3. 費用」を参照)

2. ワークフロー

投稿するワークフローの抜粋です。

on:
  schedule:
    - cron: "7 22,2,6,10,13 * * *"   # JST 7:07/11:07/15:07/19:07/22:07
concurrency:
  group: queue                        # 同時に走らせない(二重投稿の防止)
  cancel-in-progress: false
permissions:
  contents: write                     # state.json を commit する
steps:
  - run: python -m unittest discover -s social -p "test_*.py"   # 落ちたら投稿しない
  - run: python social/post_next.py                              # キーは secrets.X_API_KEY など 4 つ
  - name: Commit state
    if: ${{ always() }}                                          # 投稿に失敗した日も記録を残す
    run: |
      git add social/state.json
      git diff --cached --quiet && exit 0
      git commit -m "social: 投稿結果を記録"
      for i in 1 2 3; do git pull --rebase origin main && git push && exit 0; sleep 5; done

毎時 0 分を避けて 7 分にしているのは、GitHub のドキュメントに次のように書かれているからです。

High load times include the start of every hour. If the load is sufficiently high enough, some queued jobs may be dropped. To decrease the chance of delay, schedule your workflow to run at a different time of the hour.

(出典: Events that trigger workflows - GitHub Docs)

3. 費用

X の公式の料金表(2026 年 10 月に確認)をもとに計算しました。

操作 単価 月の回数 月額
通常の投稿 $0.015 約 150 回(5 回 × 30 日) 約 $2.25
URL 付きの投稿(告知) $0.20 約 4 回 約 $0.8
合計 約 $3

画像付きの投稿は、公式の料金表にアップロードの単価が見当たりませんでした。実際に投稿してみると、残高の減りは文字だけの投稿とほぼ同じでした。

4. Automated ラベルを付けていなかった

この記事を書いていて、X の開発者向けガイドラインに次の一文があることに気づきました。

Automated accounts must be labeled.

(出典: Developer Guidelines - X)

動かし始めてから 6 日間、ラベルを付けていませんでした。プロフィールに「Automated」のラベルを付け、プロフィール文にも自動で投稿していることと運用者を書きました。

5. 実際の投稿を見て

文字だけの投稿が並ぶタイムラインは、見窄らしかったです。

そこで、写真を付けた投稿を出しました。見た目は変わり、こども農園の投稿には初めていいねが 1 件付きました(インプレッション 22、10 月 31 日時点)。文字だけの投稿との比較は、まだしていません。

写真は、自分で撮ったものと、フリー素材(Wikimedia Commons の CC0・CC BY、Pexels など)を使っています。位置情報を消し、写り込み(名札など)を切り落とし、出典とライセンスを記録しました。CC BY の写真は、投稿の本文にクレジットを入れています。

6. 次にやること

自動化しているのは投稿だけです。4 章で引用した開発者向けガイドラインでは、自動のいいね・フォローは禁止されています。

Automated, bulk, or indiscriminate liking — including auto-liking by keyword, hashtag, user, or schedule — is prohibited.

No bulk, aggressive, or automated following.

返信やいいねは、手でやります。

もう一つは、写真の効果を確かめることです。11 月 14 日と 21 日に、写真付きと文字だけの投稿でインプレッションを比べます。

おわりに

月 $3 の勉強代だと思って、3 か月続けてみます。

相方にも、写真を頼んでみようと思います。結果はまた書きます。

参照

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?