# Show HN： 我用了3周时间，借助Claude和Codex开发了一款社交媒体管理工具

- 来源：Hacker News 热门（buzzing.cc 中文翻译）
- 作者：JanSchu
- 发布时间：2026-04-13 21:38
- AIHOT 链接：https://aihot.virxact.com/items/cmnx97ghg003gslrsaal3cdk3
- 原文链接：https://github.com/brightbeanxyz/brightbean-studio

## AI 摘要

开发者仅用3周时间，借助Claude和Codex开发了一款社交媒体管理工具，并在GitHub开源。该项目在Hacker News发布后立即获得102个点赞，展示了AI辅助编程在快速构建产品原型方面的高效性。项目代码已托管于brightbeanxyz/brightbean-studio仓库，为开发者提供了可参考的AI协作开发实践案例。

## 正文

Open-source social media management for creators, agencies, and SMBs.

About BrightBean Studio

BrightBean Studio is an open-source, self-hostable social media management platform built for creators, agencies and SMBs. It does what Sendible, SocialPilot, or ContentStudio do, but free and without per-seat, per-channel, or per-workspace limits. Plan, compose, schedule, approve, publish, and monitor content across Facebook, Instagram, LinkedIn, TikTok, YouTube, Pinterest, Threads, Bluesky, Google Business Profile, and Mastodon from a single multi-workspace dashboard.

It's for people managing many client accounts under one roof who'd rather own their social stack than pay $100–300/month to a SaaS vendor. Every feature is available to every user. No paid tier, no feature gate, no upsell.

A free hosted version is available at brightbean.xyz/studio. You can also deploy it yourself with a one-click button on Heroku, Render, or Railway, run it on your own VPS via Docker, or run it locally. All platform integrations talk directly to the official first-party APIs using your own developer credentials, so there's no aggregator middleman, no vendor lock-in, and no third party sitting between you and your data.

Features

Multi-workspace & teams Unlimited orgs → workspaces → members. Granular RBAC with custom roles, invitations, and a separate Client role for external collaborators. Content composer Rich editor with per-platform caption/media overrides, version history, reusable templates, content categories & tags, a Kanban idea board. Calendar & scheduling Visual calendar with recurring weekly posting slots per account and named queues that auto-assign posts to the next available slot. Publishing engine Direct first-party API integrations (no aggregator), automatic retries, per-account rate-limit tracking, and a 90-day publish audit log. Approval workflows Configurable stages (none / optional / internal / internal + client), threaded internal & external comments, reminders, and a full audit trail. Unified social inbox Comments, mentions, DMs, and reviews from every connected platform in one place, with sentiment analysis, assignments, threaded replies, and historical backfill. Analytics Per-post and channel-level performance from every connected platform's native API, with KPI cards, 7/30/90-day trend charts, and a sortable all-posts table for views, engagement, follower growth, reach, and watch time. Media library Org- and workspace-scoped libraries with nested folders, auto-generated platform-optimized variants, and alt text. Client portal Passwordless 30-day magic-link access so clients can approve or reject posts without creating an account. Notifications In-app, email, and webhook delivery with per-user preferences for every event type. Security & ops Encrypted token & credential storage, Google SSO, Sentry support, and a 14-day reversible org-deletion grace period. 2FA (TOTP) is on the roadmap. White-label friendly Per-workspace branding (logo, colors) and workspace defaults for hashtags, first comments, and posting templates.

A quick look

Visual calendar - drag-and-drop scheduling with recurring slots and queues. Post editor - composer with per-platform overrides and previews. Idea board - Kanban workflow to keep track of all your post ideas. Connect anything - 10+ first-party integrations, no aggregator. Performance analytics - per-post and channel-level metrics with KPI cards and trend charts.

Supported Platforms

