「Zenn用に書き直して、Qiita用にも書き直して、X用の告知文作って...」このコピペ地獄、経験ありませんか?
playparkでは、MDX記事を1つ書いたらZenn・Qiitaへの記事転載とSNS 5媒体への告知配信を自動化するパイプラインを構築しました。Claude Code Skillsで作りました。ブログ運用の全体自動化は以前紹介しました。今回は記事転載とSNS配信パイプラインの2つを深掘りします。
この記事で学べること
- MDX → Zenn/Qiita変換で「同じ記事の使い回し」を避ける設計
- How型/Why型で切り口を変える戦略
- 5プラットフォームのSNS告知文を1コマンドで生成する仕組み
- Zernio CLIによる一括予約投稿の設計パターン
前提条件
- Claude Code Skillsの基本を知っていること(設計思想参照)
- Zenn/Qiitaへの投稿経験があること
- SNS運用の「めんどくささ」を身をもって知っていること
パイプライン全体像
5つのスキルが2つのパイプラインとして連携します。Cross-Post(Zenn/Qiita転載)とSNS Distribution(5媒体告知配信)です。1記事 → 7プラットフォーム配信を実現します。
blog-cross-post: コピペ問題を解く
なぜコピペがダメなのか
ZennとQiitaに同じ記事を投稿するとSEO効果が分散します。Googleは重複コンテンツを嫌い、どちらか片方が検索結果から消える可能性があります。ZennユーザーとQiitaユーザーでは求めているものも違います。
How型 vs Why型の切り分け
blog-cross-postの設計思想は 「コア版 + 深掘り導線」 です。完全コピーではなく、その場で学びが完結するコア版を作り、公式への自然な導線を設けます。
しかもZennとQiitaで切り口を変える:
| Zenn | Qiita | |
|---|---|---|
| 読者層 | モダン技術志向 | 幅広い技術者 |
| 切り口 | Deep How + 持論 | Why(選定理由) |
| 冒頭 | 課題共感 → 実装 → 持論 | 背景 → 課題 → 選択肢 |
| 読後感 | 「深い、使える」 | 「なるほど」 |
たとえば「Skills設計」記事なら、Zenn版は「設計パターンと判断基準」(実装+持論)、Qiita版は「なぜこう設計するのか」(課題→比較検討)。同じトピックなのに読後感が違う。これが「コピペじゃないcross-post」です。
アーキテクチャ: プラットフォーム知識の分離
以前はZenn/Qiita両方のテンプレートとSEOルールを内包するモノリシック設計でした。現在はプラットフォーム固有の知識を各publishスキルに分離しています。
blog-cross-post(共通ロジックのみ)
├── cross-post-strategy.md ← 差別化原則、コア版設計
├── MDXコンポーネント変換ルール
└── canonical URL対策
zenn-publish/references/
└── content-guide.md ← Zenn専用テンプレート、変換ルール、SEO
qiita-publish/references/
└── content-guide.md ← Qiita専用テンプレート、変換ルール、SEO
新しいプラットフォームを追加するとき、blog-cross-post本体を触る必要はありません。Open/Closedの原則が効いています。
変換で何をやっているか
元記事(MDX)
├── frontmatter変換(Zenn: emoji/topics、Qiita: tags/private)
├── コンポーネント変換(Mermaid、InteractiveDemo等)
├── 画像パス → 絶対URL化
├── 内部リンク → 絶対URL化
├── コア部分の抽出 + 深掘り導線の生成
└── canonical URL代替のテキストリンク追加
重要なのがcanonical URL対策。ZennもQiitaもfrontmatterをサポートしていません(ZennはIssue #78で要望あるが未実装)。テキストリンクで「この記事はplaypark Blogからの転載です」と明示します。これを忘れるとSEO事故が起きます。
コア版の設計原則
「続きは公式で」は読者を裏切る行為です。blog-cross-postではその場で学びが完結することを最優先に設計しています。
コア版で提供するもの:
├── 問題提起(読者の共感)
├── 解決アプローチの概要
├── 動作するコード例(1-2個)
├── 主要な結論
└── 【ここで記事として完結】
深掘り導線で示すもの:
├── 「さらに詳しく知りたい方へ」
│ ├── 複数パターンの比較
│ ├── 実運用での知見・失敗談
│ └── 応用・発展的な内容
└── 具体的に何が読めるかを明示
Zenn版は1,500〜2,500字、Qiita版は1,200〜2,000字が目安です。公式が5,000字超でも収まります。
cross-post-publish: オーケストレーター設計
cross-post-publishは「記事選択 → 変換 → 投稿」を一気通貫で実行するオーケストレーターです。
Phase 1: 記事選択(ユーザー入力はここだけ)
↓ 止まらない
Phase 2: blog-cross-postで変換(Zenn版 + Qiita版)
↓ 止まらない
Phase 3: zenn-publish + qiita-publishを並列実行
対象カテゴリ
全記事は対象外で、tech-tipsとlab-reportsだけが対象です。
| カテゴリ | Cross-post | 理由 |
|---|---|---|
| tech-tips | 対象 | エンジニア向け、適性高い |
| lab-reports | 対象 | 技術実験、Zenn向き |
| solutions | 対象外 | ビジネス層向け |
| case-studies | 対象外 | ビジネス層向け |
事例記事も出したい気持ちはわかりますが、Zennに「シフト管理自動化事例」を投稿しても誰も読みません。
list-articles.sh
記事選択時、単に並べません:
# 直近10件の対象記事を取得
bash ~/.claude/skills/cross-post-publish/scripts/list-articles.sh --recent 10
このスクリプトが3つのフィルタを自動適用:
- カテゴリフィルタ: tech-tips/lab-reportsのみ
- 日付フィルタ: 公開日が今日以前(未来記事を除外)
- 既存チェック:
post/cross-post/<slug>/が存在する記事を除外
3番目が地味に便利。「もうcross-postしたっけ?」を防いでくれます。
sns-announce: SNS告知文生成
ここまではcross-postの話。ここからはもう1つのパイプライン — SNS配信です。
プラットフォームごとの違いが面倒
| プラットフォーム | 文字数上限 | スタイル |
|---|---|---|
| X | 実質120字(日本語) | Hook + URL + ハッシュタグ2-3個 |
| 1,300字 | 箇条書き、ハッシュタグ4-6個 | |
| Google Business | 1,500字 | ハッシュタグ非対応、CTA重視 |
| 500字推奨 | カジュアル | |
| Bluesky | 300字 | X風だがよりカジュアル |
Xで120字に収めた文章をLinkedInにコピペしたらスカスカ。手動でやると1記事あたり30分は溶けます。
sns-announceの仕組み
# MDXファイルから全プラットフォームの告知文を一括生成
/sns-announce content/blog/2026-04-23-cross-post-pipeline-design.mdx
内部の処理フロー:
1. load-config.sh → 設定読み込み(プラットフォーム有効/無効、文字数制限)
2. extract-metadata.sh → MDXからタイトル・description・タグ・URLを抽出
3. get-posting-time.sh → プラットフォーム別の最適投稿時間を取得
4. AI生成 → 各プラットフォーム向けに最適化された告知文
5. 出力 → JSON(Zernio API形式)or Markdown
最適投稿時間
各プラットフォームに「いつ投稿すべきか」のデータが組み込まれています:
{
"x": {
"weekday": ["07:30", "12:00", "19:00"],
"weekend": ["12:00", "14:00", "16:00"]
},
"linkedin": {
"weekday": ["08:30", "12:00"],
"best_days": ["tue", "wed", "thu"]
}
}
Xは朝・昼・夜の3回、LinkedInは火〜木の午前中です。平日にLinkedInで投稿し週末にXで投稿する戦略が自動で組めます。
dedupeで二重投稿を防ぐ
# すでにスケジュール済みのプラットフォームをスキップ
/sns-announce content/blog/article.mdx --dedupe
Zernio APIに問い合わせ予約済みのプラットフォームをスキップします。不要な文章を生成しないのでトークン節約にもなります。
zernio CLI
なぜZernioか
SNS予約投稿サービスはBufferやHootsuiteが有名ですが、APIが公開されているのはZernio(旧Late)だけです($19/月〜)。
「UIがリッチ」は価値ゼロでAPIがあるかないかが全てです。以前はTypeScriptで書いたlate-schedule-postスキルでAPI呼び出ししていました。現在はzernio CLIに移行し、メンテが不要になりました。
JSON入力
sns-announceの出力がそのまま入力になり、フォーマット変換不要です。
[
{
"content": "【🔧 cross-postパイプライン設計】\n\n1記事書いたら5プラットフォームに自動拡散...",
"schedule": "2026-04-23 12:00",
"platforms": ["x"]
},
{
"content": "ブログ記事を書いたら、Zenn・Qiita・X・LinkedIn...",
"schedule": "2026-04-23 08:30",
"platforms": ["linkedin"]
}
]
# dry-runで確認してから本番投稿
zernio post --json posts.json --dry-run
# 問題なければ本番
zernio post --json posts.json
X、LinkedIn、Facebook、Google Business、Blueskyに一括予約できます。1コマンドで5媒体です。
エイリアス設計
zernio CLIのプラットフォーム名と、人間が使いたい名前は微妙に違う:
| 入力 | 実際のプラットフォーム |
|---|---|
x, twitter | X (Twitter) |
google, gbp | Google Business Profile |
bsky | Bluesky |
fb |
「googlebusinessって長い」問題をgoogleやgbpで解決します。
generate-thumbnail
Gemini APIでMDXのfrontmatterからサムネイルを自動生成します。
# MDXファイルからサムネイル生成 → WebP変換まで一気に
~/.claude/skills/generate-thumbnail/scripts/generate_thumbnail.sh \
content/blog/2026-04-23-cross-post-pipeline-design.mdx --optimize
1枚約$0.13。Canvaで15分かけるか$0.13で自動生成するか、時給換算すると答えは明白です。
全体の設計判断
なぜ分割するのか
cross-post-publishが全部やればいいのでは、と思うかもしれません。でも分割しておくと組み合わせの自由度が上がります:
| やりたいこと | 使うスキル |
|---|---|
| Zennだけに投稿 | blog-cross-post → zenn-publish |
| SNS告知文だけ欲しい | sns-announce |
| 予約だけやり直したい | zernio CLI |
| サムネだけ再生成 | generate-thumbnail |
「全部入り」のスキルは一見便利ですが部分的にやり直したいとき詰みます。「一つのことをうまくやれ」はAIスキル設計でも生きています。
skill-config.jsonの3層設定
設定はスクリプト内蔵デフォルト → グローバル → プロジェクトの3層マージ:
スクリプト埋め込みデフォルト
← ~/.claude/skill-config.json (グローバル: 全プロジェクト共通)
← <project>/.claude/skill-config.json (プロジェクト: 最優先)
blog-cross-postの場合:
{
"blog-cross-post": {
"base_url": "https://www.playpark.co.jp",
"content_dir": "content/blog",
"blog_path_prefix": "/blog/",
"cross_post_categories": ["tech-tips", "lab-reports"]
}
}
プロジェクトごとにbase_urlやカテゴリを変えられます。OSS開発と自社ブログで設定を分けたいときに効きます。
注意点・Tips
canonical URL対策を忘れない
ZennもQiitaもcanonical URLをfrontmatterでサポートしていません。テキストリンクが唯一の手段です。省略するとどちらを正規と判断するかGoogleが分からなくなります。
対象カテゴリは絞る
「全記事cross-postしたい」は罠です。ビジネス層向けの事例記事をZennに投稿しても読者にはノイズです。読者層を尊重すること。
dry-runを習慣にする
zernio CLIでの予約投稿は取り消しが面倒です。--dry-runで内容を確認してから本番投稿する癖をつけましょう。
まとめ
1記事書いたら7プラットフォームに自動配信する仕組みです。中身を分解すると2本立てになります。ひとつはCross-Postパイプライン(Zenn=How型/Qiita=Why型に変換して転載)。もうひとつはSNS Distributionパイプライン(sns-announce → zernio CLIで5媒体に告知配信)です。
手動で1記事あたり1時間以上かかる転載 + SNS配信が、パイプライン化で数分になります。「記事を書く」に集中し、配信はパイプラインに任せる。これが私たちの結論です。



