Communitygithub.com

erberkk/social-publishing

スケジュールに沿ったマーケティングコンテンツの公開を、Instagram(リール、カルーセル、ストーリー)、Threads、X、TikTokの公式APIを使って設定する際に使用します。PostizをDockerでセルフホストし、Cloudflare Tunnelで公開。Metaアプリの新しいユースケースフロー、Xの従量課金制、TikTok/YouTubeの監査制限、安全なOAuthアカウント選択、リソース制限、実際のローンチイベントに合わせた公開カレンダーの段階的運用に対応します。

social-publishing とは?

このスキルは、Instagram、Threads、X、TikTok、YouTubeといった主要ソーシャルプラットフォームの公式APIを通じて、ブランドのマーケティングコンテンツを自動的にスケジュール公開するための手順を提供します。中心となるツールはオープンソースのPostizで、Docker Composeを使ってセルフホストし、Cloudflare Tunnelで安全に外部公開します。このスキルは、各プラットフォームのAPI制限や監査プロセス、OAuth認証の落とし穴を考慮した実践的なガイドであり、個人アカウントとブランドアカウントを間違えて接続するリスクを回避するための具体的な手順も含まれています。特にMeta系(Instagram、Threads)では新しいビジネスポートフォリオフロー、Xでは従量課金制、TikTokではサンドボックス監査と公開制限、YouTubeではプライベートアップロード制限など、プラットフォームごとの最新の状況に対応しています。さらに、公開カレンダーを実際のローンチイベント(プレローンチ、ストアローンチ、両方公開)に連動させ、各投稿の主張を実際のビルドやストアの状態と照合する重要性も強調しています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/erberkk/mobile-app-launch-skills/tree/HEAD/skills/social-publishing

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

ソーシャル公開

目的

ローンチコンテンツを、各プラットフォームの公式APIを通じて一箇所からスケジュールに従って公開します。個人アカウントをブランドに、またはブランドを個人アカウントに誤って関連付けることを防ぎます。ここで使用するツールはPostiz(オープンソース、セルフホスト)です。プラットフォームごとの手順は、他のスケジューラにも適用できます。

前提条件

  • ブランドアカウントがすでに作成されていること:Instagram プロフェッショナルアカウント、Threadsプロフィール(Instagramから派生)、Xアカウント、オプションでTikTok。
  • Cloudflare上のドメイン(トンネルのホスト名用)、Docker Desktop、公開時間帯に稼働し続けるマシン(または小規模なVPS)。
  • コンソールをブラウザから操作する場合、console-automationの設定。
  • コンテンツカレンダー(以下の「カレンダー」を参照)。

プラットフォームの現実(開始前に再度確認してください。これらは変更されます)

プラットフォーム公式ルート障害となるもの
InstagramMetaアプリ + Facebookログイン、InstagramプロフェッショナルアカウントがFacebookページにリンクされている新しいMetaアプリは「統合ログイン」Instagram設定を必要とし、これにはビジネスポートフォリオが必要。古いInstagramログインのみの設定は「新しいアプリでは利用できません」。ストーリーはメディアのみとして公開され、APIによる投票、リンク、カウントダウンステッカーは使用不可。
ThreadsThreadsユースケースを含むMetaアプリアプリレビューが通るまで、Threadsテスターロールを持つアカウントのみが接続可能。テスターはThreads › 設定 › アカウント › Webサイトの権限 › 招待で承諾します。
X有料APIアクセスを持つデベロッパーアカウント(現在のX API料金を確認)支払い方法が必要。利用上限を設定します。
TikTokコンテンツ投稿API監査が通るまで、未監査のアプリはプライベートのみ投稿可能(監査には時間がかかります)。新しいアカウントは電話番号認証が必要で、1つの番号は1つのアカウントにしか使用できません。
YouTubeData APIアップロード未確認のAPIプロジェクトは、コンプライアンス監査が通るまでプライベートとしてアップロードされます。

障害に対処する計画を立ててください。監査は早めに開始し、TikTok/YouTubeは監査が通るまではネイティブ(TikTok Studio、YouTube Studioのスケジューラー)で投稿するか、プラットフォーム自体をスキップします。

手順

