Communitygithub.com

erberkk/social-publishing

用于通过官方 API 将应用的营销内容定时发布到 Instagram(Reels、轮播图、快拍)、Threads、X 和 TikTok,实现自我托管 Postiz(Docker + Cloudflare Tunnel)、Meta 应用创建(业务组合、Facebook 主页、Threads 测试者邀请)、X 开发者按需付费、TikTok 和 YouTube 审核限制、安全 OAuth 账户选择以及资源限制,并围绕真实发布事件编排发布日历。

social-publishing 是什么?

该技能(erberkk/social-publishing)提供了一个完整的解决方案,用于通过各平台的官方 API 定时发布应用的营销内容。它主要指导如何自托管开源调度器 Postiz(通过 Docker 部署,并配合 Cloudflare Tunnel 实现公网访问),同时涵盖 Meta(Instagram 和 Threads)、X、TikTok 和 YouTube(通过 Data API)的配置。技能详细说明了如何创建专业的 Meta 应用(使用新的业务组合流程),避免常见的 OAuth 账户混淆问题(例如将个人 Instagram 账户错误连接到品牌),以及处理各种 API 限制(如 TikTok 的审核状态和 X 的付费额度)。它还强调了围绕真实发布事件(而非固定日期)规划发布日历的重要性,并包含了资源限制(如 Docker 内存限制)和关键决策点(如创建品牌账户、购买 API 积分)的讨论。该技能适用于 Claude Code、Cursor、Codex 等平台。

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

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

社交媒体定时发布

目的

从一个地方按计划发布启动内容,通过每个平台的官方 API,避免将个人账户丢失给品牌,或将品牌账户丢失给个人。本教程使用的工具是 Postiz(开源、自托管);平台相关步骤适用于任何调度器。

先决条件

  • 品牌账户已创建:Instagram 专业账户、Threads 个人主页(来自 Instagram)、X 账户,可选 TikTok。
  • 在 Cloudflare 上有一个域名(用于隧道主机名)、Docker Desktop、一台在发布时段保持开机的机器(或小型 VPS)。
  • 如果从浏览器驱动控制台,需要 console-automation 设置。
  • 内容日历(见下文“日历”部分)。

平台现状(开始前再次检查,因为会变化)

