Handling SMS
Process incoming text messages with router.sms()
Handle incoming SMS messages sent to a phone number. Phone numbers are configured in code and integrated with Twilio automatically when deployed.
Routes Location
All routes live in src/api/. Import agents you need and call them directly.
Basic Example
import { createRouter } from '@agentuity/runtime';
import smsResponder from '@agent/sms-responder';
const router = createRouter();
router.sms({ number: '+1234567890' }, async (c) => {
// Parse Twilio payload
const formData = await c.req.parseBody();
const from = formData['From'] as string;
const body = formData['Body'] as string;
const reply = await smsResponder.run({
sender: from,
message: body,
});
// Return value is sent as SMS reply
return c.text(reply);
});
export default router;Parsing Twilio Payloads
Twilio sends webhooks in form-encoded format by default, but can also send JSON:
import smsHandler from '@agent/sms-handler';
router.sms({ number: '+1234567890' }, async (c) => {
let from = 'unknown';
let body = '';
const contentType = c.req.header('content-type') || '';
if (contentType.includes('application/x-www-form-urlencoded')) {
// Default Twilio format
const formData = await c.req.parseBody();
from = formData['From'] as string;
body = formData['Body'] as string;
} else if (contentType.includes('application/json')) {
// JSON format (if configured)
const data = await c.req.json();
from = data.From || data.from;
body = data.Body || data.message;
}
const reply = await smsHandler.run({ from, body });
return c.text(reply);
});Full Example
An SMS handler that processes commands:
import { createRouter } from '@agentuity/runtime';
import statusChecker from '@agent/status-checker';
import balanceChecker from '@agent/balance-checker';
const router = createRouter();
router.sms({ number: '+1234567890' }, async (c) => {
try {
const formData = await c.req.parseBody();
const from = formData['From'] as string;
const body = (formData['Body'] as string).trim().toLowerCase();
c.var.logger.info('SMS received', { from, body });
// Handle commands
if (body === 'help') {
return c.text('Commands: STATUS, BALANCE, HELP');
}
if (body === 'status') {
const status = await statusChecker.run({ userId: from });
return c.text(`Your status: ${status.message}`);
}
if (body === 'balance') {
const balance = await balanceChecker.run({ phone: from });
return c.text(`Balance: $${balance.amount}`);
}
// Default response
return c.text('Unknown command. Text HELP for options.');
} catch (error) {
c.var.logger.error('SMS processing failed', { error });
return c.text('Sorry, something went wrong. Try again later.');
}
});
export default router;Phone Number Format
Phone numbers must use E.164 international format: +[country code][number] with no spaces or dashes (e.g., +1234567890).
How Replies Work
The text you return from the handler is automatically sent as an SMS reply to the sender. Agentuity handles the Twilio TwiML response format for you.
// This text is sent back to the sender as an SMS
return c.text('Thanks for your message!');Standalone Usage
SMS handlers work without agents. This example sends an auto-reply based on keywords:
import { createRouter } from '@agentuity/runtime';
const router = createRouter();
router.sms({ number: '+1234567890' }, async (c) => {
const formData = await c.req.parseBody();
const body = (formData['Body'] as string).toLowerCase();
if (body.includes('hours')) {
return c.text('We are open Mon-Fri 9am-5pm EST.');
}
return c.text('Thanks for your message! Reply HOURS for business hours.');
});
export default router;Next Steps
- Email Handling: Process incoming emails
- WebSockets: Real-time bidirectional communication
- HTTP Routes: Standard API endpoints
Need Help?
Join our Community for assistance or just to hang with other humans building agents.
Send us an email at hi@agentuity.com if you'd like to get in touch.
Please Follow us on
If you haven't already, please Signup for your free account now and start building your first agent!