Documentation/Reference apps/Did the post go out? Amplify, a social media management app, records it
Did the post go out? Amplify, a social media management app, records it
Amplify is an open-source social media management app that can post to four networks and records live or simulated delivery. Source on GitHub, with a live demo.
- apps
- marketing
- integrations
- workflows
- saas
Overview
This open-source social media management app enables eight services in
config.py, four of them social networks, and keeps three fields on the post that stop the app from overstating what it did.Press Publish on a post in Amplify and the app stores what happened next. The evidence is on the row. These are the last three attributes of
Post in schemas.py:python
# Real-posting result: did it actually post to the channel, or fall back to simulated?
{"name": "delivery", "type": "string", "values": ["live", "simulated", "failed"]},
{"name": "provider_post_id", "type": "string"},
{"name": "publish_error", "type": "string"},I searched the
config.py and ui/app.js of all 19 apps for the four posting services (instagram, linkedin, x_social, youtube). Only this app lists them. The hosted demo simulates posting, so a Publish there does not reach a real social network. The source is the amplify folder of the supero-apps repo.An operator and their customers in one tenant
Amplify models a SaaS business, so it has two audiences who never share a screen. The customer is a marketer. The operator is the company running Amplify. Both live in one tenant, a single shared set of records: a customer company is a row in
Workspace, and setup.py scopes the marketer (tenant_user) to rows they own.python
PolicyRule(entity="workspace", can_read=True,
filter_field="owner_username", filter_match="$user.name"),The same filter sits on the three working objects (
channel, campaign, post) with create and update added. This is policy-based row scoping, and the workspace rule is read-only for the marketer. A customer can see their plan and billing state and cannot write to either.The operator signs in as
tenant_admin and gets a different console, with tabs for billing and for every workspace and campaign on the platform. Its MRR (monthly recurring revenue) tile sums mrr over workspaces whose state is active or past_due. I counted the seed: 4 plans and 6 workspaces, then 10 channels, 8 campaigns, 16 posts. On those rows the tile comes to $456 from four counted workspaces, and the marketer login owns 9 of the 16 posts.Plan is the one public schema, so the pricing page renders for a logged-out visitor.Why workflows comes last in the list
config.py enables eight services, and a comment above the list explains their order:python
services: list = field(default_factory=lambda: ["email", "slack", "ai",
"instagram", "linkedin", "x_social", "youtube",
"workflows"])The comment's reason is that event bindings are wired up when the
workflows service registers, so every other service has to be present first.There are three workflows and two of them have no button.
campaign_launch is bound to @create:amplify:campaign and sends an email plus a message to the #campaigns Slack channel. workspace_welcome is bound to @create:amplify:workspace. The third, post_publish, is a saga that marks the post published, emails the owner and then writes the metrics, and its first step carries a compensate block that sets post_state back to scheduled if a later step fails.Captions with a fallback you can see
The composer has an AI panel. You type a brief and pick platforms. It calls the
ai service once per platform with a short style guide for each, asking for under 280 characters on X and for a hook line with a single call to action on LinkedIn, and when the service is unavailable or returns no text, generateCaption falls back to a template written for that platform.Each draft card is tagged "AI" or "template", from a flag
generateCaption returns with the text.The front end is a single file,
ui/app.js, 840 lines in the repo. You edit it and refresh the page.Try the marketer, then the operator
Two demo accounts are listed on the login page at amplify.supero.live. Sign in as the marketer and open the Composer and Posts tabs. In the seed, two of the marketer's 9 posts are scheduled and two are drafts. Then sign in as the operator, whose console lists every workspace. The seed has six.
To run it from the source folder:
bash
git clone https://github.com/supero-platform/supero-apps
cd supero-apps/apps/marketing/amplify
cp .env.example .env # set SUPERO_DOMAIN and SUPERO_PASSWORD
./run.shIt needs no account and is running in about two minutes on
http://localhost:5672. Everything in the folder is MIT-licensed, while the platform underneath is hosted and its source is not open. Until a network's credentials are configured on your own domain, every publish will be recorded as simulated on the row. To build a scheduler around your own channels, the starting point is supero.dev.On this page