Skip to main content

Overview

The WhatsApp resource enables you to send WhatsApp messages with support for attachments, reactions, typing indicators, and automatic SMS fallback for non-WhatsApp users.

Sending Messages

Send a WhatsApp message to a phone number.
const result = await contiguity.whatsapp.send({
  to: '+1234567890',
  message: 'Hello from WhatsApp!',
  from: '+0987654321'
});

console.log(result.message_id);

Parameters

to
string
required
The recipient’s phone number in E.164 format
message
string
required
The message content to send
from
string
The sender’s phone number. If not provided, a number will be automatically selected
attachments
string[]
Array of attachment URLs (images, videos, documents, etc.)
fallback
object
SMS fallback configuration for non-WhatsApp users
fallback.when
array
required
Array of conditions triggering fallback: whatsapp_unsupported or whatsapp_fails
fallback.from
string
Optional different phone number to use for SMS fallback
fast_track
boolean
Enable fast-track delivery for time-sensitive messages

Returns

{
  message_id: string
}

Replying to Messages

Reply to an incoming WhatsApp webhook. This method automatically extracts to and from fields from the webhook event.
import { Contiguity } from 'contiguity';

const contiguity = new Contiguity('your-api-key');

// Inside your webhook handler
app.post('/webhook', async (req, res) => {
  const event = req.body;
  
  const result = await contiguity.whatsapp.reply(event, {
    message: 'Thanks for your WhatsApp message!'
  });
  
  res.json({ success: true });
});

Parameters

event
WebhookEventBase
required
The incoming webhook event object containing data.to and data.from
params
Omit<WhatsappSendParams, 'to' | 'from'>
required
Send parameters excluding to and from (automatically populated from event)

Typing Indicators

Show typing indicators to let users know you’re composing a response.
await contiguity.whatsapp.typing({
  to: '+1234567890',
  action: 'start',
  from: '+0987654321'
});

Parameters

to
string
required
The recipient’s phone number
action
'start' | 'stop'
required
Start or stop the typing indicator
from
string
The sender’s phone number

Reactions

Add or remove reactions (emojis) to WhatsApp messages.
const result = await contiguity.whatsapp.react('add', {
  to: '+1234567890',
  reaction: '❤️',
  message: 'Original message text'
});

Parameters

action
'add' | 'remove'
required
Whether to add or remove the reaction
params
object
required
Reaction parameters
params.to
string
required
The recipient’s phone number
params.reaction
string
The emoji reaction to add or remove
params.message
string
The original message text to react to
At least one of reaction or message must be provided

Complete Conversation Example

import { Contiguity } from 'contiguity';

const contiguity = new Contiguity('your-api-key');

app.post('/webhook/whatsapp', async (req, res) => {
  const event = req.body;
  
  // Show typing indicator
  await contiguity.whatsapp.typing({
    to: event.data.from,
    from: event.data.to,
    action: 'start'
  });
  
  // Simulate processing time
  await new Promise(resolve => setTimeout(resolve, 2000));
  
  // Stop typing indicator
  await contiguity.whatsapp.typing({
    to: event.data.from,
    from: event.data.to,
    action: 'stop'
  });
  
  // Send reply
  await contiguity.whatsapp.reply(event, {
    message: 'Thanks for your message! How can I help?'
  });
  
  res.json({ success: true });
});

Business Use Case Examples

Order Confirmation

async function sendOrderConfirmation(phoneNumber, orderDetails) {
  const result = await contiguity.whatsapp.send({
    to: phoneNumber,
    message: `✅ Order Confirmed!\n\nOrder #${orderDetails.id}\nTotal: $${orderDetails.total}\nEstimated delivery: ${orderDetails.delivery_date}`,
    from: '+1234567890',
    attachments: [orderDetails.receipt_url]
  });
  
  return result.message_id;
}

Customer Support

app.post('/webhook/whatsapp', async (req, res) => {
  const event = req.body;
  const message = event.data.message.toLowerCase();
  
  // Show typing
  await contiguity.whatsapp.typing({
    to: event.data.from,
    from: event.data.to,
    action: 'start'
  });
  
  // Route to appropriate response
  let response;
  if (message.includes('order status')) {
    response = 'Let me check your order status...';
  } else if (message.includes('help')) {
    response = 'How can I assist you today?';
  } else {
    response = 'I\'ve received your message. A support agent will respond shortly.';
  }
  
  await contiguity.whatsapp.typing({
    to: event.data.from,
    from: event.data.to,
    action: 'stop'
  });
  
  await contiguity.whatsapp.reply(event, {
    message: response
  });
  
  res.json({ success: true });
});

Marketing Campaigns

async function sendPromotion(subscribers) {
  const results = await Promise.all(
    subscribers.map(phone => 
      contiguity.whatsapp.send({
        to: phone,
        message: '🎉 Special Offer! Get 20% off your next purchase. Use code: SAVE20',
        from: '+1234567890',
        fallback: {
          when: ['whatsapp_unsupported'],
          from: '+0987654321' // SMS fallback
        }
      })
    )
  );
  
  return results;
}

Appointment Reminders

async function sendAppointmentReminder(appointment) {
  await contiguity.whatsapp.send({
    to: appointment.customer_phone,
    message: `📅 Reminder: You have an appointment tomorrow at ${appointment.time}\n\nLocation: ${appointment.location}\nWith: ${appointment.provider}`,
    from: '+1234567890',
    attachments: [appointment.calendar_link]
  });
}

Fallback Strategy Example

// Try WhatsApp first, fall back to SMS if unavailable
const result = await contiguity.whatsapp.send({
  to: '+1234567890',
  message: 'This works on WhatsApp or SMS',
  from: '+0987654321',
  fallback: {
    when: ['whatsapp_unsupported', 'whatsapp_fails']
  }
});

// Use different number for SMS fallback
const result2 = await contiguity.whatsapp.send({
  to: '+1234567890',
  message: 'Premium message on WhatsApp, standard on SMS',
  from: '+0987654321', // WhatsApp number
  fallback: {
    when: ['whatsapp_unsupported'],
    from: '+1111111111' // Different SMS number
  }
});

Error Handling

try {
  const result = await contiguity.whatsapp.send({
    to: '+1234567890',
    message: 'Hello!'
  });
} catch (error) {
  if (error instanceof z.ZodError) {
    console.error('Validation error:', error.errors);
  } else {
    console.error('API error:', error);
  }
}
All methods validate input parameters using Zod schemas and throw validation errors for invalid input.

Best Practices

  • Always configure fallback for better delivery rates
  • Use typing indicators for natural conversation flow
  • Keep messages concise and formatted for mobile reading
  • Use emojis to make messages more engaging
  • Respect user preferences and opt-out requests
  • Test attachment file sizes and formats
  • Use fast_track only for truly urgent messages
  • Implement webhook handlers for two-way conversations

Build docs developers (and LLMs) love