1. Postizをセルフホストする(Docker)

  1. 公式の postiz-docker-compose ファイルから始めます。up する前に:
    • 不要なサービスを削除し、マシン上ですでに使用されているポートにバインドするものを削除します(アップストリームファイルはTemporal UIを 127.0.0.1:8080 にバインドします)。
    • Elasticsearchを削除します:Temporalの ENABLE_ES=false と SKIP_ADD_CUSTOM_SEARCH_ATTRIBUTES=true を設定します(SQL可視性)。Postizは2つのキーワード属性のみを登録します。Temporalが最初にElasticsearchで起動された場合、データベースにはデフォルトのテキスト属性が残り、Postizは「3つ以上のText型の検索属性を持つことはできません」というエラーで失敗します。何かがスケジュールされる前に、Temporalデータベースのボリュームを再作成してください。
    • Postizは 127.0.0.1 のみにバインドします。MAIN_URL、FRONTEND_URL、NEXT_PUBLIC_BACKEND_URL をHTTPSの公開ホスト名に設定します。
    • シークレット(JWT_SECRET、トンネルトークン、アプリキー)はgit管理外の .env ファイルに配置し、composeファイル内では ${VAR} として参照します。
    • サービスごとに mem_limit/cpus を追加します。Postizはフロントエンド、バックエンド、オーケストレーターを1つのコンテナで実行し、約1.5 GBのメモリを使用することが確認されているため、2 GBの制限で上限に達するのを防ぎます。Windowsでは、%USERPROFILE%\.wslconfig でWSL VMの上限も設定し(memory=4GB、processors=4、autoMemoryReclaim=gradual)、その後 wsl --shutdown してDocker Desktopを再起動します。
  2. 最初のアカウントはブラウザで、ページがハイドレートされた後に作成します(ハイドレートされていないフォームはGETとして送信され、パスワードがURLに含まれます)。その後、DISABLE_REGISTRATION=true を設定して再起動します。
  3. restart: always を維持し、「サインイン時にDocker Desktopを起動」を有効にします。マシンがスケジューラーとして機能する場合は、スリープを無効にします。

2. 公開ホスト名(Cloudflare Tunnel)

  • リモート管理トンネルを作成します(API:POST /accounts/{id}/cfd_tunnel に config_src: cloudflare を指定、PUT .../configurations にイングレスルールを指定、プロキシされた CNAME を <tunnel-id>.cfargotunnel.com に向ける、GET .../token)。
  • cloudflared を同じcomposeネットワーク内のサービスとして実行し、イングレスを localhost ではなく http://postiz:5000 に向けます。
  • 承認が必要:トンネルはローカルサービスをインターネットに公開するため、作成前に承認を得てください。オプションで、Cloudflare Accessを前面に追加することもできます(アカウントでZero Trustが有効である必要があります。Metaのメディア取得のために /uploads へのアクセスは維持してください)。

3. Meta(Instagram + Threads)

  1. 公開用に別のMetaアプリを作成します(アプリ内機能(例:Instagramストーリー共有)を既に動かしているアプリにユースケースを追加しないでください)。ユースケース:「Instagramのメッセージとコンテンツを管理」と「Threads APIにアクセス」。
  2. Instagram:
    • ユースケースで求められたらビジネスポートフォリオを作成します(無料。名前、オーナー名、ビジネスメール)。本人確認は、他のユーザーのデータやアプリレビューが必要な場合のみ必要です。
    • ブランド用のFacebookページを作成し(Meta広告にも必要)、Instagramのプロフェッショナルアカウントをリンクします:ページ設定 › リンクされたアカウント › Instagram › 接続。OAuthポップアップは、ブラウザが保持するInstagramアカウントでログインします。「次のユーザーとしてログイン:...」という名前を読み、個人アカウントの場合は先にアカウントを切り替えてください(個人アカウントを接続すると、プロフェッショナルアカウントに変換されます)。
    • Instagramユースケースで、スケジューラーが要求するスコープを正確に追加します(Postizの場合:instagram_basic、pages_show_list、pages_read_engagement、business_management、instagram_content_publish、instagram_manage_comments、instagram_manage_insights)。ビジネス向けFacebookログインのリダイレクトURIをスケジューラーのコールバックに設定します(Postizの場合:/integrations/social/instagram)。
    • アプリIDとシークレット(アプリ設定 › Basic。シークレットを表示するにはFacebookパスワードが必要)→ FACEBOOK_APP_ID/SECRET。
  3. Threads:threads_basic、threads_content_publish、threads_manage_replies、threads_manage_insights を追加します。リダイレクト(/integrations/social/threads)とアンインストール/削除コールバックURLを設定します。別のThreadsアプリID/シークレットを使用します。ブランドプロフィールをThreadsテスターとして追加し、電話で招待を承諾します。
  4. Threadsの同意URLが同意画面ではなくThreadsのホームページに遷移する場合、ブラウザのセッションは threads.com にありますが、スケジューラーは threads.net を使用しています。同じURLを threads.com で開いてください。
  5. ブラウザが現在ページとして動作している場合(編集後)、Facebookの同意は最初に「<あなたの名前>に切り替える必要があります」と表示します。ページではなく、個人として続行してください。
  6. Facebookの同意時に、Metaはデフォルトで「現在および将来のすべてのページ/ビジネス/Instagramアカウント」を選択します。他のブランドも管理しているアカウントでは、「現在のもののみ」を選択し、ブランドのアセットを選択してください。

