WhatsApp Cloud API: Panduan Resmi Meta
Panduan lengkap WhatsApp Cloud API dari Meta. Setup, pricing, fitur, dan best practices. Official API guide untuk developer!
WhatsApp Cloud API = Official API dari Meta!
Hosted oleh Meta, tidak perlu server sendiri. Gratis untuk mulai, bayar per conversation.
Apa Itu Cloud API?
WHATSAPP CLOUD API:
- Official API dari Meta/Facebook
- Hosted di infrastructure Meta
- Tidak perlu maintain server
- Pay-per-use model
- 1,000 free conversations/month
VS ON-PREMISE API:
- Self-hosted
- Butuh server sendiri
- Untuk enterprise besar
- More control, more responsibilityPricing Structure
Free Tier:
1,000 free service conversations/month
(User-initiated conversations)Paid Conversations:
BUSINESS-INITIATED (Template Messages):
- Utility: ~$0.005 - 0.02/conversation
- Authentication: ~$0.005 - 0.02/conversation
- Marketing: ~$0.02 - 0.08/conversation
USER-INITIATED (24h Window):
- Service: ~$0.003 - 0.01/conversation
*Harga vary by countryConversation Window:
1 conversation = 24 hours window
Unlimited messages dalam window
Window mulai dari:
- Business-initiated: Saat template terkirim
- User-initiated: Saat customer kirim pesanSetup WhatsApp Cloud API
Step 1: Create Meta Developer Account
1. Buka developers.facebook.com
2. Login dengan Facebook
3. Create App → Business type
4. Add WhatsApp productStep 2: Setup WhatsApp Business
1. Create/connect Meta Business Account
2. Add phone number (bisa test number dulu)
3. Verify phone number
4. Get Phone Number ID & Access TokenStep 3: Configure Webhook
1. Setup webhook endpoint (HTTPS)
2. Add callback URL
3. Add verify token
4. Subscribe to messagesStep 4: Send Test Message
bash
curl -X POST \
'https://graph.facebook.com/v17.0/PHONE_NUMBER_ID/messages' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"to": "628123456789",
"type": "text",
"text": {"body": "Hello from Cloud API!"}
}'Code Examples
Send Text Message:
javascript
const axios = require('axios');
async function sendTextMessage(to, message) {
const response = await axios.post(
`https://graph.facebook.com/v17.0/${PHONE_NUMBER_ID}/messages`,
{
messaging_product: 'whatsapp',
to: to,
type: 'text',
text: { body: message }
},
{
headers: {
'Authorization': `Bearer ${ACCESS_TOKEN}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}Send Template Message:
javascript
async function sendTemplateMessage(to, templateName, language, components) {
const response = await axios.post(
`https://graph.facebook.com/v17.0/${PHONE_NUMBER_ID}/messages`,
{
messaging_product: 'whatsapp',
to: to,
type: 'template',
template: {
name: templateName,
language: { code: language },
components: components
}
},
{
headers: {
'Authorization': `Bearer ${ACCESS_TOKEN}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
// Usage
await sendTemplateMessage(
'628123456789',
'order_confirmation',
'id',
[
{
type: 'body',
parameters: [
{ type: 'text', text: 'John' },
{ type: 'text', text: '#12345' }
]
}
]
);Send Image:
javascript
async function sendImage(to, imageUrl, caption) {
const response = await axios.post(
`https://graph.facebook.com/v17.0/${PHONE_NUMBER_ID}/messages`,
{
messaging_product: 'whatsapp',
to: to,
type: 'image',
image: {
link: imageUrl,
caption: caption
}
},
{
headers: {
'Authorization': `Bearer ${ACCESS_TOKEN}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}Send Interactive Buttons:
javascript
async function sendButtons(to, bodyText, buttons) {
const response = await axios.post(
`https://graph.facebook.com/v17.0/${PHONE_NUMBER_ID}/messages`,
{
messaging_product: 'whatsapp',
to: to,
type: 'interactive',
interactive: {
type: 'button',
body: { text: bodyText },
action: {
buttons: buttons.map((btn, i) => ({
type: 'reply',
reply: {
id: `btn_${i}`,
title: btn
}
}))
}
}
},
{
headers: {
'Authorization': `Bearer ${ACCESS_TOKEN}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
// Usage
await sendButtons(
'628123456789',
'Pilih menu:',
['Order', 'Katalog', 'Bantuan']
);Message Templates
Kenapa Butuh Template?
Business-initiated message (outside 24h window)
HARUS pakai template yang sudah di-approve.
User-initiated (dalam 24h window)
Bisa kirim free-form message.Create Template:
1. WhatsApp Manager → Message Templates
2. Create Template
3. Pilih kategori (Marketing/Utility/Authentication)
4. Tulis template dengan variables {{1}}, {{2}}
5. Submit untuk review
6. Tunggu approval (biasanya < 24 jam)Template Example:
Category: Utility
Name: order_status
Header: Order Update
Body: Hai {{1}}, order #{{2}} kamu sedang {{3}}.
Estimasi sampai: {{4}}
Footer: Terima kasih sudah belanja di Toko Kami
Buttons: [Track Order] [Hubungi CS]Webhook Integration
Handle Incoming Messages:
javascript
app.post('/webhook', (req, res) => {
const body = req.body;
if (body.object === 'whatsapp_business_account') {
body.entry.forEach(entry => {
entry.changes.forEach(change => {
if (change.value.messages) {
change.value.messages.forEach(message => {
handleMessage(message, change.value.contacts[0]);
});
}
});
});
res.sendStatus(200);
} else {
res.sendStatus(404);
}
});
function handleMessage(message, contact) {
const from = message.from;
const name = contact.profile.name;
console.log(`Message from ${name} (${from})`);
switch (message.type) {
case 'text':
processTextMessage(from, message.text.body);
break;
case 'image':
processImageMessage(from, message.image);
break;
case 'interactive':
processInteractiveReply(from, message.interactive);
break;
}
}Best Practices
1. Template Strategy
✅ Prepare templates untuk common use cases
✅ Use variables untuk personalisasi
✅ Test sebelum production
❌ Jangan hard-code text di template2. Handle 24h Window
javascript
// Track conversation windows
const windows = new Map();
async function sendMessage(to, message) {
const window = windows.get(to);
const now = Date.now();
if (window && (now - window) < 24 * 60 * 60 * 1000) {
// Within window - send free-form
await sendTextMessage(to, message);
} else {
// Outside window - need template
await sendTemplateMessage(to, 'general_notification', 'id', [
{ type: 'body', parameters: [{ type: 'text', text: message }] }
]);
}
}
// Update window saat customer kirim pesan
function onMessageReceived(from) {
windows.set(from, Date.now());
}3. Quality Rating
Maintain good quality rating:
✅ Relevant messages
✅ Honor opt-out
✅ Quick response time
❌ Spam
❌ Ignored complaintsFAQ
Gratis atau bayar?
1,000 free service conversations/month. Lebih dari itu bayar per conversation.
Berapa lama approval template?
Biasanya < 24 jam. Bisa lebih cepat atau lebih lama tergantung content.
Bisa pakai nomor existing?
Bisa, tapi nomor akan di-migrate ke Business Account dan tidak bisa balik ke personal.
Kesimpulan
Cloud API = Best official option!
| Feature | Cloud API |
|---|---|
| Hosting | Meta-managed |
| Setup | Easy |
| Reliability | High |
| Cost | Pay-per-use |
| Templates | Required for business-initiated |
Start with Cloud API for production!