ソーシャルメディアスケジューラーのスケジューリング部分は週末で作れます。キュー、ワーカー、cron。それ自体は本当に難しくありません。だからこそ見積もりが常に外れるのです。
コストがかかるのはすべて、その先にあります。
簡単な部分
投稿予定時刻を持つ投稿テーブルと、起動して該当する投稿を見つけて公開するワーカー。リトライを加えれば完成です。
これを学習用プロジェクトとして、あるいは自分が管理する1つのプラットフォーム向けに作るのであれば、ここで読むのをやめて構いません。この先は、実際のアカウントと複数のプラットフォームが関わる場合に何が起きるかについての話です。
実際に必要なデータモデル
人が想像するよりも多くの状態が必要になります。
- draft(下書き):作成済みだがキューには入っていない
- scheduled(予約済み):時刻を指定してキューに入っている
- processing(処理中):プラットフォームに送信済みだが結果は未確定
- published(公開済み):確定済み
- failed(失敗):理由付き
- partial(部分成功):一部の対象には公開され、一部には公開されていない
processingが存在する理由は、複数のプラットフォームが投稿を受け付けたあとに非同期で公開するためです。200番台のレスポンスは公開の完了を意味せず、結果は後から別経路で届きます。この状態がなければ、UIは成功したと表示しながら実際には間違っていることがあります。
partialが存在する理由は、1つの投稿が通常複数のプラットフォームを対象とするためです。3つは成功し、1つは失敗する。「公開済み」でも「失敗」でもなく、どちらかに無理やり当てはめると、ユーザーに嘘をつく製品になってしまいます。
投稿全体に1つのステータスを持たせるのではなく、対象ごとの行を用意する必要もあります。失敗はプラットフォームごとに発生するからです。
タイムゾーン
オフセットではなく、瞬間(instant)とIANAのタイムゾーンを保存してください。
「毎平日ローカル時間の午前9時」は、サマータイムの切り替え前後で異なるUTCの瞬間になります。UTCだけを保存する方法は3月までは機能しますが、その後はすべてが1時間ずれてしまい、1年の半分は正しく動くためバグ報告が混乱を招きます。
プラットフォーム対応の作業
ここで見積もりが崩れます。プラットフォームごとに以下が必要です。
個別のOAuthフロー:異なるスコープ、異なるトークンの有効期限、異なる同意画面。
個別のリフレッシュジョブ:これが最も痛い部分です。トークンは期限切れになり、リフレッシュはサイレントに失敗し、予約投稿が公開されないまで誰も気づきません。スケジュールされたリフレッシュ、リフレッシュ失敗の監視、接続切れの状態、再接続フローが必要です。これはOAuthフロー自体よりも手間がかかります。
個別のメディアパイプライン:あるプラットフォームはURLを取得し、あるプラットフォームは再開可能なチャンク単位のアップロードを求め、あるプラットフォームは特定の解像度やコーデックを求めます。ホスティングや、場合によってはトランスコードも必要になります。
個別のレート制限:それぞれ独自のウィンドウと、超過時の独自の挙動を持ちます。
アプリレビュー:複数のプラットフォームが、アプリ、プライバシーポリシー、場合によってはデモ動画を含むレビューの通過を公開の条件にしています。これは自分でコントロールできないスケジュール上の時間であり、拒否される可能性もあります。
絶え間ない変更:APIバージョンは非推奨になり、フィールド名は変わり、権限は厳格化されます。すべてプラットフォーム側のスケジュールで起こり、自分が設定していない締め切り付きの計画外の作業になります。
これをプラットフォームの数だけ掛け合わせてください。そしてそれを永遠に払い続けることになります。
公開ルール
配信そのものを超えて、ユーザーが本当に求めているのは、却下されるようなものを公開しないことです。つまり、プラットフォームごとに以下をエンコードする必要があります。
- 文字数制限
- メディアの枚数、サイズ、フォーマット、長さ、アスペクト比
- どの投稿タイプにメディアが必須か
- そもそもどのフォーマットが存在するか
そして公開時ではなく作成時に検証すべきです。公開時の失敗は、ユーザーがそのタイミングを逃したあとに気づく失敗だからです。
作るべきケース
- 1つのプラットフォームだけに、永続的に公開する場合
- 公開機能そのものが製品であり差別化要因である場合
- 広告管理のような、公開を大きく超えた深さが必要な場合
作るべきでないケース
公開機能が、あなたが作っている別の何かの一機能であり、3つ以上のプラットフォームに対応する必要がある場合です。コストは構築ではなくメンテナンスにあり、メンテナンスはプラットフォーム数に応じて増えていく一方、チームの人数はそうではありません。
代替案
1つの統合先だけを扱い、プラットフォームの変化への対応は他社の問題にする、という選択肢です。
- ベースURL:
https://app.bulkpublish.com - 認証: APIキー、またはユーザーのアカウントを代理操作する場合はOAuth 2.1
- 提供範囲: ドキュメント化された59のエンドポイント
- プラットフォーム: 15
- 検証: 公開時ではなく作成時に制限をチェック
- SDK: NodeとPython、加えてPostmanコレクションとMCPサーバー
| Free | Pro | Business | |
|---|---|---|---|
| API リクエスト/日 | 30 | 5,000 | 50,000 |
| APIキー | 1 | 5 | 10 |
まとめ
キュー自体は週末で作れます。状態管理、タイムゾーン、そしてプラットフォームごとに1つのOAuthフロー、1つのリフレッシュジョブ、1つのメディアパイプラインこそが実際のプロジェクトであり、プラットフォームの変化のせいでそれは決して終わりません。公開機能が自社の製品である場合、あるいは1つのプラットフォームに永続的に留まる場合は自分で作りましょう。そうでなければ、自分でメンテナンスしなくて済む統合の方が価値があります。