Platform Publish Comments DMs Insights Facebook ✓ ✓ ✓ ✓ Instagram ✓ ✓ ✓ ✓ Instagram (Direct) ✓ ✓ ✓ ✓ LinkedIn (Personal) ✓ ✓ — ✓ LinkedIn (Company) ✓ ✓ — ✓ TikTok ✓ — — ✓ YouTube ✓ ✓ — ✓ Pinterest ✓ — — ✓ Threads ✓ ✓ — ✓ Bluesky ✓ ✓ — — Google Business Profile ✓ — — ✓ Mastodon ✓ ✓ — —

Hosted Version

A free hosted version of Brightbean Studio is available at brightbean.xyz/studio. It runs the same codebase as this repository, with no setup or maintenance required.

If you'd rather self-host, choose one of the options below.

One-Click Deploy

Heroku Render Railway

After deploying, set these environment variables in your platform's dashboard:

Variable Required Description DJANGO_SETTINGS_MODULE Auto-set config.settings.production. Set if deployment config has not placed it. SECRET_KEY Auto-generated Django secret key. Set automatically by the deploy button. ENCRYPTION_KEY_SALT Auto-generated Encryption salt. Set automatically by the deploy button. DATABASE_URL Auto-provisioned PostgreSQL connection string. Set automatically. ALLOWED_HOSTS Yes Your app's domain, e.g. your-app.herokuapp.com APP_URL Yes Full public URL, e.g. https://your-app.herokuapp.com STORAGE_BACKEND No Set to s3 for S3/R2 storage. Default: local. Heroku, Render, and Railway have ephemeral filesystems, so uploaded files are lost on redeploy without S3. S3_ENDPOINT_URL If using S3 S3-compatible endpoint URL S3_ACCESS_KEY_ID If using S3 S3 access key S3_SECRET_ACCESS_KEY If using S3 S3 secret key S3_BUCKET_NAME If using S3 S3 bucket name EMAIL_HOST No SMTP server for sending invitations and password resets EMAIL_PORT No SMTP port (default: 587) EMAIL_HOST_USER No SMTP username EMAIL_HOST_PASSWORD No SMTP password GOOGLE_AUTH_CLIENT_ID No For Google OAuth login. Get from Google Cloud Console → Credentials. GOOGLE_AUTH_CLIENT_SECRET No Google OAuth secret

DJANGO_SETTINGS_MODULE

config.settings.production

SECRET_KEY

ENCRYPTION_KEY_SALT

DATABASE_URL

ALLOWED_HOSTS

your-app.herokuapp.com

APP_URL

https://your-app.herokuapp.com

STORAGE_BACKEND

s3

local

S3_ENDPOINT_URL

S3_ACCESS_KEY_ID

S3_SECRET_ACCESS_KEY

S3_BUCKET_NAME

EMAIL_HOST

EMAIL_PORT

587

EMAIL_HOST_USER

EMAIL_HOST_PASSWORD

GOOGLE_AUTH_CLIENT_ID

GOOGLE_AUTH_CLIENT_SECRET

For social media API keys, see Platform Credentials. Full variable reference: .env.example.

.env.example

Quick Start (Docker)

git clone https://github.com/brightbeanxyz/brightbean-studio.git cd brightbean-studio cp .env.example .env

Edit .env - change DATABASE_URL to point to the Docker service name:

.env

DATABASE_URL

DATABASE_URL=postgres://postgres:postgres@postgres:5432/brightbean

DATABASE_URL=postgres://postgres:postgres@postgres:5432/brightbean

Then start everything:

docker compose up -d --build docker compose exec app python manage.py migrate docker compose exec app python manage.py createsuperuser

Tailwind compiles automatically via the tailwind Compose service. First build takes ~60–90 seconds (running npm install in a fresh container); subsequent starts are instant. Watch progress with docker compose logs -f tailwind.

tailwind

npm install

docker compose logs -f tailwind

Open http://localhost:8000 - you're running.

Fully Local Development (without Docker)

Run everything natively - no Docker, no PostgreSQL install. Uses SQLite for the database.

Prerequisites

Python 3.12+

Node.js 20+

Setup

1. Clone and configure

