Map out the API logic for creating posts
Post Generation Logic
Initial Campaign Post: When a campaign is created, create an initial post for the campaign.
Automated Daily Post Creation: After the initial post is created and approved, create new posts with the following logic:
- Maximum of 3 posts per campaign that have not been sent (
status != 'sent') - Create a new post every day at 9 AM via scheduler (see
api/scheduler/bree.ts) - New posts are created in the "new" state
- Send an email notification to the user that a new post has been created and they need to review it
- Maximum of 3 posts per campaign that have not been sent (
Post Status Workflow
Posts flow through the following states:
| Status | Description | Next States |
|---|---|---|
new | Draft created, awaiting review | pending_review, revision_requested |
pending_review | Presented to client for approval | approved, revision_requested, rejected |
approved | Client approved, ready to schedule | scheduled, sent |
revision_requested | Client requested changes | new (after edits) |
scheduled | Scheduled for future publishing | sent (on publish) |
sent | Published to platforms | terminal state |
rejected | Client rejected | terminal state |
MCP Integration
All GoClaw agent interactions with posts happen via the MCP server (POST /mcp). The following tools manage the post lifecycle:
- Creation:
generate-content(full generation) orcreate-post+save-platform-content(manual) - Review:
list-pending-posts,get-post-status - Approval:
approve-post(with actions: approve/reject/request_edit) - Scheduling:
schedule-post,schedule-multiple-posts,unschedule-post - Publishing:
publish-content(triggers platform adapters)
Platform Content Generation
The contentMap in api/src/modules/posts.ts maps each platform to its generator function:
facebook→generateFacebookPost()instagram→generateInstagramPost()twitter→generateTwitterPost()linkedin→generateLinkedInPost()blog→generateBlogPost()ghost→generateGhostPost()wordpress→generateWordPressPost()blogger→generateBloggerPost()email→generateEmail()
Each generator returns:
{
content: string,
images?: string[],
character_count?: number,
metadata?: object
}
Publishing Adapters
Platform-specific publishing is handled by adapters in api/src/integrations/:
| Platform | Adapter | Credentials Source |
|---|---|---|
TwitterAdapter | customer_integration.metadata (api_key, api_secret, access_token, access_secret) | |
LinkedInAdapter | customer_integration.metadata (access_token, person_urn) | |
FacebookAdapter | customer_integration.metadata (access_token, page_id) | |
| Mailchimp | MailchimpAdapter | customer_integration.metadata (api_key, list_id, server_prefix, from_email, from_name) |
| Ghost CMS | GhostAdapter | Global env vars (GHOST_API_URL, GHOST_ADMIN_API_KEY) |
All adapters implement the PublishAdapter interface from api/src/integrations/types.ts.