Skip to content
galak06Public

About

Open-source brand-voice social automation — schedule posts, publish reels, manage engagement across FB/IG/WP with persona-driven AI

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Persona

Turn one topic into a ready-to-post Instagram carousel, caption, and reel — in your brand's voice.

CI License: MIT Python 3.11+

Carousel slide: STOP BITTER COLD BREW Carousel slide: grind coarser Carousel slide: save this

Generated by the command below from the topic “why your cold brew tastes bitter.”


Quick start

git clone https://github.com/galak06/persona.git
cd persona
pip install -r app/requirements.txt
python cli.py demo

That's it. No API key, no account, no database — demo renders the full pipeline offline and writes real files to ./out/.

When you're ready for real imagery and a written caption, add one key:

export GEMINI_API_KEY=...        # https://aistudio.google.com/apikey
python cli.py generate --topic "why your cold brew tastes bitter"

What you get

Every run writes a folder you can post from directly:

out/why-your-cold-brew-tastes-bitter/
├── slide-1.jpg      hook slide, with your @handle badge
├── slide-2.jpg      first key point
├── slide-3.jpg      second key point
├── slide-4.jpg      payoff slide, with your site CTA ribbon
├── caption.txt      80–140 words in your voice, ends on a question, 6–8 hashtags
└── reel.mp4         9:16 vertical reel, crossfaded (needs ffmpeg)

The model plans the slides; a deterministic renderer draws the text. That split matters — headlines land in the same place every time instead of wherever an image model felt like putting them.

Make it your brand

Persona has no niche baked in. Everything it says about your brand comes from one config file:

cp app/config.example.json ~/my-brand/config.json
$EDITOR ~/my-brand/config.json
python cli.py generate --brand ~/my-brand --topic "your topic"

The fields that shape the output:

Field What it does
site.name Brand name used throughout
site.niche What you write about — drives slide content
site.target_audience Who the copy speaks to
site.brand_persona The voice the caption is written in
site.mascot_name Mentioned once, naturally, in the caption
site.mascot_kind Optional. Leave blank and prompts say “the brand's mascot” — they never guess a species
social_channels.instagram.ig_username The @handle on the hook slide

See examples/demo-brand/config.json for a filled-in example.

Providers

Persona degrades instead of failing. Every provider is optional; the chain falls through to the next one.

Capability Provider Env var Without it
Slide + caption planning Gemini GEMINI_API_KEY Deterministic template plan
Slide imagery Gemini image GEMINI_API_KEY Falls through to Pexels
Stock imagery Pexels PEXELS_API_KEY Falls through to generated gradients
Reel composition ffmpeg (on PATH) Slides + caption only, no MP4

On Linux, text rendering needs a font: apt-get install fonts-dejavu-core.

CLI

python cli.py demo                        # zero-config sample
python cli.py generate --topic "..."      # your topic
    --brand PATH      brand dir or config.json  (default: demo brand)
    --out DIR         output directory          (default: ./out)
    --offline         skip all network calls
    --no-reel         skip MP4 composition
    -v                show progress

Beyond the studio

The studio above is the part that runs anywhere with one API key. The repository also contains a fuller platform — a FastAPI backend, a React dashboard, a WordPress publishing pipeline, scheduling, and outbound social engagement.

Those parts need real accounts and infrastructure (Postgres, Redis, a Meta app), and they are not wired into cli.py. Setup lives in app/SETUP.md.

A note on the engagement modules. Persona can drive a logged-in browser session to like and comment on Instagram and Facebook. That is against Meta's Terms of Service, and accounts doing it can be restricted.

Nothing in cli.py reaches them, and they can't run without the full platform — Postgres, a provisioned brand, and a browser session you have logged in yourself. But once you provision a brand through onboarding, ig-engager is in the default enabled flow set and will run on its schedule. Turn it off in Brand Settings, or pass a different enabled_flows, if that isn't what you want.

Understand the risk to your own account before leaving it on. The maintainers don't recommend pointing it at an account you can't afford to lose.

Status and roadmap

What works today, what's parked, and what's planned: ROADMAP.md.

Contributing

Issues and pull requests are welcome — see CONTRIBUTING.md.

License

MIT — see LICENSE.

About

Open-source brand-voice social automation — schedule posts, publish reels, manage engagement across FB/IG/WP with persona-driven AI

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages