3 周用 Claude 交付社媒管理工具
HN 高赞案例展示 AI 驱动快速开发的实际成果。对评估 AI 编程效率、规划项目周期的程序员有参考价值。
HN 高赞案例展示 AI 驱动快速开发的实际成果。对评估 AI 编程效率、规划项目周期的程序员有参考价值。
BrightBean Studio 是一个开源、自托管的社交媒体管理平台,专为创意工作者、代理商和中小企业打造。它提供了 Sendible、SocialPilot 或 ContentStudio 所提供的功能,但完全免费,没有按座位、按渠道或按工作区的费用限制。支持在单个多工作区仪表板中规划、撰写、安排、批准、发布和监控 Facebook、Instagram、LinkedIn、TikTok、YouTube、Pinterest、Threads、Bluesky、Google Business Profile、Mastodon 和 DEV.to 上的内容。
它为需要在同一平台下管理多个客户账户、又不愿意每月支付 100-300 美元给 SaaS 供应商的人打造。所有功能对所有用户开放,没有付费版本、没有功能限制、没有额外收费。
免费托管版本可在 brightbean.xyz/studio 上使用。你也可以通过 Heroku、Render 或 Railway 上的一键按钮自行部署、在自己的 VPS 上通过 Docker 运行,或在本地运行。所有平台集成直接与官方第一方 API 通信,使用你自己的开发者凭证,因此没有中间聚合商、没有供应商锁定,也没有第三方介于你和你的数据之间。
BrightBean Studio 的免费托管版本可在 brightbean.xyz/studio 获得。它运行的是本仓库的相同代码库,无需设置或维护。
如果你更喜欢自托管,请从以下选项中选择一个。
部署后,在平台的仪表板中设置这些环境变量:
关于社交媒体 API 密钥,请参阅平台凭证。完整的变量参考:.env.example。
git clone https://github.com/brightbeanxyz/brightbean-studio.git
cd brightbean-studio
cp .env.example .env
编辑 .env - 将 DATABASE_URL 改为指向 Docker 服务名称:
DATABASE_URL=postgres://postgres:postgres@postgres:5432/brightbean
然后启动所有内容:
docker compose up -d --build
docker compose exec app python manage.py createsuperuser
数据库迁移通过 migrate Compose 服务在应用和 worker 服务启动前自动运行,因此没有单独的迁移步骤。
Tailwind 通过 tailwind Compose 服务自动编译。首次构建需要约 60-90 秒(在全新容器中运行 npm install);后续启动立即完成。通过 docker compose logs -f tailwind 查看进度。
打开 http://localhost:8000 - 你已准备就绪。
本地运行所有内容 - 无 Docker、无 PostgreSQL 安装。使用 SQLite 作为数据库。
git clone https://github.com/brightbeanxyz/brightbean-studio.git
cd brightbean-studio
cp .env.example .env
打开 .env 并替换 DATABASE_URL 行:
DATABASE_URL=sqlite:///db.sqlite3
就这样 - 无需安装或管理数据库服务器。
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cd theme/static_src
npm install
cd ../..
python manage.py migrate
python manage.py createsuperuser
标签页 1 - Tailwind 监视器:
cd theme/static_src && npm run start
标签页 2 - Django 开发服务器:
source .venv/bin/activate
python manage.py runserver
标签页 3 - 后台 worker:
source .venv/bin/activate
python manage.py process_tasks
打开 http://localhost:8000 并使用你创建的超级用户账户登录。
source .venv/bin/activate # 激活 Python 环境
python manage.py runserver # 启动 web 服务器
# (打开另一个标签页)
python manage.py process_tasks # 启动 worker
注意:SQLite 适合本地开发和小规模部署。对于生产环境或大量并发使用,请切换到 PostgreSQL。
pytest
pytest --cov=apps --cov-report=term-missing
ruff check . # lint
ruff format --check . # 格式检查
mypy apps/ config/ --ignore-missing-imports # 类型检查
自动修复 lint 问题:
ruff check --fix .
ruff format .
# 在你的服务器上:
git clone https://github.com/brightbeanxyz/brightbean-studio.git
cd brightbean-studio
cp .env.example .env
# 编辑 .env:
# SECRET_KEY=<生成一个随机 50+ 字符的字符串>
# DEBUG=false
# ALLOWED_HOSTS=yourdomain.com
# APP_URL=https://yourdomain.com
# DATABASE_URL=postgres://postgres:<strong-password>@postgres:5432/brightbean
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
docker compose exec app python manage.py createsuperuser
这会启动 5 个容器:app(Gunicorn)、worker、PostgreSQL、Caddy(自动 HTTPS)和一个一次性 migrate 容器,在启动时自动运行数据库迁移。使用你的域名编辑 Caddyfile。
git pull
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
所有具有短暂文件系统的平台都需要 STORAGE_BACKEND=s3 - 见 .env.example 了解 S3 配置。
详见 architecture.md 获取每个平台的详细说明和成本分解。
brightbean-studio/
├── config/
│ ├── settings/
│ │ ├── base.py # 共享设置
│ │ ├── development.py # 本地开发覆盖
│ │ ├── production.py # 生产环境加固
│ │ └── test.py # 测试覆盖
│ ├── urls.py # 根 URL 配置
│ ├── wsgi.py
│ └── asgi.py
├── apps/
│ ├── accounts/ # 自定义 User 模型、认证、OAuth、会话
│ ├── organizations/ # 组织管理
│ ├── workspaces/ # 工作区 CRUD
│ ├── members/ # RBAC、邀请、中间件、装饰器
│ ├── settings_manager/ # 可配置的级联默认值逻辑
│ ├── credentials/ # 平台 API 凭证存储(加密)
│ └── common/ # 共享:加密字段、作用域模型管理器
├── providers/ # 社交平台 API 模块(每个平台一个文件)
├── templates/ # Django 模板
│ ├── base.html # 包含侧边栏 + 导航的布局
│ └── components/ # 可复用的 HTMX 片段
├── static/
│ └── js/ # 精选的 HTMX + Alpine.js
├── theme/ # django-tailwind 主题应用
│ └── static_src/
│ ├── src/styles.css # Tailwind 指令
│ └── tailwind.config.js
├── Dockerfile
├── docker-compose.yml # 开发:app + worker + postgres
├── docker-compose.prod.yml # 生产覆盖:添加 Caddy,使用 Gunicorn
├── Caddyfile # 反向代理 + 自动 HTTPS 配置
├── .env.example # 所有环境变量
├── Procfile # Heroku
├── app.json # Heroku 部署按钮
├── railway.toml # Railway 配置
└── render.yaml # Render blueprint
DJANGO_SETTINGS_MODULE 环境变量控制 Django 使用哪个设置文件。已为每个上下文预配置默认值:manage.py 使用开发环境,wsgi.py/asgi.py 使用生产环境,pytest 使用测试环境(通过 pyproject.toml)。Docker Compose 文件和平台部署配置(Heroku、Render)也明确设置它。仅当你想为特定命令使用非默认模块时,才需要手动覆盖它,例如 DJANGO_SETTINGS_MODULE=config.settings.production python manage.py check --deploy。
要连接社交媒体账户,你需要从每个平台的开发者门户获取 API 凭证。你可以通过 .env 中的环境变量设置这些凭证(见 .env.example),或者在 Django 管理员 {APP_URL}/admin/ → 凭证 → 平台凭证处按组织进行设置(仅限超级用户)。如果某个平台同时在两个地方配置,.env 值优先。
Django 管理员位于 {APP_URL}/admin/(例如 https://brightbean.example.com/admin/),仅限超级用户账户 - 只有超级用户才能在那里查看或编辑平台凭证。如果你还没有超级用户,请创建一个,然后登录并打开凭证 → 平台凭证:
python manage.py createsuperuser
# Docker:docker compose exec app python manage.py createsuperuser
在任何平台上注册应用时,将 OAuth 重定向 URI 设置为:
{APP_URL}/social-accounts/callback/{platform}/
例如,如果你的 APP_URL 是 https://brightbean.example.com,Facebook 重定向 URI 应该是 https://brightbean.example.com/social-accounts/callback/facebook/。
TikTok:使用 slug social1 代替 tiktok - TikTok 会拒绝包含其品牌名称的重定向 URI。见 TikTok 部分。
Facebook、Instagram 和 Threads 都使用相同的 Meta 应用凭证。
前往 Meta for Developers,创建一个新应用(类型:Business)
前往 Meta for Developers,创建一个新应用(类型:Business)
在 App Settings → Basic 下,复制你的 App ID 和 App Secret
在 App Settings → Basic 下,复制你的 App ID 和 App Secret
在 App Dashboard 中,前往 Use cases,并添加以下四个用例。对于每个用例,点击进入,然后前往 Permissions and features,添加所需的可选权限:用例:“Manage everything on your Page”(Facebook)该用例会自动包含 business_management、pages_show_list 和 public_profile 添加以下可选权限:pages_manage_posts、pages_manage_engagement、pages_read_engagement、pages_read_user_content、pages_manage_metadata、read_insights 用例:“Messenger from Meta”(Facebook Messaging)启用 pages_messaging 权限需要此用例,该权限在“Manage Pages”用例下不可用 添加可选权限:pages_messaging 用例:“Manage messaging & content on Instagram”(Instagram)添加以下权限:instagram_basic、instagram_content_publish、instagram_manage_comments、instagram_manage_insights 用例:“Access the Threads API”(Threads)该用例会自动包含 threads_basic 添加以下可选权限:threads_content_publish、threads_manage_insights、threads_manage_replies
在 App Dashboard 中,前往 Use cases,并添加以下四个用例。对于每个用例,点击进入,然后前往 Permissions and features,添加所需的可选权限:
用例:“Manage everything on your Page”(Facebook)
该用例会自动包含 business_management、pages_show_list 和 public_profile
添加以下可选权限:pages_manage_posts、pages_manage_engagement、pages_read_engagement、pages_read_user_content、pages_manage_metadata、read_insights
用例:“Messenger from Meta”(Facebook Messaging)
启用 pages_messaging 权限需要此用例,该权限在“Manage Pages”用例下不可用
添加可选权限:pages_messaging
用例:“Manage messaging & content on Instagram”(Instagram)
添加以下权限:instagram_basic、instagram_content_publish、instagram_manage_comments、instagram_manage_insights
用例:“Access the Threads API”(Threads)
该用例会自动包含 threads_basic
添加以下可选权限:threads_content_publish、threads_manage_insights、threads_manage_replies
在 Facebook Login → Settings → Valid OAuth Redirect URIs 下,添加以下重定向 URI:{APP_URL}/social-accounts/callback/facebook/ {APP_URL}/social-accounts/callback/instagram/ {APP_URL}/social-accounts/callback/threads/
在 Facebook Login → Settings → Valid OAuth Redirect URIs 下,添加以下重定向 URI:
{APP_URL}/social-accounts/callback/facebook/
{APP_URL}/social-accounts/callback/instagram/
{APP_URL}/social-accounts/callback/threads/
设置环境变量:PLATFORM_FACEBOOK_APP_ID=your-app-id PLATFORM_FACEBOOK_APP_SECRET=your-app-secret
设置环境变量:
PLATFORM_FACEBOOK_APP_ID=your-app-id
PLATFORM_FACEBOOK_APP_SECRET=your-app-secret
Instagram(直连,通过 Instagram Login)
Instagram(直连)连接器使用带 Instagram Login 的 Instagram API——这是一个独立于上述基于 Facebook Login 的 Instagram 连接器的 OAuth 流程。它适用于专业 Instagram 账户(Business 或 Creator),无需关联 Facebook Page。
账户类型要求:自 Instagram Basic Display API 于 2024-12-04 停用后,个人 Instagram 账户便无法访问 API。用户必须先将账户转换为专业账户(免费,可在 IG Settings → Account type and tools → Switch to professional account 中操作)。
在同一个 Meta 应用中,前往 Use cases,并添加“Instagram API”用例
在 API setup with Instagram Login 下,记下你的 Instagram App ID 和 Instagram App Secret(它们与 Facebook App ID/Secret 不同)
前往 Permissions and features,并添加所需权限:instagram_business_basic、instagram_business_content_publish、instagram_business_manage_comments、instagram_business_manage_messages、instagram_business_manage_insights
instagram_business_basic、instagram_business_content_publish、instagram_business_manage_comments、instagram_business_manage_messages、instagram_business_manage_insights
在 API setup with Instagram Login → Step 4: Set up Instagram business login 下,点击 Set up 并添加重定向 URI(必须完全匹配,包括末尾的斜杠):{APP_URL}/social-accounts/callback/instagram_login/
{APP_URL}/social-accounts/callback/instagram_login/
在 API setup with Instagram Login → Step 3: Configure webhooks 下,设置:Callback URL:{APP_URL}/webhooks/instagram_login/ Verify token:你的 .env 中 INSTAGRAM_LOGIN_WEBHOOK_VERIFY_TOKEN 的值(可以是任意随机字符串;请先生成一个并设置该环境变量,然后再点击 Verify and save)。验证完成后,订阅 messages、comments 和 mentions 字段。
Callback URL:{APP_URL}/webhooks/instagram_login/
Verify token:你的 .env 中 INSTAGRAM_LOGIN_WEBHOOK_VERIFY_TOKEN 的值(可以是任意随机字符串;请先生成一个并设置该环境变量,然后再点击 Verify and save)。验证完成后,订阅 messages、comments 和 mentions 字段。
设置环境变量:PLATFORM_INSTAGRAM_APP_ID=your-instagram-app-id PLATFORM_INSTAGRAM_APP_SECRET=your-instagram-app-secret INSTAGRAM_LOGIN_WEBHOOK_VERIFY_TOKEN=your-random-verify-token
PLATFORM_INSTAGRAM_APP_ID=your-instagram-app-id
PLATFORM_INSTAGRAM_APP_SECRET=your-instagram-app-secret
INSTAGRAM_LOGIN_WEBHOOK_VERIFY_TOKEN=your-random-verify-token
Brightbean Studio 支持两种 LinkedIn 接入路径。请选择你的 LinkedIn 开发者应用能够获得的路径,也可以使用两个独立应用同时支持两种路径。
路径 A——仅限个人账户(任何个人开发者都可以使用):
前往 LinkedIn Developer Portal,创建一个新应用(无需验证 Company Page)。
在 Products 下,申请访问以下产品(两者均会自动获批):Sign In with LinkedIn using OpenID Connect Share on LinkedIn
Sign In with LinkedIn using OpenID Connect
在 Auth 下,添加重定向 URI:{APP_URL}/social-accounts/callback/linkedin_personal/
{APP_URL}/social-accounts/callback/linkedin_personal/
Scopes:openid、profile、email、w_member_social。
设置环境变量:PLATFORM_LINKEDIN_PERSONAL_CLIENT_ID=your-client-id PLATFORM_LINKEDIN_PERSONAL_CLIENT_SECRET=your-client-secret
PLATFORM_LINKEDIN_PERSONAL_CLIENT_ID=your-client-id
PLATFORM_LINKEDIN_PERSONAL_CLIENT_SECRET=your-client-secret
路径 A 的限制:访问令牌的有效期约为 60 天,并且 LinkedIn 不会为这些 scopes 签发刷新令牌——用户必须大约每 60 天手动重新连接一次。此路径下的个人账户无法使用收件箱或评论读取功能。
路径 B——Company Pages(同时启用完整的个人账户功能):
前往 LinkedIn Developer Portal,创建一个新应用。
验证该应用与 LinkedIn Company Page 的关联关系。
在 Products 下,申请访问:Community Management API(受限——需要 LinkedIn 审核)
Community Management API(受限——需要 LinkedIn 审核)
在 Auth 下,添加以下两个重定向 URI:{APP_URL}/social-accounts/callback/linkedin_personal/ {APP_URL}/social-accounts/callback/linkedin_company/
{APP_URL}/social-accounts/callback/linkedin_personal/
{APP_URL}/social-accounts/callback/linkedin_company/
Scopes:个人账户:r_basicprofile、w_member_social、r_member_social 公司账户:r_basicprofile、w_member_social、w_organization_social、r_organization_social、rw_organization_admin
个人账户:r_basicprofile、w_member_social、r_member_social
公司账户:r_basicprofile、w_member_social、w_organization_social、r_organization_social、rw_organization_admin
设置环境变量:PLATFORM_LINKEDIN_COMPANY_CLIENT_ID=your-client-id PLATFORM_LINKEDIN_COMPANY_CLIENT_SECRET=your-client-secret
PLATFORM_LINKEDIN_COMPANY_CLIENT_ID=your-client-id
PLATFORM_LINKEDIN_COMPANY_CLIENT_SECRET=your-client-secret
如果只设置路径 B(公司账户)的凭据,Brightbean Studio 也会自动复用这些凭据进行个人账户连接——刷新令牌(有效期 365 天)和收件箱均可正常使用。只有当你拥有一个独立的、仅支持个人账户的应用时,才需要路径 A 的变量。
注意:“Sign In with LinkedIn using OpenID Connect”/“Share on LinkedIn”与“Community Management API”无法在同一个 LinkedIn 应用中同时使用。路径 A 和路径 B 需要使用不同的应用。
向后兼容性:旧版 PLATFORM_LINKEDIN_CLIENT_ID / PLATFORM_LINKEDIN_CLIENT_SECRET 环境变量仍会作为 linkedin_personal 和 linkedin_company 的备用配置继续生效——现有的自托管用户无需进行任何更改即可继续使用。系统会假定旧版凭据已获 Community Management API 批准;如果你的旧版应用仅支持 OIDC,请将其迁移至 PLATFORM_LINKEDIN_PERSONAL_*。
前往 TikTok Developer Portal,创建一个新应用
添加 Login Kit 和 Content Posting API 产品
配置重定向 URI — 使用 social1,不是 tiktok(TikTok 拒绝包含其品牌名的 URI):
{APP_URL}/social-accounts/callback/social1/
所需权限范围:user.info.basic、video.publish、video.upload、video.list
注意:TikTok 使用客户端密钥(Client Key),而非客户端 ID。从应用仪表板复制客户端密钥和客户端密钥。
设置环境变量:
PLATFORM_TIKTOK_CLIENT_KEY=your-client-key
PLATFORM_TIKTOK_CLIENT_SECRET=your-client-secret
关于生产审核,请录制演示视频,在 TikTok 沙箱环境中展示所有请求的权限范围。
YouTube 和 Google 商业档案共用相同的 Google Cloud 凭证。
前往 Google Cloud 控制台并创建新项目(或选择现有项目)
在 API 和服务 → 库下启用以下 API:
前往 API 和服务 → 凭证,创建 OAuth 2.0 客户端 ID(类型:网络应用)
在"已授权的重定向 URI"下添加以下重定向 URI:
{APP_URL}/social-accounts/callback/youtube/
{APP_URL}/social-accounts/callback/google_business/
所需权限范围:
PLATFORM_GOOGLE_CLIENT_ID=your-client-id
PLATFORM_GOOGLE_CLIENT_SECRET=your-client-secret
前往 Pinterest 开发者门户并创建新应用
在应用设置下,添加重定向 URI:
{APP_URL}/social-accounts/callback/pinterest/
复制应用 ID 和应用密钥
所需权限范围:user_accounts:read、boards:read、pins:read、pins:write
设置环境变量:
PLATFORM_PINTEREST_APP_ID=your-app-id
PLATFORM_PINTEREST_APP_SECRET=your-app-secret
无需开发者应用注册。用户通过输入其 Bluesky 句柄和应用密码连接账户:
前往设置 → 隐私和安全 → 应用密码
创建新的应用密码,在 Brightbean Studio 中连接账户时使用该密码
无需开发者应用注册。Brightbean Studio 在用户连接账户时自动在每个 Mastodon 实例上注册 OAuth 应用。用户只需输入其实例 URL(例如 mastodon.social)。
无需开发者应用注册。用户通过输入个人 API 密钥连接:
登录 DEV.to 并打开设置 → 扩展
在 DEV Community API Keys 下,输入描述(例如 Brightbean)并点击生成 API 密钥
复制生成的密钥并在 Brightbean Studio 中连接账户时粘贴
文章作为 DEV.to 发布(标题 + Markdown 正文)。密钥可随时从同一设置页面撤销。
请参阅上方的受支持平台矩阵了解各平台的收件箱功能。
要导入历史消息(例如过去 7 天的消息):
python manage.py backfill_inbox --days 7
参数:
--days N — 回填的天数(默认:7)--platform NAME — 仅回填特定平台(例如 youtube、linkedin、tiktok)--account-id UUID — 仅回填特定账户Brightbean Studio 提供 REST API 和 MCP(Model Context Protocol)服务器,以便 AI 智能体和脚本可以读取分析、管理媒体,以及创建或安排文章发布。两者共享相同的身份验证、权限模型、速率限制和审计日志。选择适合你的客户端的协议。
基础 URL: {APP_URL}/api/v1/(例如 https://your-studio.example.com/api/v1/)
从组织 → API 密钥颁发 API 密钥。密钥是工作区级别,可列入白名单仅限于特定社交账户,并继承颁发者的工作区权限子集。撤销立即生效。将密钥作为 Bearer 令牌发送:
Authorization: Bearer bb_studio_...
权限密钥:create_posts、publish_directly、upload_media、view_analytics。每个端点需要相关权限;缺少权限返回 403。
速率限制响应 (429) 包括 Retry-After、X-RateLimit-Limit 和 X-RateLimit-Remaining 标头。
所有写入端点接受 idempotency_key(或 Idempotency-Key 标头)以安全重试。
MCP 服务器位于 POST {APP_URL}/api/v1/mcp,通过可流式 HTTP 传输使用 JSON-RPC 2.0。它实现标准的 initialize、tools/list、tools/call 和 ping 方法。工具包括:
服务器位于 {APP_URL}/api/v1/mcp,支持两种身份验证模式 — 选择适合你的客户端的方式。
Claude Desktop(及其他本地 OAuth 连接器)。在 Claude Desktop 中打开设置 → 连接器 → 添加自定义连接器,命名,并输入服务器 URL {APP_URL}/api/v1/mcp。Claude 自动注册(动态客户端注册)并打开浏览器登录 Brightbean Studio 并批准访问 — 无需 API 密钥。任何 Studio 用户都可以连接;连接...