4. X

  1. デベロッパーコンソールのオンボーディング:アカウント名、正確なユースケースの説明(自分のアカウントのみ、データの再販なし、自動いいね/フォロー/DMなし)、利用規約に同意。
  2. 最小のクレジットパックを購入します。自動チャージはオフにし、請求サイクルの上限を設定します。ダッシュボードの合計は、クレジットページの値に遅れる場合があります。
  3. アプリ › ユーザー認証設定:読み取りと書き込み、「Webアプリ、自動化アプリ、またはボット」、コールバック = スケジューラーのコールバック(Postizの場合:/integrations/social/x)、ウェブサイト、利用規約、プライバシーURL。保存すると、OAuth 2.0クライアントシークレットが一度だけ表示されます。
  4. PostizはOAuth 1.0aを使用します。コンシューマーキーを再生成し、キーと**「コンシューマーキーシークレット」**(正確にそのラベル)を一度コピーします → X_API_KEY/X_API_SECRET。
  5. 認証:「このアプリを信頼する」にチェックを入れ、画面にブランドのハンドルが表示されていることを確認し、認証します。

5. TikTok(オプション)

アカウント:

  • 新しいアカウントは電話番号認証が必要で、1つの番号は1つのアカウントにのみ使用できます。ウェブサインアップは「アプリで続行」で終了する場合があります。選択肢:ブランドアカウント用に別の番号を用意する、または既存の個人アカウントを変換する(新しいユーザー名と表示名、プロフィール写真、バイオ。古い個人動画はアーカイブ/非公開にする)。
  • 一部の地域では、ワンタップの「ビジネスアカウントに切り替える」がなくなり、メニューには「認証済みビジネスアカウントになる」が表示され、会社の書類が求められます。個人アカウントで十分です。TikTok Studioのスケジューリング、分析、Spark Ads、コンテンツ投稿APIはすべて個人アカウントで動作します。ビジネス向け音楽ライブラリが主な損失です。
  • ユーザー名は30日に1回、表示名は7日に1回変更できます。ウェブプロフィール(名前、バイオ、写真、数値)はアプリより1日以上遅れる場合があります。アプリの情報を信頼してください。
  • アカウントの地域はサインアップ時のSIM/IPから設定され、設定で変更できない場合があります。

デベロッパーアプリ(スケジューラー用):

  • developers.tiktok.com のサインアップでは「エンタープライズデベロッパー」のみ表示されますが(メール + コード + パスワード)、アプリ作成時に個人所有を選択できるため、開始に会社は必要ありません。
  • アプリを作成し、次にサンドボックスを作成します。基本情報(アイコン1024²、カテゴリ、説明≤120文字、利用規約/プライバシーURL、WebプラットフォームURL)、製品ログインキット(WebリダイレクトURI = スケジューラーのコールバック。Postizの場合 /integrations/social/tiktok)とコンテンツ投稿API(ダイレクト投稿をオン)、およびスケジューラーが要求するすべてのスコープ。Postizは user.info.basic、user.info.profile、user.info.stats、video.list、video.upload、video.publish を要求します。不足しているものがあると、同意ページに「Something went wrong … correct the following: scope」と表示されます。編集のたびに「変更を適用」をクリックします。
  • ブランドアカウントをサンドボックスのターゲットユーザーとして追加します(ログインポップアップは電話アプリからのQRスキャンを受け入れます)。スケジューラーにはサンドボックスのクライアントキー/シークレットを使用します。
  • ファイルによるプッシュにはドメイン検証は不要で、URLによるプルには必要です。
  • 監査前:UPLOAD モードは動画をアカウントのTikTok受信箱に下書きとして送信します(24時間以内に電話から公開可能。24時間あたり最大5件保留)。DIRECT_POST は機能しますが、プライベートでのみ投稿されます。公開ダイレクト投稿のために、デモ動画を含む本番アプリのレビューを提出します。
  • 同意手順では、メールコードによる「本当にあなたですか?」の確認が求められる場合があります。1日に多くのアカウント変更(メール、名前、バイオ、新しいログイン)を行った後、TikTokはこれらのコードをレート制限します(「最大試行回数に達しました」)。何度も試行するのではなく、翌日まで停止して再試行してください。

