# Launch Plan: BillionMail + FrostByte Go-Live ## Summary FrostByte at `/Users/imorgado/Desktop/Workspace/projects/frostbyte/` is production-ready (14 integrations). Needs: LLM layer refactor for GLM-4.7, API key setup via Chrome DevTools, VPS provisioning, domain/DNS creation, frontend fixes. --- ## Monthly Cost: ~$56/mo at launch, ~$95/mo with video | Service | Cost | Notes | |---|---|---| | Hetzner VPS (CX22) | $7-12 | 2 vCPU, 4GB RAM, Ubuntu | | GLM-4.7 | $0 | Yearly plan, OpenAI-compatible API | | Apollo.io Basic | $49 | 5K credits + unlimited emails | | Cal.com (free cloud) | $0 | 30-min meetings, Google Calendar | | RapidAPI LinkedIn | $0 | Free tier | | Cartesia (voice) | Usage-based | TTS + voice clone | | SyncLabs (lip sync) | Usage-based | Lip sync API | | Cloudflare R2 | ~$0-5 | Video/thumbnail storage | | **Launch total** | **~$56-61** | | | **With video** | **~$65-80** | Depends on volume | --- ## PHASE 1: Refactor FrostByte LLM Layer [DONE] > Completed in `dc2f622`. Provider abstraction added, GLM-4.7 support via OpenAI-compatible client. 351 tests pass. **Changes made:** - `frostbyte/personalization/llm.py` — `LLMProvider` ABC + `AnthropicProvider`, `GroqProvider`, `OpenAICompatProvider`. Config-driven routing with fallback. - `frostbyte/config.py` — Added `glm_api_key`, `glm_base_url`, `glm_model`, `first_touch_provider`, `followup_provider`, `classify_provider` - `pyproject.toml` — Added `openai>=1.0.0` - `.env.example` — Added GLM env vars - Tests updated to match new provider architecture --- ## PHASE 2: Link FrostByte + VPS Setup ### 2a. Symlink FrostByte ```bash ln -s /Users/imorgado/Desktop/Workspace/projects/frostbyte \ /Users/imorgado/Desktop/Workspace/projects/BillionMail/frostbyte ``` Verify Dockerfile EXPOSE vs docker-compose port 8001. ### 2b. Provision Hetzner VPS (Chrome DevTools) 1. Navigate to hetzner.com -> Cloud Console 2. Create CX22 server (2 vCPU, 4GB, Ubuntu 22.04) 3. Note public IP 4. Configure rDNS to match sending domain ### 2c. Create Josh's Workspace Domain (Chrome DevTools) 1. Navigate to admin.google.com -> Account -> Domains -> Manage domains -> Add domain 2. Purchase/add sending domain 3. Verify domain ownership (DNS TXT record) 4. Create josh@ user account 5. This is a prerequisite for DNS records + Gmail app password ### 2d. DNS Records for Sending Domain On the domain registrar, add: - **SPF**: `v=spf1 ip4: include:_spf.google.com ~all` - **DKIM**: Generated by BillionMail after deploy - **DMARC**: `v=DMARC1; p=none; rua=mailto:dmarc@` - **MX**: Point to VPS IP - **rDNS**: Set on Hetzner to match domain --- ## PHASE 3: API Keys via Chrome DevTools Use Chrome DevTools MCP to log into each dashboard and get keys: | # | Service | URL | Free? | |---|---|---|---| | 1 | GLM / Z.AI | api.z.ai | Yes (yearly plan) | | 2 | Apollo.io | app.apollo.io -> Settings -> API | $49/mo Basic | | 3 | RapidAPI | rapidapi.com -> Fresh LinkedIn Profile Data | Free tier | | 4 | Cal.com | cal.com -> Settings -> Security -> API Key | Free | | 5 | Gmail App Password | myaccount.google.com -> Security -> App Passwords | Free | | 6 | Cartesia | cartesia.ai (voice clone + TTS) | Usage-based | | 7 | SyncLabs | synclabs.so (lip sync) | Usage-based | | 8 | Cloudflare R2 | dash.cloudflare.com (video storage) | ~$0-5/mo | Write to `/Users/imorgado/Desktop/Workspace/projects/frostbyte/.env`: ```env # LLM (GLM-4.7 via yearly plan) GLM_API_KEY= GLM_BASE_URL=https://api.z.ai/api/paas/v4/ GLM_MODEL=glm-4.7 FIRST_TOUCH_PROVIDER=glm FOLLOWUP_PROVIDER=glm CLASSIFY_PROVIDER=glm # Keep as fallbacks (empty until needed) ANTHROPIC_API_KEY= GROQ_API_KEY= OPENAI_API_KEY= # Enrichment APOLLO_API_KEY= RAPIDAPI_KEY= HUNTER_API_KEY= PROSPEO_API_KEY= # Video Pipeline (Cartesia + SyncLabs + R2) ANTHROPIC_API_KEY= CARTESIA_API_KEY= SYNCLABS_API_KEY= R2_ACCOUNT_ID= R2_ACCESS_KEY_ID= R2_ACCESS_KEY_SECRET= R2_BUCKET_NAME= R2_PUBLIC_URL= VOICE_SAMPLE_URL= VOICE_DEFAULT_ID= # Booking CALCOM_API_KEY= # Gmail GMAIL_APP_PASSWORDS={"josh@":""} # Config SENDING_BACKEND=billionmail SECRET_KEY= NOTIFICATION_EMAIL=josh@ SENDER_NAME=Josh Izzy SENDER_COMPANY=Douro Digital ``` --- ## PHASE 4: Configure BillionMail UI (Chrome DevTools) 1. Navigate to BillionMail instance on VPS 2. Login 3. **Settings > AI Model**: Add GLM-4.7 supplier (base URL + API key) 4. **Settings > SMTP Relay**: Configure Gmail relay 5. **Domain Management**: Add sending domain, generate DKIM keys, verify DNS --- ## PHASE 5: Frontend Fixes (Code Changes) ### 5a. Remove automation stub - **Delete**: `core/frontend/src/views/automation/index.vue` - **Delete**: `core/frontend/src/router/modules/automation.ts` - Remove import from router index ### 5b. Enable sequences create - **File**: `core/frontend/src/views/sequences/list/index.vue:4` — remove `disabled` - **File**: `core/frontend/src/api/modules/sequences.ts` — add `createSequence()`, `toggleSequence()` - **New**: `core/frontend/src/views/sequences/list/components/SequenceForm.vue` (modal pattern) ### 5c. Cleanup - **Delete**: `core/frontend/src/views/contacts/group/temp.vue` ### 5d. i18n - **Files**: `core/frontend/src/i18n/lang/{en,zh,ja}.json` — sequence form keys --- ## PHASE 6: Cal.com + Google Calendar (Chrome DevTools) 1. Josh creates Cal.com account with Workspace email 2. Connect Google Calendar via OAuth 3. Create "30-Minute Meeting" event type 4. Copy API key + event type ID -> frostbyte `.env` 5. Apple Calendar: syncs via Google Calendar bridge --- ## PHASE 7: Deploy & Verify 1. Push code to VPS, `docker-compose up -d` 2. Verify FrostByte: `curl http://:8001/health` 3. Test sequence creation from frontend 4. Test lead scraping via enrichment UI 5. Send test email through sequence engine 6. Verify tracking webhooks ### Verification Checklist - [ ] VPS provisioned, rDNS configured - [ ] Domain created, DNS records set (SPF/DKIM/DMARC) - [ ] FrostByte containers running (api, worker, beat) - [ ] `/health` returns 200 - [ ] GLM-4.7 responds via LLM layer - [ ] Sequences list loads + create works - [ ] Leads list loads - [ ] Enrichment scraper runs - [ ] Gmail relay sends test email - [ ] Cal.com booking link -> Google Calendar - [ ] Automation route gone from nav --- ## POST-LAUNCH BACKLOG ### Blocked on Josh - [ ] Record voice sample (clear audio, 30s+) for Cartesia voice clone - [ ] Set VOICE_SAMPLE_URL or VOICE_DEFAULT_ID in env - [ ] Create Cloudflare R2 bucket + generate API tokens ### How Video Personalization Works (Built in Go) Full pipeline implemented in `core/internal/service/video_gen/`. Per contact: 1. **Enrichment** populates lead data (website_url, business_name, signals) 2. **Screenshots** — Playwright captures homepage, contact, Google pages 3. **Annotate** — ImageMagick overlays signal callouts on screenshots 4. **Script** — Claude Sonnet generates personalized 15-30s narration 5. **Voice** — Cartesia TTS with cloned or default voice 6. **Composite** — FFmpeg stitches annotated images + audio into video 7. **Lip Sync** — SyncLabs adds lip sync (optional, if API key set) 8. **Upload** — Cloudflare R2 storage, generates landing page URL 9. **Update** — Stores video_url, thumbnail_url, landing_page_url in contact attribs ### Feature Gaps - [ ] Leads detail/edit view (frontend only has list) - [ ] Sequences edit UI (can create but not edit) - [ ] Enrichment data results view (UI shows config only) - [ ] Richer video scripts using full enrichment data ### Bug Fixes - [ ] Excel export returns 500 — `core/internal/controller/contact/contact_v1_export_contacts.go:86` - [ ] SSL cert listing returns `CodeNotImplemented` ### Future Upgrades - [ ] Anthropic Claude as fallback LLM (if GLM quality insufficient for English copy) - [ ] Apollo upgrade tiers as credit usage grows - [ ] Alternative TTS providers as fallback to Cartesia --- ## Resolved - GLM endpoint: **api.z.ai** (international), model: **glm-4.7** - Domain: needs creation in Google Workspace (done in Phase 2c via Chrome DevTools) ## Unresolved - What domain name for Josh's sending email? (need to pick/purchase before Phase 2c)