平台官方途径阻碍因素
InstagramMeta 应用 + Facebook 登录,链接到 Facebook 主页的 IG 专业账户新的 Meta 应用会获得“统一登录”的 Instagram 设置,这需要一个业务组合;旧的仅 Instagram 登录设置“对新应用不可用”。快拍以纯媒体形式发布:无法通过 API 发布带有投票、链接或倒计时贴纸的快拍。
Threads带有 Threads 用例的 Meta 应用在应用审核通过之前,只有拥有 Threads 测试者角色的账户才能连接;测试者在 Threads › 设置 › 账户 › 网站权限 › 邀请中接受邀请。
X具有付费 API 访问权限的开发者账户(查看当前 X API 定价)需要支付方式;设置消费上限。
TikTok内容发布 API未经审核的应用只发布私密内容,直到审核通过(审核需要时间)。新账户需要电话验证,一个号码只能属于一个账户。
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 只注册两个关键字属性。如果 Temporal 首次启动时启用了 ES,其数据库仍会保留默认的文本属性,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.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:使用 config_src: cloudflare 调用 POST /accounts/{id}/cfd_tunnel,调用 PUT .../configurations 设置入口规则,创建一个代理的 CNAME 指向 <tunnel-id>.cfargotunnel.com,调用 GET .../token)。
  • 将 cloudflared 作为服务运行在相同的 compose 网络中,并将入口指向 http://postiz:5000,而不是 localhost。
  • 审批:隧道会将本地服务暴露到互联网;创建前需获得批准。可选地在前面添加 Cloudflare Access(需要账户启用 Zero Trust;保持 /uploads 可访问,以便 Meta 获取媒体)。

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 + 密钥(应用设置 › 基本资料;显示密钥需要输入 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:在 threads.com 上打开相同的 URL。
  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(可选)

账户:

  • 新账户需要电话验证,一个号码只能用于一个账户;通过网页注册可能会以“在应用中继续”结束。选项:为品牌账户使用第二个号码,或转换现有的个人账户(新的用户名和显示名称、个人资料照片、简介;归档/隐藏旧的个人视频)。
  • 在某些地区,“切换到企业账户”的一键选项已消失;菜单中提供“成为已验证的企业账户”,这需要公司文件。个人账户就足够了:TikTok Studio 调度、分析、Spark Ads 和内容发布 API 都适用。企业音乐库是主要损失。
  • 用户名每 30 天可更改一次,显示名称每 7 天可更改一次。网页个人资料(名称、简介、照片、计数)可能比应用延迟一天或更久;以应用为准。
  • 账户地区在注册时由 SIM/IP 决定,且无法在设置中更改。

开发者应用(用于调度器):

  • developers.tiktok.com 注册只显示“企业开发者”(邮箱 + 验证码 + 密码),但在创建应用时,你可以选择个人所有权,因此开始不需要公司。
  • 创建应用,然后创建一个沙箱:基本信息(图标 1024²、类别、描述 ≤120 字符、服务条款/隐私 URL、Web 平台 URL)、产品 Login Kit(Web 重定向 URI = 调度器回调;Postiz /integrations/social/tiktok)和 Content Posting API(开启直接发布),以及调度器请求的所有作用域。Postiz 请求 user.info.basic、user.info.profile、user.info.stats、video.list、video.upload、video.publish;缺少任何一个都会在同意页面上显示“出了问题……更正以下内容:作用域”。每次编辑后点击“应用更改”。
  • 将品牌账户作为沙箱目标用户添加(登录弹窗接受手机应用的二维码扫描)。在调度器中使用沙箱客户端密钥/密文。
  • 通过文件推送不需要域名验证;通过 URL 拉取则需要。
  • 审核前:UPLOAD 模式将视频发送到账户的 TikTok 收件箱作为草稿(24 小时内从手机发布;每 24 小时最多 5 个待处理)。DIRECT_POST 模式有效,但仅在私密状态下发布。提交生产应用供审核,并附上用于公开直接发布的演示视频。
  • 同意步骤可能要求通过邮箱验证码“验证是你本人”。在一天内进行大量账户更改(邮箱、名称、简介、新登录)后,TikTok 会限制这些验证码(“已达到最大尝试次数”):停止操作,第二天再试,不要继续尝试。

6. 验证

  • 调度器频道列表显示每个品牌账户(名称/句柄),没有被禁用的。
  • 在日历开始前,在每个平台上发布一个私密/低风险的测试内容,或一个草稿。
  • 一天后的资源使用情况:docker stats --no-stream。

日历

  • 将发布日历与真实的发布事件挂钩,而不是固定日期:发布前(无下载行动号召,无价格),然后每个商店的发布,最后两者上线。商店审核日期会变动;当它们变动时,重新调整日历。
  • 对照已发布的版本检查帖子中的每个声明,并对照每个商店实际在线的内容检查每个行动号召。
  • 带有投票、链接或倒计时的快拍无法通过 API 发布;请通过应用发布。

需要人工批准的决策点

创建品牌账户、业务组合、Facebook 主页;通过隧道暴露本地服务;购买 API 积分和设置消费上限;哪些个人账户永远不能连接;转换个人账户;删除 Docker 卷或数据。

常见陷阱

  • 因为 OAuth 弹窗复用了浏览器的会话,导致连接了个人 Instagram 账户。
  • 假设在全新的 Meta 应用上存在旧的 Instagram 登录设置。
  • 将发布用例添加到移动应用内部使用的 Meta 应用中。
  • 当 Temporal SQL 可见性足够时,仍保留 Elasticsearch 在栈中。
  • 上游的 compose 文件占用了本地其他服务已使用的端口。
  • 从错误的标签处保存了 X 密钥(“消费者密钥密文”,而不是对话框标题)。
  • 日历编写成仿佛应用在第一天就在两个商店上线。
  • 在同一天完成所有 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.

相关技能