# Build an SMS Triage Bot on Telnyx Edge Compute

> Source: <https://dev.to/sonam_50a41a4ced7e6b4f3fa/build-an-sms-triage-bot-on-telnyx-edge-compute-4gin>
> Published: 2026-08-13 18:58:07+00:00

Support SMS inboxes are usually a routing problem before they are an AI problem.

Someone asks about billing. Someone else needs technical support. A third person wants to talk to sales. The app has to understand the message, pick the right destination, reply to the customer, and remember what happened.

This TypeScript example does that on Telnyx Edge Compute with the Agent SDK.

Code: [https://github.com/team-telnyx/telnyx-code-examples/tree/main/agent-sms-triage-bot](https://github.com/team-telnyx/telnyx-code-examples/tree/main/agent-sms-triage-bot)

`agent-sms-triage-bot`

receives inbound SMS webhooks, classifies each message into one of four topics, looks up the route for that topic, replies by SMS, and stores triage history in durable actor state.

The topics are:

`billing`

`support`

`sales`

`general`

The default route table maps those topics to queue names:

``` php
billing -> billing-queue
support -> support-queue
sales   -> sales-queue
general -> general-queue
php
Inbound SMS
  -> POST /webhooks/sms
  -> TriageAgent.triage(from, text)
  -> Telnyx AI Inference classifies topic
  -> durable route table lookup
  -> SMS reply
  -> triage history update
```

The app uses one `TriageAgent`

actor per inbound number. That actor stores route rules, recent history, total messages, and topic counts.

`POST /webhooks/sms`

receives Telnyx `message.received`

events`POST /debug/triage`

simulates inbound SMS`POST /routes`

updates the route table`GET /routes`

lists route rules`GET /history`

returns recent triage history`GET /debug/state`

inspects actor state`GET /health/liveness`

and `GET /health/readiness`

provide health checksThe core class is `TriageAgent`

.

It extends the Agent SDK `Agent`

class and uses durable state for:

The AI classification call uses the Telnyx binding:

``` js
const completion = await this.env.TELNYX.ai.openai.chat.createCompletion({
  model: this.env.AI_MODEL || "moonshotai/Kimi-K2.6",
  messages: [
    { role: "system", content: CLASSIFY_SYSTEM_PROMPT },
    { role: "user", content: `Customer message: "${text}"` },
  ],
  max_tokens: 2000,
  temperature: 0.2,
});
```

The SMS reply uses the same binding pattern:

```
await this.env.TELNYX.messages.send({
  from: state.fromNumber || state.phoneNumber,
  to: from,
  text: replyText,
});
```

That means the example does not hardcode an API key in application code. Messaging and inference both go through `this.env.TELNYX`

.

After deploying with `telnyx-edge ship`

, you can test without sending a real SMS:

```
curl -X POST https://agent-sms-triage-bot-<id>.telnyxcompute.com/debug/triage \
  -H "Content-Type: application/json" \
  -d '{"from":"<customer-number>","to":"<triage-number>","text":"Why was I charged twice this month?"}'
```

Example response:

```
{
  "action": "triaged",
  "from": "<customer-number>",
  "to": "<triage-number>",
  "text": "Why was I charged twice this month?",
  "topic": "billing",
  "route": "billing-queue",
  "confidence": 0.95
}
```

Then inspect the actor history:

```
curl "https://agent-sms-triage-bot-<id>.telnyxcompute.com/history?number=<triage-number>"
```

For a small support workflow, this keeps the first version compact:

You can later replace queue names with real integrations: Slack, Zendesk, Salesforce, email, or an internal queue.

Before using this with real customer traffic, I would add:

Resources:
