しずかなインターネット

日記やエッセイにちょうどいい
文章書き散らしサービス

ログイン

完全ローカル版・画像対応マルチSNS同時投稿システム

touban_546
·
公開:2026/5/5

前回の

🏛️ システムの全体構成(変更後)

GitHub Actionsを用いた「テキスト単発送信」の構成から、Proxmox上のコンテナを用いた「常時待機型の画像対応サーバー」へとアーキテクチャを刷新しました。

  • 入力・送信: PCのローカルに置いた「自作のHTMLファイル」前回のを微修正

  • 中継・実行: Proxmox上のLXCコンテナ内で常時稼働する「Node.js (Express) サーバー」

  • エンドポイント (各SNS): Bluesky (AT Protocol)、Misskey (REST API)、mixi2 (gRPC API)

ブラウザのHTMLから「画像とテキスト(FormData)」をローカルサーバーのIP宛てにPOST送信し、サーバーがそれを受け取って各SNSの仕様に合わせて画像を処理・一斉アップロードするという流れです。


🛠️ 構築のステップとポイント

1. インフラ環境の準備(Proxmox LXC)

  • Proxmox上に軽量なLXCコンテナ(Ubuntu/Debian)を構築。

2. Node.js環境とパッケージの準備

  • コンテナ内にNode.js(v24)をインストール。

  • プロジェクトフォルダを作成し、以下の主要ライブラリを導入。

    • express: Webサーバー化するため

    • multer: HTMLから送られる画像データを受け取るため

    • dotenv: 各SNSのAPIキーやパスワードを隠しファイル(.env)から読み込むため

    • sharp: 画像のサイズを最適化(圧縮・リサイズ)するため

3. フロントエンド(送信画面)の改修

  • PC上のHTMLファイルに <input type="file"> を追加し、画像を選択できるように改修。

  • 送信形式をJSONから FormData 形式に変更。

HTML 例

https://sedate-word-409.notion.site/Node-js-_HTML-357e72820163803e9c79c04409ecf1f5?pvs=73

4. 中継・実行システムの構築と各SNSの「画像の壁」突破

bot.js を「終わったら閉じるスクリプト」から、「ポート3000番でリクエストを待ち続けるWebサーバー」に書き換えました。各SNSへの画像アップロードでは、それぞれの仕様と罠を攻略しました。

  • 🦋 Blueskyの壁(2MB制限)

    • 問題: 高画質な画像(2MB以上)をそのまま送るとAPIに弾かれる。

    • 解決策: サーバー側で sharp を使い、全SNS共通の前処理として「横幅1600px以下にリサイズ&画質80%で圧縮」を実行。これにより安定して2MB以下に抑え込むことに成功。

  • 🥝 Misskeyの壁

    • 仕様: 認証は MISSKEY_TOKEN のみ。画像を「ドライブ」エンドポイントにアップロードし、発行されたファイルIDをテキストと一緒にノート作成エンドポイントへ送るという素直なREST仕様でスムーズに突破。

  • 🟠 mixi2の壁(4ステップ仕様と非公式ライブラリのバグ)

    • 仕様: ①アップロード開始宣言 → ②バイナリ送信 → ③完了ポーリング(状態確認) → ④ポスト作成、という複雑なgRPC仕様。

    • 罠①(バイナリ送信): Node.js標準の fetch を使って巨大なデータを送ると、サイズ不明(または0バイト)の不正なデータとして送られてしまい、mixi2側でIDが即座に破棄される。

    • 解決策①: Node.jsネイティブの https モジュールを使用し、ファイルサイズ(Content-Length)を明示して生データ(Buffer)を直接流し込むことで確実な送信に成功。

    • 罠②(ポーリングのバグ): 非公式ライブラリ(mixi2-js)の「状態確認(Step 3)」機能自体にバグがあり、リクエスト形式の不一致で invalid media_id エラーを起こして自爆する。

    • 解決策②: Step 2の送信完了後、「状態確認APIをあえて使わず、強制的に8秒待機してすぐStep 4(投稿)を実行する」 という強行突破(スキップ)で解決。画像圧縮により処理は1〜2秒で終わるため、これで安全に動作する。

bot.js 例

https://sedate-word-409.notion.site/Node-js-_bot-jp-357e728201638063b044c2c8a291c3a3?pvs=73


こんな感じで同時送信できました。99%Geminiに聞きながらできたので、楽な時代になったような、駄目な時代になったような。

(割と作って満足したので今後どれだけ使うかは謎ですが)各種アカウントはこちらです。