Add Social Scheduler — global social media post scheduling
- New /social page with left/right layout (form + post list) - Social topbar link - Tables: social_posts, social_targets (project-agnostic posts, per-target project refs) - CRUD: create, edit, duplicate, delete, retry - Image upload (JPEG/PNG/GIF/WebP, 10MB max) stored in data/social-uploads/ - Per-platform image toggle (Discord multipart, Mastodon /api/v2/media, LinkedIn Assets API) - bin/dispatch-social.php cron dispatcher (every minute via /etc/cron.d) - Settings: eligible projects section to enable bot projects as social account sources - Platforms: Discord (webhook), Mastodon, LinkedIn personal profile Cron setup: * * * * * www-data /usr/bin/php /opt/hackmancms/bin/dispatch-social.php >> /var/log/hackman_social.log 2>&1 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
45b9e15152
commit
ac5c262bfb
9 changed files with 1081 additions and 0 deletions
24
sql/010_social_posts.sql
Normal file
24
sql/010_social_posts.sql
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
-- Global social post scheduler (project-agnostic posts, per-target project refs)
|
||||
CREATE TABLE IF NOT EXISTS social_posts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
content TEXT NOT NULL,
|
||||
image_path TEXT,
|
||||
scheduled_at TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'pending', -- pending | processing | done | partial | failed
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS social_targets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
post_id INTEGER NOT NULL REFERENCES social_posts(id) ON DELETE CASCADE,
|
||||
project_id INTEGER NOT NULL,
|
||||
platform TEXT NOT NULL, -- discord | mastodon | linkedin
|
||||
target_key TEXT NOT NULL,
|
||||
include_image INTEGER NOT NULL DEFAULT 0,
|
||||
status TEXT NOT NULL DEFAULT 'pending', -- pending | sent | failed
|
||||
error TEXT,
|
||||
sent_at TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_social_posts_status ON social_posts(status, scheduled_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_social_targets_post ON social_targets(post_id);
|
||||
Loading…
Add table
Add a link
Reference in a new issue