← back to Rentv 2026
PR intel: linkedin-enrich prioritizes media/PR contacts (org-id set sort)
f40b0bc9a24b3f074a81db532674eac79a6dd93e · 2026-08-05 14:29:13 -0700 · Steve
The /people API has no organization_type filter, so build the media org-id
set from /organizations and sort media contacts first (LI_MEDIA_ONLY filters
to them). Fixes the first batch spending queries on non-media contacts.
Files touched
M src/pr/tools/linkedin-enrich.js
Diff
commit f40b0bc9a24b3f074a81db532674eac79a6dd93e
Author: Steve <steve@designerwallcoverings.com>
Date: Wed Aug 5 14:29:13 2026 -0700
PR intel: linkedin-enrich prioritizes media/PR contacts (org-id set sort)
The /people API has no organization_type filter, so build the media org-id
set from /organizations and sort media contacts first (LI_MEDIA_ONLY filters
to them). Fixes the first batch spending queries on non-media contacts.
---
src/pr/tools/linkedin-enrich.js | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/src/pr/tools/linkedin-enrich.js b/src/pr/tools/linkedin-enrich.js
index 8ad12f13..d6d6c590 100644
--- a/src/pr/tools/linkedin-enrich.js
+++ b/src/pr/tools/linkedin-enrich.js
@@ -44,18 +44,19 @@ async function api(p, opts = {}) {
async function main() {
if (!search.configured()) { console.error('no search key (BRAVE_SEARCH_API_KEY) in rentv/.env — run: node ~/Projects/secrets-manager/cli.js sync'); process.exit(1); }
- // no-LinkedIn people; media/PR contacts first (they're the outreach targets)
- const orgTypes = "trade_publication,association,pr_agency,marketing_agency,public_affairs";
- let targets = [];
+ // Media/PR contacts are the outreach targets — enrich them first. The /people API
+ // has no organization_type filter, so build the media org-id set and sort by it.
+ const MEDIA_TYPES = ['trade_publication', 'association', 'pr_agency', 'marketing_agency', 'public_affairs'];
+ const mediaIds = new Set();
try {
- const media = await api(`/people?linkedin_status=none&organization_type=${encodeURIComponent(orgTypes)}&limit=${MAX}`);
- targets = media.rows || media.people || [];
- } catch { /* fall through */ }
- if (!process.env.LI_MEDIA_ONLY && targets.length < MAX) {
- const more = await api(`/people?linkedin_status=none&limit=${MAX - targets.length}`);
- const seen = new Set(targets.map((t) => t.id));
- for (const p of (more.rows || more.people || [])) if (!seen.has(p.id)) targets.push(p);
- }
+ const orgs = await api(`/organizations?limit=1000`);
+ for (const o of (orgs.rows || orgs.organizations || [])) if (MEDIA_TYPES.includes(o.organization_type)) mediaIds.add(o.id);
+ } catch { /* best effort */ }
+ const pool = (await api(`/people?linkedin_status=none&limit=${Math.max(MAX * 4, 300)}`));
+ let targets = (pool.rows || pool.people || []);
+ if (process.env.LI_MEDIA_ONLY) targets = targets.filter((p) => mediaIds.has(p.organization_id));
+ // media contacts first, then the rest
+ targets.sort((a, b) => (mediaIds.has(b.organization_id) ? 1 : 0) - (mediaIds.has(a.organization_id) ? 1 : 0));
console.log(`[linkedin-enrich] backend=${search.configured()} targets=${targets.length} (Brave free tier ≈ $0)`);
let found = 0, queries = 0, miss = 0;
for (const p of targets.slice(0, MAX)) {
← 493127a2 chore: session close — search buyer/seller/broker on closing
·
back to Rentv 2026
·
Cody-gate: posts public-status now published|live in lockste 1fd2ec07 →