AutoGPT 平台 Ayrshare「Post To Bluesky」块:从源码到工作流的完整发布指南
本指南以 AutoGPT 平台(autogpt_platform)的 Ayrshare 社交发布块为核心,讲解如何借助 Ayrshare 的统一社交 API,在 AutoGPT 的可视化工作流中把文本、图片与视频一键发布到 Bluesky。读完本文,你将掌握该块的每个输入输出参数与默认值、底层凭据与认证机制、平台规则校验逻辑、按内容类型计费的成本模型,以及跨平台分发、定时发布等典型落地用法。
该块对应的官方说明文档为 post_to_bluesky.md,完整实现位于 post_to_bluesky.py,是 backend/blocks/ayrshare/ 目录下 Ayrshare 家族块(Facebook、X/Twitter、LinkedIn、Instagram、YouTube、Reddit、Telegram、Threads、TikTok 等)中的一员,注册的 Block ID 为 cbd52c2a-06d2-43ed-9560-6576cc163283(见 init.py)。
该块是什么
PostToBlueskyBlock 是一个用于向 Bluesky 发布内容的块(Block),其定位一句话即可概括:Post to Bluesky using Ayrshare。
- 所属分类:
SOCIAL(社交类) - 类型:
BlockType.AYRSHARE - 描述(源码类 docstring):"Block for posting to Bluesky with Bluesky-specific options.",即它是面向 Bluesky 做了平台特有约束与选项封装的发布块。
- 注册状态:源码中该块以
disabled=True初始化(post_to_bluesky.py),说明它默认以禁用形态注册,实际部署中需要在块列表中启用后才会出现在构建器中,使用前请确认所在环境的块启用配置。
相比同一目录下的其他平台块,它的差异点集中在三处:将正文长度限制在 Bluesky 的 300 字符以内、将媒体数量限制为 最多 4 张图片或 1 个视频、额外提供了媒体无障碍说明 alt text(无障碍替代文本)这一 Bluesky 特有选项。
工作原理
该块的运行链路清晰分为四层,全部依赖 Ayrshare 作为发布代理:
- 凭据就绪:块通过
credentials字段(类型CredentialsMetaInput)拿到当前用户的 Ayrshare 个人 Profile Key,而不是组织级 API Key。AutoGPT 会以托管(managed)方式为每个用户自动发放该凭据,用户无需手动创建;之后用户仍需通过构建器(Builder)中弹出的 Ayrshare SSO 窗口,把自己要使用的社交账号(如 Bluesky)逐个授权关联到该 Profile 上(见 _config.py 与 managed_providers/ayrshare.py 的模块注释)。 - 构造客户端:块调用
create_ayrshare_client()(见 _util.py)。若服务端未配置AYRSHARE_API_KEY,会捕获MissingConfigError并直接yield "error", "Ayrshare integration is not configured. Please set up the AYRSHARE_API_KEY.",块的运行即告失败。 - 本地校验:
run()在真正请求上游前先做两条 Bluesky 平台规则校验(下文详述),不合法时立刻产出 error 输出并return,不会消耗一次真实发布调用。 - 调用统一 API:把输入字段翻译成 Ayrshare
/api/post的载荷,请求头Profile-Key携带用户 profile key,platforms固定为["bluesky"](SocialPlatform.BLUESKY枚举值)。Ayrshare 收到后负责把内容转投给 Bluesky,成功后把各平台的 post id、状态与链接返回给块。
底层客户端封装在 integrations/ayrshare.py:AyrshareClient 以 https://api.ayrshare.com/api/post 为端点,用 Authorization: Bearer <org API Key> 标识应用本身,再用 Profile-Key 头区分“以哪个用户/哪个 Profile 的身份发布”。所有 HTTP 调用均由项目统一的 Requests 工具执行,且关闭了 raise_for_status,改为解析 Ayrshare 返回的 status 信封并抛出带原始错误消息的 AyrshareAPIException,从而把“Twitter is not linked”“Missing post parameter”这类可读信息原样透传给下游,而不是一个笼统的 HTTP 错误码(详见该文件 _extract_error_message 对三种错误形态的兼容处理)。
托管凭据体系(进阶原理)
值得单独说明的是凭据这套设计。AutoGPT 里除 AYRSHARE_API_KEY(组织级管理员 Key)与 AYRSHARE_JWT_KEY(SSO 签名用)两个环境变量外,还存在每个用户一份的 profile key:
- managed_providers/ayrshare.py 中
AyrshareManagedProvider负责在用户触发 SSO 流程时,用组织 Key 调用 Ayrsharecreate_profile接口创建专属 profile,把返回的profileKey以APIKeyCredentials(provider="ayrshare", is_managed=True)存入该用户凭据列表; - provider 显式设置了
auto_provision = False,即不会在后台无差别地为所有用户预建 profile——因为每个 Ayrshare profile 都会占用组织 Ayrshare 订阅配额,故采用“用户需要时再按需开通”的策略; - 兼容历史数据:若发现旧版旁路字段
managed_credentials.ayrshare_profile_key已有值,会优先复用该旧 key,保证已关联的社交账号继续可用,并在托管凭据持久化成功后才清理旧字段(失败则保留以便重试复用)。
这一点之所以重要,是因为它解释了“块为什么能一键授权多个社交账号”以及“为什么需要先在构建器里完成一次 SSO 授权才能发布”的体验来源。对应行为有完整单元测试覆盖,见 managed_providers/ayrshare_test.py(含 test_is_available_true_when_secrets_set、test_auto_provision_opt_out、test_reuses_legacy_key_without_clearing、test_post_provision_clears_populated_legacy_field 等用例)。
输入参数详解
文档给出的输入表如下(其 Required 列均为 No,即全部为可选输入):
| Input | 说明 | 类型 | Required |
|---|---|---|---|
| post | 要发布的正文文本(Bluesky 上限 300 字符) | str | No |
| media_urls | 可选的媒体 URL 列表。Bluesky 最多支持 4 张图片或 1 个视频 | List[str] | No |
| is_video | 媒体是否为视频。上传视频时设为 True,以便按视频档位计费 | bool | No |
| schedule_date | 定时发布的 UTC 时间(YYYY-MM-DDThh:mm:ssZ) | str (date-time) | No |
| disable_comments | 是否关闭评论 | bool | No |
| shorten_links | 是否缩短链接 | bool | No |
| unsplash | Unsplash 图片配置 | str | No |
| requires_approval | 是否启用审批工作流 | bool | No |
| random_post | 是否生成随机正文 | bool | No |
| random_media_url | 是否生成随机媒体 | bool | No |
| notes | 该条 post 的附加备注 | str | No |
| alt_text | 每条媒体对应的替代文本(无障碍),Bluesky 特有 | List[str] | No |
为了让你在拖拽配置时对每个输入有更精确的把握,下面结合源码补充类型默认值与面板位置(advanced=False 显示在基础区,advanced=True 折叠在高级区):
- post(
str,默认"",基础区):正文。源码在其字段描述中显式标注 "The post text to be published (max 300 characters for Bluesky)"。 - media_urls(
List[str],默认[],基础区):媒体文件的公网 URL 列表,Bluesky 上限为 4 张图片或 1 个视频。若上传视频还需在高级区把is_video设为 true(_util.py中通用字段描述原话:"Set is_video in advanced settings to true if you want to upload videos.")。 - is_video(
bool,默认false,高级区):置为 true 时按视频计费(影响成本,见下文成本模型)。 - schedule_date(
Optional[datetime],默认None,高级区):定时发布时间,格式为YYYY-MM-DDThh:mm:ssZ(UTC)。源码在发送前会执行input_data.schedule_date.isoformat()将其转成 ISO 8601 字符串再放入请求。 - disable_comments(
bool,默认false,高级区):对支持评论的平台关闭评论。 - shorten_links(
bool,默认false,高级区):开启后 Ayrshare 会对正文中的链接做短链处理。 - unsplash(
Optional[str],默认None,高级区):透传给 Ayrshare 的 Unsplash 配图指令字符串(对应上游 API 的unsplash字段)。 - requires_approval(
bool,默认false,高级区):开启后发布进入审批流,而不是即时直发(对应上游requiresApproval参数)。 - random_post(
bool,默认false,高级区):由 Ayrshare 生成随机正文(对应randomPost)。 - random_media_url(
bool,默认false,高级区):由 Ayrshare 随机挑选媒体 URL(对应randomMediaUrl)。 - notes(
Optional[str],默认None,高级区):随请求上送的备注,方便在 Ayrshare 后台定位该条记录(对应notes)。 - alt_text(
List[str],默认[],高级区,Bluesky 专属):按顺序为media_urls中每条媒体提供的无障碍替代文本。块会将其包装成blueskyOptions = {"altText": [...]}传递给 Ayrshare 的 Bluesky 选项(上游接口blueskyOptions字段),这是该块与通用 Ayrshare 基础输入最实质性的差异之一。
注意:块本身不承接任何额外文本字段(如 hashtag、首条评论、自动排程等)——同一
create_post客户端虽支持autoSchedule、autoRepost、autoHashtag、firstComment等能力(见 integrations/ayrshare.py 的create_post全量签名),但当前块只把上面表格列出的字段暴露给用户,其余能力不在此块范围。
Bluesky 平台规则:本地的两道硬校验
虽然所有输入都是可选的,但 run() 在执行发布前会基于 Bluesky 的平台约束做两层本地校验,任何一条不满足都会立即以 error 输出结束,不会产生对 Ayrshare 的请求(因此也不产生计费消耗):
- 正文长度 ≤ 300 字符:
错误信息会带上当前实际字符数,便于你据此裁剪文案。if len(input_data.post) > 300: yield "error", f"Post text exceeds Bluesky's 300 character limit ({len(input_data.post)} characters)" return - 媒体数量 ≤ 4:
if len(input_data.media_urls) > 4: yield "error", "Bluesky supports a maximum of 4 images or 1 video" return
这两条校验从源码层面印证了文档“text posts (up to 300 characters), images (up to 4), and video content”的能力边界,也让“Bluesky 特有约束”不止停留在文档描述层面,而是真实发生在每次执行路径上。
输出说明
块共声明三类输出:
| Output | 说明 | 类型 |
|---|---|---|
| error | 操作失败时的错误消息 | str |
| post_result | 发布请求的整体结果 | PostResponse |
| post | 单平台发布结果(每发成一个平台产出一次) | PostIds |
结合 integrations/ayrshare.py 的响应模型,可以更精确地理解它们:
- post_result:类型
PostResponse,承载status(如 success/error)、id、refId、profileTitle、post(回显的正文)、postIds、scheduleDate、errors等字段。它在发布被 Ayrshare 受理后产出,是“整单”级别的结果。 - post:类型
PostIds,包含status、id、postUrl(该平台上的帖子直链)、platform四个字段。块在response.postIds存在时逐条yield "post", p,因此每成功送达一个平台就会产出一条 post 输出,便于你在下游分别处理每个平台的链接。由于本块固定只发 Bluesky,此处通常为一条。 - error:覆盖三类失败——服务端未配置 Ayrshare(
AYRSHARE_API_KEY缺失)、本地校验未通过、以及 Ayrshare API 返回非成功状态(此时 AyrshareClient 抛出的AyrshareAPIException消息会包含上游原始错误,例如某平台“未关联/not linked”)。
调用方拿到 post_url 即可作为“发布成功”的锚点用于后续工作流,例如串联到通知块做发布确认。
成本模型:按是否视频分档计费
Ayrshare 属于订阅代理服务,因此 AutoGPT 平台把它折算为按次积分(credits)计费,规则见 _cost.py:
is_video = True→ 每次运行计 5 积分(视频档);is_video = False→ 每次运行计 2 积分(图文档)。
源码注释还揭示了两点工程细节:其一,cost_filter 是在 run() 执行前按 input_data.is_video 匹配的,所以这个开关必须在输入求值时就是正确的,不能依赖运行中途再改;其二,block_usage_cost 遵循“先匹配先生效”,因此 _cost.py 把视频档常量放在列表首位。对既能发图文又能发视频的平台(Bluesky 即属此类),是否准确设置 is_video 直接决定了每次运行的真实扣费档位——这也是文档把 is_video 描述为“billing applies the video tier”的原因。
典型使用场景
文档给出了三个高度契合该块的设计场景,均可直接在 AutoGPT 可视化画布中组合实现:
- 跨平台分发(Cross-Platform Publishing):在同一个 Agent 工作流中把上游产出的内容并行分发到多个社交网络。例如将一段 LLM 生成的内容同时接到本块(Bluesky)与 Ayrshare 家族的其它平台块(如 post_to_x、post_to_threads 等),实现“一次内容生产、多平台同步露出”,而不必为每个平台各写一套 API 对接。
- 定时内容日历(Scheduled Content Calendar):为
schedule_date传入符合YYYY-MM-DDThh:mm:ssZ的 UTC 时间(例如由上游的定时/排程块计算得出),把预写好的内容在指定时刻推送到 Bluesky,从而维持稳定的发布节奏。 - 视觉内容分享(Visual Content Sharing):配合
media_urls传入图片画廊地址,并利用块独有的alt_text按顺序补充每张图片的无障碍说明,为以图为主的创作/宣传策略提供更友好的可访问性。
部署前提与运行环境
要让该块真正可运行,需满足以下前提(全部以仓库实际逻辑为准):
- 后端进程已配置 Ayrshare 组织级密钥:
AYRSHARE_API_KEY(所有 Ayrshare 块的共同要求,AyrshareClient构造时缺失会抛MissingConfigError)与AYRSHARE_JWT_KEY(SSO 授权链所需,见settings_available()的判定逻辑); - 用户侧已完成一次 Ayrshare SSO 授权:AutoGPT 为其自动创建(或复用)profile,且用户已通过 SSO 弹窗把目标 Bluesky 账号关联到该 profile——否则上游会返回形如“Bluesky is not linked”的平台级错误,并作为 error 输出返回;
- 块在当前环境的块注册表中处于启用状态(源码注册时
disabled=True)。
深入源码的建议阅读路径
如果你希望基于本块做二次开发或排查问题,建议按以下顺序阅读:
- post_to_bluesky.py:块的输入/输出 Schema、本地校验、
create_post调用与blueskyOptions拼装逻辑; - _util.py:
BaseAyrshareInput公共输入字段与create_ayrshare_client(); - _config.py:Ayrshare provider 的声明方式与“managed profile key”语义;
- _cost.py:分档计费规则与匹配顺序;
- integrations/ayrshare.py:
AyrshareClient.create_post的完整参数签名、PostResponse/PostIds模型及错误消息提取策略; - managed_providers/ayrshare.py 与 ayrshare_test.py:托管凭据的按需开通、历史数据迁移及对应测试。
综上,Post To Bluesky 块本质上是“Ayrshare 统一发布 API 的 Bluesky 定制入口”:它把平台差异(字符上限、媒体配额、无障碍文本)收口为两个本地校验与一个 alt_text 选项,把认证复杂度收敛进托管凭据体系,再以固定的 platforms=["bluesky"] 完成投递——在你把它接入 AutoGPT 画布的那一刻起,Bluesky 发布就只是工作流里一个语义清晰、可计费、可失败的普通节点了。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00