【自動化】Qiitaの更新をXに投稿する仕組みをPythonで作ってみたのでまとめました！

## はじめに

今回は、Qiitaの組織アカウントに新着記事が投稿された際に、自動でX（旧Twitter）へ投稿する仕組みを趣味で作ってみたので、その実装方法とポイントをまとめます。

前回の記事の続きになります。

https://qiita.com/free-honda/items/6919ff23fc904e2dd1d9

手動で投稿する手間を省き、最新情報をリアルタイムで発信できるようにすることが目的です。**また、個人的にも興味のある仕組みだったため、実際に手を動かして検証してみました。**

## 書こうと思ったきっかけ

Qiitaの組織アカウントに新しい記事が投稿されたときに、すぐにXへ投稿したいと思ったのがきっかけです（※すでにX側に同様の機能はありますが…笑）。

**将来的には、自分で作った仕組みを使って、文字などもカスタマイズして色々実装してみたいと考えています！**

![Screenshot 2025-06-16 at 22.08.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/b7865fae-c50b-4da1-97da-f7d69f1abef5.png)

特に、手動で投稿する作業が煩雑であること、そして「**次回のハッカソンに向けたテスト検証を進めていきたい！**」という思いがあります。

前回の記事では「Xへの自動投稿の仕組み」を作成しましたが、今回はその続きとして、Qiita上に新着記事があるかを判定し、「**新着がある場合のみ投稿、なければ何もしない**」ように制御する部分を実装しました。

## 事前準備など

* Qiitaの組織アカウント（友達にテスト用で作成していただきました！）

![Screenshot 2025-06-16 at 22.13.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/874cddb9-77fb-4c94-853e-f0f3fb218ef8.png)

* QiitaのRSSフィード（ATOM形式）

https://qiita.com/organizations/hackathon-challenge/activities.atom

**これです！**

![Screenshot 2025-06-16 at 22.10.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/973d7799-a123-416a-ba3e-ea33740af284.png)

* Tweepyライブラリ（Twitter API v2用）
* feedparser（RSSフィード解析用）
* python-dotenv（環境変数管理）
* ローカルに保存するIDファイル（同一記事の重複投稿防止）

### RSSフィードURL及びテスト記事の追加

