Saltar para o conteúdo principal

Documentation Index

Fetch the complete documentation index at: https://docs.lovi.ai/llms.txt

Use this file to discover all available pages before exploring further.

Introdução

Este guia abrange boas práticas de segurança, otimização de desempenho e diretrizes de integração para ajudá-lo a construir aplicações robustas com a API da Lovi.

🔒 Boas Práticas de Segurança

Gerenciamento de Chaves de API

✅ FAÇA:
  • Armazene chaves de API em variáveis de ambiente ou gerenciamento de configuração seguro
  • Use chaves de API diferentes para ambientes diferentes (desenvolvimento, staging, produção)
  • Rotacione chaves de API regularmente (recomendado: a cada 90 dias)
  • Monitore o uso de chaves de API e configure alertas para atividades incomuns
  • Use o princípio de menor privilégio (chaves separadas para funções diferentes se disponível)
❌ NÃO FAÇA:
  • Hardcode de chaves de API no código fonte ou commit no controle de versão
  • Compartilhar chaves de API via email, chat ou outros canais inseguros
  • Usar chaves de API de produção em ambientes de desenvolvimento
  • Registrar chaves de API completas nos logs da aplicação

Segurança de Autenticação

// ✅ Bom - Armazenar em variáveis de ambiente
const ACCESS_KEY = process.env.LOVI_ACCESS_KEY;

// ❌ Ruim - Hardcoded no código
const ACCESS_KEY = 'sua-chave-api-real-aqui';

Segurança de Requisição

Sempre use HTTPS:
// ✅ Bom - Apenas HTTPS
const BASE_URL = 'https://cloud.lovi.ai';

// ❌ Ruim - HTTP inseguro
const BASE_URL = 'http://cloud.lovi.ai';
Valide dados de entrada:
function validatePhoneNumber(number) {
  const cleaned = number.replace(/\D/g, '');

  if (!/^\d{10,15}$/.test(cleaned)) {
    throw new Error('Formato de número de telefone inválido');
  }

  return cleaned;
}

⚡ Otimização de Desempenho

Gerenciamento de Conexão

Reutilize conexões HTTP:
// ✅ Bom - Reutilizar pool de conexões
const https = require('https');
const agent = new https.Agent({
  keepAlive: true,
  maxSockets: 10
});

Processamento em Lote

Processe notificações em lotes:
async function sendNotificationsBatch(notifications, batchSize = 10) {
  const results = [];

  for (let i = 0; i < notifications.length; i += batchSize) {
    const batch = notifications.slice(i, i + batchSize);
    const batchPromises = batch.map(notification =>
      sendNotification(notification)
    );

    const batchResults = await Promise.allSettled(batchPromises);
    results.push(...batchResults);

    if (i + batchSize < notifications.length) {
      await sleep(100);
    }
  }

  return results;
}

Estratégias de Cache

Cache informações de templates:
class TemplateCache {
  constructor(ttl = 3600000) { // 1 hora de TTL
    this.cache = new Map();
    this.ttl = ttl;
  }

  async getTemplate(templateName) {
    const cached = this.cache.get(templateName);

    if (cached && Date.now() - cached.timestamp < this.ttl) {
      return cached.data;
    }

    const template = await fetchTemplateFromAPI(templateName);
    this.cache.set(templateName, {
      data: template,
      timestamp: Date.now()
    });

    return template;
  }
}

📊 Limitação de Taxa e Throttling

Entendendo os Limites de Taxa

OperaçãoLimiteJanela
Autenticação10 requisições1 minuto
Notificações100 requisições1 minuto
Recuperação de templates50 requisições1 minuto
Criação de templates5 requisições1 hora

🏗️ Padrões de Arquitetura

Padrão Repository

class NotificationRepository {
  constructor(apiClient) {
    this.apiClient = apiClient;
  }

  async sendWhatsAppNotification(notification) {
    const payload = this.formatWhatsAppPayload(notification);
    return await this.apiClient.post('/notify', payload);
  }

  async sendVoiceNotification(notification) {
    const payload = this.formatVoicePayload(notification);
    return await this.apiClient.post('/notify/voice', payload);
  }
}

Padrão Factory para Notificações

class NotificationFactory {
  static create(type, data) {
    switch (type) {
      case 'whatsapp':
        return new WhatsAppNotification(data);
      case 'voice':
        return new VoiceNotification(data);
      default:
        throw new Error(`Tipo de notificação desconhecido: ${type}`);
    }
  }
}

🧪 Estratégias de Teste

Testes Unitários

const mockAPIClient = {
  post: jest.fn()
};

describe('NotificationService', () => {
  test('deve enviar notificação WhatsApp com sucesso', async () => {
    mockAPIClient.post.mockResolvedValue({
      success: true,
      notification_id: 'test-123'
    });

    const service = new NotificationService(mockAPIClient);
    const result = await service.sendWhatsApp({
      phoneNumber: '34666033135',
      templateName: 'welcome',
      contactName: 'John Doe'
    });

    expect(result.success).toBe(true);
  });
});

🔍 Monitoramento e Logging

Logging Estruturado

const logger = require('winston');

async function loggedAPICall(endpoint, data) {
  const requestId = generateRequestId();

  logger.info('Requisição API iniciada', {
    request_id: requestId,
    endpoint: endpoint,
    method: 'POST',
    timestamp: new Date().toISOString()
  });

  try {
    const response = await makeAPICall(endpoint, data);

    logger.info('Requisição API concluída', {
      request_id: requestId,
      status_code: response.status,
      success: true
    });

    return response;
  } catch (error) {
    logger.error('Requisição API falhou', {
      request_id: requestId,
      error: error.message,
      status_code: error.statusCode
    });

    throw error;
  }
}

🔧 Gerenciamento de Configuração

Configuração de Ambiente

// config/lovi.js
module.exports = {
  development: {
    baseURL: 'https://cloud.lovi.ai',
    accessKey: process.env.LOVI_DEV_ACCESS_KEY,
    rateLimits: {
      requests: 10,
      window: 60000
    },
    retries: 3,
    timeout: 30000
  },
  production: {
    baseURL: 'https://cloud.lovi.ai',
    accessKey: process.env.LOVI_PROD_ACCESS_KEY,
    rateLimits: {
      requests: 100,
      window: 60000
    },
    retries: 5,
    timeout: 60000
  }
};

🚨 Armadilhas Comuns e Soluções

Armadilha: Valores Hardcoded

// ❌ Ruim
const templateName = 'welcome_template_final_v2';

// ✅ Bom
const templateName = config.templates.welcome;

Armadilha: Tratamento de Erros Deficiente

// ❌ Ruim
try {
  await sendNotification(data);
} catch (error) {
  console.log('Erro:', error);
}

// ✅ Bom
try {
  await sendNotification(data);
} catch (error) {
  logger.error('Notificação falhou', {
    error: error.message,
    data: sanitizeForLog(data),
    stack: error.stack
  });

  throw new NotificationError(
    'Falha ao enviar notificação',
    error.statusCode,
    error.requestId
  );
}

Armadilha: Ignorar Limites de Taxa

// ❌ Ruim - Enviar tudo de uma vez
notifications.forEach(notification => {
  sendNotification(notification);
});

// ✅ Bom - Respeitar limites de taxa
await sendNotificationsBatch(notifications, 10);
Lembre-se: Seguir essas boas práticas ajudará você a construir integrações mais confiáveis, seguras e manuteníveis com a API da Lovi.