#!/usr/bin/env node /** * CLI: pull pharmacies from webhook and insert into database.sqlite * * npm run import-farmacias * FARMACIAS_WEBHOOK_URL=https://... npm run import-farmacias * * Region (adds ?lat=&lon=&radio= in metres), e.g. your city: * node import-farmacias.js --lat 41.5631 --lon 2.0038 --radio 1500 * node import-farmacias.js "https://n8n.example/webhook/farmacias" --lat 41.5631 --lon 2.0038 --radio 1500 * * Env defaults for region: FARMACIAS_IMPORT_LAT, FARMACIAS_IMPORT_LON, FARMACIAS_IMPORT_RADIO */ import sqlite3 from 'sqlite3'; import { promisify } from 'util'; import path from 'path'; import { fileURLToPath } from 'url'; import { runFarmaciaWebhookImport, DEFAULT_FARMACIAS_WEBHOOK, } from './farmacias-webhook-import.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const dbPath = path.join(__dirname, 'database.sqlite'); const db = new sqlite3.Database(dbPath); function dbRun(sql, params = []) { return new Promise((resolve, reject) => { db.run(sql, params, function (err) { if (err) reject(err); else resolve({ lastID: this.lastID, changes: this.changes }); }); }); } const dbGet = promisify(db.get.bind(db)); function parseCli(argv) { const region = {}; const positional = []; for (let i = 2; i < argv.length; i++) { const a = argv[i]; if (a === '--lat' && argv[i + 1] != null) { region.lat = argv[++i]; continue; } if ((a === '--lon' || a === '--lng') && argv[i + 1] != null) { region.lon = argv[++i]; continue; } if (a === '--radio' && argv[i + 1] != null) { region.radio = argv[++i]; continue; } if (a.startsWith('--')) { console.warn('Unknown flag:', a); continue; } positional.push(a); } if (process.env.FARMACIAS_IMPORT_LAT && region.lat == null) region.lat = process.env.FARMACIAS_IMPORT_LAT; if (process.env.FARMACIAS_IMPORT_LON && region.lon == null) region.lon = process.env.FARMACIAS_IMPORT_LON; if (process.env.FARMACIAS_IMPORT_RADIO && region.radio == null) { region.radio = process.env.FARMACIAS_IMPORT_RADIO; } const url = positional[0] || DEFAULT_FARMACIAS_WEBHOOK; const hasRegion = region.lat != null || region.lon != null || region.radio != null; return { url, region: hasRegion ? region : null }; } async function main() { const { url, region } = parseCli(process.argv); console.log('Fetching pharmacies from:', url); if (region) console.log('Region query:', region); try { const result = await runFarmaciaWebhookImport(dbGet, dbRun, url, region); console.log('Done.'); console.log(' Total rows in response:', result.totalReceived); console.log(' Inserted:', result.inserted); console.log(' Skipped (duplicate name+address):', result.skipped); console.log(' Invalid (missing name or address):', result.invalid); if (result.errors.length) { console.log(' Row errors:', result.errors.length); console.log(result.errors.slice(0, 5)); } } catch (e) { console.error('Import failed:', e.message); if (e.message.includes('Unused Respond to Webhook')) { console.error( '\n Hint: In n8n, connect the Webhook to a single "Respond to Webhook" node, or remove unused ones.' ); } process.exitCode = 1; } finally { db.close(); } } main();