AI自動化

ローカル予約UIでSNS素材を一覧管理する設計メモ

ローカル予約UIでSNS素材を一覧管理する設計メモ

ローカル予約UIでSNS素材を一覧管理する設計メモ

SNS運用を毎日続けていると、投稿処理そのものより、「今どの素材が予約済みで、どれが未使用で、どこで失敗したのか」を追跡する作業のほうが重くなる。今回私が試したのは、複数媒体へ使う画像や動画素材を、ローカルWeb画面で一覧化し、予約状態と実行結果を同じ場所で確認できる構成だった。使用したのはlocal web UI、SQLite、launchd worker。固定条件は1日1本、候補最大3件、画像最低2枚。この条件を崩さず、毎日同じ確認導線で回せるかを検証した。

この設計にした理由は、素材フォルダ、予約メモ、投稿ログが分散すると、確認漏れと重複使用が急激に増えるからだった。特に毎日投稿では、「予約済みだと思っていたが未実行だった」「同じ画像を別媒体で再利用していた」「失敗ログを見落としていた」という事故が積み重なりやすい。自動投稿そのものより、「今どこまで進んでいるか」を一画面で把握できる状態を作る必要があった。

この記事では、ローカル予約UIを使ってSNS素材管理を一本化した時の実験ログを整理する。単なる管理画面の紹介ではなく、何を固定し、どこで失敗し、どう直したかを中心にまとめる。同じように個人運用でSNS素材を扱っている人なら、かなり再現しやすい構成だと思う。

記事内容の要約図
この記事の流れ。Codex画像生成で作成。

分散管理で起きた問題

最初は、素材フォルダ、予約メモ、投稿ログをそれぞれ別管理していた。画像と動画はFinder、予約はテキストメモ、実行結果はJSONログという構成だった。単体で見ると軽かったが、運用日数が増えるほど、「今の状態を確認するためにどこを見るべきか」が曖昧になった。

特に問題だったのは、素材の重複使用だった。未使用に見えていた画像が、別媒体側では予約済みになっているケースがあった。さらに、launchd worker側で投稿失敗が発生していても、JSONログを見忘れると「投稿済み」と誤認しやすかった。

実際に困ったのは、候補最大3件という制限を入れていた時だった。画像最低2枚という条件を固定していたため、投稿直前に不足へ気づくと、その日の公開全体が止まる。しかし、予約メモと素材フォルダが分離していると、どの素材が現在候補なのかが見えにくい。結果として、「素材はあるのに使えない」という状態が頻発した。

さらに悪かったのは、「未確認状態」が蓄積することだった。自動化では成功ログばかりを見たくなる。しかし、実際に事故を起こすのは「予約したつもり」「投稿されたはず」という未確認状態だった。成功は後からでも追えるが、確認漏れは放置されやすい。

この段階で感じたのは、素材数を減らすことではなく、「見る場所」を減らす必要があるということだった。管理対象が増えること自体は避けられない。ただ、確認導線を一本化できれば、毎日の運用負荷はかなり下げられる。

local web UIを入口へ固定した理由

今回の構成では、local web UIを全体の入口へ固定した。画像一覧、予約状態、実行ログを同じ画面へ横並び表示し、「素材単位」で状態を追跡できるようにした。

ここで優先したのは、機能追加より状態把握だった。例えば、豪華なカレンダー機能や分析画面を増やすより、「この素材は予約済みか」「投稿済みか」「失敗したか」が瞬時に分かるほうが重要だった。

SQLiteを選んだ理由も同じだった。SNS素材管理では、高度な予約システムを作ることが目的ではない。毎日見る情報を、できるだけ単純な形で照合できることのほうが重要だった。そのため、保存する情報もかなり絞った。

保存対象は主に5項目だった。素材ID、媒体名、予約日時、投稿結果、エラー理由。この程度でも、「未使用素材」「予約済み素材」「失敗素材」は十分整理できた。逆に、状態履歴や詳細ログまで全部SQLiteへ入れ始めると、管理画面そのものが重くなり、確認速度が落ちた。

launchd worker側では、一定間隔で予約状態を確認し、対象素材を実行する形にした。この時に重要だったのは、「成功条件」より「停止条件」を先に定義したことだった。

画像が2枚未満なら止める。同タイトルが存在するなら止める。ログ保存に失敗したら止める。予約状態が不明なら止める。この停止条件を固定したことで、「問題があるのに通ってしまう状態」をかなり減らせた。

以前は、投稿成功だけを基準にしていた。しかし毎日運用では、「公開してはいけない状態で止まれるか」のほうが重要だった。低品質な状態を通すと、あとから修正するコストが大きくなる。

JSON中心運用で失敗した話

最初に失敗したのは、「素材管理」と「投稿管理」を別画面にしたことだった。設計時には整理されているように見えたが、実際には画面移動が増え、「予約したつもり」が発生しやすかった。

もう一つ失敗したのは、JSONファイルを直接確認する運用だった。具体的には、publish_result_before_repair_flow.json、prepare_result_before_repair_flow.json、publish_result.json、prepare_result.jsonを毎回確認していた。

ログとしては便利だったが、毎日見るUIとしてはかなり弱かった。異常時しか開かなくなり、通常運用で状態を見失いやすかった。

特に悪かったのは、「正常系だけ見えている状態」だった。JSONは成功時には整って見える。しかし、実際の事故は「途中停止」や「未確認」で起きる。その状態を一覧比較しにくかった。

対処として、JSON全体を読むのではなく、必要情報だけSQLiteへ抽出した。具体的には、素材名、予約状態、投稿結果、エラー理由だけを保存し、local web UI側で一覧化した。

