UNPKG

@horizon-modules/arbo-crm-integration

Version:

Integração CRM Arbo para conversion de dados imobiliários para property-model-v3

210 lines (166 loc) 6.09 kB
#!/usr/bin/env node /** * 🏠 Script de Sincronização Arbo CRM * * Este script baixa imóveis da API Arbo e envia para sua API. * Uso no site do cliente: node scripts/arbo-sync.js */ const { ArboDownloader } = require('@horizon-modules/arbo-crm-integration') require('dotenv').config() // ===== CONFIGURAÇÕES DO SCRIPT ===== const CONFIG = { // API Arbo ARBO_TOKEN: process.env.ARBO_TOKEN, // Sua API API_ENDPOINT: process.env.API_ENDPOINT, API_TOKEN: process.env.API_TOKEN, // Configurações do .env (com valores padrão) ARBO_START_PAGE: parseInt(process.env.ARBO_START_PAGE) || 1, ARBO_END_PAGE: parseInt(process.env.ARBO_END_PAGE) || 10, ARBO_PER_PAGE: parseInt(process.env.ARBO_PER_PAGE) || 50, API_BATCH_SIZE: parseInt(process.env.API_BATCH_SIZE) || 10, DATA_DIR: process.env.DATA_DIR || './data/arbo-imports', OPERATION_MODE: process.env.OPERATION_MODE || 'download-only', } function validateConfig() { const errors = [] if (!CONFIG.ARBO_TOKEN) { errors.push('❌ ARBO_TOKEN não configurado no .env') } if (CONFIG.OPERATION_MODE !== 'download-only' && !CONFIG.API_ENDPOINT) { errors.push('❌ API_ENDPOINT não configurado no .env') } if (CONFIG.OPERATION_MODE !== 'download-only' && !CONFIG.API_TOKEN) { errors.push('❌ API_TOKEN não configurado no .env') } if (errors.length > 0) { console.log('🚫 Erros de configuração:') errors.forEach(error => console.log(` ${error}`)) console.log('\n📋 Verifique seu arquivo .env') process.exit(1) } } function printConfig() { console.log('🔧 Configuração:') console.log(` 📥 Arbo: Páginas ${CONFIG.ARBO_START_PAGE}-${CONFIG.ARBO_END_PAGE || CONFIG.ARBO_MAX_PAGES || '∞'}, ${CONFIG.ARBO_PER_PAGE} por página`) console.log(` 📁 Dados salvos em: ${CONFIG.DATA_DIR}`) console.log(` 🔄 Modo: ${CONFIG.OPERATION_MODE}`) if (CONFIG.OPERATION_MODE !== 'download-only') { console.log(` 📤 API: ${CONFIG.API_ENDPOINT}`) console.log(` 📦 Lotes de: ${CONFIG.API_BATCH_SIZE} imóveis`) } console.log('') } async function downloadOnly(downloader) { console.log('📥 Modo: Apenas Download') const downloadOptions = { startPage: CONFIG.ARBO_START_PAGE, perPage: CONFIG.ARBO_PER_PAGE } if (CONFIG.ARBO_END_PAGE) { downloadOptions.endPage = CONFIG.ARBO_END_PAGE } else if (CONFIG.ARBO_MAX_PAGES) { downloadOptions.maxPages = CONFIG.ARBO_MAX_PAGES } const result = await downloader.downloadPages(downloadOptions) console.log('✅ Download concluído!') console.log(` 📊 ${result.downloadedItems} imóveis baixados`) console.log(` 📁 Arquivos salvos em: ${CONFIG.DATA_DIR}`) if (result.errors.length > 0) { console.log(` ⚠️ ${result.errors.length} erros encontrados`) result.errors.forEach(error => console.log(` - ${error}`)) } return result } async function uploadOnly(downloader) { console.log('📤 Modo: Apenas Upload (dados já baixados)') const result = await downloader.uploadToApi({ endpoint: CONFIG.API_ENDPOINT, headers: { 'Authorization': `Bearer ${CONFIG.API_TOKEN}`, 'Content-Type': 'application/json', 'X-Source': 'arbo-integration' }, batchSize: CONFIG.API_BATCH_SIZE }) console.log('✅ Upload concluído!') console.log(` 📊 ${result.totalSent}/${result.totalProcessed} imóveis enviados`) if (result.totalErrors > 0) { console.log(` ⚠️ ${result.totalErrors} erros encontrados`) result.errors.forEach(error => console.log(` - ${error}`)) } return result } async function downloadAndUpload(downloader) { console.log('🔄 Modo: Download + Upload') const downloadOptions = { startPage: CONFIG.ARBO_START_PAGE, perPage: CONFIG.ARBO_PER_PAGE } if (CONFIG.ARBO_END_PAGE) { downloadOptions.endPage = CONFIG.ARBO_END_PAGE } else if (CONFIG.ARBO_MAX_PAGES) { downloadOptions.maxPages = CONFIG.ARBO_MAX_PAGES } const uploadOptions = { endpoint: CONFIG.API_ENDPOINT, headers: { 'Authorization': `Bearer ${CONFIG.API_TOKEN}`, 'Content-Type': 'application/json', 'X-Source': 'arbo-integration' }, batchSize: CONFIG.API_BATCH_SIZE } const { downloadResult, uploadResult } = await downloader.downloadAndUpload( downloadOptions, uploadOptions ) console.log('✅ Operação completa!') console.log(` 📥 Download: ${downloadResult.downloadedItems} imóveis`) console.log(` 📤 Upload: ${uploadResult.totalSent} enviados`) if (downloadResult.errors.length > 0 || uploadResult.errors.length > 0) { console.log(` ⚠️ Erros encontrados:`) downloadResult.errors.forEach(error => console.log(` 📥 ${error}`)) uploadResult.errors.forEach(error => console.log(` 📤 ${error}`)) } return { downloadResult, uploadResult } } async function main() { console.log('🚀 Iniciando sincronização Arbo CRM\n') // Valida configuração validateConfig() printConfig() // Cria o downloader const downloader = new ArboDownloader({ token: CONFIG.ARBO_TOKEN, outputDir: CONFIG.DATA_DIR }) try { const startTime = Date.now() // Executa operação baseada no modo switch (CONFIG.OPERATION_MODE) { case 'download-only': await downloadOnly(downloader) break case 'upload-only': await uploadOnly(downloader) break case 'download-and-upload': await downloadAndUpload(downloader) break default: throw new Error(`Modo inválido: ${CONFIG.OPERATION_MODE}`) } const duration = Math.round((Date.now() - startTime) / 1000) console.log(`\n🎉 Concluído em ${duration}s`) } catch (error) { console.error('\n❌ Erro durante a sincronização:') console.error(error.message) process.exit(1) } } // Executa se chamado diretamente if (require.main === module) { main() } module.exports = { main, CONFIG }