変更履歴

出荷したもの

機能を出したら、同じコミットでここに書きます。

変更履歴

1.0.0 — 2026-09-04

初回リリース。AutoPost 配信エンジンの上に、製品サイトと運用コンソールを載せた。

配信エンジン(AutoPost)

  • 21媒体へのアダプタ:WordPress / WordPress.com / Ghost / はてなブログ / ライブドアブログ /
    Qiita / Zenn / dev.to / Hashnode / Medium / Blogger / Notion / LinkedIn / X / Threads /
    Facebookページ / LINE公式アカウント / Webhook / メール投稿 / note / Ameba
  • 役割順(primary → syndicate → variant / manual → social → line)の配信と、
    自社公開URLの後続への引き回し
  • 重複コンテンツ対策:canonical対応媒体にのみ全文転載、非対応媒体は別原稿、無ければ要約+リンク
  • CTAの本文差し込み(冒頭 / 中盤 / 末尾)と、位置別 utm_content を含む計測パラメータの自動付与
  • ドライラン、指数バックオフつきリトライ、媒体単位の失敗隔離、ジョブの永続化
  • note / Ameba の手動投稿パッケージ生成と、投稿後URLの書き戻し

製品サイト

  • ランディング、仕組み、対応媒体一覧、料金、ドキュメント、ブログ、変更履歴、
    お問い合わせ、利用規約 / プライバシー / 特定商取引法
  • 記事ライブラリ:data/articles/ の記事JSON・フロントマター付きMarkdownを読み込み、
    目次・読了時間・パンくず・Article / BreadcrumbList 構造化データ付きで公開
  • テクニカルSEO:robots.txtsitemap.xml、RSS、自己参照canonical、OGP / Twitterカード、404ページ

機能カタログ

  • SEO運用基盤に必要な500機能を24カテゴリに整理し、実装状況(実装済み / 一部実装 / 計画)つきで公開
  • /features で検索・状態フィルタ、/v1/features でJSON取得

運用コンソール

  • 概要ダッシュボード、配信(ドライラン固定)、ジョブ履歴と詳細、記事ライブラリ、
    クライアント設定、配信先マトリクス、LINE配信のリクエスト生成、機能カタログの進捗

API

  • /v1/features/v1/library/v1/library/{slug} を追加
  • Swagger UI を /docs-api へ移動(/docs は製品ドキュメントのページ)

1.0.1 — 2026-09-04

  • Space を Aisnsio/SEOBuilder から組織 AisnsioDev/SEOBuilder へ移動したことに伴い、
    canonical / sitemap / OGP の既定URLを aisnsiodev-seobuilder.hf.space に更新。
    旧サブドメインは応答しないため、そのままだと全ページの正規URLが死んだURLを指していた。

2.0.0 — 2026-09-04

機能カタログの「計画」を実装に変えた回。実装済みは 199 → 347 / 500(69.4%、一部実装を含めて76.4%)。
新しく13のモジュールと74のAPIエンドポイント、15の管理画面を追加した。
外部サービスが要る機能はアダプタ+正直な未設定表示にしてあり、資格情報が無い状態でも
「何が使えて何が使えないか」が画面で分かる。

追加した基盤

  • SQLite永続化層 (store.py) — 順位・計測・ワークフロー・予約・課金の状態を持つ。
    書けない環境では /tmp へ自動フォールバック。
  • 記事診断エンジン (analysis.py) — 日本語向け。タイトル長(全角換算)・キーワード配置・
    読みやすさ(1文長/漢字比率/受身率)・表記ゆれ・出典の無い数値・薬機法/景表法の断定表現・
    altの欠落・弱いアンカー。外部API不使用。
  • 構造化データ (schema.py) — Article / BreadcrumbList / FAQPage / HowTo / LocalBusiness /
    VideoObject。必須項目を埋められない型は出さない
  • キーワード台帳 (keywords.py) — 意図推定・クラスタリング・カバレッジ・カニバリ検出・
    優先度スコア・地域展開・CSV入出力。
  • 内部リンク (linking.py) — 孤立記事・弱いアンカー・ピラー/クラスタ・リンク切れ確認・301管理。
  • 画像 (media.py) — alt点検と生成案・OG画像のSVG生成・SNS別の切り出し指示・出典台帳。
  • ワークフロー (workflow.py) — 状態遷移(不正な遷移は拒否)・担当・チェックリスト・
    コメント・版管理と差分。
  • 予約と自動化 (scheduler.py) — 予約公開・繰り返し・営業日回避・リトライ・
    デッドレター・編集カレンダー・公開頻度ルール。
  • 計測 (analytics.py) — 自前のイベント収集。AI検索(ChatGPT/Perplexity 等)を独立チャネルとして分離。
    CTA位置別クリック・KPI・異常検知・同意管理・削除要求への対応。
  • 順位計測 (ranks.py) — 推移・変動アラート・競合比較・シェアオブボイス・SERP機能・
    改稿優先度・アルゴリズム更新の年表。
  • レポート (reports.py) — 月次レポートのHTML/JSON生成、前月比、次の打ち手の自動導出、共有URL。
  • 認可 (auth.py) — スコープ付きAPIキー・レート制限・IP制限・監査ログ。
  • 課金 (billing.py) — プラン・利用量メータリング・上限警告・インボイス対応の請求明細。
  • AI検索最適化 (llmo.py) — 引用されやすさの診断・llms.txt・AIクローラ方針・表記統一。
  • ローカルSEO (localseo.py) — NAP一貫性・店舗ページ生成・LocalBusiness・口コミ返信案。
  • 執筆補助 (writing.py) — 構成案・タイトル案・メタ説明・FAQ・alt は規則ベースで常に動作。
    本文生成・リライト・翻訳は Claude 設定時のみ(未設定なら理由を返して失敗)。
  • 配信管理 (delivery.py) — 失敗分のみ再実行・更新配信・撤回・二重投稿防止・
    配信先グループ・媒体別成功率。
  • 外部連携 (integrations/) — GA4 / Search Console / IndexNow / Slack / SMTP / Stripe /
    Googleビジネスプロフィール / 順位プロバイダ / Claude。

サイト

  • 公開ステータスページ /status — 媒体別の配信成功率を実測から出す
  • /llms.txt、robots.txt にAIクローラ方針を明記
  • リダイレクト(301)をミドルウェアで適用
  • レポートの共有URL /r/{token}(閲覧に認証不要)

直したもの

  • 媒体の成功率で skipped(送らないと判断したぶん)を失敗に数えていた。
    下書き記事をSNSに出さなかっただけで danger 表示になっていたのを、分母から外した。

テストは 70 → 163

2.1.0 — 2026-09-04

実装済み 347 → 420 / 500(84.0%、一部実装を含めて90.6%)。テスト 163 → 260
「外部の有料データが要る」以外のものを、ほぼ実装に変えた。

