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
- A technician messages your branded internal bot in Teams (“what should I work on next?”).
- The agent queries your live helpdesk queue for eligible, unassigned tickets and orders them by SLA.
- It re-checks the top candidate is still free, then assigns it to the requesting technician and replies with the ticket to start on.
- If nothing qualifies right now, it says so and asks them to check back shortly.
Setup
Create the Internal chat agent
Chat → New 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)
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.
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
assignedResourceRoleIDfield automatically whenever you allowassignedResourceID, so if you scope the Tickets permission to specific fields, listassignedResourceIDandstatus— 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.
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):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.
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.
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.
Deploy it to your technicians
Chat → Channels → New 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:- 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.”
- In the dispatch policy, treat the requester’s standing instructions as additional eligibility:
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 see | Why | Fix |
|---|---|---|
| ”Ask your Neo admin to map your account” | The technician isn’t linked to a Microsoft account | Connect 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 PSA | Your 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 person | It used a name or guessed an ID instead of the requester’s identity | Make 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 one | Confirm 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 technicians | The candidate wasn’t re-checked before assigning | Confirm 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 loads | Add the per-technician scope rule to the policy, set the technician’s profile custom instructions, and confirm they’re mapped |
Related
- Custom internal bot — how the Teams deployment works
- Assign Technician (Basic) — the push alternative: Neo assigns automatically on a trigger or schedule, no one asks