この変更だけでも、毎日の確認時間はかなり短縮できた。以前は、投稿確認だけで複数ファイルを往復していたが、変更後はほぼ一画面で完結した。

また、記事本文側でも似た問題が起きていた。タイトルは素材管理の話なのに、本文が一般的なSNS運用論へ流れるケースがあった。対策として、導入3段落で必ず「何を試したか」「なぜその設計にしたか」「読者が真似できること」を固定するようにした。

これはUI設計でも同じだった。情報を増やしすぎると、結局どこを見るべきか分からなくなる。だから今回のUIでは、「素材」「予約」「実行結果」の3軸以外は極力増やさなかった。

予約と実行結果を同じ画面で見た効果

設計変更後に最も効果が大きかったのは、予約状態と実行結果を同じ画面で確認できるようになったことだった。

以前は、投稿されたかどうかを公開先側で確認していた。しかし、それだと「なぜ失敗したのか」が分からない。local web UI側で、素材一覧の横に実行状態を表示する形へ変更すると、問題箇所がかなり見えやすくなった。

例えば、次のような状態差分を一覧で確認できるようになった。

予約済みだがworker未実行、投稿成功だが画像不足、JSON生成済みだが公開停止、予約なしで実行対象へ入っている、同素材が複数媒体で予約済み。このような状態が一覧で見えるだけでも、毎日の確認精度はかなり変わった。

これまでは、JSONログを個別に開かなければ見えなかった状態が、一画面で把握できるようになった。

特に重要だったのは、「未処理」を目立たせたことだった。成功ログは後からでも追える。しかし、未確認状態は放置されやすい。そのため、UI上では「成功」より、「保留」「失敗」「画像不足」を強調表示する方向へ寄せた。

また、候補最大3件という制限もかなり効いた。候補数を増やすほど、一見自由度は上がる。しかし確認対象が増えると、「今日どれを使うべきか」が曖昧になる。結果として、素材在庫だけ増え、運用負荷が下がらなかった。

今回は1日1本という条件を固定し、その日の候補を最大3件に制限したことで、確認速度がかなり安定した。数を増やすより、「毎日同じ手順で確認できること」のほうが重要だった。

今回固定した判断基準

今回の検証では、「自動化を増やすこと」より、「確認導線を固定すること」のほうが重要だった。

実際、投稿処理自体はそこまで難しくない。しかし、素材数が増え、複数媒体へ展開し始めると、「何が予約済みで、何が失敗しているのか」を追跡する作業のほうが重くなる。

だから今回の設計では、いくつかの判断基準を固定した。

まず、入口を増やさないこと。状態確認は必ずlocal web UIから行う。次に、停止条件を先に決めること。成功条件より、「止まる理由」を先に定義する。さらに、JSONを直接読まないこと。必要情報だけをSQLiteへ集約し、一覧で比較できるようにする。

この構成にしてから、確認作業の迷いがかなり減った。「どのファイルを開けばいいか」を毎回考えなくなったのが大きい。

また、素材管理と記事管理の考え方もかなり近かった。タイトルと本文がズレる記事は読みづらい。同じように、素材と予約状態が分離しているUIも運用しづらい。どちらも、「何を見るべきか」が曖昧になると崩れやすかった。

今後も機能追加はすると思うが、まず優先するのは「一画面で状態を追えること」を崩さないことだと思っている。毎日触る仕組みは、高機能より、確認の迷いが少ないほうが長く回しやすい。

真似する場合の最小構成

同じ構成を試すなら、最初から多機能化しないほうが良いと思う。まずは、管理対象を「素材」「予約」「実行結果」の3つだけに絞る。

次に、SQLiteへ最低限の情報だけを保存する。重要なのは、「後から分析できること」より、「今の状態が分かること」だった。

その後、local web UI側で横並び表示を作る。ここで重要なのは、デザイン性ではなく状態遷移の見やすさだった。

私が特に見やすかったのは、未使用、予約済み、実行待ち、投稿成功、画像不足、投稿失敗の6状態だった。この状態を色分けし、素材一覧と並べるだけでも、かなり確認しやすくなった。

launchd worker側では、毎回投稿を成功させることより、「異常時に止まる」設計を優先した。画像最低2枚を満たしているか、同タイトルが存在しないか、ログ保存に成功しているか。この停止条件を固定するだけでも、毎日の運用がかなり安定した。

また、自動化を増やしすぎないことも重要だった。通知、分析、順位予測などを追加したくなるが、入口が複雑になると、結局「今どこで止まっているのか」が分からなくなる。

今回の構成で一番効果が大きかったのは、「毎日どこを見るか」を固定できたことだった。SNS素材の在庫、予約、実行結果を一画面で確認できるようになると、手動確認の負荷がかなり減った。

公開前チェック

冒頭3段落で「何を試した記事か」が分かるか

H2がすべて同じ主題へ戻っているか

実測、失敗、原因、対処が含まれているか

読者が真似できる構成になっているか

素材、予約、実行結果の関係が説明されているか

画像最低2枚の停止条件が説明されているか

URL、タイトル、画像表示を公開後確認できるか

✨ AUTHOR'S KDP BOOKS

かかる人向ケ、10分でわかるAI自動化入門

Claude Code / Ollama / launchd の実践テクニックをコンパクトにまとめたシリーズ。非エンジニアの会社員向けに書いてます。

Amazonで見る ›

✨ FOLLOW ME

AI自動化の実験・失敗・実測データを毎日発信中

𝕏 フォローする