実ユーザー計測(static/js/sb.js

記事に1行入れるだけの計測タグ(依存なし・Cookieを使わない)。これ1つで
Core Web Vitals(LCP/INP/CLS)・滞在時間・スクロール深度・クリック位置・CTAクリック・
離脱の兆候・A/B割り当て
を集める。同意が取れるまで送信しない。
CWVは平均でなく75パーセンタイルで評価する(遅い端末を平均で薄めないため)。

新モジュール

  • suggest.py — 検索サジェストの収集。Google / DuckDuckGo の公開JSONエンドポイントを使う
    (SERPのスクレイピングはしない)。五十音展開・疑問形の抽出・業種別の定番セット・
    自社コーパスの共起語・問い合わせログからのテーマ起こし・季節変動・指名/一般の分離・
    競合のRSS新着監視。取得できないときは0件ではなく理由を返す。
  • cta.py — LINE以外のオファー(フォーム / 電話 / 資料DL / 予約 / チャット)と、
    検索意図による出し分け。A/B・スクロール率連動・離脱時ポップアップ・電話タップ。
    記事のオファー名とLINEあいさつ文の言葉のズレを検出する。
  • dedupe.py — 4文字シングルのJaccardで重複率を測る。別原稿が実質コピーになっていないか、
    teaserが本文の何割を露出しているか、転載の遅延、引用の囲み、AI生成比率の開示。
  • technical.py — hreflang・ページネーション・タグページの間引き・URL設計の検査・
    サイト構造ツリー・画像のwidth/height補完・HTTPヘッダ・クローラの巡回とエラー記録。
  • line_ops.py — あいさつ文・よくある質問の辞書(記事のFAQ節から取り込める)・
    AIに答えさせない範囲(見積もり/苦情/医療/法律は必ず人へ)・営業時間での人/AI切替・
    narrowcast・push・通数の見積もりとまとめ配信・友だち数の推移・Flexプレビュー。
  • social.py — 媒体別の投稿文(上限・タグ数・リンクの効き方)・連投生成・トンマナ検査・
    ブランドタグ・再告知・反応の取り込み・Instagram / Pinterest / TikTok アダプタ。
  • authoring.py — 全角半角と送り仮名のゆれ・著者と監修者(E-E-A-T)・更新履歴・
    鮮度スコア・編集ロック(期限つきなので放置されても詰まらない)・出典セクション。
  • tenancy.py — クライアント追加ウィザード(設定の下書きと必要な環境変数を出す)・
    顧客に渡す閲覧専用リンク /c/{token}・代理店の階層と横断比較・分離の実測。
  • ops.py — 構造化ログ(1行1JSON)・Prometheus /metrics・媒体別レート制御・
    同時実行の門番・SQLiteのオンラインバックアップと世代管理。

SDK

/static/sdk/seobuilder.js(ESM)と /static/sdk/seobuilder.py。どちらも依存パッケージなし
使い方は /sdk

そのほか

  • レポートを印刷(PDF保存)前提の体裁に。ロゴ・担当者の所見欄・改ページ制御を追加
  • 顧客向けポータル /c/{token}/metrics/healthz の中身を実装
  • 301リダイレクトとクローラ記録をミドルウェア化

直したもの

  • /v1/social/engagement/v1/social/{slug} に食われて404になっていた(登録順を修正)
  • 同じ秒に2回バックアップを取るとファイル名が衝突し、上書きされていた

2.1.1 — 2026-09-05

  • サジェスト収集が遅かった(既定の修飾語20個 × 2エンジンを順番に叩いていたため約40秒)。
    並列化して 1.4秒にした。深い階層(depth=2)も同じ経路で速くなる。

3.0.0 — 2026-09-05

機能カタログ 500/500 を実装済みにした(420 → 500)。テスト 260 → 339。
残っていたのは「外部の有料データが要る」「ブラウザ/エンコーダの同梱が要る」もの。
前者は取り込み口を開けて分析側を全部作る、後者は外部に委ねつつ手前を全部作るという
方針で埋めた。未設定のときは必ず理由を返し、0件を「存在しない」とは言わない。

認証・セキュリティ

  • 人のアカウント (accounts.py) — PBKDF2-HMAC-SHA256(24万回・個別ソルト)、
    TOTP二要素認証を hmac で自前実装(Google Authenticator でそのまま使える)、
    使い捨てリカバリコード、5回失敗で15分ロック、パスワード変更で全セッション失効
  • OAuth セルフ接続 (oauth.py) — Google / LinkedIn / Facebook / WordPress.com / Shopify。
    state を必ず検証(CSRF対策)
  • シークレットの暗号化 (secrets_store.py) — PBKDF2 + Encrypt-then-MAC を標準ライブラリだけで。
    鍵が無ければ保存を拒否する(平文でこっそり保存しない)
  • セキュリティヘッダを推奨するだけでなく実際に付けるようにした

検索データ

  • SERP分析 (serp.py) — 取り込みはプロバイダ/CSV/JSON、分析は全部内製。
    上位の構成・共通話題・網羅率の採点・強調スニペットの型・難易度・検索意図の変化検知・
    PAA収集・被リンクとドメイン評価
  • Search Console / GA4 (gsc.py) — あと一歩の語、表示だけされている語、
    順位のわりにクリックされない語、キーワード→CVの紐付け、インデックス状況
  • 順位と流入の相関、上位化した語の共通構成

画像

  • 実際のピクセル処理 (imaging.py, Pillow) — リサイズ・圧縮・WebP/AVIF変換・
    SNS別の切り出し・内容ハッシュでの重複排除・メディアライブラリ。12KB→3KB を確認
  • ストックフォト検索(Unsplash / Pexels の無料API)、AI画像生成、CDNキャッシュ破棄、
    スクリーンショット、数値からのグラフSVG生成

収益・自動化

  • Stripe決済 (payments.py) — Checkout へ委ね、カード情報を自社サーバに通さない。
    署名検証を自前実装(再送攻撃も弾く)、Webhookは冪等
  • 自動化 (automation.py) — if-thenトリガー、タイトルA/B、自動アーカイブ、
    承認済みの自動昇格、インバウンドWebhook(HMAC署名)、Zapier用ポーリング、
    SSEでの実行ログ配信、接続テスト、トークンの期限監視と自動更新

そのほか

  • 一次データ (primary_data.py) — n数・調査時期・方法を必須にした自社データ。
    表・グラフ・Dataset構造化データ・引用文を生成
  • GBP / 地図 (gbp.py) — 投稿の下書き、口コミの取り込みと返信案、
    地点グリッドでの地図順位、掲載先チェックリスト
  • AI引用監視 (aicite.py) — 流入からの実測と、Claude/Perplexity への能動確認
  • テナント分離の強制 (tenant_guard.py) — 絞り忘れが起きない窓口、
    混在していないことの検証、データの書き出しと完全削除
  • 短尺動画の台本と絵コンテ、コメントの一元受信、パイプライン定義(承認ゲート)
  • 軽量版ページ /lite/blog/{slug}(外部リクエスト0・44%小さい)、独自ドメインの手順
  • 新しい配信先: Shopify / Wix / Squarespace / YouTube概要欄(25媒体に)

直したもの

  • Store.run が DELETE/UPDATE でも lastrowid を返しており、削除件数を取り違えていた
  • キーワードから作る仮slugに日本語が入り、自分で定めたURL規約に違反していた
  • サジェスト収集が約40秒かかっていた(並列化して1.4秒)

3.1.0 — 2026-09-05

  • デモデータの投入 (demo_seed.py) — コンソールの多くの画面はデータが無いと
    「空です」としか出ないため、機能を確かめるための一式を入れられるようにした。
    60日ぶんの計測(曜日の波・AI検索からの流入つき)・順位6語×6時点(1語はわざと下落)・
    Search Console・SERP・被リンク・配信ジョブ・一次データ・ワークフロー・コメント。
    乱数の種を固定しているので何度入れ直しても同じ数字になる。
    投入分には印が付いており DELETE /v1/demo で全部消える。
    入っている間はコンソール全画面に注意書きを出す(実測と誤読させないため)。
  • 記事を追加: 「canonical の設定で、転載した記事の評価を自社に集める」
  • 媒体数を文言に直書きしていたのをやめ、カタログの実数から出すようにした
    (増やしたときに古い数字が残らない。テストでも固定)

直したもの

  • 英単語のキーワードが日本語に隣接すると数えられていなかった
    「SEOの話」で \bSEO\b が境界にならず0件になっていた。英数字が続かないことを条件に変更
  • 複合キーワードの見出し判定が厳しすぎた — 3語すべてを1つの見出しに含めるのは
    現実的でないため、過半数の語が入っていれば「その語を狙っている」とみなすようにした
  • キーワード密度が水増しされていた — 語間の空白を文字数に含めて計算していた

3.1.1 — 2026-09-05

直したもの

  • コンバージョンが取得元チャネルに紐付いていなかった。 CVイベント自体にはリファラが無いため、
    そのまま数えると全部「サイト内」に落ちていた(デモデータを入れて画面を見て気づいた)。
    訪問者の最初の閲覧チャネルを取得元とみなして集計する。訪問者IDが無く紐付けられないCVは、
    隠さず「取得元不明」として別枠で出す。

3.2.0 — 2026-09-05

  • 導入の進み具合 (onboarding.py / /console/start) — コンソールが38画面になり、
    初めて触る人がどこから手を付ければよいか分からなくなっていた。
    実際の状態を見て次にやることを1つだけ示す。チェックは手で付けさせない
    (付けたつもりで設定できていない、が起きるため)。概要画面にも次の一手を出す。
  • 静的ページのキャッシュ (cache.py) — 500行の機能カタログの描画に2秒かかっていたのを
    25ms→2msに。対象は「入力が同じなら出力も同じ」と言い切れるページだけで、
    計測・順位の数字はキャッシュしない(古い数字を見せるくらいなら遅いほうがまし)。

直したもの

  • 認証情報の設定判定が甘かった — 宣言された値のうち1つでも埋まっていれば
    「設定済み」としていたため、site_url だけ書いてある状態を設定済みと誤判定していた。
    すべて埋まっていることを条件に変更(${ENV} は未設定だと空文字に展開されるため、
    この判定でないと通ってしまう)。

3.2.1 — 2026-09-05

直したもの

  • 応答を圧縮していなかった。 機能カタログのページは254KBあり、転送だけで1秒以上
    かかっていた(キャッシュを入れて描画は2msになったのに速くならず、計測して判明)。
    gzip を有効にして 254KB → 34.7KB(86%減)。1KB未満の応答は、
    ヘッダ分で逆に増えるため圧縮しない。

3.3.0 — 2026-09-05

  • エラー画面 — 未処理の例外で素の "Internal Server Error" だけを返していた。
    参照IDを振ってログに出し、その番号を画面に見せる。番号を伝えてもらえればログから
    該当の1件を引ける。例外の中身は画面に出さない(内部構造が漏れるため)。
    API パスは同じ参照IDつきのJSONを返す。
  • 機能カタログにカテゴリのジャンプ — 500行を上から探すしかなかったのを、
    24カテゴリへの目次と「先頭へ戻る」で移動できるようにした。

3.3.1 — 2026-09-05

  • アクセシビリティ — コンソール上部のクライアント/デバイス選択など、
    12ファイル分の入力欄にラベルが無く、スクリーンリーダーでは何の欄か分からなかった。
    すべてに aria-label を付け、主要14ページで
    「ラベルの無い入力欄が無い」「alt の無い画像が無い」「h1 が1つ」「lang がある」を
    テストで固定した。

3.4.0 — 2026-09-05

  • 記事を3本に — 「LINE公式アカウントの自動応答を、よくある質問20問から作る」を追加。
    記事が増えたことで、関連記事の推薦・ピラー/クラスタ構造・内部リンクの点検が
    実データで動くようになった。
  • 収録した3本はすべて自分の診断にかけて指摘を潰してから入れている
    (診断 87 / 93 / 97、AI検索適性 75 / 88 / 100)。
    自分で「出典を添えろ」「断定を避けろ」と言う道具が、自分の記事で警告を出したままでは筋が通らない。

  • 3本とも診断の warn/error をゼロにした(診断 97 / 97 / 97、AI検索適性 88 / 88 / 100)。
    記事どうしを内部リンクで繋いだので、孤立記事なし・平均被リンク1.33・
    カテゴリごとのピラー構造が実データで出るようになった。

  • 記事の中身に依存していたテスト3件を合成データに置き換えた。
    記事を直すたびにテストが落ちるのは、テストが中身を固定してしまっていたため。

直したもの

  • 記事の meta ブロックに書いたメタ説明が読まれていなかった。 記事ライブラリは
    トップレベルの meta_descriptionmeta.description しか見ておらず、
    生成タスクが使う meta.meta_description を素通りしていた。
    結果、ページの <meta name="description"> が抜粋で代用され、診断も
    「メタ説明にキーワードが無い」と誤って警告していた。ありうる置き場所を順に見るよう変更。
    収録記事が診断の warn/error をゼロに保つことをテストで固定した。

3.4.1 — 2026-09-05

公開中のサイトを自分のリンクチェッカーでクロールして見つけたもの。

直したもの

  • POST専用のAPIを <a href> で指していた — 押すと 405 が返るだけだった
    (LINE運用の「記事から取り込む」、発掘・競合の「いま取り込む」)。form + button に変更。
    テンプレートを静的に見て同じ間違いを防ぐテストを追加。
  • デモ記事のCTAが存在しないURL(lin.ee/XXXXXXX)を指していた — 公開ページに
    404のボタンが載っていた。プレースホルダのまま出荷しない。自サイトの問い合わせへ向けた。