WhatsApp Notification - Frontend Implementation Guide
Overview
The WhatsApp notification endpoint allows you to send WhatsApp messages from the frontend. Currently, messages are sent to a hardcoded recipient phone number for testing purposes. The endpoint requires authentication via Firebase Auth.
API Endpoint
Send WhatsApp Notification
POST /v1/whatsapp/notify
Content-Type: application/json
Authorization: Bearer <firebaseIdToken>
Purpose: Send a WhatsApp notification message
Authentication: Required - Firebase ID token in Authorization header
Request Body (optional):
{
"message": "Your custom message text"
}
Note: If message is not provided, a default test message will be sent.
Response Format
Success Response (200 OK)
{
"success": true,
"message": "WhatsApp message sent successfully",
"messageId": "wamid.xxx",
"recipient": "+972-54-6800360"
}
Error Responses
400 Bad Request - Invalid JSON:
{
"error": "Invalid JSON",
"message": "Request body must be valid JSON"
}
401 Unauthorized - Missing or invalid authentication:
- Missing Authorization header
- Invalid Firebase ID token
500 Internal Server Error - Configuration or API error:
{
"error": "Configuration error",
"message": "WhatsApp API credentials are not configured. Please set WHATSAPP_PHONE_NUMBER_ID and WHATSAPP_ACCESS_TOKEN environment variables."
}
Or:
{
"error": "WhatsApp API error",
"message": "WhatsApp API error: 400 Bad Request - {...}"
}
Implementation
Step 1: Get Firebase ID Token
First, ensure you have a Firebase ID token from your authenticated user:
import { getAuth } from 'firebase/auth';
// Get current user
const auth = getAuth();
const user = auth.currentUser;
if (!user) {
// User not authenticated
throw new Error('User must be authenticated');
}
// Get ID token
const idToken = await user.getIdToken();
Step 2: Send WhatsApp Message
async function sendWhatsAppNotification(message) {
try {
// Get Firebase ID token
const auth = getAuth();
const user = auth.currentUser;
if (!user) {
throw new Error('User must be authenticated');
}
const idToken = await user.getIdToken();
// Prepare request
const API_BASE_URL = 'https://api.maintor.systems'; // or your API URL
const response = await fetch(`${API_BASE_URL}/v1/whatsapp/notify`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${idToken}`
},
body: JSON.stringify({
message: message || undefined // Optional - omit if you want default message
})
});
// Handle response
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || error.error || 'Failed to send WhatsApp message');
}
const result = await response.json();
return {
success: true,
messageId: result.messageId,
recipient: result.recipient
};
} catch (error) {
console.error('Error sending WhatsApp notification:', error);
throw error;
}
}
Step 3: Usage Example
// Example 1: Send custom message
try {
const result = await sendWhatsAppNotification('Hello from Maintor!');
console.log('Message sent successfully:', result.messageId);
// Show success notification to user
} catch (error) {
console.error('Failed to send message:', error.message);
// Show error notification to user
}
// Example 2: Send default message (omit message parameter)
try {
const result = await sendWhatsAppNotification();
console.log('Default message sent:', result.messageId);
} catch (error) {
console.error('Failed to send message:', error.message);
}
Complete Example with Error Handling
import { getAuth } from 'firebase/auth';
const API_BASE_URL = 'https://api.maintor.systems'; // or your API URL
async function sendWhatsAppNotification(message) {
const auth = getAuth();
const user = auth.currentUser;
// Check authentication
if (!user) {
return {
success: false,
error: 'User must be authenticated to send WhatsApp messages'
};
}
try {
// Get Firebase ID token
const idToken = await user.getIdToken();
// Send request
const response = await fetch(`${API_BASE_URL}/v1/whatsapp/notify`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${idToken}`
},
body: JSON.stringify(message ? { message } : {})
});
// Parse response
const data = await response.json();
// Handle different status codes
if (response.status === 200) {
return {
success: true,
messageId: data.messageId,
recipient: data.recipient,
message: data.message
};
} else if (response.status === 400) {
return {
success: false,
error: data.message || 'Invalid request'
};
} else if (response.status === 401) {
return {
success: false,
error: 'Authentication failed. Please log in again.'
};
} else if (response.status === 500) {
return {
success: false,
error: data.message || 'Server error. Please try again later.'
};
} else {
return {
success: false,
error: 'Unexpected error occurred'
};
}
} catch (error) {
console.error('Error sending WhatsApp notification:', error);
return {
success: false,
error: error.message || 'Network error. Please check your connection.'
};
}
}
// Usage in your component
async function handleSendWhatsApp() {
const message = 'Test message from frontend';
const result = await sendWhatsAppNotification(message);
if (result.success) {
// Show success message
showNotification('WhatsApp message sent successfully!', 'success');
} else {
// Show error message
showNotification(result.error, 'error');
}
}
React/Vue Example
React Hook Example
import { useState } from 'react';
import { getAuth } from 'firebase/auth';
function useWhatsAppNotification() {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const sendNotification = async (message) => {
setLoading(true);
setError(null);
try {
const auth = getAuth();
const user = auth.currentUser;
if (!user) {
throw new Error('User must be authenticated');
}
const idToken = await user.getIdToken();
const API_BASE_URL = 'https://api.maintor.systems';
const response = await fetch(`${API_BASE_URL}/v1/whatsapp/notify`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${idToken}`
},
body: JSON.stringify(message ? { message } : {})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message || errorData.error || 'Failed to send message');
}
const result = await response.json();
return result;
} catch (err) {
setError(err.message);
throw err;
} finally {
setLoading(false);
}
};
return { sendNotification, loading, error };
}
// Usage in component
function MyComponent() {
const { sendNotification, loading, error } = useWhatsAppNotification();
const handleClick = async () => {
try {
const result = await sendNotification('Hello from React!');
console.log('Message sent:', result.messageId);
} catch (err) {
console.error('Error:', err);
}
};
return (
<button onClick={handleClick} disabled={loading}>
{loading ? 'Sending...' : 'Send WhatsApp Message'}
</button>
);
}
Important Notes
- Authentication Required: The endpoint requires a valid Firebase ID token in the Authorization header
- Recipient: Currently hardcoded to
+972-54-6800360for testing purposes - Message Optional: If no message is provided, a default test message will be sent
- Rate Limiting: Be aware of WhatsApp API rate limits - don't send too many messages in quick succession
- Error Handling: Always handle errors gracefully and show appropriate messages to users
- Testing: Use this endpoint for testing WhatsApp integration. Production rules will be added later
Error Handling Checklist
- Check if user is authenticated before calling the endpoint
- Handle 400 errors (invalid request)
- Handle 401 errors (authentication failed)
- Handle 500 errors (server/configuration issues)
- Handle network errors (connection issues)
- Show user-friendly error messages
- Log errors for debugging
Testing
-
Test with custom message:
await sendWhatsAppNotification('Test message from frontend'); -
Test with default message:
await sendWhatsAppNotification(); -
Test error handling:
- Try without authentication
- Try with invalid token
- Test network errors
API Base URL
Use your API base URL:
- Production:
https://api.maintor.systems - Development: Your Cloud Functions URL (if using GCP)
- Local:
http://localhost:8080(if running locally)
Future Enhancements
The following features will be added in the future:
- Configurable recipient phone numbers
- Scheduled notifications
- Automatic notifications for overdue tickets
- Notification rules engine
- Message templates
- Delivery status tracking
For detailed API schemas and examples, refer to the OpenAPI specification at /openapi.json.