Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
230 lines
5.5 KiB
TypeScript
230 lines
5.5 KiB
TypeScript
import { supabaseAdmin } from "../_shared/supabaseAdmin.ts";
|
|
import type { Attachment } from "./extractAndUploadAttachments.ts";
|
|
import { MAIL_PROVIDERS } from "./mailProvider.const.ts";
|
|
|
|
export const getOrCreateCompanyFromDomain = async ({
|
|
domain,
|
|
salesId,
|
|
companyName,
|
|
website,
|
|
}: {
|
|
domain: string;
|
|
salesId: number;
|
|
companyName: string;
|
|
website: string;
|
|
}) => {
|
|
if (MAIL_PROVIDERS.includes(domain)) {
|
|
// We don't want to create companies for generic mail providers, as they are not really companies and it would pollute the database with useless entries.
|
|
return null;
|
|
}
|
|
|
|
// Check if the company already exists
|
|
const { data: existingCompany, error: fetchCompanyError } =
|
|
await supabaseAdmin
|
|
.from("companies")
|
|
.select("*")
|
|
.or(`website.eq.${website},name.eq.${companyName},name.eq.${domain}`)
|
|
.maybeSingle();
|
|
if (fetchCompanyError) {
|
|
throw new Error(
|
|
`Could not fetch companies from database, name: ${domain}, error: ${fetchCompanyError.message}`,
|
|
);
|
|
}
|
|
|
|
if (existingCompany) {
|
|
return existingCompany;
|
|
}
|
|
|
|
const { data: newCompanies, error: createCompanyError } = await supabaseAdmin
|
|
.from("companies")
|
|
.insert({ name: companyName, sales_id: salesId, website })
|
|
.select();
|
|
if (createCompanyError) {
|
|
throw new Error(
|
|
`Could not create company in database, domain: ${domain}, error: ${createCompanyError.message}`,
|
|
);
|
|
}
|
|
return newCompanies[0];
|
|
};
|
|
|
|
export const getOrCreateContactFromEmailInfo = async ({
|
|
email,
|
|
firstName,
|
|
lastName,
|
|
salesId,
|
|
domain,
|
|
companyName,
|
|
website,
|
|
}: {
|
|
email: string;
|
|
firstName: string;
|
|
lastName: string;
|
|
salesId: number;
|
|
domain: string;
|
|
companyName: string;
|
|
website: string;
|
|
}) => {
|
|
// Check if the contact already exists
|
|
const { data: existingContact, error: fetchContactError } =
|
|
await supabaseAdmin
|
|
.from("contacts")
|
|
.select("*")
|
|
.contains("email_jsonb", JSON.stringify([{ email }]))
|
|
.maybeSingle();
|
|
if (fetchContactError) {
|
|
throw new Error(
|
|
`Could not fetch contact from database, email: ${email}, error: ${fetchContactError.message}`,
|
|
);
|
|
}
|
|
|
|
if (existingContact) {
|
|
return existingContact;
|
|
}
|
|
|
|
const company = await getOrCreateCompanyFromDomain({
|
|
domain,
|
|
salesId,
|
|
companyName,
|
|
website,
|
|
});
|
|
|
|
// Create the contact
|
|
const { data: newContacts, error: createContactError } = await supabaseAdmin
|
|
.from("contacts")
|
|
.insert({
|
|
first_name: firstName,
|
|
last_name: lastName,
|
|
email_jsonb: [{ email, type: "Work" }],
|
|
company_id: company ? company.id : null,
|
|
sales_id: salesId,
|
|
first_seen: new Date(),
|
|
last_seen: new Date(),
|
|
tags: [],
|
|
})
|
|
.select();
|
|
if (createContactError || !newContacts[0]) {
|
|
throw new Error(
|
|
`Could not create contact in database, email: ${email}, error: ${createContactError?.message}`,
|
|
);
|
|
}
|
|
return newContacts[0];
|
|
};
|
|
|
|
export const findActiveSaleByEmail = async (salesEmail: string) => {
|
|
const normalizedEmail = salesEmail.trim().toLowerCase();
|
|
|
|
const byPrimaryEmail = await supabaseAdmin
|
|
.from("sales")
|
|
.select("*")
|
|
.eq("email", normalizedEmail)
|
|
.neq("disabled", true)
|
|
.maybeSingle();
|
|
|
|
if (byPrimaryEmail.error || byPrimaryEmail.data) {
|
|
return byPrimaryEmail;
|
|
}
|
|
|
|
const bySecondaryEmail = await supabaseAdmin
|
|
.from("sales")
|
|
.select("*")
|
|
.contains("secondary_emails", JSON.stringify([normalizedEmail]))
|
|
.neq("disabled", true)
|
|
.order("id", { ascending: true })
|
|
.limit(2);
|
|
|
|
if (bySecondaryEmail.error) {
|
|
return { data: null, error: bySecondaryEmail.error };
|
|
}
|
|
|
|
const matches = bySecondaryEmail.data ?? [];
|
|
|
|
if (matches.length > 1) {
|
|
console.error(
|
|
`Ambiguous sender ${normalizedEmail}: registered as a secondary email by sales ${matches
|
|
.map((sale: { id: number }) => sale.id)
|
|
.join(", ")}. Refusing to attribute the note.`,
|
|
);
|
|
return { data: null, error: null };
|
|
}
|
|
|
|
return { data: matches[0] ?? null, error: null };
|
|
};
|
|
|
|
export const addNoteToContact = async ({
|
|
sales,
|
|
salesEmail,
|
|
email,
|
|
domain,
|
|
firstName,
|
|
lastName,
|
|
noteContent,
|
|
attachments,
|
|
companyName,
|
|
website,
|
|
}: {
|
|
sales: { id: number };
|
|
salesEmail: string;
|
|
email: string;
|
|
domain: string;
|
|
firstName: string;
|
|
lastName: string;
|
|
noteContent: string;
|
|
attachments: Attachment[];
|
|
companyName: string;
|
|
website: string;
|
|
}) => {
|
|
const { contact, error } = await getOrCreateContactFromEmailInfo({
|
|
email,
|
|
firstName,
|
|
lastName,
|
|
salesId: sales.id,
|
|
domain,
|
|
companyName,
|
|
website,
|
|
})
|
|
.then((contact) => ({
|
|
contact,
|
|
}))
|
|
.catch((error) => {
|
|
return {
|
|
error,
|
|
};
|
|
});
|
|
|
|
if (error) {
|
|
console.error(
|
|
"Error in getOrCreateContactFromEmailInfo for email:",
|
|
email,
|
|
"sales:",
|
|
salesEmail,
|
|
"error:",
|
|
error,
|
|
);
|
|
return new Response(
|
|
`Could not get or create contact from database, email: ${email}, sales: ${salesEmail}`,
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
|
|
// Add note to contact
|
|
const { error: createNoteError } = await supabaseAdmin
|
|
.from("contact_notes")
|
|
.insert({
|
|
contact_id: contact.id,
|
|
text: noteContent,
|
|
sales_id: sales.id,
|
|
attachments,
|
|
});
|
|
if (createNoteError) {
|
|
return new Response(
|
|
`Could not add note to contact ${email}, sales ${salesEmail}`,
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
|
|
await supabaseAdmin
|
|
.from("contacts")
|
|
.update({ last_seen: new Date() })
|
|
.eq("id", contact.id);
|
|
};
|