AINode.jsAutomation

AI-Powered SMS Response Bot with Twilio

TT
TopicTrick Team
AI-Powered SMS Response Bot with Twilio

AI-Powered SMS Response Bot with Twilio

SMS is the most universally accessible communication channel — no app, no account, works on every phone. This tool builds an intelligent two-way SMS bot that reads incoming messages and responds with GPT-4o, maintaining conversation context per phone number.

This is Tool 16 of the Build 50 AI Automation Tools course.


What You'll Build

  • Receive incoming SMS via Twilio webhook
  • Generate intelligent GPT-4o responses
  • Maintain conversation history per phone number
  • Custom commands: HELP, STOP, RESET

Setup

bash
mkdir sms-bot && cd sms-bot
npm init -y
npm install express twilio openai dotenv
bash
# .env
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=your-auth-token
TWILIO_PHONE_NUMBER=+15551234567
OPENAI_API_KEY=sk-your-key-here
PORT=3000

Get credentials from console.twilio.com.


SMS Bot Server

js
// src/server.js
import 'dotenv/config';
import express from 'express';
import twilio from 'twilio';
import OpenAI from 'openai';

const app = express();
app.use(express.urlencoded({ extended: false }));

const client = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const { MessagingResponse } = twilio.twiml;

// Conversation history per phone number
const conversations = new Map();

const SYSTEM_PROMPT = `You are a helpful AI assistant responding via SMS.
Rules:
- Keep responses under 160 characters when possible (one SMS)
- If more detail is needed, keep under 320 characters
- Be direct and helpful — no unnecessary pleasantries
- If asked for a list, use simple numbered format: 1) ... 2) ...
- Never use markdown formatting (no **bold**, no #headers)`;

async function generateReply(from, message) {
  if (!conversations.has(from)) conversations.set(from, []);
  const history = conversations.get(from);

  history.push({ role: 'user', content: message });

  const response = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [
      { role: 'system', content: SYSTEM_PROMPT },
      ...history.slice(-6), // Last 3 exchanges
    ],
    temperature: 0.7,
    max_tokens: 200,
  });

  const reply = response.choices[0].message.content.trim();
  history.push({ role: 'assistant', content: reply });

  // Keep history manageable
  if (history.length > 20) history.splice(0, 2);

  return reply;
}

// Twilio webhook — receives incoming SMS
app.post('/sms', async (req, res) => {
  const { Body: message, From: from } = req.body;
  const twiml = new MessagingResponse();

  let reply;

  if (!message?.trim()) {
    reply = 'Hi! Send me a message and I\'ll help you.';
  } else if (message.toUpperCase() === 'STOP') {
    conversations.delete(from);
    reply = 'You have been unsubscribed. Reply START to opt back in.';
  } else if (message.toUpperCase() === 'RESET') {
    conversations.delete(from);
    reply = 'Conversation cleared. How can I help you?';
  } else if (message.toUpperCase() === 'HELP') {
    reply = 'Commands: RESET (clear history), STOP (unsubscribe). Ask me anything!';
  } else {
    try {
      reply = await generateReply(from, message);
    } catch (err) {
      console.error(err);
      reply = 'Sorry, I had trouble processing that. Please try again.';
    }
  }

  twiml.message(reply);
  res.type('text/xml').send(twiml.toString());
});

// Send outbound SMS
app.post('/send', async (req, res, next) => {
  try {
    const { to, message } = req.body;
    if (!to || !message) return res.status(400).json({ error: 'to and message required' });

    const msg = await client.messages.create({
      body: message,
      from: process.env.TWILIO_PHONE_NUMBER,
      to,
    });

    res.json({ success: true, sid: msg.sid });
  } catch (err) { next(err); }
});

app.get('/health', (_req, res) => res.json({ status: 'ok' }));
app.use((err, _req, res, _next) => res.status(500).json({ error: err.message }));
app.listen(process.env.PORT ?? 3000, () => console.log('SMS Bot running'));

Connecting Twilio

  1. In the Twilio Console, go to Phone Numbers → Manage → Active Numbers
  2. Click your Twilio number
  3. Under Messaging, set A MESSAGE COMES IN webhook to: https://your-ngrok-url.ngrok.io/sms
  4. Method: HTTP POST
  5. Save

For development, use ngrok: ngrok http 3000


Testing

bash
# Send a test outbound SMS
curl -X POST http://localhost:3000/send \
  -H "Content-Type: application/json" \
  -d '{"to": "+15559876543", "message": "Hello from your AI SMS bot!"}'

Then text your Twilio number from your phone:

text
You: What is the capital of France?
Bot: Paris is the capital of France, with a population of about 2.1 million in the city proper.

You: How far is it from London?
Bot: Paris is about 340 km (214 miles) from London. By Eurostar, it takes around 2.5 hours.

Business Use Case: FAQ Bot

js
const FAQ_SYSTEM_PROMPT = `You are the customer support bot for Acme Coffee Roasters.

Business info:
- Hours: Mon-Fri 8am-6pm EST
- Shipping: Free over $50, otherwise $5.99
- Subscriptions: Weekly, bi-weekly, monthly
- Returns: 30-day satisfaction guarantee
- Phone: 555-COFFEE

Answer questions about our products and policies. If you cannot help, tell them to call 555-COFFEE during business hours.
Keep responses under 160 characters when possible.`;

WhatsApp Support

Change the sending number to a WhatsApp-enabled number:

js
const msg = await client.messages.create({
  body: message,
  from: 'whatsapp:+15551234567',  // WhatsApp-enabled Twilio number
  to: `whatsapp:${to}`,
});

Build 50 AI Automation Tools — Tool 16 of 50

SMS bot is live. Phase 3 complete. Continue to Phase 4 with Tool 17: Image Caption Generator with GPT-4o Vision.


    Summary

    • Twilio webhook receives incoming SMS and the bot responds with TwiML in under 1 second
    • Per-phone conversation history enables natural multi-turn SMS conversations
    • Built-in commands (STOP, RESET, HELP) give users control over the experience
    • gpt-4o-mini balances quality and cost — at $0.15/1M tokens, 1,000 SMS conversations cost under $0.10
    • Replace the system prompt to deploy for customer support, appointment booking, or FAQ handling

    Continue to Tool 17: Image Caption Generator with GPT-4o Vision →