Text Messages
Text messages are the foundation of WhatsApp communication. The SDK provides a simple yet powerful interface for sending text messages with advanced features like URL previews and reply support.Basic Usage
Copy
import { WhatsAppClient } from 'whatsapp-client-sdk';
const client = new WhatsAppClient({
accessToken: process.env.WHATSAPP_ACCESS_TOKEN!,
phoneNumberId: process.env.WHATSAPP_PHONE_NUMBER_ID!,
});
// Simple text message
await client.sendText('+1234567890', 'Hello, World!');
Method Signature
Copy
async sendText(
to: string,
text: string,
options?: TextOptions
): Promise<MessageResponse>
Parameters
- to (
string): Recipient phone number in international format - text (
string): Message content (max 4,096 characters) - options (
TextOptions, optional): Additional message options
TextOptions Interface
Copy
interface TextOptions {
previewUrl?: boolean; // Enable URL preview (default: false)
replyToMessageId?: string; // Reply to specific message
}
Examples
Basic Text Message
Copy
const response = await client.sendText(
'+1234567890',
'Welcome to our service! We\'re excited to help you.'
);
console.log('Message ID:', response.messages[0].id);
Text with URL Preview
Copy
// Enable URL preview for shared links
await client.sendText(
'+1234567890',
'Check out our latest blog post: https://blog.example.com/latest-updates',
{ previewUrl: true }
);
Reply to Message
Copy
// Reply to a specific message
await client.sendText(
'+1234567890',
'Thanks for your question! Here\'s the answer...',
{ replyToMessageId: 'wamid.HBgLM2E5YzE3...' }
);
Formatted Text with Emojis
Copy
await client.sendText(
'+1234567890',
'🎉 Congratulations! 🎉\n\n' +
'Your order has been confirmed:\n' +
'• Order ID: #12345\n' +
'• Total: $29.99\n' +
'• ETA: 2-3 business days\n\n' +
'Track your order: https://track.example.com/12345'
);
Multi-line Messages
Copy
const orderDetails = `
📦 Order Confirmation
Order #: 123456
Date: ${new Date().toLocaleDateString()}
Total: $99.99
Items:
• Product A - $49.99
• Product B - $39.99
• Shipping - $10.00
Delivery Address:
123 Main St
New York, NY 10001
Expected delivery: 3-5 business days
`.trim();
await client.sendText('+1234567890', orderDetails);
Character Limits and Validation
Maximum Length
Text messages are limited to 4,096 characters. The SDK automatically validates this:Copy
try {
const longMessage = 'A'.repeat(5000); // Too long
await client.sendText('+1234567890', longMessage);
} catch (error) {
if (error instanceof MessageValidationError) {
console.error('Message too long:', error.message);
// Output: "Text exceeds 4096 characters limit"
}
}
Character Counting
Copy
const message = 'Your message content here...';
// Check message length before sending
if (message.length > 4096) {
console.error(`Message too long: ${message.length} characters (max 4096)`);
return;
}
console.log(`Message is valid (${message.length} characters)`);
await client.sendText('+1234567890', message);
URL Preview Feature
WhenpreviewUrl is enabled, WhatsApp will generate a preview for the first URL found in the message.
URL Preview Examples
Copy
// News article with preview
await client.sendText(
'+1234567890',
'Breaking: Important announcement from our team.\n\n' +
'Read the full story: https://news.example.com/breaking-news\n\n' +
'Let us know what you think!',
{ previewUrl: true }
);
// Product link with preview
await client.sendText(
'+1234567890',
'Check out this amazing product we found for you!\n\n' +
'https://shop.example.com/product/amazing-widget\n\n' +
'💰 Special discount code: SAVE20',
{ previewUrl: true }
);
URL Preview Best Practices
- ✅ Good Practices
- ❌ Avoid
Copy
// Single URL for clean preview
await client.sendText(to,
'Article: The Future of Technology\n\n' +
'https://blog.example.com/future-tech',
{ previewUrl: true }
);
// Descriptive context before URL
await client.sendText(to,
'Your invoice is ready for download:\n' +
'https://billing.example.com/invoice/123',
{ previewUrl: true }
);
Copy
// Multiple URLs (only first gets preview)
await client.sendText(to,
'Check these links:\n' +
'https://example1.com\n' +
'https://example2.com',
{ previewUrl: true } // Only first URL previewed
);
// URLs without context
await client.sendText(to,
'https://example.com',
{ previewUrl: true } // No context provided
);
Reply Messages
Reply to specific messages to maintain conversation context:Basic Reply
Copy
// In webhook handler, get the message ID
const webhookProcessor = client.createWebhookProcessor({
onTextMessage: async (message) => {
// Reply to the user's message
await client.sendText(
message.from,
'Thanks for your message! We received: "' + message.text + '"',
{ replyToMessageId: message.id }
);
}
});
Contextual Replies
Copy
// Support conversation example
const webhookProcessor = client.createWebhookProcessor({
onTextMessage: async (message) => {
const userText = message.text.toLowerCase();
if (userText.includes('help')) {
await client.sendText(
message.from,
'🆘 Our support team will assist you shortly.\n\n' +
'In the meantime, check our FAQ: https://help.example.com',
{
replyToMessageId: message.id,
previewUrl: true
}
);
} else if (userText.includes('order')) {
await client.sendText(
message.from,
'📦 Please provide your order number and I\'ll look it up for you.',
{ replyToMessageId: message.id }
);
}
}
});
Text Formatting and Styling
Emoji Usage
Copy
// Effective emoji usage
await client.sendText('+1234567890',
'🎉 Welcome to our service!\n\n' +
'✅ Account created successfully\n' +
'📧 Confirmation email sent\n' +
'🔗 Setup your profile: https://app.example.com/setup',
{ previewUrl: true }
);
// Status indicators
await client.sendText('+1234567890',
'📊 System Status Update\n\n' +
'✅ Website - Operational\n' +
'✅ API - Operational\n' +
'⚠️ Database - Degraded Performance\n' +
'❌ Email Service - Down\n\n' +
'Updates: https://status.example.com'
);
Text Structure
Copy
// Well-structured message
const structuredMessage = [
'📋 Daily Report Summary',
'',
'📈 Metrics:',
'• Sales: +15% vs yesterday',
'• Traffic: 25,847 visitors',
'• Conversion: 3.2%',
'',
'🎯 Top Performers:',
'1. Product A - 127 sales',
'2. Product B - 89 sales',
'3. Product C - 56 sales',
'',
'Full report: https://dashboard.example.com/daily'
].join('\n');
await client.sendText('+1234567890', structuredMessage, { previewUrl: true });
Advanced Use Cases
Dynamic Content
Copy
async function sendPersonalizedWelcome(phoneNumber: string, userName: string) {
const welcomeMessage = `
Hello ${userName}! 👋
Welcome to our platform. Here's what you can do:
🚀 Get started: Complete your profile
📚 Learn more: Check out our tutorials
💬 Get help: Contact our support team
Ready to begin? https://app.example.com/onboarding
`.trim();
return await client.sendText(phoneNumber, welcomeMessage, { previewUrl: true });
}
// Usage
await sendPersonalizedWelcome('+1234567890', 'John');
Conditional Messaging
Copy
async function sendOrderUpdate(phoneNumber: string, order: any) {
let message = `📦 Order Update - #${order.id}\n\n`;
switch (order.status) {
case 'confirmed':
message += '✅ Your order has been confirmed!\n';
message += `💰 Total: $${order.total}\n`;
message += `📅 Expected delivery: ${order.deliveryDate}`;
break;
case 'shipped':
message += '🚚 Your order has shipped!\n';
message += `📦 Tracking: ${order.trackingNumber}\n`;
message += `🔗 Track here: ${order.trackingUrl}`;
break;
case 'delivered':
message += '🎉 Your order has been delivered!\n';
message += 'We hope you love your purchase.\n\n';
message += '⭐ Rate your experience: https://review.example.com';
break;
}
return await client.sendText(phoneNumber, message, { previewUrl: true });
}
Template-like Messages
Copy
class MessageTemplates {
static appointmentReminder(name: string, date: string, time: string): string {
return `
🏥 Appointment Reminder
Hi ${name},
This is a reminder about your upcoming appointment:
📅 Date: ${date}
🕐 Time: ${time}
📍 Location: Main Clinic
Need to reschedule? Reply "RESCHEDULE"
Questions? Call us at (555) 123-4567
`.trim();
}
static paymentReceived(amount: string, invoice: string): string {
return `
💳 Payment Received
Thank you! We've received your payment:
💰 Amount: $${amount}
📄 Invoice: #${invoice}
📅 Date: ${new Date().toLocaleDateString()}
Receipt: https://billing.example.com/receipt/${invoice}
`.trim();
}
}
// Usage
await client.sendText(
'+1234567890',
MessageTemplates.appointmentReminder('John Doe', 'March 15', '2:30 PM')
);
Error Handling
Common Errors
Copy
import {
MessageValidationError,
WhatsAppApiError
} from 'whatsapp-client-sdk';
try {
await client.sendText(to, message);
} catch (error) {
if (error instanceof MessageValidationError) {
switch (error.field) {
case 'to':
console.error('Invalid phone number:', error.value);
break;
case 'text.body':
console.error('Invalid text content:', error.message);
break;
}
} else if (error instanceof WhatsAppApiError) {
switch (error.code) {
case 131:
console.error('Number not on WhatsApp');
break;
case 132:
console.error('Message undeliverable');
break;
default:
console.error('API error:', error.details);
}
}
}
Retry Logic
Copy
async function sendTextWithRetry(
to: string,
text: string,
options?: TextOptions,
maxRetries: number = 3
): Promise<MessageResponse> {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await client.sendText(to, text, options);
} catch (error) {
if (attempt === maxRetries) throw error;
// Wait before retry (exponential backoff)
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw new Error('Max retries exceeded');
}
Best Practices
1. Message Length
Copy
// ✅ Good: Concise and clear
await client.sendText(to,
'Order #12345 confirmed! 📦\n' +
'Tracking: https://track.example.com/12345'
);
// ❌ Avoid: Too verbose
await client.sendText(to,
'We are pleased to inform you that your order number 12345 has been successfully confirmed and is now being processed by our fulfillment team...'
);
2. URL Preview Usage
Copy
// ✅ Good: Enable for important links
await client.sendText(to,
'Your invoice is ready: https://billing.example.com/invoice/123',
{ previewUrl: true }
);
// ❌ Avoid: Preview for every URL
await client.sendText(to,
'Contact us at https://contact.example.com or https://support.example.com',
{ previewUrl: true } // Only first URL gets preview
);
3. Reply Context
Copy
// ✅ Good: Meaningful replies
await client.sendText(to,
'Thanks for your order inquiry! Here are the details you requested...',
{ replyToMessageId: originalMessageId }
);
// ❌ Avoid: Generic replies
await client.sendText(to,
'OK',
{ replyToMessageId: originalMessageId }
);
Next Steps
Media Messages
Learn to send images, videos, and documents
Interactive Messages
Create buttons and lists for user interaction
Webhook Handling
Handle incoming text messages and replies
Template Messages
Use pre-approved templates for business messaging