How a newsletter issue gets approved and sent
A review message lands in the owner’s Slack at 8:03am. This week’s issue is drafted, the sources are shown, there are three buttons. What happens when one gets tapped? The honest answer is “it depends which one.” This post walks through the three things the owner can do — approve, edit, skip — and how the send, the item state, and the audit trail all stay in sync. The one rule underneath all of it: nothing reaches the list until the owner approves.
Key takeaways
- Three actions per review: approve (queue to send), edit (change the draft), skip (don’t send this week).
- Approve waits out a cooling-off window before sending, so a typo caught late can still be pulled.
- Edit opens the draft in a doc; re-submitting re-runs the grounding check on the changed text.
- A sent issue marks its items as used, so they don’t show up in next week’s count.
- Every action writes a before-and-after snapshot to the audit trail.
Three actions on the review message
Action 1: approve (the most common)
The owner read the issue, the sources check out, the voice sounds right. They tap Approve. The button submits to a Function URL Lambda. The Lambda marks the issue approved in nc-issues, then — and this is the part that matters — it doesn’t send right away. It starts a cooling-off window by creating a one-off EventBridge Scheduler rule (default 30 minutes, set in the rules doc). During that window the review message shows a small “Sending in 28 min — [Pull it back]” line. If the owner spots a typo two minutes after approving, they tap Pull it back and the issue returns to draft, unsent.
When the window closes, the Scheduler invokes the send Lambda. It renders the final issue, sends it to the subscriber list through SES outbound (in batches, respecting SES send limits), marks every item used in the issue as used in nc-items-state so it won’t pad a future count, and writes a sent row to nc-audit with the recipient count and a snapshot of exactly what went out. The cooling-off window is the difference between “a send is permanent the instant you tap a button” and “a send is permanent after a half-hour grace period.” For something as hard to unsend as an email blast, that half hour earns its keep.
Action 2: edit (the most useful)
Often the issue is 90% right. The owner likes it but would phrase the opening differently, or wants to drop one item, or wants to add a line of their own. They tap Edit. A Lambda copies the draft into a Google Doc in the issues folder, pre-filled with the current text, and replies with the link. The owner edits the Doc like any other document — rewrite the intro, delete a paragraph, tighten the sign-off — and taps a Re-submit button when they’re done.
Re-submit matters more than it looks. The changed text goes back through the same grounding check from Part 4: any new sentence the owner added is checked against the items too, and if they wrote a claim with no source, it’s flagged on the fresh review message. The owner’s own edits don’t get a free pass on accuracy. The re-composed review message comes back with the updated draft and the three buttons again. Editing can loop as many times as needed; the issue only sends when the owner finally taps Approve.
Action 3: skip (the “not this week”)
Sometimes the owner reads the draft and decides it can wait. Maybe a bigger announcement is coming next week and they’d rather lead with it. Maybe the items are fine but thin and they’d rather hold for one more. Maybe the timing is wrong — a sober week isn’t the moment for a cheerful update. They tap Skip.
Skip writes a skipped row to nc-audit and marks the issue skipped in nc-issues. Crucially, it does not mark the items as used. They stay fresh in nc-items-state, so next week’s run counts them again alongside whatever new items arrived. Nothing is lost by skipping — the week’s news simply waits and joins the next issue. This is the manual twin of the automatic skip from Part 3: there, the composer skips because there aren’t enough items; here, the owner skips because the timing isn’t right. Both are logged the same way, so the trail always explains why an issue did or didn’t go out.
Every action is logged, every send is reversible up to a point
The nc-audit table records every approve, edit, skip, and pull-back with the user who acted, the timestamp, and a snapshot of the draft before and after. Up until the cooling-off window closes, an approval is fully reversible — the pull-back returns the issue to draft and nothing went out. After the send, the snapshot is your record of exactly what every subscriber received, which is what you’ll want the next time someone asks “wait, did we say that?” six months later.
There’s no “undo a sent email” button, because there’s no such thing — once SES hands the mail to the world, it’s gone. That’s exactly why the cooling-off window, the grounding check, and the owner’s approval all sit in front of the send. The system spends its care before the irreversible step, not after it.
Next post: the cost breakdown. The whole pipeline above runs in coffee-money territory at SMB volume; Part 6 explains exactly where the dollars go and why the weekly draft is the one real line item.
All posts