sns-network-solutions/businesses/sns-hospitality-group/marketing/DEPLOY-README.md

19 KiB
Raw Blame History

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:

  1. Sign up at buffer.com
  2. Connect all 5 social accounts
  3. Generate API token
  4. 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)
  • 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 repohttps://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)

  • Google Business Profile created for The Daily Pour
  • Facebook Business Page created
  • Instagram Business Account connected to Facebook page
  • TikTok Business Account created
  • LinkedIn Company Page created (SnS Hospitality Group or The Daily Pour)

Content Library (Annie — ongoing, seed before launch)

  • Logos — PNG (dark/light/icon), SVG source
  • Product photos — at least 10 menu item shots
  • Trailer photos — exterior, window, signage (even mockups/renders to start)
  • Video clips (optional for launch) — espresso pulls, morning prep, b-roll
  • Brand voice doc — committed to repo
  • Hashtag sets — committed to repo (expand with Tier 2/3/4 config)
  • Rules doc — committed to repo
  • Platform config — committed to repo

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)

  1. Create GitLab repo
  2. Push scaffold
  3. Add CI variables (Kestra, OpenAI, OpenWeather)
  4. Build + test preflight checks
  5. Build + test weather caption flow

Phase 2: Publishing Pipeline (This Week)

  1. Sign up for Buffer → connect platforms → add API token
  2. Sign up for RiteKit → get API key
  3. Build hashtag-rotation.yml config
  4. Build hashtag-selector.py script (Tier 1-4 + rotation logic)
  5. Build platform-formatter.py (per-platform caption + hashtag assembly)
  6. Build full daily-post-rotation workflow (preflight → gen → hashtags → format → Buffer)
  7. Test end-to-end: one real post on one platform

Phase 3: Content & Handoff (Before Launch)

  1. Seed content library (10+ photos, 7 caption templates)
  2. Annie reviews brand voice + hashtag sets
  3. Enable cron schedules
  4. Set up Kestra ↔ GitLab sync (auto-pull from repo every 15 min)
  5. Publish GCP OAuth app (prevent token expiry)

Phase 4: Analytics & Optimization (After Launch)

  1. Build hashtag-performance weekly analytics workflow
  2. Set up A/B testing framework (same content, different hashtag sets)
  3. Connect Buffer analytics → Kestra for automated optimization
  4. 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)

Repo What Action
charlie947/social-media-skills Claude skills behind 350K-follower creator Fork post-writer + post-scorer for caption logic
rampstackco/claude-skills 65 Claude skills including SEO/content Adapt keyword research → hashtag research

Created 2026-08-13. Updated 2026-08-14 with Buffer publishing layer, hashtag engine, and research findings.