关于 omnisocials
通过 OmniSocials 管理社交媒体内容的技能,涵盖账号设置、创作、排期、发布和数据分析,支持 11 个平台,并为敏感操作设置明确的确认要求。
主要功能
- 01创建并安排社交媒体帖子
- 02向 11 个平台发布内容
- 03查看帖子分析数据
- 04管理收件箱消息和评论
- 05整理媒体与话题标签集
适用场景
- 01为已连接的渠道安排帖子
- 02查看排期内容和表现
- 03处理收到的评论与消息
- 04按平台要求准备媒体内容
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ omnisocials/ omnisocials-agent-skills --skill omnisocials安装后在 Claude Code 中输入/omnisocials确认已加载。
附带文件CHANGELOG.mdscripts/omnisocials.js
详细介绍
OmniSocials 技能
使用 OmniSocials 在 11 个平台上创建、安排和发布社交媒体内容。
OmniSocials 是一款社交媒体管理工具,可让你在 Instagram、Facebook、LinkedIn(个人主页 + 公司主页)、YouTube、TikTok、X(Twitter)、Pinterest、Bluesky、Threads、Mastodon 和 Google Business 上安排帖子并跟踪分析数据。
LinkedIn 有两个频道 ID:
linkedin_page是公司主页。两者都可以连接到同一个工作区,并分别发布内容。务必检查accounts:list,确认用户连接了哪些账号。
设置
使用此技能前,请确保:
-
API 密钥:运行设置命令,以安全地配置 API 密钥
- 在 https://app.omnisocials.com/settings/api 获取密钥
- 运行:
<skill-path>/scripts/omnisocials.js setup - 或设置环境变量:
export OMNISOCIALS_API_KEY=omsk_live_your_key
-
要求:Node.js 18+(用于内置的 fetch API)。无需其他依赖项。
配置优先级(从高到低):
OMNISOCIALS_API_KEY环境变量./.omnisocials/config.json(项目本地,位于用户的工作目录中)~/.config/omnisocials/config.json(用户全局)
处理“未找到 API 密钥”错误
重要:当 CLI 返回“未找到 API 密钥”错误时:
- 告诉用户运行设置命令。设置过程为交互式操作,需要用户输入,因此你不能代替用户运行。
- 停止操作并等待。不要继续执行任务。等待用户完成设置并确认后再继续。
注意:本文档中的所有脚本路径都相对于此 SKILL.md 文件所在的技能目录。请根据技能的安装位置解析这些路径。
安全规则
重要:始终遵循以下规则。
- 未经用户明确确认,绝不发布帖子。 创建草稿是安全的;发布不可撤销,而且会立即公开。
- 未经用户明确确认,绝不删除帖子、媒体或 Webhook。
- 创建帖子前,始终先列出账号,以获取有效的频道 ID。不要猜测频道 ID。
- 创建帖子前,始终确认媒体要求:
- 快拍:始终需要图片或视频。一个快拍包含 1 到 10 个媒体项目;每个项目都是一张幻灯片,按给定顺序在 Instagram/Facebook 上分别发布为一个快拍(超过 10 个会返回 400)。每张快拍视频最长 60s。询问用户要使用哪些媒体以及顺序。
- Reels:始终需要视频。
- Instagram 帖子:始终至少需要一张图片或一个视频。
- TikTok 帖子:始终至少需要一张图片或一个视频。
- Pinterest 帖子:始终需要一张图片和一个
--pinterest-board-id。 - 其他平台(LinkedIn Profile、LinkedIn Page、X、Facebook 帖子、Bluesky、Threads、Mastodon、Google Business):媒体可选。
- 各平台的媒体数量上限(超出会返回 400 validation_error,并注明确切上限):最多项目数 — X/Bluesky/Mastodon ≤4、Instagram/Threads ≤10、TikTok 照片 ≤35;线程的每个部分也适用相同上限(X/Bluesky/Mastodon 每部分 4 个,Threads 每部分 10 个)。单个帖子中混合图片和视频:Instagram/Threads 允许(混合轮播),Facebook/LinkedIn/LinkedIn Page/X/Bluesky/Mastodon/TikTok 不允许(仅图片,或单个视频)。视频时长/大小 — 免费/Basic 账号的 X 为 140s(2min 20s)/512MB;连接的 X 账号拥有 Premium 或 Premium+ 时为 125min/16GB(根据连接自动检测套餐;升级后重新连接 X),Bluesky 180s、Threads 5min、Instagram 15min、TikTok 10min、YouTube Short 3min。如果用户的视频超出上限,告知其限制,以便他们剪辑视频。
- 信息流图片的宽高比(Instagram、Pinterest):Instagram 信息流图片的比例范围为 4:5 到 1.91:1;如果图片更高(例如 9:16 手机照片),Instagram 会自行裁剪至 4:5,并以中心位置盲裁。Meta 无法推广超出此范围的信息流帖子。默认情况下,OmniSocials 仅针对 Instagram 频道围绕主体将此类图片裁剪为 4:5(竖图)或 1.91:1(横图),并报告处理结果。Pinterest 会保留高于 2:3 的 Pin,并报告其可能在首页信息流中被裁剪。快拍、Reels、TikTok 照片和视频绝不会被裁剪。将竖版(9:16)图片发布到 Instagram 前,运行
media:check --media-id <id>(仅适用于图库图片:如果某个频道会裁剪图片,命令会输出Image fit区块)。如果图片不适合 Instagram,询问用户:“裁剪为 4:5(推荐,Meta 可以推广该帖子),还是保留原图(Instagram 会自行裁剪,且无法推广)?”并将用户的回答传入--media-fit instagram=crop或--media-fit instagram=keep(Pinterest:pinterest=crop会裁剪至 2:3)。如果用户未表达偏好,采用默认设置,并转告命令行在帖子创建后输出的[image_fit]警告:说明裁剪了什么、裁剪后的尺寸,以及posts:update <id> --media-fit instagram=keep可以恢复原图。绝不要因为图片比例而从帖子中移除某个频道;无论如何都会发布帖子。 - Pinterest 图板 — 默认自动选择第一个:如果用户想发布到 Pinterest,但未指定图板,不要因此停止并询问,也不要跳过 Pinterest。运行
accounts:get <pinterest_account_id>— 输出会列出每个图板的名称和 ID。自动使用第一个图板。帖子创建后,告知用户使用了哪个图板(例如:“已发布到你在 Pinterest 上的 ‘Marketing’ 图板 — 如果你更想使用其他图板,请告诉我,我会帮你移动。”)。如果用户在请求中指定了图板名称,则对照列表进行不区分大小写的匹配,并使用匹配项。
- 除非用户明确要求,否则帖子之间不得出现重复内容。
- 安排帖子时,始终与用户确认时区/日期时间。
- 批量操作时,逐项处理,并在操作之间征求确认。
- 查看审批审核结果后,才能报告或更改审核中的帖子。 如果帖子显示
approval_status: "rejected"或"pending"(帖子status为rejected或in_approval),请先运行posts:approval <id>。该命令会说明由谁作出决定、原因以及审核者的意见。不要猜测帖子被拒绝的原因或正在等待谁审核;在阅读审核结果并告知用户其内容之前,不要编辑、重新安排或重新创建该帖子。 - 评论转私信自动化会以账号名义发送私信。 创建此类自动化(
automations:create,或在帖子上使用--dm-keywords/--dm-message)之前,先向用户展示确切的私信文本和关键词,并征得确认;每位评论该关键词的人都会收到一条私信,而且已发送的私信无法撤回。除非用户要求回复每条评论,否则绝不要使用--match any(或--dm-match any),因为它会回复所有评论。Automations 的权限范围需在 API key 上主动启用:403 insufficient_scope表示用户需要在密钥上启用 Automations(Settings > API),并不表示请求有误。
Common Actions
| 用户说…… | 操作 |
|---|---|
| “把这个发到 Instagram” | 使用 accounts:list 查找 Instagram 渠道 ID,然后运行 posts:create --text "..." --channels <id> |
| “安排明天发布一条帖子” | 运行 posts:create --text "..." --channels <ids> --schedule "2026-04-07T09:00:00Z" |
| “提议一个时间,但先让我确认” | 运行 posts:create --text "..." --channels <ids> --schedule "2026-04-07T09:00:00Z" --draft。计划草稿会在日历上的指定时间显示为虚线轮廓,在有人安排发布之前不会发布。用户同意后,运行 posts:update <id> --no-draft |
| “显示我安排的帖子” | 运行 posts:list --status scheduled |
| “上传这张图片” | 运行 media:upload --url "https://..."(本地文件则运行 media:upload-base64 --file ./img.jpg) |
| “为 TikTok 创建一条 Reels 视频” | 运行 posts:create --text "..." --channels <tiktok_id> --type reel --media-urls "https://video.mp4" |
| “发到所有平台” | 运行 accounts:list,然后运行 posts:create --text "..." --channels <all_ids> |
| “在 X 上发布一个串文” | 运行 `posts:create --channels <x_id> --x-thread "part 1 |
| “在 Bluesky 上发布一个串文” | 运行 `posts:create --channels <bluesky_id> --bluesky-thread "part 1 |
| “在 Mastodon 上发布一个串文” | 运行 `posts:create --channels <mastodon_id> --mastodon-thread "part 1 |
| “在 Threads 上发布一个串文” | 运行 `posts:create --channels <threads_id> --threads-thread "part 1 |
| “在 Instagram 上标记地点” | 运行 locations:search "<place name>",然后运行 posts:create ... --location-id <id> |
| “在 Threads 上标记地点” | 运行 locations:search "<place name>" --platform threads,然后运行 posts:create ... --threads-location-id <id>(逐步推出中) |
| “在 Pinterest Pin 上标记商品” | 运行 pinterest:products 列出该账号的商品 Pin,然后运行 posts:create ... --pinterest-board-id <id> --pinterest-product-tags <pin_id,pin_id>(最多 24 个,且只能是自己的商品 Pin;Pinterest 拒绝的商品不会导致帖子发布失败) |
| “发布一条带音乐的 Reels 视频” | 运行 audio:search "<song or artist>"(不填写查询内容则搜索热门曲目),然后运行 posts:create ... --type reel --instagram-audio-id <id> |
| “把这张竖版(9:16)照片发到 Instagram” | 运行 media:check --media-id <id>;如果 Image fit 区块显示 Instagram 会裁剪图片,请询问“裁剪为 4:5,还是保留原图?”,然后运行 posts:create ... --media-ids <id> --media-fit instagram=crop 或 instagram=keep。转告用户 CLI 打印的 [image_fit] 警告 |
| “我的帖子表现如何?” | 运行 analytics:overview --period 7d;要一次查看多条帖子,则运行 analytics:posts <id,id,...> |
| “有新的私信/评论吗?” | 运行 inbox:list --unread(添加 --platform / --type dm|comment|mention 进行筛选;添加 --unanswered 则仅显示仍待回复的内容)。需要 inbox:read 权限范围 |
| “处理所有需要回复的内容”/“回复我的收件箱” | 使用 inbox:next 循环:inbox:next 会提供下一条未回复内容(优先提供仍可回复的私信,然后是已超过 24 小时回复窗口的 Instagram/Facebook 私信,接着按从旧到新的顺序提供评论和提及),并附带其对话串、所在帖子和 reply_window;根据这些内容拟好回复,再使用 inbox:reply <conversation-id> --text "..." --next 发送,响应中会附带下一条内容。回复评论或提及时,始终添加 --message-id <message-id>(“Message to answer”的 ID),确保回复显示在该用户的评论下方。当 reply_window.open 为 false 时,无法通过 API 回复该私信:请告知用户在 Instagram/Facebook 应用中回复,或使用 inbox:read 跳过。使用 inbox:read <conversation-id> 永久跳过某条内容;添加 --exclude <conversation-id> 仅在本次调用中跳过。打印“Nothing is waiting for an answer.”时循环结束。需要 inbox:read(回复还需要 inbox:write) |
| “回复那条消息” | 运行 inbox:messages <conversation-id> 阅读对话串,然后运行 inbox:reply <conversation-id> --text "..."。回复评论或提及时,添加 --message-id <message-id>(要回复的评论 ID,来自 inbox:messages 或 inbox:next):一条帖子上的所有评论共用一个对话,若不添加此参数,回复会显示在最新评论下方,而该评论可能来自其他人。需要 inbox:write |
| “将那个对话标记为已读” | 运行 inbox:read <conversation-id>。需要 inbox:write |
| “隐藏那条评论” | 运行 inbox:hide <message-id>(消息 ID 来自 inbox:messages 或 inbox:next;适用于 Facebook、Instagram、TikTok、YouTube、Threads;添加 --unhide 可撤销隐藏;需要 inbox:write) |
| “删除那条评论” | 运行 inbox:delete <message-id>(适用于 Facebook、Instagram、TikTok 评论;无法撤销,因此须先征得用户确认;YouTube:使用 inbox:hide;需要 inbox:write) |
| “整理我的媒体” | 运行 folders:list / folders:create --name "...",然后上传时添加 --folder-id <id> |
| “添加我常用的主题标签” | 运行 hashtag-sets:list 查找主题标签组,然后运行 posts:create ... --hashtag-set "<name>"(添加 --hashtag-placement first_comment,可避免主题标签出现在说明文字中) |
| “保存这些主题标签以便重复使用” | 运行 hashtag-sets:create --name "Brand" --tags "#a #b #c" |
| “向这条帖子下评论了某个关键词的所有人发送私信” | 先确认私信内容和关键词(安全规则 9)。对于新帖子:运行 posts:create ... --channels <instagram_id> --dm-keywords "guide" --dm-message "Here is the guide: https://..."(添加 --dm-reply "Sent you a DM!",可在评论下方公开回复)。对于已有帖子:运行 posts:list 查找其 ID,然后运行 automations:create --post-id <id> --keywords "guide" --dm "...";在 OmniSocials 之外发布的帖子需改用 --instagram-media-id <id>。使用 automations:events <id>查看执行情况。需要选择启用的 automations:write 权限范围(列出和读取则需要 automations:read) |
| “删除那条帖子” | 先征得用户确认,然后运行 posts:delete <id> |
| “发布我的草稿” | 先征得用户确认,然后运行 posts:publish <id> |
| “重试发布失败的帖子” | 运行 posts:list --status failed 查找帖子,然后运行 posts:retry <id>(仅重试发布失败的平台;使用 posts:get 查看结果)。注意:posts:publish 不接受发布失败的帖子;应使用重试命令 |
| “批准/拒绝那条待处理的帖子” | 运行 posts:list --status in_approval 查找帖子,运行 posts:approval <id> 阅读审核人员目前的意见,然后运行 posts:approve <id> 或 posts:reject <id> --comment "..."。仅当已连接的用户是该帖子当前工作流步骤中列出的审批人时才有效(否则会返回 forbidden) |
| “为什么我的帖子被拒绝了?”/“审核人员怎么说?” | 运行 posts:list --status rejected 查找帖子,然后运行 posts:approval <id>:输出会显示拒绝者、拒绝的步骤、原因和评论串。在进行任何更改之前,先将这些信息转告用户。被拒绝的帖子不会发布;用户可以在控制面板中编辑并重新提交(在帖子上选择 Edit & Resubmit),或者在用户同意后使用 posts:create ... --approval-workflow <id> 创建修正后的帖子 |
| “我的帖子正在等谁审批?”/“为什么还没发布?” | 运行 posts:approval <id>:“Waiting on”一行会列出当前步骤,以及仍需作出决定的审批人。如果帖子在预定时间到达时仍处于 in_approval 状态,则不会发布;延迟获批后会立即发布 |
| “我想在帖子发布前审核”/“发给我审批” | 运行 approval-workflows:list 查找工作流 ID,然后运行 posts:create ... --schedule <ISO8601> --approval-workflow <id>。帖子会进入 in_approval 状态,并通知审批人;最后一个步骤获批后,帖子会在预定时间发布(可通过控制面板中的 Approvals 页面或 posts:approve 操作)。如果没有工作流,请告知用户在控制面板的 Approvals 下创建 |
| “设置 Webhook” | 运行 webhooks:create --url "https://..." --events post.published,post.failed |
| “帖子获批或被拒绝时通知我的系统” | 运行 webhooks:create --url "https://..." --events post.approved,post.rejected |
工作流
创建帖文时请遵循以下工作流:
-
列出账号以查找可用的频道 ID:
./scripts/omnisocials.js accounts:list -
如有需要,上传媒体(限时动态、Reels、Instagram、TikTok、Pinterest 必需):
./scripts/omnisocials.js media:upload --url "https://example.com/image.jpg"记下返回的
media_id。 -
使用合适的频道、媒体和平台选项创建帖文:
./scripts/omnisocials.js posts:create --text "..." --channels <id1>,<id2> --media-ids <media_id> -
根据需要安排发布时间或发布:
- 添加
--schedule "2026-04-10T14:00:00Z"以安排发布时间 - 在
--schedule旁添加--draft,将该时间提议为计划草稿,由他人确认(posts:update <id> --no-draft会安排发布时间) - 使用
posts:create-and-publish立即发布 - 或先创建草稿,确认后再执行
posts:publish <id>
- 添加
命令参考
设置与配置
| 命令 | 描述 |
|---|---|
setup | 交互式设置——提示输入 API 密钥、验证并保存 |
setup --api-key <key> --global | 以非交互方式设置全局配置 |
config:show | 显示当前配置及 API 密钥来源 |
帖文
| 命令 | 描述 |
|---|---|
posts:list | 列出帖子。标志:--status draft|in_approval|scheduled|posting|published|failed|warning|rejected(in_approval = 在审批工作流中等待审核者处理,rejected = 审批者已拒绝;两者都会打印一行 Approval:,其中包含 posts:approval <id>)、--limit、--offset |
posts:get <id> | 获取完整的帖子详情 |
posts:recent-platform | 从已连接的平台 API 实时获取近期帖子,包括在 OmniSocials 之外发布的内容。用于 posts:list 结果为空的情况(全新工作区)。每条帖子都会返回平台原生 id(用于存储帖子的稳定去重键)、permalink、完整文案、格式、时间戳、标准化互动数据,以及平台公开的所有原始指标(精确整数)(Instagram 会通过单帖洞察数据提供覆盖人数/浏览量/收藏/分享;工作区启用了 TikTok 评论时,TikTok 会提供平均观看时长/完整视频观看率/总观看时长/收藏/覆盖人数)。记录还会包含 duration_seconds(整数,可为 null):平台的列表 API 报告的视频时长,以整秒为单位;目前适用于 TikTok 和 YouTube;图片及未公开此数据的平台为 null(Instagram 的媒体 API 不含时长字段)。添加 --json 可获取完整且未截断的文案、精确指标、ID 和永久链接(人类可读表格会截断/四舍五入)。LinkedIn 不向应用授予列出个人主页帖子的权限,因此无法实时列出;linkedin 结果是通过 OmniSocials 发布的帖子及其最新收集的统计数据;TikTok 照片帖子也会以相同方式回填。标志:--limit(1–50,默认 25;除非显式设置,否则 X 默认为 10——其 API 按返回的帖子数量计费)、--platforms(逗号分隔的筛选条件)。X 的结果可能来自最多 24 小时前的快照;通过 OmniSocials 向 X 发布内容后会立即刷新。需要 analytics:read 作用域。 |
posts:create | 创建新帖子。标志:--text、--channels、--schedule、--draft(计划草稿,需搭配 --schedule)、--type post|story|reel、--media-ids、--media-urls、--link-url(+--link-title/--link-description/--link-thumbnail-url)、--location-id、--collaborators、--user-tags、--x-thread、--bluesky-thread、--mastodon-thread、--threads-thread、--threads-location-id、--video-cover-json、--dm-keywords + --dm-message(绑定到此帖的评论转私信自动化,需搭配 --dm-reply、--dm-match、--dm-max-sends、--dm-stop-at;--channels 必须包含 Instagram;参见自动化),以及平台标志 |
posts:create-and-publish | 创建并立即发布。标志与 posts:create 相同,但不包括 --schedule |
posts:update <id> | 更新草稿或已排期的帖子。标志与 posts:create 相同。对待审批(in_approval)的帖子使用 --schedule 只会更改时间,不会更改状态。--no-draft 会在计划草稿当前记录的时间安排发布(若没有时间或该时间已过,则返回 400 validation_error;此时请传入新的 --schedule)。--draft 会取消已排期帖子的排期并保留其时间。--dm-* 标志会替换帖子的评论转私信自动化,--no-dm 会将其移除 |
posts:publish <id> | 立即发布草稿或已排期的帖子。若帖子状态为 failed 或 warning,则会拒绝执行;请对这类帖子使用 posts:retry |
posts:retry <id> | 重试失败帖子或部分失败帖子中发布失败的平台;已成功的平台不会再次发布;异步执行,每个平台最多重试 3 次。响应表示重试已排队:请轮询 posts:get 查看结果。某个平台重试 3 次后,API 会返回 max_retries_reached,必须重新创建帖子。帖子响应包含 retry_of(此帖子正在重试的失败帖子)和 retries(基于此帖子创建的重试帖子);如果帖子状态为 published,但 published_urls 为空且已设置 retries,则表示失败已解决,实时链接位于重试帖子上 |
posts:approve <id> | 批准帖子审批工作流的当前步骤(approval_status: "pending",帖子 status: "in_approval")。已连接的用户必须是当前步骤列出的审批者——各步骤按顺序审批,因此,后续步骤的审批者在前面的步骤完成前会收到 forbidden。如果这是最后一步,帖子会立即进入最终状态(scheduled 或 posting);否则帖子会继续保持 in_approval,并通知下一步的审批者 |
posts:reject <id> | 拒绝帖子的审批工作流。审批者要求与 posts:approve 相同。与批准不同,此操作会立即终止整个工作流(而不仅是当前步骤),帖子状态会变为 rejected。标志:--comment "..."(可选,向请求者和其他审批者显示) |
posts:approval <id> | 查看经过审批工作流的帖子的审核记录(只读,需要 posts:read)。输出审核记录 status(none、pending、approved、rejected)、工作流、请求者、帖子正在等待的步骤及仍需作出决定的审批者、拒绝者及其原因、每个步骤中每位审批者的决定,以及按时间从早到晚排列的评论串(标记为 [instagram]、[linkedin_page] 等的评论仅与相应渠道有关;评论串还包括 OmniSocials 在审核者编辑帖子时写入的条目)。--json 会返回完整对象:post_id、status、workflow、requested_by、requested_at、current_step、steps[](order、name、require_mode、status、包含 id、name、email、status、decided_at、comment 的 approvers[])、rejection(by、reason、at、step)以及 comments[](id、author、message、account、created_at)。没有工作流的帖子会返回 status: "none",且 steps 和 comments 为空。如果帖子不属于此工作区,则返回 404 not_found。每当帖子显示 approval_status 为 rejected 或 pending 时,都要运行此命令,然后再告知用户相关情况或编辑帖子 |
approval-workflows:list | 列出此工作区可使用的审批工作流(ID、名称,以及包含指定审批者的步骤;workspace_id 为 null 表示公司范围内适用)。工作流在仪表板(Approvals)中创建。将 ID 传给 posts:create --approval-workflow <id>(需要 --schedule,不允许与 --publish-now 搭配使用):帖子会以 in_approval 状态创建并通知审批者,最后一步批准后会在预定时间发布。错误:404 workflow_not_found、400 validation_error(未指定 --schedule,或工作流的第 1 步没有审批者) |
posts:delete <id> | 从 OmniSocials 中移除帖子(无法撤销)。不会删除平台上的实时帖子 |
媒体
| 命令 | 描述 |
|---|---|
media:list | 列出已上传的媒体文件。标志:--limit、--offset |
media:upload | 从 URL 上传媒体——图片、视频或 PDF。标志:--url(必需)、--filename、--name(便于查找的标签)、--folder、--folder-id、--pdf-mode |
media:upload-base64 | 上传本地文件或 base64 数据(图片、视频或 PDF)。标志:--file <path>(自动编码并推断 MIME 类型,包括 .pdf)或 --data + --mime-type;以及 --filename、--name(便于查找的标签)、--folder、--folder-id、--pdf-mode |
--pdf-mode | 仅适用于 PDF 上传。slides(默认):每页生成一个图片媒体项,每项对应一个 ID;将所有 ID 传给 posts:create --media-ids。document:整个 PDF 生成一个媒体项(type: document,页面位于 pdf.pages 中);将其唯一 ID 传给 --media-ids,帖子就会按顺序包含每一页。两种模式都会保留原始文件,LinkedIn 会收到该文件。当用户希望整个演示文稿作为一个媒体库项目时,优先使用 document。media:list --json 会将文档项显示为 type: "document" |
| PDF 轮播 | 上传一个PDF,系统会将其拆分为每页一张图片幻灯片(最多 20 张)。响应会列出每张幻灯片的媒体 ID——将所有 ID 传给 posts:create --media-ids,即可将演示文稿作为轮播发布。原始文件会保留(响应中包含 pdf.id、pdf.name、pdf.url;每张幻灯片都带有 pdf: { id, page, total_pages, ... })。只要幻灯片按原样并按顺序发布,在 LinkedIn 上就会作为基于原始 PDF 制作的原生可滑动文档发布(文本保持清晰,文档内的链接可用,访客可下载原始文件,即使超过 20 张的上限也会包含所有页面);在 Instagram、TikTok、Threads 和 Pinterest 上则会作为图片轮播发布。无需手动逐页导出,即可发布现有演示文稿(由 Canva/PowerPoint/Figma 导出为 PDF)。 |
media:check | 发布前检查媒体是否符合目标平台的要求。标志:--url,或 --media-id,或 --size-bytes + --mime。对于媒体库中的图片(--media-id),响应还会包含 file.width / file.height 和 fit[],并以 Image fit 区块显示:Instagram 和 Pinterest 如何将其显示为动态帖子(宽高比、是否适配、裁剪目标、默认操作:Instagram 为 crop,Pinterest 为 keep),以及用于覆盖默认设置的 --media-fit 值。视频和 --url 检查不会包含 fit 行。将高纵横比图片发布到 Instagram 前请先查看(安全规则第 4 条) |
media:delete <id> | 删除媒体文件 |
文件夹
| 命令 | 描述 |
|---|---|
folders:list | 列出媒体文件夹(ID、名称、父级、项目数)。将文件夹 ID 与 media:upload-base64 --folder-id 配合使用。 |
folders:create | 创建文件夹。标志:--name(必需)、--parent-id(嵌套到另一个文件夹下) |
话题标签集
按工作区保存的可重复使用的话题标签组。创建帖子时,使用 posts:create --hashtag-set "<name>" 应用一个话题标签集——标签只会合并到说明文字中一次(帖子存储的是纯文本;之后编辑话题标签集不会更改现有帖子)。说明文字中已有的标签会被跳过;超过 Instagram 的 30 个话题标签上限时,会立即报错 hashtag_limit_exceeded。添加 --hashtag-placement first_comment,即可将标签作为自动发布的首条评论添加到 Instagram / Facebook / LinkedIn / LinkedIn Page / YouTube(其他频道会改为添加到说明文字中);添加 --hashtag-platforms instagram,tiktok,则只为帖子中的部分频道添加标签。
| 命令 | 说明 |
|---|---|
hashtag-sets:list | 列出已保存的话题标签集(id、名称、标签数量、预览)。 |
hashtag-sets:create | 保存一个话题标签集。标志:--name(必填,在工作区内唯一)、--tags(必填,例如 "#fitness #gym workout"——# 可省略,按大小写不敏感方式去重,最多 100 个) |
hashtag-sets:update <id> | 重命名和/或替换标签。--tags 会替换完整列表——请传入完整的新列表。 |
hashtag-sets:delete <id> | 删除一个话题标签集。已使用该标签集的帖子会保留其话题标签。 |
自动化(评论转私信)
自动化会在 Instagram 评论中检测关键词,并向每个人发送一次私信;还可选择在评论下方公开回复(“已给你发私信!”)。它也可以在私信或快拍回复中检测关键词(--triggers dm,story_reply)。它可以监听一篇帖子(--post-id,即发布到 Instagram 的 OmniSocials 帖子,可以是已安排发布或已发布的帖子;或者 --instagram-media-id,用于在 OmniSocials 之外发布的帖子)、工作区发布的下一篇 Instagram 帖子(--scope next_post),或每篇帖子(--scope any)。每篇帖子只能有一个自动化。Instagram 允许在 7 天内针对每条评论发送一条私密回复,OmniSocials 每个账号每小时最多发送 180 条私信。API 密钥需选择启用以下权限范围:automations:read(列表、获取、事件)和 automations:write(创建、更新、删除,以及帖子的 --dm-* 标志);若未启用,API 会返回 403 insufficient_scope,CLI 会告知你在哪里启用这些权限(Settings > API)。遵循安全规则 9:创建自动化前,先与用户确认私信文本和关键词。
| 命令 | 说明 |
|---|---|
automations:list | 列出自动化:id、状态(active、paused、completed = 已达到限制)、名称、触发条件、帖子及其说明文字或链接,以及统计数据(已发送 / 匹配 / 已跳过 / 失败)。标志:--status active|paused|completed、--post-id <id> |
automations:get <id> | 完整详情:触发条件、帖子、私信文本、公开回复的不同版本、限制、统计数据、日期 |
automations:create | 创建自动化。标志:--dm "<text>"(必填,最多 1000 个字符)、--keywords "guide,link"(最多 20 个;除非使用 --match any,否则必填)、--post-id <id> 或 --instagram-media-id <id>(帖子评论触发条件必须指定其中一个)、--reply "<text>"(在评论下方公开回复;重复此标志或传入逗号分隔的列表,可设置最多 10 个轮换版本;包含逗号的回复需单独使用一个标志)、--match word|contains|any(默认 word = 完整单词;any 会回复每条评论)、--scope post|next_post|any(默认 post)、--triggers comment,dm,story_reply(默认 comment;公开回复仅适用于评论)、--max-sends <n>、--stop-at <ISO8601>、--name "..."、--paused(创建后暂停)。CLI 会在调用 API 前拒绝缺少 --dm、同时指定两个帖子标志,以及为帖子设置评论触发条件却未指定帖子的情况。错误:400 post_required、400 post_not_instagram、404 post_not_found、404 instagram_media_not_found、409 instagram_not_connected、409 instagram_needs_reauth、409 automation_exists(CLI 会指出现有自动化) |
automations:update <id> | 只更改你传入的内容;其他内容保留已存储的值(新的 --keywords 保留触发条件、范围和匹配方式;新的 --dm 保留公开回复;--stop-at 保留 --max-sends)。标志与 automations:create 相同,另加 --pause 和 --resume。--keywords 是完整的新关键词列表。另一个 --post-id / --instagram-media-id 会将自动化移至该帖子。当 completed 自动化的限制或触发条件发生变化时,它会重新启动 |
automations:delete <id> | 删除自动化。请先征得用户确认。已发送的私信不会撤回 |
automations:events <id> | 活动记录:先显示一行计数(整个自动化的已发送、已跳过、失败、待处理数量),然后每个事件占一行,包含时间、类型(评论、私信、快拍回复)、结果及原因(already_sent、limit_reached、stopped、window_passed、rate_limited 或平台错误文本)、用户、对方写的内容(评论;仅当密钥同时具有 inbox:read 时,才显示私信或快拍回复)以及已发送的私信。标志:--outcome sent|skipped|failed|pending、--limit <1-100>(默认 25)、--offset |
位置
| 命令 | 描述 |
|---|---|
locations:search "<name>" | 搜索可标记的位置(至少 2 个字符)。默认使用 --platform instagram 搜索 Facebook Places,并返回 location_id 值,供 posts:create --location-id 使用。--platform threads 则搜索 Threads 位置并返回 id,供 posts:create --threads-location-id 使用;也可以用 --latitude + --longitude 代替名称。这两种 id 命名空间不同:切勿将 Instagram 的 location_id 用作 Threads 的 id,反之亦然。Threads 位置搜索正在逐步推出;在 Meta 批准该权限之前,API 会返回 not_available,较早连接的 Threads 账号则会返回 threads_reauth_required,直到重新连接为止。 |
Pinterest 商品
商品标签会将商品添加到 Pin 上,让用户可以购买图片中的商品。标签使用的是已连接 Pinterest 账号的商品 Pin ID。Pinterest 仅接受满足以下条件的商品:Pin 为公开状态、属于同一个 Pinterest 账号,且链接指向该账号已认领的网站。无法标记其他商家的商品。将 Pin ID 传给 posts:create --pinterest-product-tags(每个 Pin 最多 24 个)。两个命令都需要 posts:read 范围。
| 命令 | 描述 |
|---|---|
pinterest:products | 列出已连接 Pinterest 账号的商品 Pin。每一行都以 pin_id 开头,供 --pinterest-product-tags 使用。选项:--source catalog|pins、--product-group-id <id>、--bookmark <bookmark>、--page-size <1-100>(默认值为 25,仅适用于 catalog)。--source catalog 会读取 Pinterest 商品目录:行中包含价格、币种、库存状态和商家的商品 id,输出还会列出商品组,可使用 --product-group-id 选择其他商品组。需要已连接的 Pinterest 账号具有商品目录访问权限,用户可在 OmniSocials 撰写器中授予一次(Pinterest 选项、Add products、Connect catalog)。--source pins 会读取账号自己的 Pins,并返回 Pinterest 标记为商品 Pin 的内容;适用于所有连接。未指定 --source 时,如果连接具有商品目录访问权限,API 会使用 catalog,否则使用 pins。一次 pins 调用最多扫描 250 个 Pin,因此可能同时显示“No product Pins in this batch”和一个 --bookmark 值:使用该书签再次运行,直到不再显示书签。出现问题时会显示为 Error [code]: message,而不是空列表:pinterest_not_connected(工作区未连接 Pinterest 账号)、pinterest_catalog_access_required(使用 --source catalog 但没有商品目录访问权限:请用户连接商品目录,或使用 --source pins)、platform_error(Pinterest 未响应或拒绝请求;消息中包含 Pinterest 返回的文本)、validation_error(--product-group-id 不是该账号的商品组)。--json 会返回 products[](pin_id、title、description、link、image_url、price、currency、availability、item_id;最后四项仅适用于商品目录)、bookmark、source、catalog_access,以及在商品目录来源下的 product_groups[] 和 product_group_id |
pinterest:validate <pin-id-or-link> | 在标记 Pin 前检查它。可接受 Pin ID 或 Pin 链接(https://www.pinterest.com/pin/<id>/;不支持 pin.it 短链接)。如果是已连接账号的商品 Pin,则显示 Valid product Pin: <pin_id>;如果该 Pin 不是商品 Pin、属于其他账号或不存在,则显示 Not valid (<pin_id>): <reason>;如果无法执行检查(未连接 Pinterest 账号、Pinterest 未响应,或 Pinterest 未说明该 Pin 是否为商品 Pin),则显示 Not checked (<pin_id>): <reason>;此时发布步骤会进行最终检查。此检查不会核验网站认领规则;Pinterest 会在发布时执行该规则。--json 会返回 valid、pin_id、title、link、image_url、unverified、reason |
音频(Instagram Reel 音乐)
| 命令 | 描述 |
|---|---|
audio:search ["<song/artist>"] | 搜索 Meta 授权的 Instagram Reels 音乐目录。不填写查询内容 = 当前热门音频;--type original_sound 可搜索原创音频。返回 audio_id 值,供 posts:create --instagram-audio-id 使用。仅显示已获第三方发布授权的曲目(可选曲目可能与 IG 应用不同);需要连接一个其主页关联了 Instagram 账号的 Facebook 账号。 |
账号
| 命令 | 描述 |
|---|---|
accounts:list | 列出所有已连接的社交媒体账号,以及频道 ID、平台、内容类型和 Pinterest 画板 |
accounts:get <id> | 获取账号完整详情,包括平台特定信息 |
分析
| 命令 | 描述 |
|---|---|
analytics:post <post-id> | 获取帖子分析数据:展示次数、覆盖人数、互动、点赞、评论、分享、收藏、点击,以及各平台统计数据(X/Bluesky/Mastodon/Threads 上的串帖会汇总各部分数据;比率和平均值则取平均值)。各平台返回的原始 metrics 包含其提供的全部数据:链接点击、个人主页访问、关注(通过该帖子新增的关注者)、按类型划分的回应、视频指标(视频观看次数、平均观看时长、总观看时长、观看时长百分比、完播率、跳过率、重播次数、有效观看次数)、YouTube 流量来源、TikTok 展示来源/受众类型、Pinterest 图钉点击/站外点击、Instagram 快拍导航和完播数据。对于无法衡量的内容(如 Google Business 帖子、已删除的视频),会返回 metrics_unavailable: true 和 note,而不是 0。X、Pinterest、YouTube、Threads、Bluesky、Mastodon 和 Facebook 不会返回 reach(Meta 于 2026 年 6 月停用了 Facebook 帖子覆盖人数指标;替代指标也不返回数据):仅汇总提供该数据的平台的覆盖人数。 |
analytics:best-times | 推荐发布时段(星期+小时),根据工作区自身的发布历史计算(按近期程度加权、降低异常值影响,并采用账号时区);平台提供受众在线数据时(Instagram、TikTok Business),会将两者结合(basis: own_data_and_audience,响应包含 audience_online)。返回排名前 3 的时段和每天的得分。分析的帖子少于 15 条时,仅使用受众在线情况(basis: audience),或返回明确标注的行业默认值及 posts_needed — 请告知用户这一点。未指定时间时,请在安排发布前使用。标志:--platform(必填)、--timezone(IANA 时区覆盖值)。需要 analytics:read。 |
analytics:posts <id,id,...> | 一次调用批量获取最多 100 条帖子的分析数据。请使用此命令,而不要循环调用 analytics:post,以避免触发速率限制。 |
analytics:overview | 工作区分析概览。标志:--period 7d|30d|90d、--start-date YYYY-MM-DD、--end-date YYYY-MM-DD |
analytics:accounts | 账号级分析数据:关注者、正在关注、帖子,以及平台针对快照日期报告的日数据(展示次数/观看次数、覆盖人数、互动、个人主页浏览、链接点击、新增关注者、取消关注者;Google Business 的来电、路线请求、网站点击、平均评分、评价数量;Pinterest 月浏览量)。包含日数据的行带有 period: "daily"。在有数据时返回受众对象:demographics(以及 demographics_unit)和 online_followers(UTC 小时对应的在线关注者数;Instagram 和 TikTok Business 账号需有 100 名以上关注者)。标志:--platform、--date YYYY-MM-DD。各平台的指标范围不同 — 请阅读每行的 note。 LinkedIn 个人资料会在 impressions_lifetime 中保留总累计展示次数(所有历史内容,包括在 OmniSocials 之外发布的帖子);如果未提供每日明细,则会带有 period: "lifetime"。切勿将累计总数与指定时间范围内的导出数据进行比较。缺少某个键表示平台不提供该指标(Bluesky 和 Mastodon 不提供观看次数;YouTube 日数据需要 YouTube Analytics 权限范围;TikTok 日数据需要 Business 授权)。 |
收件箱(社交收件箱)
在已连接的账号中读取并回复私信、评论和提及。每个评论/提及对话串都会附带所属帖子(post:id、caption、thumbnail、url、media_type);CLI 会在对话串上方打印这些信息,方便你查看帖子并拟写回复。同一帖子的所有评论共用一个对话,因此回复评论或提及时必须使用 --message-id <message-id> 指明要回复的评论;如果不提供,API 会将回复发布在该帖子下最新收到的评论中,而该评论可能来自其他人。Instagram 和 Facebook 私信只能通过 API 在 Meta 的 24 小时消息窗口内回复(自客户最后一条消息起 24 小时):每条返回的内容都包含 reply_window(open、closes_at);如果回复窗口已关闭,回复该私信会返回 422 outside_messaging_window,且不会发送任何内容,因此应在 Instagram/Facebook 应用中回复该私信,或使用 inbox:read 跳过。通过原生应用(Instagram 应用、Messenger)输入的回复会同步到收件箱,作为已发消息并计为已回复,因此不会将同事已在手机上回复的对话串作为未回复内容返回;即使在窗口关闭后通过应用回复私信,也会以同样方式清除未回复状态。TikTok 仅支持视频评论(不支持私信或提及);TikTok 回复仅限文本,最多 150 个字符。YouTube 仅支持视频评论(不支持私信或提及);YouTube 频道每天检查一次新评论,因此新评论最多可能需要一天才会显示。Threads 支持回复用户帖子上的内容(type: comment)和提及(不支持私信);回复会作为原生 Threads 回复发布。添加收件箱权限前建立的 Threads 连接需要在控制面板中重新连接一次;在此之前,Threads 对话不会显示,Threads 回复/隐藏操作会返回 401 reauth_required。在 Facebook、Instagram、TikTok、YouTube(审核状态为 rejected)和 Threads(仅限顶层回复)上,可以使用 inbox:hide 隐藏用户自己帖子上的评论;在 Facebook、Instagram 和 TikTok 上,可以使用 inbox:delete 永久删除评论。需要选择启用 inbox:read/inbox:write 权限范围:用户在创建 API 密钥时需启用“Social Inbox access”。如果调用返回 insufficient_scope,请告知用户创建一个启用了 Social Inbox access 的新密钥。conversation_id 值可能包含 : 和 ()(LinkedIn URN);请按 inbox:list 返回的原样传入(CLI 会自动对其进行 URL 编码)。结果采用游标分页:如果还有更多结果,CLI 会打印用于获取下一页的 --cursor 值。
回复收件箱中的消息(inbox:next 循环)。 inbox:next 会返回一条需要回复的消息,其中包含整个会话线程(按时间从早到晚)、消息所在的帖子、reply_window,以及还有多少条消息在等待回复。如果某条消息是客户最近发送的私信,且之后没有收到回复,或者是尚未回复且未隐藏的评论/提及,就需要回复。队列分为三组:首先是仍可回复的私信(Instagram/Facebook 私信须在 Meta 的 24 小时窗口内,窗口关闭时间最早的排在前面;X 私信没有时间窗口);然后是 24 小时窗口已关闭的 Instagram/Facebook 私信(reply_window.open 为 false;客户仍在等待,但 API 无法回复:请告知用户从 Instagram/Facebook 应用回复,或使用 inbox:read 跳过该条消息);最后是评论和提及,按时间从早到晚排列。--order newest 会反转每组内的顺序。默认只提供未读消息,因此,使用 inbox:read <conversation-id> 是跳过某条消息的持久方式(该消息不会再次出现);--exclude <id,id> 可在单次调用中排除会话(临时跳过,最多 100 条);--include-read 也会提供已读但尚未回复的消息。回溯 30 天。使用 inbox:reply <conversation-id> --text "..." --next 回复,响应中会附带下一条消息,因此处理收件箱时每次回复只需调用一次。对于评论或提及,始终使用所提供的消息 ID(“要回复的消息”)添加 --message-id <message-id>:同一帖子的所有评论共用一个会话;如果不指定该参数,回复会发布在该帖子的最新评论下,而发布该评论的人可能不是你原本要回复的人。CLI 显示“Nothing is waiting for an answer.”时,循环结束。两个 ID 很重要:conversation_id(inbox:reply / inbox:read 使用)和未回复消息的 id(--message-id、inbox:hide 和 inbox:delete 使用);CLI 会分别标出两者。
| 命令 | 描述 |
|---|---|
inbox:list | 列出对话(每个对话显示最新消息)。标志:--platform instagram|facebook|linkedin|tiktok|youtube|x|threads、--type dm|comment|mention、--unread(仅显示有未读消息的对话)、--unanswered(仅显示仍需回复的对话:客户最新的私信后没有收到回复,包括 24 小时窗口已关闭的 Instagram/Facebook 私信(无法通过 API 回复,但客户仍在等待;inbox:next 会用 reply_window 标记这些私信),或尚未回复且未隐藏的评论/提及;通过原生应用发送的回复也算作答复;忽略已读状态)、--limit、--cursor。显示参与者、未读数、最后一条消息,以及评论/提及对应的帖子。需要 inbox:read。 |
inbox:next | 显示下一个需要回复的对话及其对话串(按时间从早到晚,每条消息都显示其 ID 和方向)、所属帖子及其 reply_window({ open, closes_at };只有 Instagram/Facebook 私信有时间窗口,其他内容均为 open: true, closes_at: null),并显示还有多少条待处理。按以下顺序返回:仍可回复的私信(Meta 的 24 小时窗口内的私信,按窗口关闭时间从近到远排列,以及 X 私信),接着是窗口已关闭的 Instagram/Facebook 私信(open: false,closes_at 表示关闭时间;CLI 会打印“回复窗口已关闭……”并提示你在原生应用中回复,或使用 inbox:read 跳过),最后是按时间从早到晚排列的评论和提及。返回的消息 ID 可作为 inbox:reply 的 --message-id 参数;CLI 会打印该 ID 并附上提示。标志:--platform、--type dm|comment|mention、--order oldest|newest(反转每个分组内的顺序)、--include-read(也返回已标记为已读但从未回复的项目)、--exclude <conversation-id,...>(本次调用中排除这些项目;临时跳过,最多 100 个)。默认仅显示未读项目,因此使用 inbox:read 可永久跳过。回溯最近 30 天。队列为空时会打印“没有待回复的内容。”需要 inbox:read。 |
inbox:messages <conversation-id> | 显示单个对话的完整消息记录,按时间从早到晚排列,每条消息都包含其消息 ID、方向、时间戳以及已读/已回复/已隐藏状态。评论对话串会先显示帖子信息块(说明文字、URL、缩略图)。标志:--limit、--cursor。需要 inbox:read。 |
inbox:read <conversation-id> | 将对话中的消息标记为已读。也可永久跳过 inbox:next 中的项目(除非使用 --include-read,否则已读对话不会再次返回)。需要 inbox:write。 |
inbox:reply <conversation-id> | 发送回复。标志:--text(必需)、--message-id <message-id>(正在回复的评论或提及的收件箱 ID:即 inbox:next 中的“待回复消息”ID,或 inbox:messages 中的消息 ID;评论对话串必须始终传入此参数,因为同一帖子的所有评论共用一个对话;如果不传入,回复会发布在最新收到的评论下,而该评论者可能与起草回复时针对的人不同;对私信会忽略此参数;如果它不是此对话中的收到消息,则返回 404 not_found;如果它不是数字,则返回 400 validation_error)、--attachment-url、--attachment-type、--next(响应还会附带下一个需要回复的对话,打印方式与 inbox:next 相同,包括其 reply_window 及剩余数量)。需要 inbox:write。422 outside_messaging_window 表示 Instagram/Facebook 私信已超出 Meta 的 24 小时窗口;API 会在调用平台前检查,因此消息并未发送:告知用户通过 Instagram/Facebook 应用回复该私信(原生回复会同步到收件箱并清除该项目),或使用 inbox:read 将对话标记为已读以跳过;不要重试。409 duplicate_reply 表示过去 10 分钟内已向该评论或私信对话发送过完全相同的回复(之前看似缓慢或失败的调用其实已成功):不会再次发送,不要重试,继续使用 inbox:next。422 reply_not_allowed 表示平台永久拒绝对此项目回复(Facebook #1705:评论位于帖子分享副本或推广副本下,或评论者限制了回复;YouTube:由于视频已关闭评论、评论已删除或被暂缓审核,该对话串的 canReply 为 false):该项目会自动从 inbox:next 中移除,告知用户,不要重试。Threads 回复需要连接具有 Threads 回复权限;401 reauth_required 表示用户必须在仪表板中重新连接 Threads。 |
inbox:hide <message-id> | 以帖子所有者身份隐藏用户在其帖子下发表的评论(--unhide 可撤销隐藏)。适用于 Facebook、Instagram、TikTok、YouTube(隐藏 = 将审核状态设为拒绝,这也会让其回复不再公开显示)和 Threads(仅适用于收到的顶级回复;嵌套回复会返回 not_hideable)。使用 inbox:messages 或 inbox:next 中的消息 id,而不是对话 ID。隐藏的评论不再计为未回复。错误:403 reconnect_required(账号连接时未授予审核权限;请在仪表板中重新连接)、422 cannot_hide(Facebook 不允许主页隐藏此评论:评论者屏蔽了主页、其账号已停用或受限,或评论位于帖子分享副本下;重试也不会改变结果,告知用户,并在不应再显示该评论时使用 inbox:read)、502 hide_not_applied(仅限 Instagram:隐藏或取消隐藏后,API 会重新读取评论并返回 Instagram 自身的 hidden 状态;如果 Instagram 接受调用,但仍报告评论处于原有状态,API 就会返回此错误并保持收件箱记录不变。此情况会发生在 Instagram 将 Reels 评论列在“来自 Facebook 的评论”下,且该 Reels 也分享到了 Facebook 时:这些评论实际位于 Facebook 上,Instagram 的隐藏操作无法影响它们。请在 Instagram 或 Facebook 应用中隐藏,不要重试)、429 quota_exceeded(YouTube 每日配额已用尽;请在太平洋时间午夜后重试)、401 reauth_required、404 account_not_connected、502 platform_error。需要 inbox:write。 |
inbox:delete <message-id> | 永久从平台删除评论。仅适用于 Facebook、Instagram 和 TikTok 评论(YouTube:请改用 inbox:hide)。此操作无法撤销,因此请先与用户确认。该评论下的回复也会一并删除;响应会通过 removed_reply_ids 列出这些回复。使用消息 id,而不是对话 ID。错误代码与 inbox:hide 相同。需要 inbox:write。 |
Webhooks
| 命令 | 描述 |
|---|---|
webhooks:list | 列出所有 Webhook |
webhooks:create | 创建 Webhook。标志:--url(必填)、--events(必填,以逗号分隔:post.scheduled、post.published、post.failed、post.approved、post.rejected)。当帖子的审批工作流完成最后一步并获批时,会触发 post.approved(帖子状态变为 scheduled;如果发布时间已过,则变为 posting);审批者拒绝帖子时,会触发 post.rejected。两者都会携带 data.approval(包含 status、decided_by = 审批者的用户 ID、reason = 字符串或 null)和一个空的 targets 数组;完整审核信息见 posts:approval <id> |
webhooks:get <id> | 获取 Webhook 详情 |
webhooks:update <id> | 更新 Webhook。标志:--url、--events、--active true|false |
webhooks:delete <id> | 删除 Webhook |
webhooks:rotate-secret <id> | 轮换 Webhook 签名密钥(请立即保存新密钥) |
全局标志
所有命令均支持以下标志:
| 标志 | 描述 |
|---|---|
--json | 输出原始 JSON 响应(便于解析) |
--api-key <key> | 为此命令覆盖 API 密钥 |
--base-url <url> | 覆盖 API 基础 URL |
--help | 显示帮助 |
平台专属参考
内容类型支持矩阵
| 平台 | 帖子 | 快拍 | Reels | 是否需要媒体 |
|---|---|---|---|---|
| 是 | 是(1-10 张幻灯片,按顺序发布) | 是 | 始终需要(图片或视频) | |
| 是 | 是(1-10 张幻灯片,按顺序发布) | 是 | 帖子可选,快拍/Reels 必需 | |
LinkedIn (linkedin) | 是 | 否 | 否 | 可选 |
LinkedIn Page (linkedin_page) | 是 | 否 | 否 | 可选 |
| YouTube | 否 | 否 | 是(Shorts) | 始终需要(视频) |
| TikTok | 是 | 否 | 是 | 始终需要(图片或视频) |
| X (Twitter) | 是 | 否 | 否 | 可选 |
| 是 | 否 | 否 | 始终需要(图片或视频 + board_id) | |
| Bluesky | 是 | 否 | 否 | 可选 |
| Threads | 是(单条帖子,或通过 --threads-thread 发布由 2-25 条内容组成的串帖;通过 --threads-location-id 添加位置标签;通过 inbox:* 处理收件箱回复/提及;位置标签仍在逐步推出) | 否 | 否 | 可选 |
| Mastodon | 是 | 否 | 否 | 可选 |
| Google Business | 是 | 否 | 否 | 可选 |
平台专属标志
| Flag | Description |
|---|---|
--pinterest-board-id | 对 Pinterest 为必填。通过 accounts:get <pinterest_account_id> 获取画板 ID |
--pinterest-title | Pin 标题 |
--pinterest-link | 附加到 Pin 的链接 URL |
--pinterest-video-cover | 视频 Pin 的封面图片 URL |
--pinterest-alt-text | Pin 的替代文本 |
--pinterest-product-tags | 要在 Pin 上标记的商品:以逗号分隔的 Pin ID 列表(来自 pinterest:products)或 Pin 链接(https://www.pinterest.com/pin/<id>/),最多 24 个。作为 pinterest.product_tags 发送 |
商品标记(--pinterest-product-tags):
- 每个 Pin 最多 24 个商品。 超过 24 个,或条目不是 Pin ID 或 Pin 链接时,返回
400 validation_error。 - 只能标记自己的商品。 Pinterest 仅在商品 Pin 公开、属于同一个 Pinterest 账号,且链接到该账号认领的网站时接受该商品。不能标记其他商家的商品。
- 商品被拒绝不会导致帖子发布失败。 Pin 发布后会立即添加标记。如果 Pinterest 拒绝某个商品,Pin 仍会正常显示,其他商品仍会添加标记。
- 发布后查看结果。 添加过标记的已发布帖子会包含
pinterest.product_tags_result:requested(提交的数量)、tagged(Pin 上的 Pin ID)、skipped(每个未标记商品对应的pin_id和reason)以及error(标记请求本身失败时设置,例如 Pinterest 服务中断;此时tagged为空)。posts:list会以Pinterest products: 1 of 2 tagged (skipped: <pin_id> PIN_IS_PRIVATE)的形式显示,posts:get会显示完整对象。原因代码:PIN_MISSING(未找到 Pin)、PIN_IS_PRIVATE(Pin 为私密状态)、PRODUCT_METADATA_MISSING(不是商品 Pin)、PIN_NOT_FROM_VERIFIED_DOMAIN(商品链接不在已认领的网站上)、PIN_NOT_FROM_SAME_USER_AS_HERO_PIN(Pin 属于其他账号)。告知用户哪些商品被跳过以及原因。 - 在
posts:update中,Pinterest 标记会将已存储的 Pinterest 选项整体替换为一个对象。 重新传入帖子所需的每个 Pinterest 标记,包括--pinterest-board-id。更新时省略--pinterest-product-tags会移除这些标记。 posts:get会以 Pin ID 字符串的形式返回已存储的标记,位于pinterest.product_tags中(Pin 链接会以其 Pin ID 存储)。
YouTube(Shorts)
| Flag | Description |
|---|---|
--youtube-title | 视频标题 |
--youtube-privacy | 隐私设置:public、private 或 unlisted |
--youtube-tags | 标签(以逗号分隔) |
--youtube-category-id | YouTube 类别 ID |
--youtube-made-for-kids | 是否为儿童制作的标记 |
Short 的自定义缩略图通过 --video-cover-json 设置(参见 视频封面)。YouTube 仅在已启用 Shorts 自定义缩略图功能的频道上显示该缩略图(优先支持 Partner Program 频道);其他频道会显示视频中的一帧。
| 标志 | 描述 |
|---|---|
--instagram-share-to-feed | 将短视频分享到动态 |
--instagram-cover-url | 短视频封面图片 URL(搭配 --instagram-thumbnail-type from-library 使用) |
--instagram-thumbnail-type | 缩略图类型:from-video 或 from-library |
--instagram-thumb-offset | 从视频开始处起算的短视频封面帧时间戳,单位为 毫秒(例如,3000 = 0:03;搭配 --instagram-thumbnail-type from-video 使用)。posts:get 会读取该值 |
--instagram-audio-id | 短视频使用的授权音乐——来自 audio:search 的 audio_id。仅限短视频(Meta 的 API 无法为动态帖子、轮播或快拍添加音乐)。需要关联的 Facebook 账户,其主页须链接到此 Instagram 账户。 |
--instagram-audio-volume | 音乐音量,范围为 0–100(默认值为 100)。仅搭配 --instagram-audio-id 使用 |
--instagram-video-volume | 视频本身的音量,范围为 0–100(默认值为 100;0 = 仅音乐的短视频) |
--instagram-trial-reel | 将短视频发布为 试用短视频——先向非关注者展示,以测试表现。仅在用户明确要求发布试用短视频时使用。**仅限短视频。**并非所有账户都能使用:Instagram 要求关注者大约达到 1,000 人以上,并按账户启用此功能;不符合资格的账户发布时会收到明确的错误。 |
--instagram-trial-graduation-strategy | 试用短视频如何扩展至所有关注者:MANUAL(默认值——由用户在 Instagram 应用中决定)或 SS_PERFORMANCE(如果表现良好,Instagram 会自动分享)。仅搭配 --instagram-trial-reel 使用 |
动态图片比例(--media-fit instagram=crop|keep,这是顶层标志,不是 --instagram-* 标志):Instagram 接受比例为 9:16 至 1.91:1 的动态图片,但只显示 4:5 至 1.91:1 的部分,并会自行将较高的图片裁剪为 4:5;Meta 无法推广超出此范围的动态帖子。未设置此标志时,OmniSocials 会仅针对 Instagram 频道,将过高或过宽的图片围绕主体裁剪为 4:5 / 1.91:1(其他频道保留原图),并在帖子创建后输出带裁剪 URL 的 [image_fit] 警告。instagram=keep 会发送原图(Instagram 随后会裁剪,且无法推广)。posts:update <id> --media-fit instagram=keep 会在草稿或已排期的帖子中恢复原图;instagram=crop 会裁剪保留的图片。超出 9:16 至 1.91:1 范围的比例仍会导致 400 validation_error。请参阅 按平台设置媒体和安全规则第 4 条。
自动发布首条评论(Instagram、Facebook、LinkedIn、YouTube、TikTok)
帖子发布后,立即自动将给定文本作为首条评论发布。常用于将主题标签或链接放在主要说明文字之外。每个频道各有一个标志,因此可在同一次调用中为每个平台设置不同的首条评论。快拍不会发布首条评论。
| 标志 | 描述 |
|---|---|
--instagram-first-comment | Instagram 帖子/短视频的首条评论(最多 2200 个字符) |
--facebook-first-comment | Facebook 帖子的首条评论。仅限主页帖子(API 无法在个人主页上发表评论) |
--linkedin-first-comment | LinkedIn 个人资料帖子的首条评论(最多 1250 个字符)。适用于“链接见首条评论” |
--linkedin-page-first-comment | LinkedIn 公司主页帖子的首条评论(最多 1250 个字符) |
--youtube-first-comment | YouTube 视频的首条评论(最多 10000 个字符)。视频必须允许评论 |
--tiktok-first-comment | TikTok 视频的首条评论(最多 150 个字符)。TikTok 频道卡片必须启用评论(需要第二次 TikTok 授权);否则帖子会发布,但 first_comment_result.status 为 failed,并附带说明性错误。如果 TikTok 在发布几分钟后才返回最终视频 ID,评论会在 ID 解析完成后自动发布(在此期间 first_comment_result.pending 为 true) |
LinkedIn 多图样式
默认情况下,包含 2 张或更多图片的 LinkedIn 帖子会以 LinkedIn 可滑动的 PDF 文档轮播形式发布(图片会在服务端渲染为一个 PDF 文档)。使用这些标志可让频道退出此模式,改为普通的多图图库。每个频道独立设置;图片数量为 0–1 张、发布视频或投票时会忽略这些标志。
| 标志 | 说明 |
|---|---|
--linkedin-carousel-as-images | true = 个人资料帖子中的图片以普通图片图库形式发布。使用 posts:update 时,false 会恢复为文档轮播;省略则保留当前值 |
--linkedin-page-carousel-as-images | 公司主页帖子同理 |
LinkedIn 文档来源(原始 PDF)
当频道中的图片恰好是某个已上传 PDF 按顺序渲染出的页面,且没有经过修改时,LinkedIn 默认会收到保留的原始 PDF 文件作为文档(文本清晰、文档内链接可用、可下载原文件,并包含所有页面,即使超过 20 页的上限也不例外)。使用这些标志可让频道退出此模式,改为根据幻灯片图片重新生成文档(扁平化副本)。当图片不是 PDF 页面、--linkedin-carousel-as-images 为 true,或图片数量为 0–1 张、发布视频或投票时,会忽略这些标志。
| 标志 | 说明 |
|---|---|
--linkedin-document-source | original_pdf(默认)或 slides。使用 posts:update 时,original_pdf 会恢复为默认值;省略则保留当前值 |
--linkedin-page-document-source | 公司主页帖子同理 |
LinkedIn 投票
非赞助投票(LinkedIn 的 Poll API)——包含一个问题、2–4 个答案选项和投票时长,每个频道独立设置:linkedin(个人资料)和 linkedin_page(公司主页)可各自设置投票,也可不设置。投票与该频道帖子中的媒体内容和链接分享互斥:如果帖子中也包含媒体内容或链接,发布时会静默优先使用投票,因此请勿将它们组合使用。
| 标志 | 说明 |
|---|---|
--linkedin-poll-json | 完整的 linkedin_poll JSON 对象,以频道为键:{"linkedin": {"question": "...", "options": ["...", "..."], "duration": "ONE_DAY|THREE_DAYS|SEVEN_DAYS|FOURTEEN_DAYS"}, "linkedin_page": {...}}。每个投票的 question 最长为 140 个字符;options 需要包含 2–4 个选项,每个最长为 30 个字符。省略某个频道的键(或将其设为 null),即可让该频道发布普通帖子。 |
也适用于 posts:update <id>——存储的 linkedin_poll 对象会整体替换(两个频道都会替换),因此请发送完整的目标状态。将某个频道的键设为 null(或为整个标志传入 --linkedin-poll-json 'null'),即可清除该频道的投票并恢复为普通帖子。
# Same poll on the profile only
omnisocials posts:create \
--content "What should we build next?" \
--accounts your-linkedin-account-id \
--linkedin-poll-json '{"linkedin":{"question":"What should we build next?","options":["Mobile app","Public API","More integrations"],"duration":"SEVEN_DAYS"}}'
# A DIFFERENT poll on the profile and the page in one call
omnisocials posts:create \
--content "What should we build next?" \
--accounts your-linkedin-profile-account-id,your-linkedin-page-account-id \
--linkedin-poll-json '{"linkedin":{"question":"What should WE build?","options":["A","B"],"duration":"SEVEN_DAYS"},"linkedin_page":{"question":"What should our COMPANY build?","options":["A","B","C"],"duration":"FOURTEEN_DAYS"}}'
视频封面
媒体内容为单个视频(动态视频或短视频)的帖子的缩略图。适用于所有支持封面的平台:Instagram、Facebook、LinkedIn 个人主页和主页、TikTok、Pinterest 和 YouTube Shorts。
| 标志 | 描述 |
|---|---|
--video-cover-json | 完整的 video_cover JSON 对象:{"type": "frame", "thumb_offset": 3000}(视频中的毫秒数),或 {"type": "custom", "cover_url": "https://..."}(JPEG/PNG);还可包含可选的 "overrides" 对象,以平台为键(instagram、facebook、linkedin、linkedin_page、tiktok、pinterest、youtube),其中针对该平台的封面会覆盖基础封面 |
- TikTok 仅支持视频帧。 自定义封面会在 TikTok 上被跳过,因此,如果用户想指定某个 TikTok 视频帧,请添加
"overrides": {"tiktok": {"type": "frame", "thumb_offset": 2000}}。 - YouTube Shorts:取决于频道。 只有启用了自定义 Shorts 缩略图的频道,YouTube 才会在 Shorts 上显示封面(自 2026 年 7 月起逐步推出,优先面向合作伙伴计划频道)。在其他频道上,YouTube 会保存封面,但显示的是视频中的某一帧。请说明这取决于频道,不要作出保证。
- 旧版的平台专属标志(
--instagram-cover-url、--instagram-thumb-offset、--tiktok-video-cover-timestamp-ms、--pinterest-video-cover)仍可使用,并且会覆盖该平台的基础封面。 - 对
posts:update <id>,已存储的封面会被整体替换;传入--video-cover-json null可将其移除。posts:get会以video_cover返回封面。
# One custom cover everywhere, a chosen frame on TikTok
omnisocials posts:create \
--text "New tutorial" \
--channels <instagram_id>,<facebook_id>,<tiktok_id> \
--type reel \
--media-urls "https://example.com/video.mp4" \
--video-cover-json '{"type":"custom","cover_url":"https://example.com/cover.jpg","overrides":{"tiktok":{"type":"frame","thumb_offset":2000}}}'
TikTok
| 标志 | 描述 |
|---|---|
--tiktok-title | 仅限照片轮播。TikTok 在照片模式帖子的说明文字上方显示的标题(最多 90 个字符)。TikTok 将标题和说明文字作为独立字段处理;说明文字来自 --text。视频帖子会忽略此项。posts:get 会以 tiktok.title 返回此项 |
--tiktok-privacy | 隐私设置:PUBLIC_TO_EVERYONE、MUTUAL_FOLLOW_FRIENDS、FOLLOWER_OF_CREATOR、SELF_ONLY |
--tiktok-disable-comment | 禁用评论 |
--tiktok-disable-duet | 禁用合拍 |
--tiktok-disable-stitch | 禁用拼接 |
--tiktok-video-cover-timestamp-ms | 仅限视频。用作封面的帧的时间戳(毫秒) |
--tiktok-is-aigc | 标记为 AI 生成内容 |
--tiktok-brand-content-toggle | 推广第三方品牌的付费合作 |
--tiktok-brand-organic-toggle | 推广自己的业务/品牌 |
--tiktok-auto-add-music | 仅限照片轮播。由 TikTok 自动选择配乐 |
Google Business Profile
| 标志 | 描述 |
|---|---|
--google-business-cta-action | 帖子下方的 CTA 按钮:LEARN_MORE、BOOK、ORDER、SHOP、SIGN_UP、CALL。GBP 说明文字不允许内嵌链接和电话号码——CTA 按钮是添加两者的唯一方式;因此,用户想在 Google Business 帖子中添加链接时,请使用此项 |
--google-business-cta-url | CTA 目标 URL,格式为 http(s)://。除 CALL 外,所有操作都必须提供此项(CALL 使用商家资料中的地点电话号码) |
--google-business-topic-type | 帖子类型:STANDARD(默认)、EVENT、OFFER |
--google-business-json | 用于 EVENT/OFFER 结构的完整 google_business JSON 对象(event.title 和 event.schedule 使用 Google 的 {year,month,day}/{hours,minutes} 拆分日期;EVENT 和 OFFER 均为必填:对于优惠,此项包含优惠名称和有效期;offer.couponCode/redeemOnlineUrl/termsConditions)。与其他 --google-business-* 标志合并 |
这四项也可用于 posts:update <id>,以在草稿或已安排的帖子上添加或更改 CTA(已存储的 google_business 对象会被整体替换,因此请传入完整结构)。
X(Twitter)
| 标志 | 描述 |
|---|---|
--x-reply-settings | 谁可以回复:following 或 mentionedUsers(空字符串 = 所有人) |
--x-poll-json | X 帖子上的投票,文本为问题:{"options":["A","B"],"duration_minutes":1440}(2 到 4 个选项,每个最多 25 个字符;5 到 10080 分钟,默认为 1440)。在 X 上,投票不能与媒体同时发布;在线程中,投票会添加到第一条推文。posts:update 中设为 null 可移除投票。 |
--threads-poll-json | Threads 帖子上的投票:{"options":["A","B"]}(2 到 4 个选项,每个为 1 到 25 个字符)。Threads 会在 24 小时后关闭投票。仅限纯文本帖子。posts:update 中设为 null 可移除投票。 |
--mastodon-poll-json | Mastodon 状态上的投票:{"options":["A","B"],"expires_in":86400,"multiple":false,"hide_totals":false}(限制由实例决定;默认最多 4 个选项,每个 50 个字符,时长为 5 分钟到 1 个月)。投票不能与媒体同时发布。posts:update 中设为 null 可移除投票。 |
--x-thread "a || b || c" | 发布一个线程。各部分以 || 分隔(2–25 个部分)。如需为每条推文分别添加媒体,请改用 --json 构建帖子,并提供完整的 x.thread_parts 数组。 |
--bluesky-thread "a || b || c" | 发布一个 Bluesky 线程。各部分以 || 分隔(2–25 个部分,每部分 ≤ 300 个字符)。链接、提及和话题标签会自动变为可点击内容。如需为每条帖子分别添加媒体,请改用 --json 构建帖子,并提供完整的 bluesky.thread_parts 数组。 |
--mastodon-thread "a || b || c" | 发布一个 Mastodon 线程。各部分以 || 分隔(2–25 个部分,每部分 ≤ 500 个字符)。每条嘟文都会原生回复上一条。如需为每条嘟文分别添加媒体,请改用 --json 构建帖子,并提供完整的 mastodon.thread_parts 数组。 |
--threads-thread "a || b || c" | 发布一个 Threads(Meta)线程。各部分以 || 分隔(2–25 个部分,每部分 ≤ 500 个字符)。每个部分都会由同一账号作为回复发布,第一部分为帖子的说明文字。如需为每个部分分别添加媒体(每个部分最多 10 项,可混合图片和视频,也允许使用 {url, alt} 条目),请改用 --json 构建帖子,并提供完整的 threads.thread_parts 数组。对于 posts:update,将 threads.thread_parts: null 设为单条帖子。需要 Threads 回复权限:在添加该权限前连接的账号必须在 OmniSocials 控制面板中重新连接一次(API 会返回 400 错误并指出需要重新连接)。 |
--threads-location-id <id> | 为 Threads 帖子标记位置。使用 locations:search --platform threads 获取 Threads 位置 ID(不是 Facebook Place ID;切勿重复使用 --location-id 的值)。在多帖线程中,标记会添加到第一条帖子。对于 posts:update,传入字面值 null 可移除标记。正在逐步推出:需要 Threads 位置权限(threads_location_tagging),Meta 尚未批准该权限;在此之前,API 会返回 400 错误,说明位置标记功能尚不可用。启用后,较早连接的账号必须在 OmniSocials 控制面板中重新连接一次。 |
链接预览(LinkedIn / Facebook)
| 标志 | 描述 |
|---|---|
--link-url | 要作为链接预览卡片附加的网址 |
--link-title | 覆盖预览标题 |
--link-description | 覆盖预览描述 |
--link-thumbnail-url | 覆盖预览缩略图 |
Instagram 位置标记和用户标记
| 标志 | 描述 |
|---|---|
--location-id | 要标记的 Facebook Place ID(使用 locations:search 查找) |
--collaborators | 最多 3 个受邀共同署名的公开 Instagram 用户名(以逗号分隔) |
--user-tags | 照片标记的 JSON 数组:[{"username":"name","x":0.5,"y":0.5,"image_index":0}](x/y 的取值为 0–1,以左上角为原点) |
按平台设置媒体
所有平台可以使用相同的媒体,也可以按平台使用不同的媒体:
所有平台使用相同的媒体:
./scripts/omnisocials.js posts:create --text "..." --channels <ig>,<li> --media-urls "https://example.com/photo.jpg"
按平台使用不同的媒体(使用 --json 标志并直接调用 API 来设置各平台的媒体对象):
API 支持将 media_urls 设为对象:{ "default": ["url1"], "instagram": ["url2"], "pinterest": ["url3"] }。对于没有对应键的平台,default 键是回退值。传入空数组即可让某个平台不使用媒体。
**按频道设置图片适配方式(--media-fit):**如果动态图片的宽高比不在频道可不裁切显示的范围内,系统会按频道裁切图片或保留原图。--media-fit instagram=keep,pinterest=crop 可设置此选项(格式为 <channel>=<auto|crop|keep>,以逗号分隔;作为顶层 media_fit 对象发送)。默认值(auto):Instagram 会围绕图片的焦点将 9:16 图片裁切为 4:5(宽图则裁切为 1.91:1),因为 Instagram 无论如何都会将图片裁切至此范围,而且 Meta 无法推广宽高比超出 4:5 至 1.91:1 范围的动态;Pinterest 会保留高于 2:3 的 Pin,并提示主页动态可能会裁切图片(pinterest=crop 会裁切至 2:3)。裁切后生成的文件仅供对应频道使用;default 和所有其他频道仍使用原图。此设置仅适用于动态:不会处理快拍、Reels、TikTok 照片和视频;X、LinkedIn、Mastodon 和 Google Business 会完整显示高图,因此无需设置规则。在 posts:create、posts:create-and-publish 和 posts:update 执行后,每项决策都会以 [image_fit] 警告的形式打印(操作为 cropped,并附裁切后的 URL;kept;或 crop_failed,表示发送了原图,由平台自行裁切);--json 会在 data 旁提供相同的 warnings 数组。单独执行 posts:update <id> --media-fit instagram=keep 会重新处理已存储的图片并恢复原图;posts:get --json 会在频道的媒体项中显示 fit 和 crop: { of, id, ratio, focus }。焦点只能在控制面板中设置;如需自行裁切,请通过按平台设置的 media_urls 对象(见上文)为该频道传入不同的文件。请先使用 media:check --media-id <id> 检查(见 Media)。
**通过 URL 发布 PDF:**通过 --media-urls(或 API 中的 media_urls)传入 PDF 后,系统会将其栅格化为每页一张图片幻灯片(最多 20 页,按顺序排列),并保留原文件——在 LinkedIn 上会将原始 PDF 制作为可滑动的文档发布,在其他平台上则会作为图片轮播发布。其行为与通过 media:upload 上传 PDF 相同。
**替代文本(无障碍描述):**任何 media_urls 条目都可以是对象 { "url": "...", "alt": "..." }(任何 media_ids 条目也可以是 { "id": "...", "alt": "..." },包括帖子串各部分的媒体),而非单独的字符串;最多 1500 个字符。替代文本会发送至 Mastodon(媒体描述——Mastodon 社区非常重视替代文本)、Bluesky(嵌入内容替代文本)、X(仅照片/GIF,限制为 1000 个字符)、Pinterest(作为 pinterest.alt_text 的回退值)、Instagram(图片动态和轮播图片幻灯片的 alt_text;不适用于 Reels/快拍;限制为 1000 个字符)、LinkedIn(仅图片的 altText,适用于单张和多张图片;不适用于视频/文档)以及 Threads(每张图片和每个视频的 alt_text,包括轮播项目和帖子串各部分);其他平台会忽略此项。--media-urls 标志仅接受 URL 字符串,因此如需传入替代文本条目,请直接调用 API,例如发布 Mastodon 帖子:{"content": {"default": "Morning ride 🐘"}, "accounts": ["<mastodon_id>"], "media_urls": [{"url": "https://example.com/bike.jpg", "alt": "A red bicycle leaning against a brick wall"}]}。posts:get --json 会读取每个媒体项的替代文本。
示例
列出已连接的账号
./scripts/omnisocials.js accounts:list
在 LinkedIn 和 X 发布文字动态
./scripts/omnisocials.js posts:create --text "Excited to announce our new feature!" --channels <linkedin_id>,<x_id>
创建带封面图片的 Instagram Reel
./scripts/omnisocials.js posts:create --text "Check this out" --channels <instagram_id> --type reel --media-urls "https://example.com/video.mp4" --instagram-share-to-feed --instagram-cover-url "https://example.com/cover.jpg"
发布带主题标签且在自动首条评论中附链接的 Reel
./scripts/omnisocials.js posts:create --text "New drop is live" --channels <instagram_id> --type reel --media-urls "https://example.com/reel.mp4" --instagram-first-comment "#reels #newdrop #marketing
link: https://example.com/shop"
将动态安排在下周发布
./scripts/omnisocials.js posts:create --text "Happy Monday!" --channels <id1>,<id2> --schedule "2026-04-13T09:00:00Z"
创建 Pinterest Pin
./scripts/omnisocials.js posts:create --text "Beautiful design inspiration" --channels <pinterest_id> --media-urls "https://example.com/pin.jpg" --pinterest-board-id <board_id> --pinterest-title "Design Inspiration" --pinterest-link "https://example.com"
在 Pinterest 图钉上标记商品
./scripts/omnisocials.js pinterest:products
# Returns: pin_id: 813744226420795884 Blue ribbed top (24.99 EUR, IN_STOCK, item TOP-BLUE-M)
# Optional: check one Pin ID or Pin link first with pinterest:validate 813744226420795884
./scripts/omnisocials.js posts:create --text "Autumn outfit" --channels <pinterest_id> --media-urls "https://example.com/outfit.jpg" --pinterest-board-id <board_id> --pinterest-product-tags 813744226420795884,813744226420795885
每个 Pin 最多可标记 24 件商品,且只能标记已连接的 Pinterest 账号中的商品。Pinterest 拒绝某件商品不会导致帖子发布失败:发布后,posts:list 会打印 Pinterest products: 1 of 2 tagged (skipped: <pin_id> <reason>)。
向所有评论特定关键词的人发送私信(评论转私信)
# A new post with its automation (Instagram must be in --channels). Confirm the DM text and the keyword with the user first
./scripts/omnisocials.js posts:create --text "Comment GUIDE for the free checklist" --channels <instagram_id> --media-urls "https://example.com/photo.jpg" --schedule "2026-10-12T09:00:00Z" --dm-keywords "guide" --dm-message "Here is the checklist: https://example.com/guide" --dm-reply "Sent you a DM!"
# Prints: Comment-to-DM: on (keywords: guide; id 100000006). It starts listening once the post is live on Instagram
# An automation on a post that exists (posts:list for the id; a post published outside OmniSocials takes --instagram-media-id)
./scripts/omnisocials.js automations:create --post-id 83778183 --keywords "guide,link" --dm "Here is the guide: https://example.com/guide" --reply "Sent you a DM!" --reply "Check your inbox" --max-sends 500
# What happened: who commented, who got the DM, and why someone was skipped
./scripts/omnisocials.js automations:events 100000004
# Prints: Counts: 12 sent, 3 skipped, then one line per event:
# 2026-10-10T21:40:00.000Z comment sent @jane "guide please" DM: "Here is the guide: ..."
使用 automations:update <id> --pause 暂停自动化,使用 --keywords "<full list>" 更改关键词,使用 posts:update <post_id> --no-dm 移除帖子的自动化。API 密钥需要启用可选的 automations:read / automations:write 权限范围。
上传媒体并用它创建帖子
./scripts/omnisocials.js media:upload --url "https://example.com/photo.jpg"
# Returns: ID: media_abc123
./scripts/omnisocials.js posts:create --text "New photo!" --channels <id> --media-ids media_abc123
创建 YouTube Short
./scripts/omnisocials.js posts:create --text "Quick tip" --channels <youtube_id> --type reel --media-urls "https://example.com/short.mp4" --youtube-title "Quick Tip #1" --youtube-privacy public --youtube-tags "tips,tutorial"
创建 TikTok 视频
./scripts/omnisocials.js posts:create --text "Watch this" --channels <tiktok_id> --type reel --media-urls "https://example.com/video.mp4" --tiktok-privacy PUBLIC_TO_EVERYONE
发布 X 线程
./scripts/omnisocials.js posts:create --text "Kicking off a thread" --channels <x_id> --x-thread "First point || Second point || Wrapping up"
发布 Bluesky 线程
./scripts/omnisocials.js posts:create --channels <bluesky_id> --bluesky-thread "First point || Second point || Wrapping up"
发布 Mastodon 线程
./scripts/omnisocials.js posts:create --channels <mastodon_id> --mastodon-thread "First point || Second point || Wrapping up"
发布 Threads 线程
./scripts/omnisocials.js posts:create --channels <threads_id> --threads-thread "First point || Second point || Wrapping up"
标记 Instagram 地点
./scripts/omnisocials.js locations:search "Blue Bottle Coffee"
# Returns: location_id: 1234567890 Blue Bottle Coffee — 1 Ferry Building, San Francisco
./scripts/omnisocials.js posts:create --text "Coffee time" --channels <instagram_id> --media-urls "https://example.com/photo.jpg" --location-id 1234567890
标记 Threads 地点(逐步推出)
./scripts/omnisocials.js locations:search "Griffith Observatory" --platform threads
# Returns: threads.location_id: 17841400000000000 Griffith Observatory (2800 E Observatory Rd, Los Angeles, United States)
# Coordinates also work: locations:search --platform threads --latitude 34.1184 --longitude -118.3004
./scripts/omnisocials.js posts:create --text "Best view in the city" --channels <threads_id> --threads-location-id 17841400000000000
将本地文件上传到文件夹
./scripts/omnisocials.js folders:create --name "Summer Campaign"
# Returns: ID: 42
./scripts/omnisocials.js media:upload-base64 --file ./promo.jpg --name "summer-hero" --folder-id 42
批量获取多篇帖子的分析数据(一次请求)
./scripts/omnisocials.js analytics:posts 1024,1025,1026
分类处理社交收件箱并回复
./scripts/omnisocials.js inbox:list --unread --platform instagram
# Returns each conversation with its Conversation: <conversation_id>
./scripts/omnisocials.js inbox:list --unanswered
# Only the conversations still waiting for a reply
./scripts/omnisocials.js inbox:messages "<conversation_id>"
# Comment threads print the post (caption, url, thumbnail) first; every message prints its id
./scripts/omnisocials.js inbox:reply "<conversation_id>" --text "Thanks so much for the kind words!" --message-id "<message_id>"
# --message-id = the id of the comment being answered (all comments on a post share one
# conversation; without it the reply goes under the newest comment); leave it out on a DM
./scripts/omnisocials.js inbox:read "<conversation_id>"
# Hide a comment on your own post (Facebook, Instagram, TikTok, YouTube, Threads),
# using the message id printed by inbox:messages or inbox:next (not the conversation id)
./scripts/omnisocials.js inbox:hide "<message_id>"
./scripts/omnisocials.js inbox:hide "<message_id>" --unhide
# Delete a comment for good (Facebook, Instagram, TikTok; cannot be undone, confirm with the user first)
./scripts/omnisocials.js inbox:delete "<message_id>"
回复所有待处理内容(inbox:next 循环)
./scripts/omnisocials.js inbox:next
# Prints the next unanswered item (DMs that can still be answered first, then Instagram/Facebook
# DMs whose 24-hour window has closed, then comments oldest first): the conversation id, the
# message id to answer, its reply window, the post it is on, the thread oldest first, and
# "N more waiting"
# Reply and get the next item in the same call; repeat until the CLI prints
# "Nothing is waiting for an answer." On a comment or mention always pass --message-id
# with the "Message to answer" id; leave it out on a DM
./scripts/omnisocials.js inbox:reply "<conversation_id>" --text "Sent you a DM with the details!" --message-id "<message_id>" --next
# Skip one for good (marking it read means inbox:next will not serve it again). Also how to
# skip an Instagram/Facebook DM whose reply window is closed ("Reply window closed ..." in the
# output): the API cannot answer it, so reply from the app (that clears it too) or mark it read
./scripts/omnisocials.js inbox:read "<conversation_id>"
# Skip some for this call only
./scripts/omnisocials.js inbox:next --exclude "<conversation_id>,<conversation_id>"
# Narrow the queue, or also take items that were read but never answered
./scripts/omnisocials.js inbox:next --platform instagram --type comment
./scripts/omnisocials.js inbox:next --include-read --order newest
审核全新工作区中已有的内容(尚未通过 OmniSocials 发布过内容)
./scripts/omnisocials.js posts:recent-platform --limit 25
./scripts/omnisocials.js posts:recent-platform --platforms instagram,tiktok --json
发布到 LinkedIn 公司主页
./scripts/omnisocials.js posts:create --text "Company update" --channels linkedin_page
以 JSON 格式查看已安排的帖子
./scripts/omnisocials.js posts:list --status scheduled --json
获取过去 30 天的分析数据
./scripts/omnisocials.js analytics:overview --period 30d
获取指定日期范围的分析数据
./scripts/omnisocials.js analytics:overview --start-date 2026-03-01 --end-date 2026-03-31
查明帖子被拒绝的原因,或当前在等待谁审核
./scripts/omnisocials.js posts:list --status rejected
./scripts/omnisocials.js posts:approval 123456
会打印 Rejected by: Jordan on step 2、Reason: ...、包含审批人的每个步骤,以及审核者的评论。对于仍在审核中的帖子(posts:list --status in_approval),同一命令会打印 Waiting on: step 2 (Client approval): Jordan。编辑帖子或创建新帖子之前,请先告知用户审核意见。
创建用于帖子通知的 Webhook
./scripts/omnisocials.js webhooks:create --url "https://yoursite.com/webhook" --events post.published,post.failed
设置(交互式)
./scripts/omnisocials.js setup
设置(非交互式)
./scripts/omnisocials.js setup --api-key omsk_live_xxx --global
错误处理
常见错误
| 错误 | 原因 | 解决方法 |
|---|---|---|
API key not found | 未配置 API 密钥 | 运行 setup 或设置 OMNISOCIALS_API_KEY |
unauthorized / invalid_api_key | API 密钥无效或已过期 | 在 Settings > API 中检查密钥 |
insufficient_scope | API 密钥缺少所需权限范围 | 创建具有所需权限范围的新密钥。对于 automations:* 或 --dm-* 帖子标志:Automations 是密钥的可选功能,请在 Settings > API 中启用(会添加 automations:read 和 automations:write) |
rate_limit_exceeded | 请求过多(限制为 100 次/分钟) | 等待重置时间后重试 |
validation_error | 缺少必填字段或数据无效 | 检查平台所需的媒体/字段 |
not_found | 资源不存在 | 确认 ID 正确 |
max_retries_reached | 此帖子在某个平台上的重试已达到 3 次上限,且仍然失败 | 使用 posts:create 重新创建帖子 |
pinterest_not_connected | 在未关联 Pinterest 账号的工作区中使用了 pinterest:products | 请用户在控制面板中关联 Pinterest |
pinterest_catalog_access_required | 在无目录访问权限的连接上使用了 pinterest:products --source catalog | 请用户关联目录(composer、Pinterest 选项、Add products、Connect catalog),或运行 pinterest:products --source pins |
automation_exists | 帖子已有关联的评论转私信自动化(每篇帖子只能有一个) | 使用 automations:update <id> 更改(CLI 会打印 ID),或先删除现有自动化 |
post_required / post_not_instagram | 在未指定 --post-id / --instagram-media-id 的情况下,为不包含 Instagram 的帖子创建评论自动化 | 传入渠道中包含 Instagram 的帖子,或使用 --scope next_post / --scope any |
instagram_not_connected / instagram_needs_reauth | 工作区中没有 Instagram 账号,或其连接已过期 | 请用户在控制面板中关联 Instagram 或重新关联 |
速率限制
每个 API 密钥每分钟最多可发起 100 次请求。响应头包括:
X-RateLimit-Limit:每个时间窗口的最大请求数X-RateLimit-Remaining:剩余请求数X-RateLimit-Reset:时间窗口重置时的 Unix 时间戳
提示
- 始终先运行
accounts:list,以发现频道 ID 和平台功能 - 需要以编程方式解析输出时,使用
--json - 检查内容类型:使用
accounts:list查看每个账号支持哪些内容类型(帖子、快拍、Reel) - Pinterest 画板:运行
accounts:get <pinterest_id>,查看可用画板及其 ID - Pinterest 商品标签:运行
pinterest:products,获取可用于--pinterest-product-tags的商品 Pin ID(最多 24 个,且仅限自己的商品 Pin) - 评论转私信:通过帖子创建的自动化(
--dm-keywords+--dm-message)会在帖子于 Instagram 上线后启动;automations:events <id>会显示其回复或跳过的每条评论 - 定时发布:日期使用 ISO 8601 格式(例如,
2026-04-10T14:00:00Z) - 媒体上传:支持 JPEG、PNG、GIF、WebP 图片以及 MP4、MOV、AVI 视频(最大 50 MB)
- 先保存为草稿:不确定时,先创建草稿(不使用
--schedule),检查后再用posts:publish发布。如需提议发布时间但暂不发布,请将--schedule与--draft一起使用(创建计划草稿),并让用户通过posts:update <id> --no-draft确认