mcpField
B
buffer

buffer

github.com/dgalarza营销与增长6342 次安装1 周前更新
代码仓库

关于 buffer

用于通过 Buffer 的 GraphQL API 管理社交媒体内容的技能,涵盖组织与频道查询、帖子和串文排期,以及保存创意。

主要功能

  1. 01列出组织和频道
  2. 02筛选并分页查看帖子
  3. 03创建并排期文本或图片帖子
  4. 04排期 Twitter/X 串文
  5. 05保存创意并编辑已排期帖子

适用场景

  1. 01查看某组织的已排期帖子
  2. 02为社交频道添加待发布帖子
  3. 03排期 Twitter/X 串文
  4. 04保存社交内容创意以供后续使用

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dgalarza/agent-skills --skill buffer

安装后在 Claude Code 中输入/buffer确认已加载。

附带文件references/api-reference.md

详细介绍

Buffer 社交媒体排期

设置

需要设置 BUFFER_API_TOKEN 环境变量。请在此生成令牌: https://publish.buffer.com/settings/api

发起 API 调用前,请确认令牌已设置:

if [ -z "$BUFFER_API_TOKEN" ]; then
  echo "Error: BUFFER_API_TOKEN is not set. Get your token at https://publish.buffer.com/settings/api"
  exit 1
fi

API 配置

  • 端点: https://api.buffer.com
  • 方法: POST(所有请求均为 GraphQL)
  • Content-Type: application/json
  • 身份验证: Authorization: Bearer $BUFFER_API_TOKEN
  • User-Agent: Mozilla/5.0 — 必须设置,以避免 Cloudflare 返回 403 错误
Curl 模板

所有 API 调用都遵循此模式:

curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d '{"query": "<GRAPHQL_QUERY>", "variables": <VARIABLES_JSON>}'

始终通过 jq 管道处理,以便输出易于阅读。使用 jq -e 检测错误。

重要: 对于包含 GraphQL 变量(例如 $input)的查询,即使在单引号内,Shell 也可能会展开 $input。请使用临时文件并通过 -d @file 传入,以避免此问题:

cat > /tmp/buffer_payload.json << 'EOF'
{"query": "<GRAPHQL_QUERY>", "variables": <VARIABLES_JSON>}
EOF

curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d @/tmp/buffer_payload.json | jq .

不含变量的简单查询可以直接使用内联 -d。

模式检测

解析用户的意图,以确定要执行的操作:

意图模式示例
列出组织organizations“显示我的 Buffer 组织”
列出频道channels“我有哪些频道?”
查看帖子posts“显示我已排期的帖子”
创建文本帖子create-post“安排一条内容为……的推文”
创建 Twitter/X 话题串create-thread“在 X 上发布一个话题串……”
创建图片帖子create-post“将这张图片发布到 Instagram”
保存想法create-idea“保存一个关于……的想法”
账户信息account“显示我的 Buffer 账户”

大多数操作都需要 organizationId。如果用户未指定,请先获取组织信息。如果只有一个组织,则自动使用该组织。

模式:获取组织

获取用户的组织信息。这通常是需要进行的第一个调用。

curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d '{"query": "{ account { organizations { id name ownerEmail } } }"}' | jq .

保存响应中的 organizationId,供后续调用使用。

模式:获取频道

列出某个组织的频道(社交媒体账户)。

cat > /tmp/buffer_payload.json << 'EOF'
{"query": "query GetChannels($input: ChannelsInput!) { channels(input: $input) { id name displayName service avatar isQueuePaused } }", "variables": {"input": {"organizationId": "<ORG_ID>"}}}
EOF
curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d @/tmp/buffer_payload.json | jq .

以易于阅读的格式展示结果,包括频道名称、服务(例如 twitter、instagram、linkedin)和队列状态。

模式:获取帖子

查询帖子,并支持筛选、排序和分页。

cat > /tmp/buffer_payload.json << 'EOF'
{"query": "query GetPosts($input: PostsInput!) { posts(input: $input) { edges { node { id text status dueAt sentAt createdAt channelService externalLink } cursor } pageInfo { hasNextPage endCursor } totalCount } }", "variables": {"input": {"organizationId": "<ORG_ID>", "filter": {"status": "scheduled"}, "sort": {"field": "dueAt", "direction": "desc"}}}}
EOF
curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d @/tmp/buffer_payload.json | jq .

可用的筛选字段(status、channelIds、日期范围)、排序选项和分页详情,请参阅 references/api-reference.md。

模式:创建文本帖子

创建并排期一条文本帖子。

cat > /tmp/buffer_payload.json << 'EOF'
{"query": "mutation CreatePost($input: CreatePostInput!) { createPost(input: $input) { ... on PostActionSuccess { post { id text status dueAt } } ... on MutationError { message } } }", "variables": {"input": {"channelId": "<CHANNEL_ID>", "text": "<POST_CONTENT>", "schedulingType": "automatic", "mode": "addToQueue"}}}
EOF
curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d @/tmp/buffer_payload.json | jq .
必填字段
  • channelId(String!):要发布到的频道
  • text(String!):帖子内容
