Part 4 of 7 · Social inbox unifier series ~5 min read

How a DM finds the right teammate

The message is labeled with a topic and an urgency, and it’s not a duplicate. Now the system has to put it in front of one person — the right person, who’s actually working, who isn’t already buried, with enough context to answer without digging. Get any of those wrong and the message either sits in the queue of someone who’s off, or piles onto the one teammate who never says no. Four small guardrails sit between the labels and the message landing in a specific queue.

Key takeaways

  • Topic resolution: the message’s topic maps to the team that owns it in the rules doc.
  • Working hours: a teammate who’s off-shift is skipped, so messages don’t sit in an empty queue.
  • Fair load-sharing: among eligible teammates, the one with the fewest open threads gets it.
  • Every assignment carries the full thread, the labels, and the customer history — no digging.
  • If nobody’s eligible or a thread sits too long, it routes to a backup and posts in a team channel.

Four guardrails on every assignment

Four guardrails between a labeled message and the right teammate's queue A horizontal flow diagram. On the far left, a "Labeled message" box: the labeler produced a message with a topic, an urgency, and a language. Four guardrail gates sit in a row to the right, each drawn as a vertical bar. Gate 1: Resolve team — maps the topic to the team that owns it in the rules doc, for example refund to billing or shipping to ops; if the topic has no mapping, falls back to a general team. Gate 2: Working hours — checks each candidate teammate's working hours and status; teammates who are off-shift or marked away are skipped, so a message never lands in an empty queue. Gate 3: Fair load — among the eligible teammates, picks the one with the fewest open threads right now, so the load spreads evenly instead of piling on whoever answered last; urgent messages can interrupt to the least-loaded person immediately. Gate 4: Attach context — gathers the full thread history, the labels, the customer's past conversations, and any handy reply templates for the topic, so the teammate has everything in one view. After all four gates pass, the message is assigned and lands in that teammate's queue in the shared inbox, sorted by urgency. A note at the bottom: if no teammate is eligible, or a thread sits past its urgency target, it routes to a backup and is posted in a team channel so nothing falls through. Labeled msg topic, urgency, language Gate 1 Resolve team topic → team from rules doc e.g. refund → billing; no map? general team Gate 2 Working hours on shift and not away? skip anyone off, so no empty queue Gate 3 Fair load fewest open threads wins urgent can interrupt the least loaded Gate 4 Attach context full thread + labels + past chats, templates for the topic Assigned — lands in the teammate’s queue in the shared inbox sorted by urgency · one thread per conversation every assignment logged to DDB — reassignments keep the trail No one eligible, or a thread sits too long? It routes to a backup and posts in a team channel.
Fig 4. Four guardrails between the labels and the right queue. Resolve the team. Skip anyone off-shift. Spread the load fairly. Attach the full context. Then assign and sort by urgency — and back everything up so nothing sits unseen.

Gate 1: resolve the team from the topic

Routing starts with the topic the labeler gave the message. The rules doc has a short table that maps each topic to the team that owns it: refund and billing questions to the billing folks, shipping and order questions to ops, partnership and press to the owner, everything-else to a general team. That table is config, so the team can change who owns “wholesale” without anyone touching code. If a message comes in with a topic that isn’t mapped — rare, but it happens with a brand-new kind of question — it falls back to the general team rather than getting stuck. The general team’s job partly is to spot those and add a mapping for next time.

Gate 2: skip anyone who’s off

Assigning a message to someone who clocked out three hours ago is the same as not assigning it at all — worse, because it looks handled. So Gate 2 narrows the team down to the people actually working. Each teammate has working hours in their profile and a status they can flip to “away” for a long lunch or a sick day. Anyone off-shift or away is skipped. If a whole team is off — say a refund comes in at 2am and billing only works days — the message waits in the team’s shared lane and is the first thing they see in the morning, and if its urgency target would be blown by waiting, the backup path in the note takes over.

Gate 3: spread the load fairly

Among the teammates who are on-shift and own the topic, the system picks the one with the fewest open threads right now. This is the small piece of fairness that keeps a shared inbox from becoming one person’s burden. Without it, messages tend to pile on whoever is fastest or most senior, who then burns out while others sit idle. The count of open threads per teammate is kept in DynamoDB and updated as threads open and close, so the choice is always based on the current moment, not a fixed rotation. An urgent message is allowed to jump in: it goes to the least-loaded eligible person immediately and sorts to the top of their queue, rather than waiting its turn behind normal-priority threads.

Gate 4: attach the context, then assign

The last gate makes sure the teammate doesn’t have to go hunting for anything. It bundles the full thread (every message in the conversation so far, across whatever platforms it touched), the labels, the customer’s recent history with you (“messaged twice last month about the same order”), and a few reply templates for the topic that the teammate can start from if they want. All of that travels with the message into the assigned queue, so opening the thread shows everything in one view. The teammate reads, decides, and writes — which is Part 5.

Every assignment writes a row to DynamoDB: which thread, which teammate, when, and why (the topic and urgency that drove it). Reassignments later write their own rows, so the trail of who held a thread and when stays complete.

Why the guardrails exist

None of these gates are clever. They’re the small care a good shift lead would take if they were handing out messages by hand — give it to the team that knows the topic, don’t give it to someone who left, don’t dump everything on one person, and hand it over with everything they need to answer. Writing them as four plain checks in code means the team doesn’t depend on a shift lead being awake and paying attention at 9pm on a Saturday. And because none of it involves a model, the routing is fast and predictable: the same message, with the same team on shift, always lands the same way.

Next post: what happens when a teammate opens the thread — how a human writes the reply, how it goes back out through the right platform, and how a thread gets reassigned or closed.

All posts