A content moderator on AWS for a few dollars a month
A community page is only as good as the worst comment on it. The spam link that goes up overnight and is the first thing a prospect sees. The personal attack under your most-shared post. The off-topic rant that drowns out a real question. Most small businesses can’t afford a full-time moderator, so the job falls to whoever happens to check the page — which means it gets done late, or not at all. This post walks through the design of a small moderator that checks every new comment, review, or post against your own house rules, lets the obvious-safe ones through, holds the clear rule-breakers for review without ever deleting them, and sends the borderline ones to a person with the reason already attached.
Key takeaways
- Every comment, review, or post arrives through one webhook and is checked the same way.
- Every item ends in one of three calls: pass, hold for review, or send to a human.
- A fast rule pass settles the easy cases; only the borderline middle goes to the model.
- Nothing is ever auto-deleted. Holding is reversible; removal is always a human’s call.
- Designed on AWS for about $2/month at typical small-business volume.
The whole system on one page
Before any code, here’s the shape of what we’re designing.
What you set up once (the outside)
- New content. Wherever people post — your community page, the comments under your posts, your review pages — each new item is sent to the moderator by a webhook (a small message the platform fires whenever something new appears). One item, one message: the author, the text, a link back to where it lives, and which area it belongs to. You set this up once per platform and then forget it.
- A rules folder. Two short Google Docs in a Drive folder. The rules doc holds your house rules in plain words — the banned words and link rules, what counts as spam, what counts as a personal attack, what’s simply off-topic, and which of those mean “hold for review” versus “just flag it.” It also names the reviewer for each area and the quiet hours. The voice doc holds the review-card wording and any auto-reply templates — what the moderator’s message to the poster actually says when an item is removed.
- Moderators. The people who own each area. Each has a Slack member ID (so the review card is a private message, not a public ping) or, if Slack isn’t set up for them, an email address. Cards land with the original item, the proposed call, the confidence, the exact rule the content may break, a link to where it lives, and buttons to publish, remove, or edit-and-publish.
What runs on every item (the inside)
- The intake. A Function URL (a plain web address that runs a small piece of code — no heavy gateway in front) receives the webhook, cleans the text, and stores the item. Then a fast rule pass runs in plain Python: is the author on the known-good list, does the text trip a banned word, does it carry a link from a blocked domain, is it absurdly short or long? Most items are settled right here, with no model. Clean ones pass. Obvious spam is held.
- The checker. Only the borderline middle — the items the rule pass can’t settle on its own — goes to Bedrock Haiku 4.5. The model reads the item against the house rules and returns one of three calls. Pass: it’s fine, publish it. Hold: it clearly breaks a rule — keep it out of public view and queue it for review, but don’t delete it. Send to a human: it’s genuinely borderline — queue it with the reason and the rule so a person can decide. The model always returns a confidence score and the exact rule it leaned on. It never deletes anything.
- The review. Held and flagged items go into a review queue. The right moderator gets a card — in Slack, or email as a fallback — with the item and the proposed call already explained. They publish, remove, or edit-and-publish. Every call is logged. When a moderator overturns the system — publishes something it held, or removes something it passed — that correction is saved as a worked example so the next similar item gets the better call. A weekly digest summarizes what was held, removed, and overturned.
In plain words
A comment lands under your most-shared post at 11pm: “Great tips — check out cheap-deals dot info for even better prices!!!” The rule pass sees a link from a domain on your blocked list and holds the item before anyone sees it. It never goes public. The next morning your community lead, Sam, gets one Slack card: “Held — outbound link to a blocked domain (rule: no promotional links from unknown sites). Confidence high. [Publish] [Remove] [Edit & publish].” Sam taps Remove; the poster gets the polite house reply from the voice doc, and the removal is logged with the reason. Meanwhile a second comment — “this is the dumbest thing I’ve read all week” — isn’t a clear rule break, so the model sends it to a human as borderline. Sam reads it, decides it’s rude but within the line, and taps Publish. The system remembers both calls.
The cost of running this is about $2 a month at SMB volume. The cost of not running it is the spam link that greets your next prospect, or the pile-on under a post that you only notice after it’s done its damage, or the real question that nobody answered because it was buried under noise.
Design rules that shaped every decision
- Three calls, always. Pass, hold, or send to a human. There is no fourth.
- Nothing is auto-deleted. Holding keeps an item out of view but reversible; removal is a person’s call.
- Every flagged item ships with the reason and the exact rule. The moderator never has to guess.
- The cheap rule pass runs first; the model only reads the borderline middle.
- The house rules live in Drive. Changing a rule doesn’t need a deploy.
- Every call is logged, and every overturn teaches the system the better answer.
Why this shape
Most small teams moderate in one of three ways: a blunt keyword filter that blocks half the real comments and misses the clever spam, a platform’s built-in tool that can’t read your house rules, or a person who checks the page when they remember. The keyword filter is too dumb to trust and too noisy to leave on. The built-in tool doesn’t know what “off-topic” means for your business. And the person, of course, isn’t watching at 11pm when the spam goes up.
The setup above keeps the house rules in a doc the team already edits, but adds a small system that checks every new item against that doc the moment it arrives. The cheap rule pass handles the easy nine items out of ten for almost nothing. The model reads only the hard one. Nothing comes down without a person agreeing it should. And every time a moderator disagrees with a call, the system gets a little better at the next one. The moderator is invisible most of the time; visible only on the items that actually need a human.
The next four posts walk through each piece in turn: how a comment gets checked, how a comment gets a verdict, how flagged content reaches a moderator, and how the moderator makes the final call. One diagram per post. A cost breakdown and a final engineering reference at the end.
All posts