$npx -y skills add gooseworks-ai/goose-skills --skill render-imessage-chatAssemble an iMessage chat-reveal video ad from a thread JSON — one continuous Playwright recording of the conversation animating in (typing dots, composer typing, bubble pops, auto-scroll) crossfaded into a designed end card, with iMessage send/receive SFX and an optional ducked
| 1 | # render-imessage-chat |
| 2 | |
| 3 | The free renderer for the **imessage-chat** video ad format — a texting-thread |
| 4 | reveal where a friend-to-friend conversation animates in on a phone (typing |
| 5 | indicators, composer typing, bubble pops, smooth auto-scroll) and lands on a |
| 6 | designed brand end card. Deterministic Playwright + ffmpeg assembly; no |
| 7 | generative video of the UI, so bubble text and the wordmark stay pixel-crisp. |
| 8 | |
| 9 | This capability is the generic assembler — the template recipe (DB) supplies the |
| 10 | per-brand `thread`, product image, and `end_card` config, and gates the paid |
| 11 | calls (product image → create-image-fal, music bed → create-music-elevenlabs) to |
| 12 | their own capabilities. It bundles the iMessage-mockup HTML generator + the |
| 13 | send/receive SFX so a chat render is self-contained and $0. |
| 14 | |
| 15 | ## The three defects it fixes (QA GOOSE-2481) |
| 16 | |
| 17 | 1. **Rich-link attachment** — a product/link renders as a REAL iMessage URL |
| 18 | preview: the image (top-rounded corners) flush against a gray meta card with a |
| 19 | bold title + domain subtitle + chevron. NOT a bare image with a distorted |
| 20 | caption floating centered below it (the mockup's default `.attachment-meta`). |
| 21 | The fix is baked into `record-chat.js`'s injected style, theme-aware. |
| 22 | 2. **No text bleed** — every bubble fits. This is an AUTHORING rule the recipe |
| 23 | enforces: split any long line into multiple short bubbles (see the two `spec` |
| 24 | lines in `config.example.json`). The renderer honors the thread it's given. |
| 25 | 3. **A designed end card** — wordmark + ⭐ proof row + trust trio + CTA pill |
| 26 | (`render-end-card.js` + `end-card.template.html`), not a bare logo. |
| 27 | |
| 28 | ## Run |
| 29 | |
| 30 | ```bash |
| 31 | cd scripts && npm install # once — installs Playwright for the recorders |
| 32 | node record-chat.js --config config.json --out-dir <work> # → master-chat.mp4 + .sfx.json |
| 33 | node render-end-card.js --config config.json --out-dir <work> # → scene-end-endcard.mp4 |
| 34 | bash stitch.sh --chat <work>/master-chat.mp4 --end <work>/scene-end-endcard.mp4 \ |
| 35 | --sfx <work>/master-chat.sfx.json --out <work>/master-final.mp4 \ |
| 36 | [--music <work>/music-bed.mp3] [--also-1x1] |
| 37 | ``` |
| 38 | |
| 39 | 1. **`record-chat.js`** — reads `config.json` (`thread` + `theme` + geometry + |
| 40 | optional `background_image`), derives a believable per-message timeline |
| 41 | (received bubbles pop after an optional `…`; sent bubbles are typed out in the |
| 42 | composer then popped + Delivered; attachments dwell so a rich link lands), |
| 43 | records it as one continuous MP4, and emits a deterministic SFX cue list. |
| 44 | 2. **`render-end-card.js`** — fills `end-card.template.html` from `config.end_card` |
| 45 | (wordmark/`logo_svg`, stars, proof text, trust trio, CTA, colors) → still MP4. |
| 46 | 3. **`stitch.sh`** — crossfades chat → end card, layers the send/receive SFX (from |
| 47 | the cue list; the mp3s ship in `assets/sfx`), optionally ducks a music bed |
| 48 | under it, and optionally derives a 1:1 variant. All FREE ffmpeg. |
| 49 | |
| 50 | ## Contract |
| 51 | |
| 52 | - FREE assembly: Playwright record + ffmpeg composite/mux + the bundled SFX. No |
| 53 | AI-rendered text — the bubbles, rich-link title/domain, and end-card copy are |
| 54 | all real HTML/PIL, never invented by a model. |
| 55 | - The recipe (DB) supplies the per-brand config: the `thread` (kept short — split |
| 56 | long lines), the product image bound into the attachment, the `end_card` |
| 57 | (prefer a real `logo_svg` wordmark), theme (dark default), and an optional |
| 58 | `background_image` (a flat-lay behind the phone) + optional music bed. |
| 59 | - Craft rules preserved from the reference build (Wonderbly Concept E): |
| 60 | - Rich-link attachment card (image top-rounded, flush on the gray meta card). |
| 61 | - Keep messages SHORT — split long thoughts into multiple bubbles (no bleed). |
| 62 | - You never see your own typing dots — sent messages type in the composer. |
| 63 | - Attachment dwell (~3.6s) so the product/link registers. |
| 64 | - Designed end card (wordmark + proof + trust trio + CTA), not a bare logo. |
| 65 | |
| 66 | ## Gaps / routing notes |
| 67 | |
| 68 | - **Product image** (the attachment) and the optional **music bed** are inputs, |
| 69 | not generated here — the recipe gates them to `create-image-fal` / |
| 70 | `create-music-elevenlabs` (paid, proxy-routed, billed to the Ads agent). Pass |
| 71 | the resulting files into the config / `stitch.sh --music`. |
| 72 | - **Background flat-lay** is optional; omit it for a clean neutral gradient behind |
| 73 | the phone, or generate one via `create-image-fal` and point `background_image` |
| 74 | at it. |
| 75 | - Requires **ffmpeg/ffprobe** on PATH and Playwright Chromium (`npx playwright |
| 76 | inst |