排期选项
  • schedulingType:automatic(由 Buffer 选择时间)或 notification(发送提醒)
  • mode:控制帖子的发布时间。实际的 GraphQL 枚举为 ShareMode,只有四个值:addToQueue、shareNow、shareNext、customScheduled(注意末尾有 d,不是 customSchedule)。没有 recommendedTime 这个值;如果在任何地方看到相关引用,那就是错误的。如有疑问,请通过架构内省确认:__type(name: "ShareMode") { enumValues { name } }。
  • dueAt(String):ISO 8601 日期时间;当 mode 为 customScheduled 时必填。示例:"2026-03-15T14:00:00Z"

完整的字段定义和枚举值,请参阅 references/api-reference.md。

响应处理

该变更操作会返回联合类型。请始终检查成功和错误两种情况:

# Check if the response contains an error
result=$(curl -s -X POST https://api.buffer.com -H "User-Agent: Mozilla/5.0" ...)
echo "$result" | jq -e '.data.createPost.message' > /dev/null 2>&1 && {
  echo "Error: $(echo "$result" | jq -r '.data.createPost.message')"
} || {
  echo "$result" | jq '.data.createPost.post'
}

提及 LinkedIn 页面(公司/展示页)

如需在预定帖子中 @提及 LinkedIn 公司或展示页,请将该页面的完整 LinkedIn URL 直接粘贴到帖子 text 中。发布时,LinkedIn 会将已识别的公司/展示页 URL 转换为正式的 @提及标签——无需查找组织 ID 或构建注释负载。

示例:

https://www.linkedin.com/company/<slug>
https://www.linkedin.com/showcase/<slug>

已确认可用的示例:https://www.linkedin.com/showcase/docusigndevs(Docusign Developers 展示页)。

**底层机制(很少需要):**架构确实提供了 metadata.linkedin.annotations(类型为 AnnotationInputLinkedIn),可将 text 中的确切子字符串(start、length)标记为提及,并关联显式的 id/entity(LinkedIn 组织 URN)、link、localizedName 和 vanityName。Buffer 自带的撰写器可能就是通过这种方式实现提及选择器的。此 API 没有公开查询可将页面 URL 或 vanity name 解析为组织 URN,因此仅凭此 API 自行构建此负载并不实用——将页面 URL 粘贴到 text 中是可靠的方法。

模式:创建 Twitter/X 主题串

Twitter/X 主题串通过 createPost mutation 上的 metadata.twitter.thread 字段创建。主题串是一个 ThreadedPostInput 对象数组,每个对象都有一个 text 字段(以及可选的 assets)。

**重要:**主题串中的第一条推文必须包含在 thread 数组中。顶层 text 字段也必填,但 Buffer 使用主题串数组在其界面中呈现所有推文。请在这两个位置都填写第一条推文的相同文本。

cat > /tmp/buffer_payload.json << 'EOF'
{"query": "mutation CreatePost($input: CreatePostInput!) { createPost(input: $input) { ... on PostActionSuccess { post { id text status dueAt } } ... on MutationError { message } } }", "variables": {"input": {"channelId": "<CHANNEL_ID>", "text": "<FIRST_TWEET_TEXT>", "schedulingType": "automatic", "mode": "addToQueue", "metadata": {"twitter": {"thread": [{"text": "<FIRST_TWEET_TEXT>"}, {"text": "<SECOND_TWEET_TEXT>"}, {"text": "<THIRD_TWEET_TEXT>"}]}}}}}
EOF
curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d @/tmp/buffer_payload.json | jq .
主题串结构
  • 顶层 text:必填。使用第一条推文的文本。
  • metadata.twitter.thread:ThreadedPostInput 对象数组。每个对象包含:
    • text(String):推文内容
    • assets(AssetsInput,可选):该条推文的图片
  • thread 数组中的第一项应与顶层 text 一致(这是 Buffer 显示为第 1 条推文的内容)。
  • 后续所有项都会成为主题串中的回复推文。
主题串提示
  • 主题串中的每条推文都必须符合 Twitter 的字符限制(280 个字符)。
  • 主题串作为一个整体进行排期,并一次性发布。
  • 可通过每个 ThreadedPostInput 上的 assets 字段为单条推文附加图片。

模式:创建图片帖子

与文本帖子相同,但需包含带图片 URL 的 assets 字段。

cat > /tmp/buffer_payload.json << 'EOF'
{"query": "mutation CreatePost($input: CreatePostInput!) { createPost(input: $input) { ... on PostActionSuccess { post { id text status dueAt } } ... on MutationError { message } } }", "variables": {"input": {"channelId": "<CHANNEL_ID>", "text": "<POST_CONTENT>", "schedulingType": "automatic", "mode": "addToQueue", "assets": {"images": [{"url": "<IMAGE_URL>"}]}}}}
EOF
curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d @/tmp/buffer_payload.json | jq .

图片必须是可公开访问的 URL。可在 images 数组中包含多张图片。

模式:创建想法

保存想法以供日后使用。

cat > /tmp/buffer_payload.json << 'EOF'
{"query": "mutation CreateIdea($input: CreateIdeaInput!) { createIdea(input: $input) { ... on Idea { id content { title text services } } } }", "variables": {"input": {"organizationId": "<ORG_ID>", "content": {"title": "<IDEA_TITLE>", "text": "<IDEA_BODY>", "services": ["twitter", "linkedin"]}}}}
EOF
curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d @/tmp/buffer_payload.json | jq .

IdeaContentInput 字段详情(title、text、services、tags)请参阅 references/api-reference.md。

**注意:**标签必须是包含 id 和 color 字段的现有标签对象——使用前请先获取现有标签。

模式:获取账户

**注意:**使用标准 API 令牌权限范围时,完整账户查询(id、name、email、timezone)会失败。请改用 Get Organizations 确认账户身份。

curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d '{"query": "{ account { organizations { id name ownerEmail } } }"}' | jq .

模式:编辑现有帖子

使用 editPost mutation 更新已排期的帖子(例如,在链接可用后添加 LinkedIn 首条评论中的实际链接)。

cat > /tmp/buffer_payload.json << 'EOF'
{"query": "mutation EditPost($input: EditPostInput!) { editPost(input: $input) { ... on PostActionSuccess { post { id status dueAt channelService } } ... on MutationError { message } } }", "variables": {"input": {"id": "<POST_ID>", "text": "<FULL_POST_TEXT_AGAIN>", "metadata": {"linkedin": {"firstComment": "<COMMENT_TEXT>"}}}}}
EOF
curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d @/tmp/buffer_payload.json | jq .

**注意事项:**即使 EditPostInput 中的 text 是可选的,且你并不打算更改它,editPost 也会拒绝未同时发送 text 的请求(即仅发送 metadata 或其他字段的请求),并报错:"Invalid post: Post must have either text or media." 无论实际要更新什么字段,都请始终重新发送完整的现有 text。

常见工作流

安排帖子

当用户想要安排帖子时,采用以下多步工作流:

  1. 获取组织 → 提取 organizationId
  2. 获取渠道 → 显示可用渠道,让用户选择(或按服务名称匹配)
  3. 创建帖子 → 使用选定的 channelId 和帖子内容

如果用户指定了服务(例如“发布到 Twitter”),请将其与渠道的 service 字段进行匹配。

查看队列
  1. 获取组织 → 提取 organizationId
  2. 使用 filter: { status: "scheduled" } 和 sort: { field: "dueAt", direction: "asc" } 获取帖子
  3. 按日期分组显示帖子,并附上渠道信息
集思广益并保存想法
  1. 获取组织 → 提取 organizationId
  2. 帮助用户起草想法内容
  3. 使用标题、文本、标签和目标服务创建想法

Schema 检查

在尝试执行变更或查询不确定的字段之前,请先检查 Schema。不要猜测——API 可用范围有限。

列出所有可用的变更:

curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d '{"query": "{ __schema { mutationType { fields { name } } } }"}' | jq '[.data.__schema.mutationType.fields[].name]'

列出所有可用的查询:

curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d '{"query": "{ __schema { queryType { fields { name } } } }"}' | jq '[.data.__schema.queryType.fields[].name]'

检查特定类型上的字段:

curl -s -X POST https://api.buffer.com \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BUFFER_API_TOKEN" \
  -H "User-Agent: Mozilla/5.0" \
  -d '{"query": "{ __type(name: \"<TYPE_NAME>\") { fields { name type { name kind } } } }"}' | jq '.data.__type.fields[]'

错误处理

GraphQL 错误

检查每个响应顶层的 errors 数组:

result=$(curl -s -X POST https://api.buffer.com ...)
errors=$(echo "$result" | jq -r '.errors // empty')
if [ -n "$errors" ]; then
  echo "GraphQL Error:"
  echo "$result" | jq '.errors[].message'
  exit 1
fi
变更错误

变更会返回联合类型。务必处理 MutationError 变体:

{
  "data": {
    "createPost": {
      "message": "Validation failed: text is required"
    }
  }
}
常见问题
  • 403 Forbidden(错误代码 1010):Cloudflare 正在拦截请求。每次调用 curl 时都必须包含 -H "User-Agent: Mozilla/5.0"。
  • 401 Unauthorized:令牌无效或已过期。请在 https://publish.buffer.com/settings/api 重新生成令牌。
  • 缺少 organizationId:大多数查询都需要组织 ID。请先获取组织。
  • 无效的 channelId:请确认该渠道存在且属于当前组织。
  • dueAt 已过期:使用 customScheduled 时,dueAt 必须设置为未来时间。

评论

支持 Markdown