@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
JavaScript
/**
* 🏠 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 }