Siga estas recomendações para maximizar a eficiência, evitar problemas de ban e
garantir a melhor experiência para seus usuários.
Evitando Ban do WhatsApp
O WhatsApp possui sistemas anti-spam rigorosos. Siga estas práticas para manter
sua conta segura:
Violações podem resultar em ban temporário ou permanente do número. Use a API
de forma responsável.
O que fazer
Respeite intervalos entre mensagens
Envie no máximo 1 mensagem a cada 2-3 segundos para o mesmo contato.
Para contatos diferentes, mantenha um intervalo de 500ms-1s.const delay = (ms: number) => new Promise(r => setTimeout(r, ms));
for (const contact of contacts) {
await client.messages.sendText(sessionId, {
to: contact.phone,
text: message,
});
await delay(1000); // 1 segundo entre mensagens
}
Envie apenas para contatos que consentiram
Só envie mensagens para pessoas que explicitamente optaram por receber
comunicações. Mantenha registros de opt-in.
Evite enviar a mesma mensagem idêntica para muitas pessoas. Use variáveis
como nome, data, valores específicos.// Ruim - Mensagem idêntica
"Confira nossa promoção!"
// Bom - Mensagem personalizada
`Olá ${nome}! Temos uma oferta especial para você: ${produto} com ${desconto}% off!`
Construa histórico gradualmente
Novos números devem começar com baixo volume e aumentar gradualmente ao
longo de semanas.| Semana | Mensagens/dia |
|---|
| 1 | 10-20 |
| 2 | 30-50 |
| 3 | 50-100 |
| 4+ | 100+ |
Mantenha conversas bidirecionais
Contas que apenas enviam mensagens sem receber respostas são suspeitas.
Incentive interação e responda rapidamente.
O que NÃO fazer
Spam em massa
Enviar mensagens não solicitadas para listas compradas ou números aleatórios.
Mensagens repetitivas
Enviar a mesma mensagem idêntica para centenas de pessoas.
Volume alto imediato
Começar a usar um número novo com alto volume de mensagens.
Ignorar bloqueios
Tentar contatar pessoas que bloquearam seu número.
Gerenciamento de Sessões
Reconexão Automática
Configure handlers para reconectar automaticamente quando a sessão desconectar:
// Via Webhooks
app.post('/webhook', (req, res) => {
const event = req.body;
if (event.type === 'session.disconnected') {
const { sessionId, data } = event;
// Apenas reconecta se foi desconexão não intencional
if (data.reason !== 'logged_out') {
setTimeout(async () => {
try {
await client.sessions.connect(sessionId);
console.log(`Sessão ${sessionId} reconectada`);
} catch (error) {
console.error('Falha ao reconectar:', error);
}
}, 5000); // Aguarda 5s antes de reconectar
}
}
res.status(200).send('OK');
});
Monitoramento de Status
Verifique periodicamente o status das sessões:
async function monitorSessions() {
const sessions = await client.sessions.list();
for (const session of sessions) {
if (session.status === 'disconnected') {
// Notificar ou tentar reconectar
await notifyAdmin(`Sessão ${session.name} está desconectada`);
}
}
}
// Executar a cada 5 minutos
setInterval(monitorSessions, 5 * 60 * 1000);
Segurança
Proteja suas Credenciais
Use variáveis de ambiente
# .env (nunca commite este arquivo!)
OXENTY_API_KEY=oxt_sk_xxxxxxxx
WEBHOOK_SECRET=whsec_xxxxxxxx
const client = new OxentyClient({
apiKey: process.env.OXENTY_API_KEY,
});
Rotacione keys regularmente
Crie novas API Keys periodicamente e revogue as antigas no Dashboard.
Use permissões mínimas
Ao criar API Keys, conceda apenas as permissões necessárias para cada
integração específica.
Validação de Webhooks
Sempre valide a assinatura dos webhooks antes de processá-los:
import crypto from 'crypto';
function validateWebhook(payload: string, signature: string, secret: string) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}
Use Cache
Cache respostas que mudam pouco para reduzir requisições:
import NodeCache from 'node-cache';
const cache = new NodeCache({ stdTTL: 300 }); // 5 minutos
async function getSessions() {
const cached = cache.get('sessions');
if (cached) return cached;
const sessions = await client.sessions.list();
cache.set('sessions', sessions);
return sessions;
}
Processe Webhooks Assíncronamente
Não bloqueie a resposta do webhook com processamento pesado:
import { Queue } from 'bullmq';
const webhookQueue = new Queue('webhooks');
app.post('/webhook', async (req, res) => {
// Responde imediatamente
res.status(200).send('OK');
// Processa de forma assíncrona
await webhookQueue.add('process', req.body);
});
// Worker separado
const worker = new Worker('webhooks', async (job) => {
const event = job.data;
switch (event.type) {
case 'message.received':
await handleNewMessage(event.data);
break;
// ...
}
});
Batch Operations
Quando possível, agrupe operações:
// Ruim - Múltiplas requisições
for (const phone of phones) {
await client.contacts.check(sessionId, phone);
}
// Bom - Uma requisição
const results = await client.contacts.checkBatch(sessionId, phones);
Tratamento de Erros
Implemente retries inteligentes para falhas temporárias:
async function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3,
baseDelay = 1000
): Promise<T> {
let lastError: Error;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error: any) {
lastError = error;
// Não retry para erros de cliente
if (error.status >= 400 && error.status < 500) {
throw error;
}
const delay = baseDelay * Math.pow(2, attempt);
await new Promise(r => setTimeout(r, delay));
}
}
throw lastError;
}
// Uso
const session = await withRetry(() => client.sessions.get(sessionId));
Circuit Breaker
Para alta disponibilidade, implemente circuit breaker:
import CircuitBreaker from 'opossum';
const breaker = new CircuitBreaker(
(sessionId: string, message: any) =>
client.messages.sendText(sessionId, message),
{
timeout: 10000, // 10s timeout
errorThresholdPercentage: 50,
resetTimeout: 30000, // 30s para tentar novamente
}
);
breaker.on('open', () => {
console.log('Circuit breaker aberto - API indisponível');
// Notificar ou usar fallback
});
// Uso
await breaker.fire(sessionId, message);
Logging e Monitoramento
Estruture seus Logs
import pino from 'pino';
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
});
// Log estruturado
logger.info({
event: 'message_sent',
sessionId,
to: message.to,
messageId: result.messageId,
duration: Date.now() - startTime,
});
Métricas Importantes
Monitore estas métricas:
| Métrica | Alerta se |
|---|
| Taxa de erro | > 5% |
| Latência P99 | > 5s |
| Sessões desconectadas | > 10% |
| Taxa de delivery | < 95% |
| Webhooks falhando | > 3 consecutivos |
Checklist de Produção
Antes de ir para produção, verifique: