DEV Community

KunStudio
KunStudio

Posted on • Originally published at cancel-helper.pages.dev

Why a cancellation-script generator is a lookup table and a template matrix, not an LLM call

Why a cancellation-script generator is a lookup table and a template matrix, not an LLM call

The obvious way to build "write me a cancellation message" is to send the service name and a goal to a language model and let it generate the paragraph. I built Cancel Helper the other way — a known-service lookup table plus a fixed template matrix — because the moment the output starts citing consumer-protection law, "usually right" stops being good enough.

A known-service table with fuzzy lookup

Common services (streaming, gyms, software subscriptions) get an entry in a KNOWN table: which channel actually works for that provider (web form vs. a phone line vs. in-person only), a provider-specific gotcha worth knowing before you start, and — for gym contracts especially — the retention tactic to expect. lookupKnown() normalizes whatever the user typed (lowercased, + expanded to "plus", punctuation stripped) and tries an exact slug match first, then falls back to substring/keyword matching, so "Netflix", "netflix premium", and "NETFLIX" all resolve to the same entry without the user having to type the name exactly right. Each known entry also carries a three-tier difficulty rating, shown as a small pip meter, so someone dealing with a gym contract knows upfront it's a harder path than cancelling a streaming subscription in an app.

The template matrix instead of a per-request generation call

buildScript() takes three inputs — goal (cancel / refund / cut short a signup trial / reach a human), channel (phone / email / chat / app-store), and tone (plain / cites-the-law) — and assembles one of a fixed set of reviewed paragraphs by string concatenation. Nothing here is generated per request; every combination is a known, previously-read piece of text. The store channel gets a special case regardless of goal: App Store and Google Play subscriptions have to be cancelled in the store itself, because the merchant on the other end of the message has no ability to stop that billing even if they wanted to — a script politely asking a company to cancel a charge it doesn't control would just waste the user's time.

Why the legal-tone branch is the actual reason not to use a model here

The tone toggle's second option cites specific consumer-protection law: the federal Restore Online Shoppers' Confidence Act, the Fair Credit Billing Act for disputed charges, and the FTC's complaint channel. That's exactly the category of claim a generative model will produce fluently and occasionally wrong — a plausible-sounding statute name, a slightly-off requirement, a citation that doesn't exist. A fixed string gets checked once, by a person, and then reused verbatim for every request instead of being reconstructed (and re-risked) every time. The upside of a small, owned piece of text over a model call isn't just consistency — it's that legal-adjacent copy can be kept current on purpose: the tool's own rights summary explicitly notes that the FTC's broader "click to cancel" rule was vacated by a federal court in mid-2025 and a revival attempt was underway as of early 2026, a detail that would already be stale if it were baked into a model's training data instead of a string that gets reviewed when the law changes.

Disclosing the affiliate step instead of hiding it

Past the script itself, there's a single goal-aware recommendation block — which partner it points to depends on whether the user picked cancel, refund, cut-short-a-trial, or reach-a-human — tagged rel="sponsored" and carrying a plain disclosure line stated in the block itself rather than buried in a footer: that a signup may earn a commission, that it never changes what the user pays, and that the partner isn't affiliated with the tool. Putting the disclosure in the same block as the pitch, instead of a separate terms page, was the easy part; not routing every goal to the same generic pitch was the part actually worth doing.

Live tool: https://cancel-helper.pages.dev/?utm_source=devto&utm_medium=backlink

Happy to go deeper on the fuzzy-lookup normalization or the goal/channel/tone template matrix if useful — drop a comment.

Top comments (0)