git clone https://github.com/brightbeanxyz/brightbean-studio.git cd brightbean-studio cp .env.example .env

2. Switch to SQLite

Open .env and replace the DATABASE_URL line:

.env

DATABASE_URL

DATABASE_URL=sqlite:///db.sqlite3

DATABASE_URL=sqlite:///db.sqlite3

That's it - no database server to install or manage.

3. Set up Python

python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt

4. Set up Tailwind CSS

cd theme/static_src npm install cd ../..

5. Run database migrations

python manage.py migrate

6. Create your admin account

python manage.py createsuperuser

7. Start the app (3 terminal tabs)

Tab 1 - Tailwind watcher:

cd theme/static_src && npm run start

Tab 2 - Django dev server:

source .venv/bin/activate python manage.py runserver

Tab 3 - Background worker:

source .venv/bin/activate python manage.py process_tasks

Open http://localhost:8000 and log in with the superuser you created.

Daily workflow (Docker-free)

source .venv/bin/activate # activate Python env python manage.py runserver # start web server # (open another tab) python manage.py process_tasks # start worker

Note: SQLite is fine for local development and small deployments. For production or heavy concurrent usage, switch to PostgreSQL.

Note: SQLite is fine for local development and small deployments. For production or heavy concurrent usage, switch to PostgreSQL.

Running Tests

pytest

With coverage:

pytest --cov=apps --cov-report=term-missing

Linting & Type Checking

ruff check . # lint ruff format --check . # format check mypy apps/ config/ --ignore-missing-imports # type check

Auto-fix lint issues:

ruff check --fix . ruff format .

Production Deployment

Docker Compose on a VPS (recommended)

# On your server: git clone https://github.com/brightbeanxyz/brightbean-studio.git cd brightbean-studio cp .env.example .env # Edit .env: # SECRET_KEY= # DEBUG=false # ALLOWED_HOSTS=yourdomain.com # APP_URL=https://yourdomain.com # DATABASE_URL=postgres://postgres:@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

This starts 5 containers: app (Gunicorn), worker, PostgreSQL, Caddy (auto-HTTPS), and a one-shot migrate container that runs database migrations automatically on startup. Edit the Caddyfile with your domain.

Caddyfile

To update:

git pull docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build

Other Platforms

Platform Config file Notes Heroku Procfile + app.json Deploy-button ready. Must use Basic+ dynos (Eco dynos break the worker). Railway railway.toml Three services: web, worker, managed PostgreSQL. Render render.yaml Blueprint with web, worker, PostgreSQL. Must use paid tier.

Procfile

app.json

railway.toml

render.yaml

All platforms with ephemeral filesystems require STORAGE_BACKEND=s3 - see .env.example for S3 configuration.

STORAGE_BACKEND=s3

.env.example

See architecture.md for detailed per-platform instructions and cost breakdowns.

architecture.md

Project Structure

brightbean-studio/ ├── config/ │ ├── settings/ │ │ ├── base.py # Shared settings │ │ ├── development.py # Local dev overrides │ │ ├── production.py # Production hardening │ │ └── test.py # Test overrides │ ├── urls.py # Root URL configuration │ ├── wsgi.py │ └── asgi.py ├── apps/ │ ├── accounts/ # Custom User model, auth, OAuth, sessions │ ├── organizations/ # Organization management │ ├── workspaces/ # Workspace CRUD │ ├── members/ # RBAC, invitations, middleware, decorators │ ├── settings_manager/ # Configurable defaults with cascade logic │ ├── credentials/ # Platform API credential storage (encrypted) │ └── common/ # Shared: encrypted fields, scoped model managers ├── providers/ # Social platform API modules (one file per platform) ├── templates/ # Django templates │ ├── base.html # Layout with sidebar + nav │ └── components/ # Reusable HTMX partials ├── static/ │ └── js/ # Vendored HTMX + Alpine.js ├── theme/ # django-tailwind theme app │ └── static_src/ │ ├── src/styles.css # Tailwind directives │ └── tailwind.config.js ├── Dockerfile ├── docker-compose.yml # Dev: app + worker + postgres ├── docker-compose.prod.yml # Prod override: adds Caddy, uses Gunicorn ├── Caddyfile # Reverse proxy + auto-HTTPS config ├── .env.example # All environment variables ├── Procfile # Heroku ├── app.json # Heroku deploy button ├── railway.toml # Railway config └── render.yaml # Render blueprint