6. 確認

  • スケジューラーのチャンネルリストに各ブランドアカウント(名前/ハンドル)が表示され、無効なものがないことを確認します。
  • カレンダー開始前に、各プラットフォームでプライベートまたはリスクの低いテスト投稿を1つ、または下書きを投稿します。
  • 1日後のリソース使用量:docker stats --no-stream。

カレンダー

  • 公開カレンダーは固定日付ではなく、実際のローンチイベントに連動させます。プレローンチ(ダウンロードの呼びかけなし、価格なし)、次に各ストアのローンチ、その後両方公開。ストアのレビュー日は変動します。変更があったら、カレンダーをそれに合わせて調整します。
  • 投稿内のすべての主張を出荷されたビルドと照合し、すべての行動喚起を各ストアで実際に公開されているものと照合します。
  • 投票、リンク、カウントダウンを含むストーリーはAPIを通じて公開できません。アプリで投稿してください。

人間の承認が必要な決定ポイント

ブランドアカウント、ビジネスポートフォリオ、Facebookページの作成。ローカルサービスをトンネルで公開。APIクレジットの購入と利用上限。どの個人アカウントを絶対に接続してはいけないか。個人アカウントの変換。Dockerボリュームやデータの削除。

よくある落とし穴

  • OAuthポップアップがブラウザのセッションを再利用したため、個人のInstagramアカウントを接続してしまう。
  • 新しいMetaアプリに古いInstagramログイン設定が存在すると仮定する。
  • モバイルアプリ内に出荷されるMetaアプリに公開ユースケースを追加する。
  • Temporal SQL可視性で十分な場合に、Elasticsearchをスタックに残したままにする。
  • アップストリームのcomposeファイルが、別のローカルサービスですでに使用されているポートを取得する。
  • 間違ったラベル(ダイアログのタイトルではなく「コンシューマーキーシークレット」)からXキーを保存する。
  • アプリが1日目から両方のストアで公開されているかのようにカレンダーを作成する。
  • すべてのTikTokアカウント変更とデベロッパー接続を同じ日に行い、確認コードのレート制限に引っかかる。

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

erberkk/privacy-and-declarations

Use when filling in or auditing App Store privacy and compliance answers and Google Play App content declarations - Apple App Privacy labels, Play Data safety (CSV import), Health apps declaration and Health Connect permissions, advertising ID, PrivacyInfo.xcprivacy and required-reason APIs, export compliance (ITSAppUsesNonExemptEncryption), age rating, account deletion (in-app, web URL, re-authentication), consent and disclosure for AI features, and rules for health data. Derives every answer from a code and SDK scan so the forms, the privacy policy and the in-app text say the same thing.

erberkk/review-readiness

Use before submitting an app version or a first subscription for App Store or Google Play review, or after receiving a rejection. Runs a go/no-go checklist and writes a report - demo account that signs in with a password (no email one-time code), filled with data and premium unlocked; review notes; in-app purchases visible and purchasable (guideline 2.1(b)); iPad compatibility mode for iPhone-only apps; no placeholders or "coming soon"; metadata matching the app; live privacy URLs; crash-free cold start - and gives a playbook for replying in Resolution Center and deciding when to appeal.

erberkk/store-screenshots

Use when producing or updating App Store and Google Play screenshots and the Play feature graphic - planning a connected "panorama" story across frames, capturing real in-app screens with the app's own test/screenshot harness at each device's logical size and pixel ratio, covering the full device matrix (iPhone 6.9", the required medium Dynamic Island slot, iPhone Duo outer and inner displays, iPad 13" if the app runs on iPad, Play phone, 7" and 10" tablets, 1024x500 feature graphic), checking for alpha channels and wrong sizes, and uploading in order via the App Store Connect and Google Play APIs.

erberkk/web-presence-and-seo

Use when building, checking or deploying the website that a mobile app needs for its store listings and launch - privacy policy, terms, support and web account-deletion pages that work signed-out; hosting apple-app-site-association and assetlinks.json; invite/referral pages (/i/<code>) that open the app or fall back to the store with the Play install referrer; a landing page with store badges and honest per-country prices filled at the edge; Open Graph images; technical SEO (hreflang, canonical, sitemap, robots.txt, JSON-LD); Search Console, Bing Webmaster and IndexNow; AI crawler policy and llms.txt; and a Cloudflare Worker deploy with a production approval gate. Includes a site checker and an IndexNow ping script.

関連スキル