How a renewal gets prepared
The drafter only works on accounts that are in the registry, with the facts the offer needs — plan, price, renewal date, a usage signal, and a little history. So the first job is making sure the registry actually reflects your customers. There are three ways an account gets in: somebody types a row in the Drive sheet, somebody forwards a contract or a usage export to a dedicated address, or somebody puts a renewal date on a Google Calendar with a small tag. The first one is obvious. The other two exist because in real life nobody types a row for the deal they just closed.
Key takeaways
- Three intake lanes feed one registry: the Drive sheet, an inbox-forwarding lane, and a calendar import.
- Forwarded contracts are parsed by Textract; usage CSVs are read directly; Bedrock Haiku 4.5 proposes a row.
- Every parsed row goes to a rep’s Slack for one-tap approval before it lands in the registry.
- Calendar events tagged
#renewsget pulled hourly via the Google Calendar API. - The registry stays the canonical store. The other lanes are conveniences that write into it.
Three lanes into one registry
Lane 1: the Drive sheet itself
The simplest lane. Open the registry sheet in Drive, add a row, save. The columns are short: name, plan, current price, renewal date, usage signal, owner email, and a short history. A small Lambda — drive-sync — runs every fifteen minutes, exports the sheet as plain CSV via the Drive API, and writes it to s3://rn-registry-source/registry.csv if the sheet has changed since the last sync. The drafter reads from S3, not Drive directly. That keeps Drive API calls predictable and gives you S3 versioning for free, so a bad bulk-edit can be rolled back in one click.
This lane covers the bulk of your setup: export your billing system once, paste in the accounts, and you’re done. Most existing customers go in this way on day one.
Lane 2: inbox forwarding (the lane most teams actually use)
Set up a dedicated inbound address — something like renewals@your-company.com — via Amazon SES. Anyone on the team forwards a signed contract PDF or a usage-export CSV to that address and the system takes it from there. SES writes the raw MIME to s3://rn-raw-mime/. The S3 PUT triggers a parser Lambda. The Lambda walks the MIME tree to the attachment. For a PDF it runs Amazon Textract (Textract reads PDF, PNG, JPEG, and TIFF natively); for a CSV or spreadsheet it reads the rows directly with openpyxl or the CSV module. Either way it gets back the extracted text and tables.
Then a Bedrock Haiku 4.5 call reads the content and emits a structured row: name, plan, price, renewal date, usage signal (if present), and an owner-suggestion based on the “To” line of the original forward. The model prompt is short: “Extract an account row for the registry. Return JSON only. Mark each field with a confidence score. Do not invent a renewal date or a price that isn’t in the document.” The output goes to a small Slack interactive message that pings the rep who forwarded the email: the proposed row, the confidence per field, and three buttons — approve, edit, discard. On approve, a Lambda writes the row to the Drive sheet via the Sheets API. On edit, the rep gets a fillable modal pre-populated with the proposal. On discard, the message is logged and the file moved to a discarded prefix in S3 for audit.
The reason every parsed row goes to a human first is simple: a renewal date or a price the model misread is worse than an account that never made it into the registry at all. The misread one will quietly drive a wrong offer to a real customer.
Lane 3: calendar import
Some teams already track renewal dates on a calendar. The big enterprise deal is on the account manager’s calendar with a reminder. The annual retainer is on the founder’s calendar. Forcing those teams to also type rows in a sheet is a fight you don’t need to have on day one.
Lane 3 picks up calendar events tagged with #renews in the description. A small calendar-sync Lambda runs hourly, iterates through the configured Google Calendars (using a service-account credential stored in Secrets Manager), and pulls any events with the tag whose start time is in the future. Each pulled event becomes a proposal in the same Slack flow as Lane 2 — one-tap approve to add to the registry. Once approved, the calendar event can stay where it is or be deleted; the registry now owns the renewal.
Calendar import is the most opt-in of the three lanes. A team that doesn’t use it loses nothing; a team that does avoids retyping dates they already typed once.
Why the registry stays the source of truth
Three lanes in, but only one place where the drafter actually looks. That’s a deliberate constraint. If two lanes both wrote directly to the drafter’s state, every “why did this offer get prepared?” question would mean checking three places. Funneling everything through the Drive sheet means there is exactly one row per account, and any rep can read or edit any of it without learning a new tool. The convenience lanes are first-class for getting accounts in, but they always pass through the sheet on the way.
Next post: how the drafter reads an account, picks the plan and discount from your rules, and calls Bedrock to write the offer in your voice.
All posts