The Daily Pour — Marketing Automation Deployment
Owner: Annie (Marketing Lead)
Infra: Sam (GitLab CI + Kestra)
Target deploy date: Sunday, August 17, 2026
GitLab repo: https://gitlab.com/samueljamesinc/daily-pour-marketing (LIVE)
Code-server: https://code.snsnetlabs.com (LXC 304, Fedora 44, pve3)
What This Is
Automated daily social media promotion for The Daily Pour, powered by Kestra workflows.
Annie manages the content calendar and approvals; the system handles content generation,
hashtag selection, platform-specific formatting, and publishing — zero daily effort once
configured.
Architecture
┌──────────────┐ ┌───────────────┐ ┌──────────────┐ ┌─────────────┐ ┌────────────┐
│ Pre-Flight │ ──▶ │ Content Gen │ ──▶ │ Hashtag │ ──▶ │ Platform │ ──▶ │ Publish │
│ Checks │ │ (ChatGPT / │ │ Engine │ │ Formatter │ │ (Buffer │
│ │ │ Ollama) │ │ │ │ │ │ API) │
└──────────────┘ └───────────────┘ └──────────────┘ └─────────────┘ └────────────┘
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
APIs alive? Weather + Tier 1-4 + Per-platform One API →
Drive access? day theme → RiteKit trending + character limits, FB + IG +
Platforms up? brand voice → rotation logic → image specs, TikTok +
Content exists? caption draft anti-shadowban hashtag counts LinkedIn +
Google Biz
Data Flow (detailed)
┌─────────────────────────────────────────────────────┐
│ GitLab.com (Source of Truth) │
│ daily-pour-marketing repo │
│ ├── workflows/ (Kestra YAML) │
│ ├── config/ (brand voice, hashtags, locations) │
│ └── CI Variables (secrets, tokens) │
└───────────────────────┬─────────────────────────────┘
│ git sync (every 15 min)
▼
┌──────────────┐ ┌─────────────────────────────┐
│ Google Drive │◀────read────▶│ Kestra (Execution) │
│ (60GB) │ │ 192.168.122.71 │
│ ├── photos/ │ │ │
│ ├── videos/ │ │ Cron triggers: │
│ └── logos/ │ │ • 5:30 AM — preflight │
└──────────────┘ │ • 6:00 AM — daily post │
│ • Sun 8PM — weekly gen │
└──────────────┬──────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────────┐ ┌─────────────┐ ┌──────────────┐
│ OpenWeather │ │ ChatGPT / │ │ RiteKit │
│ API │ │ Ollama │ │ (trending │
│ (weather) │ │ (captions) │ │ hashtags) │
└──────────────┘ └─────────────┘ └──────────────┘
│
▼
┌─────────────────────────────┐
│ Buffer API │
│ (single publishing │
│ layer for all 5 │
│ platforms) │
└──────────────┬──────────────┘
│
┌────────┬───────┬───────┼───────┬────────┐
▼ ▼ ▼ ▼ ▼ │
Facebook Instagram TikTok LinkedIn Google │
Business │
│
┌────────────────────────────────┘
▼
┌─────────────────────────────┐
│ Kestra plugin-meta (backup) │
│ Direct FB + IG posting │
│ (if Buffer doesn't cover │
│ a specific need) │
└─────────────────────────────┘
Publishing Layer: Buffer API
Why Buffer instead of 5 separate platform APIs:
One integration → posts to all 5 platforms
Handles format differences (image sizes, character limits, hashtag placement)
Built-in scheduling, analytics, engagement inbox
Free tier: 3 channels, 10 posts/channel/month
Paid: ~$6/channel/month ($30/mo for all 5 — cheaper than dev time on 5 APIs)
Has an MCP server (AI agents can post directly)
REST API: https://api.bufferapp.com/1/updates/create.json
Fallback: Kestra plugin-meta for direct Facebook + Instagram posting if Buffer
doesn't cover a specific need (carousels, reels with specific metadata, etc.)
Setup:
Sign up at buffer.com
Connect all 5 social accounts
Generate API token
Add BUFFER_ACCESS_TOKEN to GitLab CI Variables + Kestra namespace secrets
Hashtag Engine
Strategy: 4-Tier System with Rotation
Tier
What
Example
Rotation
1 — Brand
Always present
#TheDailyPour #DailyPourCoffee
Never changes
2 — Category
Broad reach
#CoffeeAddict #SpecialtyCoffee #LocalCoffee
3 sets, cycle every 3 days
3 — Day Theme
Matches daily rotation
#MenuMonday #BehindTheScenes #FridayFeels
Changes daily
4 — Dynamic
Fresh per post
Weather-based, trending, time-of-day
Every post (RiteKit + weather API)
Platform Limits (enforced by the formatter)
Platform
Optimal Count
Format
Instagram
20-25
In caption or first comment (separated by dots)
TikTok
5-8
In caption only (algorithm punishes excess)
Facebook
3-5
In caption, early
LinkedIn
3-5
Final line, professional tone only
Google Business
2-3
In description, minimal
Anti-Shadowban Rules
Never repeat the same Tier 2 set within 7 days on the same platform
Rotate Tier 2 pools: A → B → C → A (3-day cycle)
Tier 4 (trending) is always unique — pulled fresh per post
Track hashtag history in Kestra (7-day lookback before selecting)
Trending Hashtag Sources
RiteKit API (https://ritekit.com ) — give it post text, returns optimized hashtags
based on real-time popularity. 100 free calls/month.
Apify TikTok Scraper — pulls TikTok Creative Center trending hashtags daily
OpenWeatherMap — weather-reactive hashtags (#SummerVibes, #CozyMorning, etc.)
Day-of-week cultural moments — #MondayMotivation, #FridayFeels, #SundayFunday
Config Files
config/
├── hashtag-rotation.yml ← Tier 2 pools (A/B/C), Tier 3 by day, rotation state
├── hashtag-limits.yml ← Per-platform max counts + format rules
└── hashtag-banned.yml ← Hashtags known to be suppressed/banned (check monthly)
content/templates/
└── hashtags.md ← Master reference (all tiers defined, human-readable)
Pre-Requisites Checklist (Updated)
Infrastructure (Sam) — ✅ = Done
GitLab.com repo — https://gitlab.com/samueljamesinc/daily-pour-marketing
Kestra running and healthy — 192.168.122.71:8080
Code-server — LXC 304, Fedora 44, code.snsnetlabs.com
GitLab SSH from code-server working
OpenWeatherMap API — key active, tested
OpenAI API — key active, tested
Google Drive OAuth — refresh token working, tested upload/list/download
Pre-flight checks flow — tested, all passing
Weather caption flow — tested, generating captions
Buffer account — sign up, connect platforms, get API token
RiteKit account — sign up, get API key (free tier)
Kestra ↔ GitLab sync flow — auto-pull workflows from repo
Publish GCP OAuth app (Testing → Production) — prevent 7-day token expiry
Platform Accounts (Sam or Annie)
Content Library (Annie — ongoing, seed before launch)
Kestra Workflows (Updated)
#
Workflow
Trigger
What it does
Status
0
preflight_checks
Before every deployment
Validates APIs, platforms, Drive, content exist
✅ LIVE
1
weather_caption_test
Manual / Cron
Weather + ChatGPT → generates caption
✅ LIVE
2
daily_post_rotation
Cron 6:00 AM daily
Preflight → content gen → hashtags → format → publish via Buffer
TODO
3
weekly_content_gen
Cron Sunday 8 PM
LLM generates 7 draft captions + hashtag sets for the week
TODO
4
location_announce
Manual or webhook
New location signed → announcement series across all platforms
TODO
5
hiring_post
Webhook from Plane
Hiring task created → generates + posts hiring content
TODO
6
review_responder
Cron daily 9 AM
Pulls Google reviews → drafts responses → Annie approves
TODO
7
engagement_repost
Cron 2x/week
Scans for UGC/mentions → queues for repost with credit
TODO
8
hashtag_performance
Cron Monday 9 AM
Pulls engagement data, correlates with hashtags, recommends rotations
TODO
Content Rotation (daily theme)
Day
Type
Platforms
Tier 3 Hashtags
Mon
Menu highlight
All
#MenuMonday #CoffeeMagic #MondayMotivation
Tue
Behind the scenes
IG, TikTok, FB
#BehindTheScenes #MorningShift #BaristaDiary
Wed
Testimonial / review
FB, Google, LinkedIn
#CustomerLove #TestimonialTuesday #FiveStars
Thu
Educational / fun fact
All
#CoffeeEd #DidYouKnow #ThursdayThoughts
Fri
Weekend teaser + location
All
#FridayFeels #WeekendPlans #CoffeeNearMe
Sat
Live energy / "we're open"
IG Stories, TikTok, FB
#WeAreOpen #SaturdayVibes #LiveEnergy
Sun
Community / gratitude
FB, LinkedIn, IG
#CommunityLove #SundayBrunch #Grateful
GitLab Repo Structure (Updated)
daily-pour-marketing/ ← https://gitlab.com/samueljamesinc/daily-pour-marketing
├── .gitlab-ci.yml ← Validates YAML + syncs to Kestra
├── README.md
├── content/
│ ├── logos/
│ ├── photos/{products,trailer,team,customers}/
│ ├── videos/{reels,tiktok,stories}/
│ └── templates/
│ ├── captions/ ← Per-day caption templates
│ ├── hashtags.md ← Master hashtag reference
│ └── canva/ ← Brand templates
├── config/
│ ├── brand-voice.md ← Annie's tone guide
│ ├── colors.md ← Brand palette
│ ├── rules.md ← What to never post
│ ├── platforms.yml ← Platform config (no secrets)
│ ├── locations.yml ← Active locations + hours
│ ├── hashtag-rotation.yml ← NEW: Tier 2 pools, rotation state
│ ├── hashtag-limits.yml ← NEW: Per-platform counts + format
│ └── hashtag-banned.yml ← NEW: Suppressed/banned hashtags
├── workflows/
│ ├── preflight-checks.yml ← ✅ LIVE
│ ├── daily-post-rotation.yml ← TODO (full pipeline)
│ ├── weather-reactive.yml
│ ├── weekly-content-gen.yml
│ ├── location-announce.yml
│ ├── hiring-post.yml
│ ├── review-responder.yml
│ ├── engagement-repost.yml
│ └── hashtag-performance.yml ← NEW: Weekly analytics
└── scripts/
├── hashtag-selector.py ← NEW: Tier selection + rotation logic
├── hashtag-validator.py ← NEW: Validates sets before posting
└── platform-formatter.py ← NEW: Formats caption + hashtags per platform
Secrets (GitLab CI Variables + Kestra Namespace Files)
Variable
Location
Status
KESTRA_API_USER
GitLab CI
✅ Set
KESTRA_API_PASSWORD
GitLab CI
✅ Set
KESTRA_URL
GitLab CI
✅ Set
OPENAI_API_KEY
GitLab CI + Kestra
✅ Set
OPENWEATHER_API_KEY
GitLab CI + Kestra
✅ Set
GOOGLE_DRIVE_REFRESH_TOKEN
Kestra namespace
✅ Set (publish GCP app to prevent 7-day expiry)
GOOGLE_DRIVE_CLIENT_ID
Kestra namespace
✅ Set
GOOGLE_DRIVE_CLIENT_SECRET
Kestra namespace
✅ Set
BUFFER_ACCESS_TOKEN
GitLab CI + Kestra
⬜ TODO (after Buffer signup)
RITEKIT_API_KEY
GitLab CI + Kestra
⬜ TODO (after RiteKit signup)
META_ACCESS_TOKEN
GitLab CI + Kestra
⬜ TODO (after FB/IG app approval)
TIKTOK_ACCESS_TOKEN
GitLab CI + Kestra
⬜ TODO (after TikTok developer app)
LINKEDIN_ACCESS_TOKEN
GitLab CI + Kestra
⬜ TODO (after LinkedIn API access)
GOOGLE_BUSINESS_TOKEN
GitLab CI + Kestra
⬜ TODO (after GBP API setup)
Tech Stack
Layer
Tool
Cost
Role
Orchestration
Kestra (self-hosted)
Free
Cron schedules, task coordination, retry logic
Source control
GitLab.com
Free
Workflow YAML, config, content templates
Dev environment
code-server (LXC 304)
Free
Browser IDE for editing flows + scripts
Content storage
Google Drive (60GB)
Free
Photos, videos, logos — large binary media
Content generation
ChatGPT (OpenAI API)
Pay-per-use (~$0.01/caption)
Caption drafting, hashtag brainstorming
Local LLM (backup)
Ollama (192.168.122.20)
Free
Fallback caption gen, no API cost
Weather data
OpenWeatherMap
Free (1000 calls/day)
Weather-reactive content
Trending hashtags
RiteKit
Free (100 calls/mo)
Real-time hashtag optimization
TikTok trends
Apify scraper
Pay-per-run (pennies)
TikTok Creative Center trending data
Publishing
Buffer API
Free– $30/mo
Single API → all 5 platforms
Publishing (backup)
Kestra plugin-meta
Free
Direct FB + IG posting
Project management
Plane CE
Free (self-hosted)
Annie's task board, hiring triggers
Deployment Steps (Updated)
Phase 1: Foundation (Done)
Create GitLab repo ✅
Push scaffold ✅
Add CI variables (Kestra, OpenAI, OpenWeather) ✅
Build + test preflight checks ✅
Build + test weather caption flow ✅
Phase 2: Publishing Pipeline (This Week)
Sign up for Buffer → connect platforms → add API token
Sign up for RiteKit → get API key
Build hashtag-rotation.yml config
Build hashtag-selector.py script (Tier 1-4 + rotation logic)
Build platform-formatter.py (per-platform caption + hashtag assembly)
Build full daily-post-rotation workflow (preflight → gen → hashtags → format → Buffer)
Test end-to-end: one real post on one platform
Phase 3: Content & Handoff (Before Launch)
Seed content library (10+ photos, 7 caption templates)
Annie reviews brand voice + hashtag sets
Enable cron schedules
Set up Kestra ↔ GitLab sync (auto-pull from repo every 15 min)
Publish GCP OAuth app (prevent token expiry)
Phase 4: Analytics & Optimization (After Launch)
Build hashtag-performance weekly analytics workflow
Set up A/B testing framework (same content, different hashtag sets)
Connect Buffer analytics → Kestra for automated optimization
Add Apify TikTok trending scraper to daily pipeline
Decision Framework Score
Gate
Score
Reason
Time
5
Zero daily posting effort once live — fully automated
Net Worth
4
Consistent presence builds brand → more customers at trailer
Freedom
5
Marketing runs without Sam; scales across all trailers
Total
14
Execute
Repos to Evaluate (from research)
Created 2026-08-13. Updated 2026-08-14 with Buffer publishing layer, hashtag engine,
and research findings.