Work/sAIge

sAIge: one helpdesk bot for web, Teams and the phone

TEKsystems built sAIge to take routine IT requests away from human service-desk agents. I designed how it fit together: the channels, the conversation flows, and the integrations that let it actually change things in ServiceNow instead of pointing people at a form.

Role
Engineer, then architecture and flow design, then module lead
Company
TEKsystems Global Services
Timeline
2020 – 2025
Stack
Dialogflow, Node.js, GCP, Azure, ServiceNow, NICE inContact

01Context

Most of what reaches an IT service desk is the same handful of requests. Where's my ticket. Add this screenshot to it. Close it, it's fixed. My direct report is locked out. Each one is simple, and each one used to mean a queue and a person.

sAIge was built so employees could get those done themselves, in a browser, inside Microsoft Teams, or on a phone call. The point was that it would do the work, not just link to a form. In its first release it covered ten kinds of request:

  • Create, add a note to, close, cancel, resolve or reopen a ServiceNow ticket, with attachments
  • Reset a direct report's password after the manager confirms a one-time code
  • Search the knowledge base, then ask whether the article actually helped
  • Request access to an application, or order a replacement charger for a registered device

If the bot couldn't finish, the conversation went to a live agent.

02My role

I joined as an associate engineer and wrote the pieces first: Node.js Cloud Functions for the ServiceNow calls, the multi-factor check, and the reads and writes to Datastore. Over the next few years the job moved up a level. I designed conversation flows for each client's requirements, then the architecture those flows sat on, and eventually led the team that deployed it for clients.

Why it matters for a PM role

This is where I learned to turn "the client wants the bot to handle X" into a flow, an API contract and a test plan, and to say no when X would break something else.

03Architecture

Three front doors, one agent, and everything that touches a real system kept in webhooks behind it.

saige / architecture.svgrequests flowing
CHANNELS CONVERSATION SYSTEMS Web UIAngular · Azure AD sign-in Microsoft TeamsAzure Bot Framework PhoneNICE inContact IVR Dialogflow agent intents, flows, entities same agent for all channels Webhooks (Node.js) Cloud Functions App Engine REST APIs Data Datastore · Pub/Sub → Cloud SQL ServiceNowTable API · Attachment API Azure ADusers synced by a timed Azure Function OTP serviceTOTP server + SMS Knowledge basearticle search Live agentNICE inContact handoff
Simplified. Per-client variations and environments left out.

The web UI signed people in with their Microsoft work account through Azure AD. Teams reached the same agent through the Azure Bot Framework, and phone calls came in through NICE inContact's IVR. Behind the agent, Node.js webhooks on Cloud Functions and App Engine did anything that touched a real system: ServiceNow's Table and Attachment APIs, the one-time-code service, knowledge search. A timed Azure Function kept user data from Azure AD in sync, and ticket events went through Pub/Sub into Cloud SQL for reporting.

04Decisions

D1One agent, three front doors

Web, Teams and voice all talk to the same Dialogflow agent. Fix a flow once and it's fixed everywhere, and reporting covers every channel without stitching.

Trade-offVoice needs shorter prompts and fewer choices than a chat window, so some flows carry channel-specific branches. More to test on every change.

D2Verify the manager, not the employee

Resetting a direct report's password hands someone access to another person's account. So the bot sends a one-time code to the manager's registered mobile, and the temporary password goes by text to that same device.

Trade-offOne more step than a plain "reset" button. For this action, the step stays.

D3Keep integrations out of the conversation layer

Dialogflow handles language. Anything that reads or writes a real system lives in the Node.js webhooks. That boundary paid off later, when a client needed Okta and Zendesk in place of Azure AD and ServiceNow.

Trade-offAn extra hop on every request, and a service layer to deploy and monitor on its own.

D4Always leave a way out to a person

If the bot can't finish, Teams and phone users go to a live agent through NICE inContact. A bot that traps people generates more tickets than it closes.

Trade-offEvery handoff is a cost to the service desk, so handoffs have to be tracked and pushed down over time.

05Results

0
channels on one agent: web, Teams, phone
0
request types handled end to end
0
IVR bot systems taken to production

I don't have usage numbers I'm able to publish. What I can say: sAIge ran in production for service-desk clients, and its password-reset flow was the starting point for the Okta and Zendesk rebuild.

06Under the hood

What I designed or built myself:

saige / what-i-built.log
  • servicenow Node.js Cloud Functions on the Table and Attachment APIs, behind every ticket action the bot takes.
  • identity A multi-factor check in Cloud Functions, and a TOTP server built on the speakeasy library for one-time codes.
  • live agents App Engine APIs that connect a Teams conversation straight to a NICE inContact agent.
  • voice The Dialogflow agent wired into NICE inContact's IVR, so the same bot answers the phone.
  • azure AD app registrations for single sign-on and the Bot Service, plus a time-triggered Azure Function that syncs users from AD into a database.
  • frontend The REST API between the Dialogflow agent and the web UI.
  • data A Pub/Sub topic and subscription, with App Engine code that writes each message to MySQL.

07Looking back

I'd log bot-versus-human outcomes from the first release. We only built that view properly on the Okta project, and once it existed, every roadmap conversation got shorter. The same data from day one would have settled a lot of early arguments.

Next case studyMoving a voice password-reset bot from Azure AD to Okta
esc
↑ ↓ move↵ open