brightbean-studio/ ├── config/ │ ├── settings/ │ │ ├── base.py # Shared settings │ │ ├── development.py # Local dev overrides │ │ ├── production.py # Production hardening │ │ └── test.py # Test overrides │ ├── urls.py # Root URL configuration │ ├── wsgi.py │ └── asgi.py ├── apps/ │ ├── accounts/ # Custom User model, auth, OAuth, sessions │ ├── organizations/ # Organization management │ ├── workspaces/ # Workspace CRUD │ ├── members/ # RBAC, invitations, middleware, decorators │ ├── settings_manager/ # Configurable defaults with cascade logic │ ├── credentials/ # Platform API credential storage (encrypted) │ └── common/ # Shared: encrypted fields, scoped model managers ├── providers/ # Social platform API modules (one file per platform) ├── templates/ # Django templates │ ├── base.html # Layout with sidebar + nav │ └── components/ # Reusable HTMX partials ├── static/ │ └── js/ # Vendored HTMX + Alpine.js ├── theme/ # django-tailwind theme app │ └── static_src/ │ ├── src/styles.css # Tailwind directives │ └── tailwind.config.js ├── Dockerfile ├── docker-compose.yml # Dev: app + worker + postgres ├── docker-compose.prod.yml # Prod override: adds Caddy, uses Gunicorn ├── Caddyfile # Reverse proxy + auto-HTTPS config ├── .env.example # All environment variables ├── Procfile # Heroku ├── app.json # Heroku deploy button ├── railway.toml # Railway config └── render.yaml # Render blueprint

Settings selection: The DJANGO_SETTINGS_MODULE environment variable controls which settings file Django uses. The defaults are already wired for each context: manage.py uses development, wsgi.py/asgi.py use production, and pytest uses test (via pyproject.toml). Docker Compose files and platform deploy configs (Heroku, Render) also set it explicitly. You only need to override it manually if you want a non-default module for a specific command, e.g. DJANGO_SETTINGS_MODULE=config.settings.production python manage.py check --deploy.

Settings selection: The DJANGO_SETTINGS_MODULE environment variable controls which settings file Django uses. The defaults are already wired for each context: manage.py uses development, wsgi.py/asgi.py use production, and pytest uses test (via pyproject.toml). Docker Compose files and platform deploy configs (Heroku, Render) also set it explicitly. You only need to override it manually if you want a non-default module for a specific command, e.g. DJANGO_SETTINGS_MODULE=config.settings.production python manage.py check --deploy.

DJANGO_SETTINGS_MODULE

manage.py

development

wsgi.py

asgi.py

production

pytest

test

pyproject.toml

DJANGO_SETTINGS_MODULE=config.settings.production python manage.py check --deploy

Platform Credentials

To connect social media accounts, you need API credentials from each platform's developer portal. You can set these via environment variables in .env (see .env.example) or, per organization, through the Django admin at {APP_URL}/admin/ → Credentials → Platform credentials (superuser only). If a platform is configured in both places, the .env value takes precedence.

.env

.env.example

{APP_URL}/admin/

.env

