Skip to main content

Overview

This recipe builds a technician-facing chat agent that hands out work on demand: an engineer messages Neo in Teams — “give me my next ticket” — and Neo finds the most urgent eligible ticket in your helpdesk queue and assigns it to them. It’s pull-based dispatch — technicians take work when they’re ready, instead of a dispatcher (or an automation) pushing it to them.
This is an Internal chat agent deployed as a custom internal bot — your prompt, your tools, your branding, running with your full MSP toolbox. New to chat agents? Start with Building a chat agent.

Why a chat agent — and not a “request ticket” workflow

It’s tempting to build this as a workflow triggered off a ticket: give each technician a permanent “status ticket” they flip to “Request Next Ticket”, and let the change fire an agent that assigns them work. Don’t. Neo’s agents keep conversation continuity per ticket by design, so a single ticket re-triggered for every request accumulates history until the agent loses track of the live queue and starts reporting “no tickets available” when eligible ones are sitting there. A chat agent is the right model:
  • Each request is a normal chat turn — no long-lived entity to accrue stale state.
  • The technician is identified automatically from their Teams sign-in, so Neo can assign to “them” without anyone typing a resource ID.
  • /reset (or /new) starts a clean conversation whenever a technician wants one.

How it works

  1. A technician messages your branded internal bot in Teams (“what should I work on next?”).
  2. The agent queries your live helpdesk queue for eligible, unassigned tickets and orders them by SLA.
  3. It re-checks the top candidate is still free, then assigns it to the requesting technician and replies with the ticket to start on.
  4. If nothing qualifies right now, it says so and asks them to check back shortly.

Setup

1

Create the Internal chat agent

ChatNew Chat Agent. Set Audience to Internal — this is a technician-facing agent that runs with your full MSP toolbox (an End-user agent is locked to one company and can’t dispatch).
  • Name: “Next Ticket” (or whatever your team will recognize in Teams)
2

Enable the toolbox

The agent needs to read the queue and write the assignment — nothing else:
  • PSA integration (ConnectWise / Autotask / Halo) → Tickets: Read & Write. Read lets the agent query the live queue; write covers setting the owner, moving the status, and adding an audit note. The agent assigns by writing to the ticket directly — it’s given the requesting technician’s PSA resource ID (from Technician Mapping, below), so there’s no separate assignment tool to add.
Keep the toolbox tight: a dispatch agent only needs to find tickets and assign them. Don’t add M365, RMM, or other write tools it won’t use.
Autotask only: assigning an owner needs the resource and its role together — assignedResourceID + assignedResourceRoleID — Autotask rejects one without the other. Two things make this just work:
  • Neo allows the assignedResourceRoleID field automatically whenever you allow assignedResourceID, so if you scope the Tickets permission to specific fields, list assignedResourceID and status — the role rides along, nothing else to configure.
  • Also enable Resources: Read so the agent can look up the engineer’s default service-desk role to send alongside.
ConnectWise and Halo have no such pairing — Tickets: Read & Write is enough.
3

Write the dispatch policy

This is the part that matters most — the rules that decide which ticket and how it’s assigned. Adapt the queue ID, statuses, and classifications to your PSA (the example uses fictitious values):
# Next-Ticket Dispatch — 1st-Line Helpdesk

You hand one 1st-line ticket to the technician who is asking, on request.

## How you're used
A technician messages you (e.g. "give me my next ticket"). Treat each message as one
request: find the single best eligible ticket and assign it to them. Never assign more
than one ticket per request.

## Who is asking
The requester is identified from their verified Teams identity, and their details — including
their PSA resource ID — are given to you in the Requesting Technician section. Assign the ticket
to that resource ID. Never ask the technician for, or guess, a PSA resource ID.

## Eligibility (hard rules — never override)
A ticket qualifies only if ALL of these are true:
- It is in the 1st Line Helpdesk queue (queue ID 12345).
- Its status is one of: New, New - Customer Note Added, Approval Required.
- It is unassigned (no current owner).
- It is not completed or closed.
- Its company's classification is Gold or Silver.
Assigned, completed, closed, or an out-of-scope classification are hard stops — never
work around them.

## Choosing the ticket
1. Query the live helpdesk queue for eligible tickets. Always pull fresh from the PSA —
   never reuse a list from memory or an earlier message.
2. Order the results by first-response SLA target, soonest due first.
3. Take the most urgent candidate, then re-fetch THAT ticket live and confirm it is still
   eligible (unassigned, allowed status, not completed, in-scope classification) right
   before assigning — another technician may have just taken it.
4. If it no longer qualifies, discard it and move to the next candidate. Repeat until one
   passes or the list is exhausted.

## Assigning
- Assign the confirmed ticket to the requesting technician as the primary owner — using their
  PSA resource ID from the Requesting Technician section — and set its status to In Progress.
- Reply in the chat with the ticket number, title, a one-line summary, and a
  clickable link to the ticket in the PSA so the technician can open it in one
  click. Always include the link.
- Add a short internal note on the ticket noting it was self-dispatched via Neo.

