AI Levels the Field for Neighborhood Franchises
Image Credit: Gemini
Small franchises lose to big chains on staff, not on product. A neighborhood waffle cart, a two-branch cafe, a community drugstore — each has regulars. Big brands have CRM teams to chase lapsed buyers. Small teams have a phone, a spreadsheet, and no time.
This post shows the system we built to close that gap: AI researches the market, writes one offer twenty different ways, and packages the whole thing as a reusable skill. Outreach becomes drafts in Gmail. A mail-tracker plugin tells us what got read. No new hires.
The starting point: scattered listings
Franchise contacts in the Philippines live in three places: the Philippine Franchise Association directory, official brand sites, and branch-level pages that may or may not be current. Names differ. Emails change. Some listings show a head-office trunkline where a franchise email should be.
We pulled all of it into one CSV: local-franchises.csv with franchise_name, contact_person, email, mobile_number, website, social_links, address. Sixteen national brands first. Then five Panay-origin brands (coffee, waffles, batchoy, pasalubong, chicken inato). Then six Calabarzon-linked brands (beverage kiosks, coffee, drugstores, Batangas food, Laguna buko pie). Twenty-seven rows. Twenty-four with a usable email.
AI did the bulk reading: PFA product pages for the formal contact, brand sites for the current franchising email, branch pages for the local proof (an outlet address, a branch phone). The judgment calls stayed human. Pure region-origin national franchisors are few, so we labeled footprint honestly instead of inventing origin stories. Single-location icons with no franchise program were excluded with a note rather than forced into the pipeline. Rows without email were skipped, not faked — no info@ guesses.
Lesson one: AI research works when the schema is strict and the skip rules are explicit.
One offer, twenty different bodies
The offer never changed: a trial Database Reactivation Service to bring back 100 past customers. SMS plus email against the franchise’s own list. Positive replies only get follow-ups. Bookings land on the team’s calendar and CRM. Live in seven to fourteen days.
What changed was the body. A waffle cart and a drugstore do not lose customers the same way.
We segmented into four buckets: QSR and dine-in, kiosk and beverage and bakery, pharmacy and refill, convenience. Each bucket got its own strategic line tied to the Christmas season. QSR talked about reunion tables and party bundles. Kiosks talked about mall and school foot traffic. Pharmacies talked about maintenance refills lapsing before December and rushing all at once. Convenience talked about late-night and last-minute December runs.
The template stayed fixed. The tokens moved: headline, greeting, strategic line, offer line, outlet hint. Jollibee’s draft mentions family feasts and party orders. Coffeebreak’s mentions Arsenal and Metro branches and lapsed regulars choosing where to meet. Generika’s mentions San Pablo City and early refills. Same engine, different letter. Readers can tell when a paragraph was written for them versus mail-merged at them. The extra sentence about their street, their product, their December is what gets the reply.
Lesson two: personalization is not a first-name token. It is one true sentence about their business.
Three examples from the run show the range. The waffle cart’s draft talked about mall and school foot traffic and sending buyers back to Iloilo outlets. The cafe’s draft talked about lapsed regulars choosing where to meet for Christmas and named the Arsenal and Metro branches. The drugstore’s draft talked about maintenance buyers lapsing before December and refilling early at San Pablo City. Same trial, same buttons, same footer. Different reason to return. Each draft took the same template and swapped four tokens: headline, greeting, strategic line, outlet hint. Generating twenty more was a loop, not a rewrite.
The copy rules stayed tight throughout. Short sentences. No throat-clearing openers, no tripled adjectives, no pull-quote closers. When every email makes exactly one ask, the ask gets answered.
HTML Gmail actually renders
The first drafts were plain text. They worked. They looked cheap next to a holiday inbox.
The HTML versions follow Gmail’s rules, which are closer to 2009 than 2026. No <style> block in the head. No JavaScript. No external stylesheets. No inline SVG — Gmail strips most of it, Outlook mangles the rest. Everything is a 600-pixel table, inline CSS, absolute URLs, and alt text with background-color fallbacks so a blocked-image view still reads.
Each email has a hosted hero banner and a thin divider, both PNGs on a CDN with width attributes and fluid max-width:100% styling. Two buttons carry the calls to action: visit the site (with UTM parameters for source, medium, and campaign) and book a meeting on Calendly. A plain-text version of both links sits below the buttons for clients that strip styling. The footer states the trial scope, the opt-in rule, and a one-line footnote that SMS is subject to network availability.
Total images stay small. Every image has a job: the hero sets the season, the divider separates the ask from the offer. Nothing decorates for its own sake.
Lesson three: design for the lowest common inbox and the email looks good everywhere.
From one-off work to a skill
The first three drafts were handmade. The next twenty were generated. That is the whole point of the project: do it once by hand, then encode it.
The local skill lives at .opencode/skills/franchise-reactivation/ with four parts. SKILL.md states the inputs (CSV path, goal count, season, CTA URLs, graphics), the workflow (filter emailed rows, segment, render, draft), and the guardrails (reactivation-only, drafts never sent, skip no-email rows, stop-slop copy, Gmail-safe HTML, SMS footnote, UTM links). templates/xmas-reactivation.html holds the layout with named tokens. scripts/gen_drafts.py reads the CSV, picks the segment, and writes one HTML file per franchise into drafts/. scripts/send_drafts.py builds a text/html MIME message per file, encodes it base64url, and calls the Gmail API through the workspace CLI to create drafts. It deletes by matching subject first, so re-runs refresh instead of duplicating.
Two commands repeat the entire campaign for a new season or a new list:
uv run python .opencode/skills/franchise-reactivation/scripts/gen_drafts.py
uv run python .opencode/skills/franchise-reactivation/scripts/send_drafts.py
The scripts run inside the repo’s virtual environment. An early version tried shell heredocs and died on quoting; writing script files and running them proved sturdier. The Gmail schema was checked before the first call rather than guessed. Draft creation sends a base64url-encoded MIME payload through the workspace CLI, and refreshes delete by matching subject so re-runs never duplicate. Twenty drafts took minutes, not an afternoon. Small discipline, large time savings.
Lesson four: a skill is a checklist with working code attached.
The tracker bonus
A mail-tracker plugin in Gmail turned the campaign into an experiment for free. Each draft reports delivery and opens, which means subject lines compete honestly: diners versus buyers versus shoppers versus refill reminders, QSR versus pharmacy versus kiosk. The next round keeps the winners and rewrites the losers. No extra instrumentation. The inbox becomes the dashboard.
For a small franchise team this matters more than it looks. They cannot A/B test like a national brand. Twenty tracked drafts give them open-rate signal they would never otherwise see. The trial sells reactivation. The tracker teaches messaging. Over two or three seasons the data compounds: which streets respond, which products pull people back, which subject verbs earn the open. A team of three ends up with the instincts of a team of thirty, because every send leaves a trace.
What small teams should copy
Start with the list, not the copy. One CSV with real emails beats ten clever subject lines. Nail one offer before adding channels — reactivation alone carries a holiday season. Write the template once, then spend your energy on the single true sentence per recipient. Build for Gmail’s limits and skip anything Gmail eats. Encode the process the second time you run it, not the fifth. Measure opens even with a free plugin; direction beats precision. And keep the human gate: AI proposes, a person approves, the draft sends only when it sounds like someone who has eaten the food, visited the branch, and means the invitation.
Big chains win with headcount. Neighborhood franchises can win with focus: their own customer list, a timely reason to return, and AI doing the research and drafting that used to take a team. The field looks more level from a full dining room in December.
Last modified: 10 Sep 2026