Admin UI access (superuser only): The Django admin at {APP_URL}/admin/ (for example https://brightbean.example.com/admin/) is restricted to superuser accounts — only a superuser can view or edit platform credentials there. If you don't already have one, create a superuser, then sign in and open Credentials → Platform credentials:

{APP_URL}/admin/

https://brightbean.example.com/admin/

python manage.py createsuperuser # Docker: docker compose exec app python manage.py createsuperuser

Redirect URI: When registering your app on any platform, set the OAuth redirect URI to:

{APP_URL}/social-accounts/callback/{platform}/

{APP_URL}/social-accounts/callback/{platform}/

For example, if your APP_URL is https://brightbean.example.com, the Facebook redirect URI would be https://brightbean.example.com/social-accounts/callback/facebook/.

APP_URL

https://brightbean.example.com

https://brightbean.example.com/social-accounts/callback/facebook/

TikTok: use the slug social1 instead of tiktok — TikTok rejects redirect URIs containing their brand name. See the TikTok section.

TikTok: use the slug social1 instead of tiktok — TikTok rejects redirect URIs containing their brand name. See the TikTok section.

social1

tiktok

Meta (Facebook, Instagram, Threads)

Facebook, Instagram, and Threads all use the same Meta app credentials.

Go to Meta for Developers and create a new app (type: Business)

Go to Meta for Developers and create a new app (type: Business)

Under App Settings → Basic, copy your App ID and App Secret

Under App Settings → Basic, copy your App ID and App Secret

In the App Dashboard, go to Use cases and add the following four use cases. For each use case, click into it and go to Permissions and features to add the required optional permissions: Use case: "Manage everything on your Page" (Facebook) This use case auto-includes business_management, pages_show_list, and public_profile Add these optional permissions: pages_manage_posts, pages_read_engagement, pages_read_user_content, pages_manage_metadata, read_insights Use case: "Messenger from Meta" (Facebook Messaging) Required to enable the pages_messaging permission, which is not available under the "Manage Pages" use case Add the optional permission: pages_messaging Use case: "Manage messaging & content on Instagram" (Instagram) Add these permissions: instagram_basic, instagram_content_publish, instagram_manage_comments, instagram_manage_insights Use case: "Access the Threads API" (Threads) This use case auto-includes threads_basic Add these optional permissions: threads_content_publish, threads_manage_insights, threads_manage_replies

In the App Dashboard, go to Use cases and add the following four use cases. For each use case, click into it and go to Permissions and features to add the required optional permissions:

Use case: "Manage everything on your Page" (Facebook)

This use case auto-includes business_management, pages_show_list, and public_profile

business_management

pages_show_list

public_profile

Add these optional permissions: pages_manage_posts, pages_read_engagement, pages_read_user_content, pages_manage_metadata, read_insights

pages_manage_posts

pages_read_engagement

pages_read_user_content

pages_manage_metadata

read_insights

Use case: "Messenger from Meta" (Facebook Messaging)

Required to enable the pages_messaging permission, which is not available under the "Manage Pages" use case

pages_messaging

Add the optional permission: pages_messaging

pages_messaging

Use case: "Manage messaging & content on Instagram" (Instagram)

Add these permissions: instagram_basic, instagram_content_publish, instagram_manage_comments, instagram_manage_insights

instagram_basic

instagram_content_publish

instagram_manage_comments

instagram_manage_insights

Use case: "Access the Threads API" (Threads)

This use case auto-includes threads_basic

threads_basic

Add these optional permissions: threads_content_publish, threads_manage_insights, threads_manage_replies

threads_content_publish

threads_manage_insights

threads_manage_replies

Under Facebook Login → Settings → Valid OAuth Redirect URIs, add the following redirect URIs: {APP_URL}/social-accounts/callback/facebook/ {APP_URL}/social-accounts/callback/instagram/ {APP_URL}/social-accounts/callback/threads/

Under Facebook Login → Settings → Valid OAuth Redirect URIs, add the following redirect URIs:

{APP_URL}/social-accounts/callback/facebook/ {APP_URL}/social-accounts/callback/instagram/ {APP_URL}/social-accounts/callback/threads/

{APP_URL}/social-accounts/callback/facebook/ {APP_URL}/social-accounts/callback/instagram/ {APP_URL}/social-accounts/callback/threads/

Set the environment variables: PLATFORM_FACEBOOK_APP_ID=your-app-id PLATFORM_FACEBOOK_APP_SECRET=your-app-secret

Set the environment variables:
