結論
Qiitaのトークンから取得できるデータに下書き (private: true) が含まれない為です。
ログの例:
id: b47e17e38e93848166fa, title: 【商品管理システムの開発】商品を追加するフォーム, private: False, coediting: False
開発手順
Qiitaの個人用アクセストークンを発行
スコープは下記を選択
スコープ | 説明 |
---|---|
write_qiita | 下書きの作成・更新・公開(投稿)に必要 |
read_qiita | 下書き一覧・記事の取得に必要(下書きを探すため) |
Pythonインストール
brew install python
仮想環境の作成(推奨)
python3 -m venv qiita_auto_env
source qiita_auto_env/bin/activate
必要パッケージのインストール
今回は以下のパッケージを使用予定です:
• requests: Qiita API を叩くための HTTP ライブラリ
• python-dotenv: .env ファイルからトークンを安全に読み込むため
pip install requests python-dotenv
.env ファイルの作成
作業ディレクトリに .env ファイルを作成して、以下のように Qiitaのアクセストークン を記載する。
QIITA_ACCESS_TOKEN=40ae811f44faf0d1164df46e291261b4436d9ccc
自動投稿スクリプト
① ライブラリ読み込みとトークン取得
import requests
import os
from dotenv import load_dotenv
load_dotenv()
QIITA_TOKEN = os.getenv("QIITA_ACCESS_TOKEN")
• requests: HTTPリクエストを送るライブラリ(API通信に必要)。
• os.getenv(): 環境変数からトークンを取得。
• .envファイルに書かれたトークン(例: QIITA_ACCESS_TOKEN=xxxx...)を QIITA_TOKEN にセット。
🔐 注意: .env ファイルの名前や配置ミスがあるとトークンが取得できません。
② API通信に使うヘッダー定義
HEADERS = {
"Authorization": f"Bearer {QIITA_TOKEN}",
"Content-Type": "application/json"
}
Qiita APIではアクセスに Bearer <トークン> を指定する必要があります。
③ 下書き一覧を取得する関数
# 下書き一覧を取得
def get_drafts():
url = "https://qiita.com/api/v2/authenticated_user/items"
params = {"page": 1, "per_page": 100}
response = requests.get(url, headers=HEADERS, params=params)
response.raise_for_status()
items = response.json()
• authenticated_user/items は「自分の投稿(下書き含む)」を取得するエンドポイント。
• params により最大100件を1ページ目から取得。
• raise_for_status() はHTTPエラーをPythonの例外に変換。
• items には記事のリストが入ります。
print(f"取得件数: {len(items)}")
for item in items:
print(f"id: {item['id']}, title: {item['title']}, private: {item.get('private')}, coediting: {item.get('coediting')}")
• APIで取得したログ
drafts = [item for item in items if item.get("private") and not item.get("coediting", False)]
• private=True: 下書き(非公開)であり、
• coediting=False: 共同編集でない(公開できる)ものだけを抽出。
return sorted(drafts, key=lambda x: x["created_at"])
• 最も古い記事から順に並べて返す。
④ 下書きを公開する関数
# 公開処理
def publish_draft(item_id):
url = f"https://qiita.com/api/v2/items/{item_id}"
data = {"private": False}
response = requests.patch(url, headers=HEADERS, json=data)
response.raise_for_status()
return response.json()
• PATCH /items/:id を使って private: False に更新 → これで公開状態になります。
⑤ 実行メイン処理
if __name__ == "__main__":
drafts = get_drafts()
if drafts:
oldest = drafts[0]
published = publish_draft(oldest["id"])
print(f"✅ 公開しました: {published['title']}")
else:
print("📭 公開可能な下書きがありません。")
• 公開できる下書きがあれば、最も古いものを1つ公開します。
• なければ「📭 公開可能な下書きがありません」と表示。
スクリプトを実行
python auto_publish_qiita.py
実行結果
(qiita-auto-post-env) kerumatomomitsu@kerumatomomitsunoMacBook-Air qiita-auto-post-env % python auto_publish_qiita.py
取得件数: 100
id: b47e17e38e93848166fa, title: 【商品管理システムの開発】商品を追加するフォーム, private: False, coediting: False
id: 7aebd168405d8397fdc7, title: 【商品管理システムの開発】削除ボタンの修正, private: False, coediting: False
id: e218904cf17859d43cb5, title: 【商品管理システムの開発】UI改良, private: False, coediting: False
id: b5c74dca329f53941a1f, title: 【商品管理システムの開発】商品一覧ページの表示, private: False, coediting: False
id: d30b1ab4a62684cf8a98, title: 【商品管理システムの開発】Firebaseへ接続, private: False, coediting: False
id: cf56ce0a83bd7918a23d, title: 【商品管理システムの開発】Firestoreのデータ型定義の整理方法, private: False, coediting: False
id: 17da5e5ad1676c67a738, title: Java解説 20250728, private: False, coediting: False
id: 3923223f5c01c5806126, title: Next.jsのpage.tsxについて, private: False, coediting: False
id: a6db1cbf011ae7101551, title: Juliaを使用したデルタヘッジ戦略のシミュレーション解説(2), private: False, coediting: False
id: 1f7eafcfd2d09f736d50, title: Juliaを使用したデルタヘッジ戦略のシミュレーション解説(1), private: False, coediting: False
id: a515e3f447686029a6a6, title: Juliaを使用したVasicekモデルの解説, private: False, coediting: False
id: 57afc356c9f746cc0145, title: モンテカルロ法のコード解説, private: False, coediting: False
id: e83d51cc191c00bc3eeb, title: 金融工学アプリ開発 コード解説(3), private: False, coediting: False
id: 89cdc2ab940b6abe4e6a, title: Java解説 20250721, private: False, coediting: False
id: 20b52d72f047df995a9f, title: 金融工学アプリ開発 コード解説(2), private: False, coediting: False