substack について
Substack のアカウント情報や記事の確認、認証済み Web API 経由での投稿を行うスキルと Python CLI です。セッション Cookie を使い、書き込みには明示的な確認が必要です。
主な機能
- 01ログイン中のアカウントと publication の確認
- 02公開済み記事と統計の一覧表示
- 03Markdown を Substack 形式に変換
- 04書き込み前の公開内容の確認
- 05下書き作成または記事の公開
活用シーン
- 01接続中のアカウントと publication の確認
- 02公開済み記事と統計の確認
- 03記事を非公開の下書きとして保存
- 04明示的な承認後の記事公開
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ acedatacloud/ skills --skill substackインストール後、Claude Code で/substackを入力して読み込まれたか確認します。
同梱ファイルscripts/substack.py
詳細
substack — 自分の Cookie を使って Substack を読み書きする
サイトが使用するものと同じ内部 Web API を通じて、ユーザーの実際の Substack アカウントを操作します(Substack には公式の公開書き込み API がありません)。認証には、ACE 拡張機能で取得したログイン Cookie を使用します。ブラウザーもサードパーティー依存関係も不要で、urllib のみを使用します。公開の流れはコミュニティ製 python-substack ライブラリーに倣い、下書きの作成 → 公開前処理 → 公開となります。
コネクターは Cookie jar を環境変数として渡します。
SUBSTACK_COOKIES— Cookie の JSON 配列(substack.sid、substack.lli、…)。秘密情報です。絶対にエコーしたり出力したりしないでください。 Substack の書き込み認証にはセッション Cookie のみを使用します(CSRF トークンヘッダーは不要です)。
CLI
このスキルには、自己完結型で標準ライブラリーのみを使用する scripts/substack.py が含まれています。
# $SKILL_DIR can point at another skill loaded this turn — anchor on our own
# script, and re-run this at the top of every Bash block (fresh shell each time).
SUB="$SKILL_DIR/scripts/substack.py"; [ -f "$SUB" ] || SUB=$(find /tmp -maxdepth 8 -path '*/skills/*/scripts/substack.py' 2>/dev/null | head -1)
[ -f "$SUB" ] || { echo "substack script not found (SKILL_DIR=$SKILL_DIR)" >&2; exit 1; }
python3 "$SUB" whoami # who is logged in + primary publication
python3 "$SUB" articles --limit 20 # my published posts + stats
最初に接続を確認する
SUB="$SKILL_DIR/scripts/substack.py"; [ -f "$SUB" ] || SUB=$(find /tmp -maxdepth 8 -path '*/skills/*/scripts/substack.py' 2>/dev/null | head -1)
python3 "$SUB" whoami
# → {"user_id": ..., "name": "...", "handle": "...", "publication": "...", "publication_url": "https://<sub>.substack.com"}
認証エラーが発生した場合、Cookie の有効期限が切れています。ユーザーに https://studio.acedata.cloud/console/connectors で再接続してもらってください。再試行を繰り返してはいけません。
公開 — 確認必須(末尾に --confirm がない場合はドライラン)
publish はユーザーの実際のアカウントに書き込みます。コンテンツはMarkdown形式で、Substack の ProseMirror ブロックに変換されます。#..######→見出し、```→コードブロック、>→引用、-/*/1.→リスト、---→水平線、それ以外→段落となります。インラインの太字、斜体、コード、取り消し線、[リンク](url) は Substack の書式として表示されます。裸の https://… URL は自動的にリンクになります。
末尾に --confirm がない場合はドライランになります。--confirm が有効になるのは、最後の引数として指定された場合のみです。必ずドライランの結果を表示して明示的な「はい」を得てから、再実行してください。
SUB="$SKILL_DIR/scripts/substack.py"; [ -f "$SUB" ] || SUB=$(find /tmp -maxdepth 8 -path '*/skills/*/scripts/substack.py' 2>/dev/null | head -1)
# dry-run (shows the plan, writes nothing)
python3 "$SUB" publish --title "Title" --content-file post.md
# private draft (visible only in the user's dashboard)
python3 "$SUB" publish --title "Title" --content-file post.md --draft-only --confirm
# go LIVE on the web (does NOT email subscribers)
python3 "$SUB" publish --title "Title" --content-file post.md --confirm
# go LIVE and email subscribers (use only when the user explicitly asks)
python3 "$SUB" publish --title "Title" --content-file post.md --send-email --confirm
--draft-onlyを指定すると下書きの状態で止まります。ユーザーが公開を依頼していない限り、これをデフォルトにしてください。Substack エディターで確認できるedit_urlが返されます。--send-emailを渡さない限り、公開しても購読者にメールは送信されません。ニュースレターのメール送信は取り消せず、すべての購読者の受信トレイに届きます。明示的な依頼がない限り、--send-emailを追加してはいけません。--subtitleは投稿のサブタイトルを設定します。--audienceにはeveryone(デフォルト、無料/公開)、only_paid、founding、only_freeのいずれかを指定します。
注意点
- これはユーザーの実際の Substack アカウントです。 公開する前に必ず確認し、安全なデフォルトとして
--draft-onlyを使用してください。 --send-emailは購読者リスト全体にメールを一斉送信し、取り消せません。 明示的な依頼がある場合にのみ選択してください。- Substack は Cloudflare の背後にあります。読み取り時にまれに発生する 403/429 は一時的なものです。CLI は読み取りを 1 回だけ自動再試行します。401/403 が継続する場合は、Cookie の有効期限が実際に切れています(再接続してください)。CLI は書き込みを再試行しません。
SUBSTACK_COOKIESを絶対に出力しないでください。 アカウントへの完全なアクセス権限を持つ情報です。- 利用規約:ユーザーが自分で取得した Cookie を使って、ユーザー自身のアカウントに対してのみ操作します。
出力を記録する
公開に成功し、公開結果の URL を取得したら、組み込みの publish_artifact ツールを 1 回だけ呼び出して、ユーザーが My Outputs でこの成果物を追跡できるようにしてください。
publish_artifact(kind="article", channel="substack", title="<title>", url="<the REAL returned URL>", status="delivered")
実際に返された URL を使用してください。URL を捏造してはいけません。公開した項目ごとに 1 回だけ、配信が確認された後に呼び出してください。公開に失敗した場合は呼び出さないか(または status="failed" を使用してください)。_shared/artifacts.md を参照してください。