## When nothing qualifies
Only after re-validating live that no candidate qualifies, tell the technician there are
no eligible tickets right now and to ask again shortly. Never invent or assume a ticket.
The two load-bearing rules are “always pull the queue fresh” and “re-fetch and confirm the candidate is still unassigned right before assigning.” Together they keep the agent honest about the live queue and safe when several technicians ask at once — that second re-check is what stops two simultaneous requests from double-booking the same ticket. See Writing effective agent instructions for the general guide.
4

Connect Technician Mapping (required to assign to the requester)

“Assign to me” only works if Neo knows which PSA technician each Teams user is. Connect the Microsoft Teams — Technician Mapping & Availability integration in your own tenant and run its auto-map — it links each technician to their Microsoft account.A technician who isn’t mapped gets a clear message asking their Neo admin to set this up, rather than a wrong assignment. (Connecting this integration only does the mapping; it doesn’t change anything about Ticket Dispatch unless you separately turn on Teams availability there.)The same mapping is what lets Neo load the requesting technician’s profile — name, IDs, and their custom instructions — into the conversation, which the next section builds on.
5

Test in the dashboard

Chat with the agent on the Chat page and ask for a ticket. Confirm it queries the queue, picks the most urgent eligible ticket, and — when you turn off test mode — actually assigns it. With test mode on, it describes the assignment instead of making it, so you can tune the policy safely first.
6

Deploy it to your technicians

ChatChannelsNew Channel: Audience: Internal, transport Teams, assign this agent, set your branding. Then follow the custom internal bot guide to Install in your tenant and roll it out to everyone — an Internal bot installs only in your own Microsoft 365 tenant.

Per-technician rules (e.g. by customer classification)

The policy above applies the same eligibility to everyone. If different engineers handle different work — say each team only takes certain customer classifications — you don’t need a separate rule per person in the agent prompt. On every turn, Neo automatically gives the agent the requesting technician’s profile, including their custom instructions, resolved from the same Teams mapping above. So you can scope per technician on the profile, and have the policy defer to it:
  1. On each technician’s profile (the Technicians area / Profiles tab), set their custom instructions — e.g. “Only assign tickets where the company classification is Gold.”
  2. In the dispatch policy, treat the requester’s standing instructions as additional eligibility:
## Per-technician scope
The requesting technician's standing instructions (their profile custom instructions, shown
to you in the Requesting Technician section) may narrow what they can take — e.g. to certain
customer classifications, queues, or companies. Apply them as extra hard-eligibility rules for
this request. If they don't restrict anything, fall back to the eligibility above.
Because the rule lives on the profile, onboarding an engineer is just setting their instructions — no agent edit, and a blank profile falls back to the agent’s default eligibility. The technician must be mapped (previous step) for their profile to load; an unmapped technician is asked to get mapped rather than dispatched against the wrong scope.

What technicians experience

A technician opens your bot in Teams and asks for work in their own words. Neo replies with the ticket to pick up — number, title, a one-line summary, and a clickable link straight to it in the PSA — and the ticket is already assigned to them and In Progress. When the queue is empty, Neo says so and to check back shortly. /reset starts a fresh conversation any time.

Keeping it reliable

  • One ticket per request. The policy assigns exactly one ticket per message — technicians come back for the next one when they’re ready.
  • Fresh queue every time. The agent must query the live PSA on every request; never let it reuse an earlier result.
  • Re-validate before assigning. The candidate is re-fetched and confirmed unassigned immediately before the write, so two technicians asking at the same moment can’t be handed the same ticket. This re-check is the safeguard against double-booking — keep it in the policy.
  • Keep technicians mapped. Coverage depends on the Technician Mapping auto-map. When you onboard an engineer, re-run it (or add a manual mapping on the Profiles tab) so “assign to me” works for them on day one.

Troubleshooting

What you seeWhyFix
”Ask your Neo admin to map your account”The technician isn’t linked to a Microsoft accountConnect Technician Mapping and run auto-map, or add a manual mapping on the Profiles tab
”No eligible tickets” when you can see some in the PSAYour eligibility rules don’t match the queue’s reality (wrong queue ID, status names, or classifications)Re-check the hard-eligibility section against your PSA’s actual queue, statuses, and company classifications
The agent assigns to the wrong personIt used a name or guessed an ID instead of the requester’s identityMake sure the policy says to assign using the PSA resource ID from the Requesting Technician section — never a name or a guessed ID
Autotask: assignment fails / “must assign both a resource and a role”The agent set the resource but not the required role, or Resources read is off so it can’t resolve oneConfirm Resources: Read is enabled; Neo already allows assignedResourceRoleID automatically when assignedResourceID is allowed, so no field-list change is needed
The same ticket goes to two techniciansThe candidate wasn’t re-checked before assigningConfirm the “re-fetch and confirm still unassigned right before assigning” rule is present in the policy
A technician gets tickets outside their scope (or their profile rule is ignored)The policy doesn’t defer to the requester’s standing instructions, or the technician isn’t mapped so no profile loadsAdd the per-technician scope rule to the policy, set the technician’s profile custom instructions, and confirm they’re mapped