ソーシャルメディアスケジューラーの作り方

ソーシャルメディアスケジューラーの作り方

キューの実装を超えて実際に必要になること:プラットフォーム対応の作業、 必要な状態管理、そして永遠にコストがかかり続ける部分について。

ソーシャルメディアスケジューラーのスケジューリング部分は週末で作れます。キュー、ワーカー、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サーバー
FreeProBusiness
API リクエスト/日305,00050,000
APIキー1510

まとめ

キュー自体は週末で作れます。状態管理、タイムゾーン、そしてプラットフォームごとに1つのOAuthフロー、1つのリフレッシュジョブ、1つのメディアパイプラインこそが実際のプロジェクトであり、プラットフォームの変化のせいでそれは決して終わりません。公開機能が自社の製品である場合、あるいは1つのプラットフォームに永続的に留まる場合は自分で作りましょう。そうでなければ、自分でメンテナンスしなくて済む統合の方が価値があります。