From 29208a39d0a42ebbd4acf79cd97543969a65cfe8 Mon Sep 17 00:00:00 2001 From: Jonathan ARNAULT Date: Mon, 12 Aug 2024 15:39:14 +0200 Subject: [PATCH] Feat(inbound): Improve company name parsing --- src/tests/supabase/functions/postmark.spec.ts | 48 +++++++++++++++++++ .../functions/postmark/addNoteToContact.ts | 10 +++- .../postmark/extractMailContactData.ts | 22 ++++++++- supabase/functions/postmark/index.ts | 9 +++- 4 files changed, 85 insertions(+), 4 deletions(-) diff --git a/src/tests/supabase/functions/postmark.spec.ts b/src/tests/supabase/functions/postmark.spec.ts index 8b02144..86b7395 100644 --- a/src/tests/supabase/functions/postmark.spec.ts +++ b/src/tests/supabase/functions/postmark.spec.ts @@ -22,6 +22,7 @@ describe('extractMailContactData', () => { lastName: 'Lastname', email: 'firstname.lastname@marmelab.com', domain: 'marmelab.com', + companyName: 'Marmelab', }, ]); }); @@ -43,12 +44,14 @@ describe('extractMailContactData', () => { lastName: 'Lastname', email: 'firstname.lastname@marmelab.com', domain: 'marmelab.com', + companyName: 'Marmelab', }, { firstName: 'John', lastName: 'Doe', email: 'john.doe@marmelab.com', domain: 'marmelab.com', + companyName: 'Marmelab', }, ]); }); @@ -66,6 +69,7 @@ describe('extractMailContactData', () => { lastName: 'Name', email: 'name@marmelab.com', domain: 'marmelab.com', + companyName: 'Marmelab', }, ]); }); @@ -83,6 +87,7 @@ describe('extractMailContactData', () => { lastName: 'Word Name', email: 'multi.word.name@marmelab.com', domain: 'marmelab.com', + companyName: 'Marmelab', }, ]); }); @@ -101,6 +106,7 @@ describe('extractMailContactData', () => { lastName: 'Doe', email: '"john@doe"@marmelab.com', domain: 'marmelab.com', + companyName: 'Marmelab', }, ]); }); @@ -118,6 +124,7 @@ describe('extractMailContactData', () => { lastName: 'doe', email: 'john.doe@marmelab.com', domain: 'marmelab.com', + companyName: 'Marmelab', }, ]); }); @@ -135,6 +142,7 @@ describe('extractMailContactData', () => { lastName: 'john', email: 'john@marmelab.com', domain: 'marmelab.com', + companyName: 'Marmelab', }, ]); }); @@ -152,6 +160,7 @@ describe('extractMailContactData', () => { lastName: 'doe multi', email: 'john.doe.multi@marmelab.com', domain: 'marmelab.com', + companyName: 'Marmelab', }, ]); }); @@ -170,6 +179,45 @@ describe('extractMailContactData', () => { lastName: 'doe"', email: '"john@doe"@marmelab.com', domain: 'marmelab.com', + companyName: 'Marmelab', + }, + ]); + }); + + it('should support subdomains', () => { + // Because it is allowed by https://www.rfc-editor.org/rfc/rfc5322 + const result = extractMailContactData([ + { + Email: 'john.doe@sub.marmelab.com', + Name: 'John DOE', + }, + ]); + expect(result).toEqual([ + { + firstName: 'John', + lastName: 'DOE', + email: 'john.doe@sub.marmelab.com', + domain: 'sub.marmelab.com', + companyName: 'Marmelab', + }, + ]); + }); + + it('should support domains with hyphens and underscores', () => { + // Because it is allowed by https://www.rfc-editor.org/rfc/rfc5322 + const result = extractMailContactData([ + { + Email: 'john.doe@sub.mar-me_lab.com', + Name: 'John DOE', + }, + ]); + expect(result).toEqual([ + { + firstName: 'John', + lastName: 'DOE', + email: 'john.doe@sub.mar-me_lab.com', + domain: 'sub.mar-me_lab.com', + companyName: 'Mar Me Lab', }, ]); }); diff --git a/supabase/functions/postmark/addNoteToContact.ts b/supabase/functions/postmark/addNoteToContact.ts index 605800e..d660a78 100644 --- a/supabase/functions/postmark/addNoteToContact.ts +++ b/supabase/functions/postmark/addNoteToContact.ts @@ -7,6 +7,7 @@ export const addNoteToContact = async ({ firstName, lastName, noteContent, + companyName, }: { salesEmail: string; email: string; @@ -14,6 +15,7 @@ export const addNoteToContact = async ({ firstName: string; lastName: string; noteContent: string; + companyName: string; }) => { const { data: sales, error: fetchSalesError } = await supabaseAdmin .from('sales') @@ -60,7 +62,7 @@ export const addNoteToContact = async ({ await supabaseAdmin .from('companies') .select('*') - .eq('name', domain) + .eq('name', companyName) .maybeSingle(); if (fetchCompanyError) return new Response( @@ -76,7 +78,11 @@ export const addNoteToContact = async ({ const { data: newCompanies, error: createCompanyError } = await supabaseAdmin .from('companies') - .insert({ name: domain, sales_id: sales.id }) + .insert({ + name: companyName, + website: `https://${domain}`, + sales_id: sales.id, + }) .select(); if (createCompanyError) return new Response( diff --git a/supabase/functions/postmark/extractMailContactData.ts b/supabase/functions/postmark/extractMailContactData.ts index b434d13..ae8a899 100644 --- a/supabase/functions/postmark/extractMailContactData.ts +++ b/supabase/functions/postmark/extractMailContactData.ts @@ -40,6 +40,26 @@ export const extractMailContactData = ( firstName = parts[0]; lastName = parts.slice(1).join(' '); } - return { firstName, lastName, email: contact.Email, domain }; + return { + firstName, + lastName, + email: contact.Email, + domain, + companyName: extractCompanyName(domain), + }; }); }; + +export function extractCompanyName(domain: string) { + const name = domain.split('.').at(-2)!; + + const lowerCaseName = name + .replace('-', ' ') + .replace('_', ' ') + .toLowerCase(); + + return lowerCaseName + .split(' ') + .map(word => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); +} diff --git a/supabase/functions/postmark/index.ts b/supabase/functions/postmark/index.ts index c18e603..93c58ee 100644 --- a/supabase/functions/postmark/index.ts +++ b/supabase/functions/postmark/index.ts @@ -48,7 +48,13 @@ Deno.serve(async req => { const contacts = extractMailContactData(ToFull); - for (const { firstName, lastName, email, domain } of contacts) { + for (const { + firstName, + lastName, + email, + domain, + companyName, + } of contacts) { if (!email) { // Return a 403 to let Postmark know that it's no use to retry this request // https://postmarkapp.com/developer/webhooks/inbound-webhook#errors-and-retries @@ -67,6 +73,7 @@ Deno.serve(async req => { firstName, lastName, noteContent, + companyName, }); }