0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PythonでQiitaの人気記事をNotionに自動転送するCLIツールを作った

Posted at

はじめに

Qiitaの人気記事を自動で取得し、Notionデータベースに転送するCLIツールを作りました。
いいね(LGTM)またはStock数が指定した閾値以上の記事のみを対象とし、Notion DBのカラム(プロパティ)が足りなければ自動で追加する機能も実装しています。

作ったもの

  • Qiita APIから過去N日分の記事を取得
  • LGTMまたはStock数が指定値以上の人気記事を抽出
  • 本文を自動要約(sumy + tinysegmenter)
  • Notionデータベースにupsert(新規追加 or 更新)
  • Notion DBにカラムがなければ自動で追加
  • CLI対話式・自動化(定時実行)どちらも対応

技術スタック

  • Python 3.11
  • Qiita API
  • Notion API
  • sumy(要約)
  • tinysegmenter(日本語分かち書き)
  • pytest(テスト)

実装のポイント

1. CLI対話式・自動化両対応

# 対話式(手動実行)
python main.py

# 自動化(定時実行)
python main.py --schedule --min-likes 500 --min-stocks 500 --backfill-days 1
  • CLIで「最低いいね数」「最低ストック数」「バックフィル日数」を日本語で入力
  • 全角/半角どちらも対応
  • --schedule--no-interactive指定時は定時実行モード

2. Notion DBのカラム自動追加

def ensure_notion_properties(self) -> None:
    """Notion DBのプロパティが足りなければ自動で追加"""
    current_properties = self.get_database_properties()
    required_properties = {
        "title": {"title": {}},
        "url": {"url": {}},
        "author": {"rich_text": {}},
        "likes": {"number": {}},
        "stocks": {"number": {}},
        "tags": {"multi_select": {}},
        "created_at": {"date": {}},
        "summary": {"rich_text": {}}
    }
    # プロパティの追加処理...

3. エラーハンドリングとリトライ

def retry_with_backoff(func):
    """指数バックオフでリトライするデコレータ"""
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        max_retries = 3
        base_delay = 1
        for attempt in range(max_retries):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                if attempt == max_retries - 1:
                    raise
                delay = base_delay * (2 ** attempt)
                time.sleep(delay)
    return wrapper

4. 型ヒントとテスト

from typing import Dict, List, Optional

class NotionClient:
    def get_database_properties(self) -> Dict[str, Dict]:
        """データベースのプロパティを取得"""
        pass

    def add_database_property(
        self, 
        property_name: str, 
        property_type: str
    ) -> None:
        """プロパティを追加"""
        pass

使い方

セットアップ

  1. リポジトリのクローン
git clone https://github.com/AirLabJP/QiitaNotionBridge.git
cd QiitaNotionBridge
  1. 必要なトークンの取得
  • Qiitaアクセストークン(read_qiitaスコープ)
  • Notion Integration Token
  • Notion Database ID
  1. 環境変数の設定
cp .env.example .env
# .envファイルを編集
  1. 依存パッケージのインストール
pip install -r requirements.txt

実行方法

対話式(手動実行)

python main.py

自動化(定時実行)

python main.py --schedule --min-likes 500 --min-stocks 500 --backfill-days 1

バックフィル実行

python main.py --backfill days=3 --min-likes 300 --min-stocks 200

今後の展望

  • Slack通知・Webhook連携
  • タグごとの閾値設定
  • Web UIやダッシュボード
  • 要約の精度向上

まとめ

  • Pythonで実用的なCLIツールを作成
  • 型ヒント・テスト・エラーハンドリングを徹底
  • 自動化と手動実行の両方に対応
  • 拡張性を考慮した設計

参考リンク

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?