Exemplos Node.js
Exemplos práticos de como usar a API ZapFlare com Node.js.
Instalação
bash
npm install axios dotenvConfiguração Inicial
javascript
// config.js
require('dotenv').config();
const config = {
apiKey: process.env.ZAPFLARE_API_KEY,
apiUrl: 'https://api.zapflare.io',
instanceId: process.env.ZAPFLARE_INSTANCE_ID
};
module.exports = config;Cliente da API
javascript
// zapflare-client.js
const axios = require('axios');
const config = require('./config');
class ZapFlareClient {
constructor(apiKey) {
this.api = axios.create({
baseURL: config.apiUrl,
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
});
}
// Listar instâncias
async listInstances() {
const response = await this.api.get('/whatsapp/instances');
return response.data;
}
// Criar instância
async createInstance(name, webhookUrl) {
const response = await this.api.post('/whatsapp/instances', {
name,
webhookUrl,
webhookEvents: ['message', 'status']
});
return response.data;
}
// Enviar mensagem de texto
async sendText(instanceId, to, message) {
const response = await this.api.post(
`/whatsapp/instances/${instanceId}/send-text`,
{ to, message }
);
return response.data;
}
// Enviar mídia
async sendMedia(instanceId, to, mediaType, mediaUrl, caption) {
const response = await this.api.post(
`/whatsapp/instances/${instanceId}/send-media`,
{ to, mediaType, mediaUrl, caption }
);
return response.data;
}
}
module.exports = ZapFlareClient;Enviando Mensagens
javascript
// send-message.js
const ZapFlareClient = require('./zapflare-client');
const config = require('./config');
async function sendWelcomeMessage(phoneNumber) {
const client = new ZapFlareClient(config.apiKey);
try {
const result = await client.sendText(
config.instanceId,
phoneNumber,
'👋 Olá! Bem-vindo ao nosso atendimento.\n\n' +
'Como posso ajudá-lo hoje?'
);
console.log('Mensagem enviada:', result);
} catch (error) {
console.error('Erro ao enviar mensagem:', error.response?.data || error.message);
}
}
// Uso
sendWelcomeMessage('5511999999999');Processando Webhooks
javascript
// webhook-server.js
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
// Verificar assinatura do webhook
function verifyWebhookSignature(payload, signature, secret) {
const hash = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return hash === signature;
}
// Processar webhook
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const payload = JSON.stringify(req.body);
// Verificar autenticidade (se configurado)
if (signature && !verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const { event, instanceId, data } = req.body;
switch (event) {
case 'message':
console.log(`Nova mensagem de ${data.from}: ${data.message}`);
// Processar mensagem recebida
handleIncomingMessage(instanceId, data);
break;
case 'status':
console.log(`Status da instância ${instanceId}: ${data.status}`);
break;
case 'connection':
console.log(`Evento de conexão: ${data.type}`);
break;
}
res.json({ success: true });
});
async function handleIncomingMessage(instanceId, data) {
// Lógica para processar mensagens recebidas
const { from, message, type } = data;
if (type === 'text' && message.toLowerCase() === 'oi') {
// Responder automaticamente
const client = new ZapFlareClient(config.apiKey);
await client.sendText(instanceId, from, 'Olá! Como posso ajudar?');
}
}
app.listen(3000, () => {
console.log('Webhook server rodando na porta 3000');
});Gerenciando Instâncias
javascript
// instance-manager.js
const ZapFlareClient = require('./zapflare-client');
const config = require('./config');
class InstanceManager {
constructor(apiKey) {
this.client = new ZapFlareClient(apiKey);
}
async checkInstanceStatus(instanceId) {
const response = await this.client.api.get(
`/whatsapp/instances/${instanceId}`
);
return response.data.data;
}
async waitForConnection(instanceId, maxAttempts = 60) {
for (let i = 0; i < maxAttempts; i++) {
const instance = await this.checkInstanceStatus(instanceId);
if (instance.status === 'connected') {
console.log('✅ Instância conectada!');
return instance;
}
if (instance.status === 'error') {
throw new Error('Erro ao conectar instância');
}
if (instance.qrCode) {
console.log('📱 Escaneie o QR Code:');
console.log(instance.qrCode);
}
// Aguardar 2 segundos antes de verificar novamente
await new Promise(resolve => setTimeout(resolve, 2000));
}
throw new Error('Timeout ao aguardar conexão');
}
async setupNewInstance(name) {
console.log('Criando nova instância...');
const result = await this.client.createInstance(
name,
'https://meuapp.com/webhook'
);
const instanceId = result.data.id;
console.log(`Instância criada: ${instanceId}`);
console.log('Aguardando conexão...');
await this.waitForConnection(instanceId);
return instanceId;
}
}
// Uso
async function main() {
const manager = new InstanceManager(config.apiKey);
try {
const instanceId = await manager.setupNewInstance('Minha Instância');
console.log(`Instância pronta para uso: ${instanceId}`);
} catch (error) {
console.error('Erro:', error.message);
}
}
main();Sistema de Notificações em Lote
javascript
// batch-notifier.js
const ZapFlareClient = require('./zapflare-client');
const config = require('./config');
class BatchNotifier {
constructor(apiKey, instanceId) {
this.client = new ZapFlareClient(apiKey);
this.instanceId = instanceId;
this.queue = [];
this.processing = false;
}
addToQueue(phoneNumber, message) {
this.queue.push({ phoneNumber, message });
if (!this.processing) {
this.processQueue();
}
}
async processQueue() {
this.processing = true;
while (this.queue.length > 0) {
const batch = this.queue.splice(0, 10); // Processar 10 por vez
await Promise.all(
batch.map(async ({ phoneNumber, message }) => {
try {
await this.client.sendText(this.instanceId, phoneNumber, message);
console.log(`✅ Enviado para ${phoneNumber}`);
} catch (error) {
console.error(`❌ Erro ao enviar para ${phoneNumber}:`, error.message);
// Recolocar na fila para retry
this.queue.push({ phoneNumber, message });
}
})
);
// Aguardar entre lotes para evitar rate limiting
if (this.queue.length > 0) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
this.processing = false;
}
}
// Uso
const notifier = new BatchNotifier(config.apiKey, config.instanceId);
// Enviar notificações em massa
const customers = [
{ phone: '5511999999999', name: 'João' },
{ phone: '5511888888888', name: 'Maria' },
// ... mais clientes
];
customers.forEach(customer => {
notifier.addToQueue(
customer.phone,
`Olá ${customer.name}! Temos novidades para você.`
);
});Tratamento de Erros
javascript
// error-handler.js
class APIErrorHandler {
static handle(error) {
if (error.response) {
// Erro da API
const { status, data } = error.response;
switch (status) {
case 401:
console.error('Erro de autenticação. Verifique sua API key.');
break;
case 403:
console.error('Acesso negado:', data.error?.message);
break;
case 404:
console.error('Recurso não encontrado:', data.error?.message);
break;
case 429:
console.error('Rate limit excedido. Aguarde antes de tentar novamente.');
break;
default:
console.error(`Erro ${status}:`, data.error?.message || 'Erro desconhecido');
}
} else if (error.request) {
// Erro de rede
console.error('Erro de rede. Verifique sua conexão.');
} else {
// Outro erro
console.error('Erro:', error.message);
}
}
}
// Uso com interceptor
const client = new ZapFlareClient(config.apiKey);
client.api.interceptors.response.use(
response => response,
error => {
APIErrorHandler.handle(error);
return Promise.reject(error);
}
);