TrueSpec

SMS Notifications with Twilio

Send/receive SMS, verification codes, and webhook handling

What You’ll Build

After following this guide, you will have a working implementation of sms notifications with twilio in your project. Send SMS messages and verification codes using Twilio. Covers sending one-time passwords (OTP) for two-factor auth, transactional SMS notifications, receiving incoming SMS via webhooks, and handling delivery status callbacks.

Use Cases & Problems Solved

  • Send transactional emails reliably without landing in spam folders
  • Set up notification systems that scale with your user base
  • Avoid building email delivery infrastructure from scratch

Prerequisites

  • Twilio account with a phone number
  • Node.js 18+

Step-by-Step Implementation

Install Twilio SDK

The following snippet shows how to install twilio sdk. Copy this into your project and adjust the values for your environment.

npm install twilio

Send SMS and verification codes

The following snippet shows how to send sms and verification codes. Copy this into your project and adjust the values for your environment.

const twilio = require('twilio')(process.env.TWILIO_SID, process.env.TWILIO_AUTH_TOKEN);

// Send a simple SMS
await twilio.messages.create({
  body: 'Your order #1234 has shipped!',
  from: process.env.TWILIO_PHONE_NUMBER,
  to: '+1234567890',
});

// Send OTP verification code
app.post('/auth/send-otp', async (req, res) => {
  const code = Math.floor(100000 + Math.random() * 900000).toString();
  await redis.setex(\`otp:\${req.body.phone}\`, 300, code); // 5 min expiry

  await twilio.messages.create({
    body: \`Your verification code is: \${code}. Expires in 5 minutes.\`,
    from: process.env.TWILIO_PHONE_NUMBER,
    to: req.body.phone,
  });
  res.json({ sent: true });
});

// Verify the OTP
app.post('/auth/verify-otp', async (req, res) => {
  const stored = await redis.get(\`otp:\${req.body.phone}\`);
  if (stored !== req.body.code) return res.status(401).json({ error: 'Invalid code' });
  await redis.del(\`otp:\${req.body.phone}\`);
  res.json({ verified: true });
});

⚠️ Don’t Do This

❌ Using predictable OTP codes or no expiration

// Sequential codes are guessable! No expiration = unlimited attempts
let counter = 0;
const code = (++counter).toString().padStart(6, '0');

✅ Use cryptographically random codes with short expiration

const crypto = require('crypto');
const code = crypto.randomInt(100000, 999999).toString();
await redis.setex(`otp:${phone}`, 300, code); // 5 min, then deleted

Testing

Verify your implementation with these tests:

// __tests__/sms-notifications-with-twilio.test.ts
import { describe, it, expect } from 'vitest';

describe('SMS Notifications with Twilio', () => {
  it('should initialize without errors', () => {
    // Test that the setup completes successfully
    expect(() => setup()).not.toThrow();
  });

  it('should handle the primary use case', async () => {
    const result = await execute();
    expect(result).toBeDefined();
    expect(result.success).toBe(true);
  });

  it('should handle edge cases', async () => {
    // Test with empty/null input
    const result = await execute(null);
    expect(result.error).toBeDefined();
  });
});

Verification

# Send a test SMS:
node send-sms.js +1234567890
# Check your phone for the message
# Test OTP flow: send code, then verify with correct/incorrect codes

Related Specs

Beginner

Send Emails with Resend

React Email templates, attachments, batch sending, and delivery tracking

Email & Notifications
Intermediate

In-App Notification Center

Bell icon, unread count, real-time updates, and mark-as-read

Email & Notifications
Beginner

Email Templates with React Email

Responsive templates, components, preview server, and testing

Email & Notifications