Part 2 of 7 · Staff policy answerer series ~4 min read

How a staff question reaches the answerer

The answerer can only help with questions it actually receives. So the first job is meeting people where they already are. There are three ways a question gets in: somebody DMs the assistant in Slack, somebody @-mentions it in a shared channel like #ask-hr, or somebody emails a dedicated address. The first two are how most teams will use it. The third exists because not everyone lives in Slack — the warehouse, the shop floor, the contractor who only has email. All three end up in the same place and run through the same answer flow.

Key takeaways

  • Three intake lanes feed one answer flow: a Slack DM, a channel @-mention, and an email fallback.
  • Slack events hit a Lambda Function URL; the request is verified before anything else runs.
  • The assistant replies in the same thread, so the question and answer stay together.
  • Email questions come in via SES inbound and get answered with a plain-text reply.
  • One question normalizer means the rest of the system never cares which lane a question came from.

Three lanes into one answer flow

Three intake lanes funnel into one answer flow A diagram with three vertical lane columns at the top and a single unified row at the bottom. Lane one, Slack DM: an employee sends a direct message to the assistant's Slack app; Slack posts a message event to a Lambda Function URL; the Lambda verifies the Slack signing secret, acknowledges within three seconds, and hands the question to the answer flow. Lane two, Channel mention: an employee @-mentions the assistant in a shared channel like ask-hr; the same Slack app_mention event hits the same Function URL and runs the same verification; the reply is posted back as a threaded message so the channel isn't cluttered. Lane three, Email fallback: an employee emails a dedicated address, policy-at-your-company; SES writes the raw MIME to S3; a small parser Lambda pulls out the question text and the sender, then hands it to the same answer flow; the reply goes back out via SES outbound. All three lanes converge on the same question normalizer, which puts every question into one shape — question text, who asked, and where to reply — so the rest of the system never cares which lane it came from. A note at the bottom: the channel and the DM are how most teams ask; email is the fallback so nobody is left out. Lane 1 · direct Slack DM • Staff DMs the assistant app • Event hits the Function URL • Signature verified, ack in 3 seconds • Reply in the same DM thread Lane 2 · @-mention Channel mention • @-mention in a shared channel • Same Function URL, same verify • app_mention event carries the text • Reply as a thread, channel stays clean Lane 3 · email Email fallback • Email the policy-address • SES writes MIME to S3 • Parser pulls the question + sender • Reply via SES outbound email Question normalizer (one shape for all lanes) question text · who asked · where to reply · thread id · channel the rest of the system never cares which lane the question came from to answerer, Part 3 The DM and the channel are how most teams ask — email is the fallback so nobody is left out.
Fig 2. Three lanes converge on one question normalizer. Slack DMs and channel mentions hit a Function URL; email comes in through SES. After the normalizer, every question is the same shape, so the answerer never has to know where it came from.

Lane 1: the Slack DM

The most private lane, and the one people reach for when the question feels personal — leave, a benefit, a rule they’re slightly embarrassed to not know. The staff member opens a direct message with the assistant’s Slack app and types their question. Slack sends a message event to a Lambda Function URL (a plain web address that runs a Lambda — no API Gateway in front of it). The Lambda’s very first job is to verify the request really came from Slack, using the signing secret stored in Secrets Manager. Slack expects an acknowledgment within three seconds, so the Lambda confirms receipt immediately and does the actual answering in the background, posting the reply back into the same DM thread when it’s ready.

Keeping the reply in the same thread matters: the question and the answer stay together, so if the person asks a follow-up the assistant has the context, and if they want to forward the answer to a teammate, it travels as one tidy exchange.

Lane 2: the channel @-mention (the one HR will love)

A shared channel — call it #ask-hr — is where the answerer earns its keep, because answers become public knowledge. Someone @-mentions the assistant: “@policy-bot what’s the work-from-home rule on Mondays?” The same Slack app sends an app_mention event to the same Function URL, runs the same verification, and the answer is posted back as a threaded reply so the channel itself stays scannable. The next person with the same question can search the channel and find it, or just ask again and get the same grounded answer.

This is the lane that quietly takes load off HR. The first time a question is answered in the channel, it’s answered for everyone, with the section link right there for anyone who wants to check it.

Lane 3: email fallback

Not everyone is in Slack all day. The warehouse team, the shop floor, a part-time contractor — for them, a dedicated email address is the lane that works. Set up policy@your-company.com via Amazon SES. An email to that address gets written as raw MIME to an S3 bucket; the S3 write triggers a small parser Lambda that walks the MIME, pulls out the plain question text and the sender’s address, and hands it to the same answer flow as the other two lanes. The answer comes back as a plain-text reply via SES outbound — same grounded answer, same section link, just delivered as an email instead of a Slack message.

Email is the most opt-in of the three lanes. A team that lives in Slack may never use it; a team with staff off the keyboard needs it on day one.

Why everything passes through one normalizer

Three lanes in, but only one shape of question after the front door. That’s deliberate. The moment a question lands, the intake Lambda turns it into the same small record regardless of source: the question text, who asked, where to reply (Slack thread or email address), and a timestamp. Everything downstream — finding the right handbook section, asking the model, deciding whether to hand off to HR — works off that one record. If you later add a fourth lane (a Microsoft Teams app, a kiosk on the shop floor), you write one more small intake adapter and the rest of the system doesn’t change.

Next post: how the answerer takes that normalized question, finds the few handbook sections most likely to hold the answer, and grounds its reply in them.

All posts