[https://qiita.com/organizations/hackathon-challenge/activities.atom](https://qiita.com/organizations/hackathon-challenge/activities.atom)

**こんな感じで簡単なテスト記事を追加してみました！**

![Screenshot 2025-06-16 at 22.54.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/091b0081-9966-4e5f-a8b1-6253c55db999.png)

## Qiitaの新着記事をX（旧Twitter）に自動投稿するBot構築手順

### 1. .envファイルを作成し、認証情報を設定
```env
BEARER_TOKEN=xxx
API_KEY=xxx
API_SECRET=xxx
ACCESS_TOKEN=xxx
ACCESS_TOKEN_SECRET=xxx
```

> ※すべてX Developer Portalから取得

**詳しくは前回の記事で紹介しているので、興味のある方はぜひご覧ください〜**

https://qiita.com/free-honda/items/6919ff23fc904e2dd1d9

### 2. Pythonコード（qiita_to_x_bot.py）

```python
import os
import tweepy
import feedparser
from dotenv import load_dotenv

# 環境変数の読み込み
load_dotenv()

# Twitter API 認証
client = tweepy.Client(
    bearer_token=os.getenv("BEARER_TOKEN"),
    consumer_key=os.getenv("API_KEY"),
    consumer_secret=os.getenv("API_SECRET"),
    access_token=os.getenv("ACCESS_TOKEN"),
    access_token_secret=os.getenv("ACCESS_TOKEN_SECRET")
)

# Qiita組織のRSS URL
FEED_URL = "https://qiita.com/organizations/hackathon-challenge/activities.atom"

# 最後に取得した記事IDを保存（ローカルファイル使用）
LAST_ID_FILE = "last_qiita_id.txt"

def get_last_id():
    if os.path.exists(LAST_ID_FILE):
        with open(LAST_ID_FILE, "r") as f:
            return f.read().strip()
    return ""

def save_last_id(entry_id):
    with open(LAST_ID_FILE, "w") as f:
        f.write(entry_id)

def fetch_latest_entry():
    feed = feedparser.parse(FEED_URL)
    if not feed.entries:
        return None
    return feed.entries[0]

def tweet_new_entry(entry):
    title = entry.title
    link = entry.link
    user = entry.author
    tweet = f"【Qiita更新】{title} by {user}\n{link} #Qiita #HackathonChallenge"
    client.create_tweet(text=tweet)
    print("✅ ツイートしました：", tweet)

def main():
    latest_entry = fetch_latest_entry()
    if not latest_entry:
        print("⚠️ フィードが空です")
        return

    last_id = get_last_id()
    if latest_entry.id != last_id:
        tweet_new_entry(latest_entry)
        save_last_id(latest_entry.id)
    else:
        print("🟢 新しい記事はありません")

if __name__ == "__main__":
    main()
```

### 簡単なコード解説

1. `feedparser` を使ってRSSフィードから最新記事を取得
2. `last_qiita_id.txt` に保存されているIDと比較
3. 最新記事のIDが異なれば投稿を実行し、そのIDを保存
4. 同じIDであれば投稿せずに終了（重複投稿を防止）

## 実際にやってみた（ローカルでの実行方法（M1 Mac対応））

### ① Python仮想環境を作成

まず、プロジェクトディレクトリに移動し、Python仮想環境を作成します：

```bash
python3 -m venv venv
```

* `python3` は macOS に標準で入っている Python3 を指定します。
* `venv` は仮想環境の名前で、任意のディレクトリ名でもOKです。

### ② 仮想環境を有効化

作成した仮想環境を有効化します：

```bash
source venv/bin/activate
```

* 仮想環境を有効にすることで、他のPythonプロジェクトやシステム環境に影響を与えずにライブラリをインストールできます。

### ③ pip を最新版にアップグレード

M1 Macでは、パッケージのビルドエラーを防ぐためにも `pip` のアップグレードが推奨されます：

```bash
pip install --upgrade pip
```

### ④ 必要なライブラリをインストール

次の3つのライブラリをインストールします：

```bash
pip install tweepy feedparser python-dotenv
```

* `tweepy`: Twitter（X）APIとのやりとり用ライブラリ
* `feedparser`: RSSフィードを解析するためのライブラリ
* `python-dotenv`: `.env` ファイルから環境変数を読み込むためのライブラリ

**参考文献**

https://scr.marketing-wizard.biz/dev/tweepy-twitter-apiv2

https://brian0111.com/python-feedparser-rss-parsing-guide/

https://qiita.com/harukikaneko/items/b004048f8d1eca44cba9

### ⑤ スクリプトを実行

最後に、スクリプトを実行します：

```bash
python qiita_to_x_bot.py
```

**いい感じにツイートされているログも出力されていることが確認できました！**

![Screenshot 2025-06-16 at 23.50.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/cb5bb016-0bce-4480-ad4d-cce691d9c08c.png)

**このように、自動でツイートされていることを確認できたので、今回の検証はひとまず成功と言えそうです！**

![Screenshot 2025-06-16 at 21.49.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/5fc0c479-a66a-499f-9c43-990e9fd941fb.png)

## まとめ

ここまで読んでいただき、ありがとうございました！Qiitaの組織記事をトリガーにXへ自動投稿する仕組みをPythonで構築してみました...！

:::note info
今回のポイントは「**記事があった場合だけ投稿する**」仕組みにより、無駄なリクエストや重複ツイートを防げるという点です。
:::

次回以降は、GitHub Actionsを使った本番運用への自動化や、複数記事の検知・投稿にも対応できるよう改善していく予定です！！

## おまけ：自動化の運用

cronやGitHub Actionsなどを使えば、以下のように定期実行が可能なので、挑戦していきたいです！！

* 1時間おきにRSSチェック → 新着があれば投稿
* 投稿済み記事IDはファイルで管理（重複防止）

***引き続き、自分に負けずにコツコツと技術検証を進めていきます…！***