← back to Ventura Corridor
scripts/import_social_handles.cjs
80 lines
/**
* Import Instagram + TikTok handles from ~/Projects/_ventura-recon/social-results.json
* into ventura_corridor.business_contacts.
*
* Matches by (name + zip) → businesses.id. Insert one contact row per platform.
* Idempotent via the dedupe_key generated column on business_contacts.
*
* No LLM. Pure data import.
*/
const fs = require('fs');
const path = require('path');
const os = require('os');
const { Client } = require('pg');
const SRC = path.join(os.homedir(), 'Projects/_ventura-recon/social-results.json');
const DATABASE_URL =
process.env.DATABASE_URL ||
'postgresql:///ventura_corridor?host=/tmp';
(async () => {
const rows = JSON.parse(fs.readFileSync(SRC, 'utf8'));
console.log(`[social] ${rows.length} rows to consider`);
const client = new Client({ connectionString: DATABASE_URL });
await client.connect();
let matched = 0, inserted = 0, skipped_nohandle = 0, skipped_nomatch = 0;
for (const r of rows) {
if (!r.business_name) continue;
if (!r.instagram_handle && !r.tiktok_handle) {
skipped_nohandle++;
continue;
}
// Match by raw business_name + zip (BTRC stored zip is the 5-digit prefix)
const zip = String(r.zip || '').slice(0, 5);
const m = await client.query(
`SELECT id FROM businesses
WHERE on_corridor
AND source = 'la_btrc'
AND zip = $1
AND (
UPPER(raw->>'business_name') = UPPER($2)
OR UPPER(raw->>'dba_name') = UPPER($2)
OR UPPER(name) = UPPER($2)
)
LIMIT 1`,
[zip, r.business_name]
);
if (m.rowCount === 0) { skipped_nomatch++; continue; }
matched++;
const businessId = m.rows[0].id;
if (r.instagram_handle && r.instagram_url) {
await client.query(
`INSERT INTO business_contacts (
business_id, role, person_name, source, source_url, confidence, notes
) VALUES ($1, 'social_handle', $2, 'ventura_recon_brave', $3, $4, 'instagram')
ON CONFLICT DO NOTHING`,
[businessId, '@' + r.instagram_handle, r.instagram_url, r.confidence === 'high' ? 0.9 : 0.7]
);
inserted++;
}
if (r.tiktok_handle && r.tiktok_url) {
await client.query(
`INSERT INTO business_contacts (
business_id, role, person_name, source, source_url, confidence, notes
) VALUES ($1, 'social_handle', $2, 'ventura_recon_brave', $3, $4, 'tiktok')
ON CONFLICT DO NOTHING`,
[businessId, '@' + r.tiktok_handle, r.tiktok_url, r.confidence === 'high' ? 0.9 : 0.7]
);
inserted++;
}
}
console.log(
`[social] matched=${matched} inserted=${inserted} skipped_nohandle=${skipped_nohandle} skipped_nomatch=${skipped_nomatch}`
);
await client.end();
})().catch((e) => { console.error(e); process.exit(1); });