From 3523ea041e54b73b3ae267a868deaba40ad5b33c Mon Sep 17 00:00:00 2001 From: Rami Abdou Date: Mon, 12 Jan 2026 08:27:32 -0800 Subject: [PATCH 1/3] for now --- .../use-cases/save-company-if-necessary.ts | 2 + packages/core/src/modules/linkedin.ts | 41 ++++++++++--------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/packages/core/src/modules/employment/use-cases/save-company-if-necessary.ts b/packages/core/src/modules/employment/use-cases/save-company-if-necessary.ts index 3c3fdac17..6564ed79c 100644 --- a/packages/core/src/modules/employment/use-cases/save-company-if-necessary.ts +++ b/packages/core/src/modules/employment/use-cases/save-company-if-necessary.ts @@ -70,6 +70,8 @@ export async function saveCompanyIfNecessary( } ); + console.log(companyNameOrLinkedInId, apifyResult); + const parseResult = z.array(Company).safeParse(apifyResult); if (!parseResult.success) { diff --git a/packages/core/src/modules/linkedin.ts b/packages/core/src/modules/linkedin.ts index a8732e002..bee77cca6 100644 --- a/packages/core/src/modules/linkedin.ts +++ b/packages/core/src/modules/linkedin.ts @@ -324,19 +324,18 @@ const LinkedInLocation = z.object({ }); const LinkedInProfile = z.object({ - element: z.object({ - education: z.array(LinkedInEducation), - experience: z.array(LinkedInExperience), - headline: z.string().nullish(), - location: LinkedInLocation, - openToWork: z.boolean().nullish(), - photo: z.string().url().nullish(), - }), + education: z.array(LinkedInEducation), + error: z.undefined(), + experience: z.array(LinkedInExperience), + headline: z.string().nullish(), + location: LinkedInLocation, + openToWork: z.boolean().nullish(), + photo: z.string().url().nullish(), originalQuery: z.object({ url: z.string() }), }); const LinkedInFailure = z.object({ - element: z.null(), + error: z.array(z.any()), originalQuery: z.object({ url: z.string() }), }); @@ -345,11 +344,11 @@ const LinkedInResult = z.union([LinkedInProfile, LinkedInFailure]); // Types type LinkedInEducation = NonNullable< - z.infer['element']['education'][number] + z.infer['education'][number] >; type LinkedInExperience = NonNullable< - z.infer['element']['experience'][number] + z.infer['experience'][number] >; type LinkedInProfile = z.infer; @@ -430,7 +429,7 @@ export async function syncLinkedInProfiles( // This is the case where there are multiple members with the same // LinkedIn URL, something that should be fixed. - if (!profile.element || !member) { + if (profile.error || !member) { await finishSync(memberId); console.log(`Profile not found for ${memberId}, moving on.`); @@ -714,6 +713,8 @@ async function scrapeProfiles(profilesToScrape: string[]) { body: { urls: profilesToScrape }, }); + // console.log(apifyResult); + // We just need the bare minimum in order to cache the profiles, we're not // trying to parse the entire profile here. This ensures that we're not // too restrictive and forcing ourselves to re-scrape profiles that we @@ -746,7 +747,7 @@ async function scrapeProfiles(profilesToScrape: string[]) { await db.transaction().execute(async (trx) => { await Promise.all( newResults.map(async (result) => { - if (result.element) { + if (!result.error) { return successfulResults.push(result); } @@ -803,7 +804,7 @@ async function processProfile({ } }); - const checkEducationPromises = profile.element.education.map( + const checkEducationPromises = profile.education.map( async (education) => { if (!education) { return; @@ -826,7 +827,7 @@ async function processProfile({ } ); - const checkExperiencesPromises = profile.element.experience.map( + const checkExperiencesPromises = profile.experience.map( async (experience) => { if (!experience) { return; @@ -896,7 +897,7 @@ type CheckMemberInput = { async function checkMember({ member, profile, trx }: CheckMemberInput) { const updatedLocation = await run(async () => { - const locationFromLinkedIn = profile.element.location.parsed?.text; + const locationFromLinkedIn = profile.location.parsed?.text; if (!locationFromLinkedIn) { return null; @@ -914,10 +915,10 @@ async function checkMember({ member, profile, trx }: CheckMemberInput) { return getMostRelevantLocation(locationFromLinkedIn, 'geocode'); }); - if (!!profile.element.photo && !profile.element.openToWork) { + if (!!profile.photo && !profile.openToWork) { await uploadProfilePicture({ memberId: member.id, - pictureUrl: profile.element.photo, + pictureUrl: profile.photo, }); } @@ -925,7 +926,7 @@ async function checkMember({ member, profile, trx }: CheckMemberInput) { .updateTable('students') .set({ ...(!member.headline && { - headline: profile.element.headline, + headline: profile.headline, }), ...(!!updatedLocation && { currentLocation: updatedLocation.formattedAddress, @@ -1265,6 +1266,7 @@ async function createWorkExperience({ memberId, trx, }: CreateWorkExperienceInput) { + // console.log(linkedInExperience); const [companyId, location] = await Promise.all([ saveCompanyIfNecessary(trx, linkedInExperience.companyId), getMostRelevantLocation(linkedInExperience.location, 'geocode'), @@ -1309,6 +1311,7 @@ async function updateWorkExperience({ linkedInExperience, trx, }: UpdateWorkExperienceInput) { + // console.log(existingExperience, linkedInExperience); const set: Updateable = {}; if (existingExperience.linkedinId !== linkedInExperience.companyId) { From ab7d0d531d6b183970572a93c1b8f5b24956b94f Mon Sep 17 00:00:00 2001 From: Rami Abdou Date: Mon, 12 Jan 2026 08:41:32 -0800 Subject: [PATCH 2/3] fix --- .../employment/use-cases/save-company-if-necessary.ts | 8 +++++--- packages/core/src/modules/linkedin.ts | 2 -- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/core/src/modules/employment/use-cases/save-company-if-necessary.ts b/packages/core/src/modules/employment/use-cases/save-company-if-necessary.ts index 6564ed79c..142f78825 100644 --- a/packages/core/src/modules/employment/use-cases/save-company-if-necessary.ts +++ b/packages/core/src/modules/employment/use-cases/save-company-if-necessary.ts @@ -65,13 +65,15 @@ export async function saveCompanyIfNecessary( async () => { return runActor({ actorId: 'harvestapi~linkedin-company', - body: { companies: [companyNameOrLinkedInId] }, + body: { + companies: [ + `https://www.linkedin.com/company/${companyNameOrLinkedInId}`, + ], + }, }); } ); - console.log(companyNameOrLinkedInId, apifyResult); - const parseResult = z.array(Company).safeParse(apifyResult); if (!parseResult.success) { diff --git a/packages/core/src/modules/linkedin.ts b/packages/core/src/modules/linkedin.ts index bee77cca6..cf5d508b0 100644 --- a/packages/core/src/modules/linkedin.ts +++ b/packages/core/src/modules/linkedin.ts @@ -713,8 +713,6 @@ async function scrapeProfiles(profilesToScrape: string[]) { body: { urls: profilesToScrape }, }); - // console.log(apifyResult); - // We just need the bare minimum in order to cache the profiles, we're not // trying to parse the entire profile here. This ensures that we're not // too restrictive and forcing ourselves to re-scrape profiles that we From 96944411679ef0a3ac90bd68e188c66cda120c89 Mon Sep 17 00:00:00 2001 From: Rami Abdou Date: Mon, 12 Jan 2026 08:42:58 -0800 Subject: [PATCH 3/3] remove --- packages/core/src/modules/linkedin.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/core/src/modules/linkedin.ts b/packages/core/src/modules/linkedin.ts index cf5d508b0..e290bfb37 100644 --- a/packages/core/src/modules/linkedin.ts +++ b/packages/core/src/modules/linkedin.ts @@ -1264,7 +1264,6 @@ async function createWorkExperience({ memberId, trx, }: CreateWorkExperienceInput) { - // console.log(linkedInExperience); const [companyId, location] = await Promise.all([ saveCompanyIfNecessary(trx, linkedInExperience.companyId), getMostRelevantLocation(linkedInExperience.location, 'geocode'), @@ -1309,7 +1308,6 @@ async function updateWorkExperience({ linkedInExperience, trx, }: UpdateWorkExperienceInput) { - // console.log(existingExperience, linkedInExperience); const set: Updateable = {}; if (existingExperience.linkedinId !== linkedInExperience.companyId) {