diff --git a/apps/api/src/app/auth/usecases/onboard-user/onboard-user.usecase.ts b/apps/api/src/app/auth/usecases/onboard-user/onboard-user.usecase.ts index 55d12b710..244c9ba2b 100644 --- a/apps/api/src/app/auth/usecases/onboard-user/onboard-user.usecase.ts +++ b/apps/api/src/app/auth/usecases/onboard-user/onboard-user.usecase.ts @@ -47,10 +47,10 @@ export class OnboardUser { 'First Name': updatedUser.firstName, 'Last Name': updatedUser.lastName, 'Lead Email': updatedUser.email, - 'Lead Source': updatedUser.source, - 'Mentioned Role': updatedUser.role, + 'CRM Source': updatedUser.source, + Role: updatedUser.role, 'Signup Method': updatedUser.signupMethod as LEAD_SIGNUP_USING, - 'Company Size': updatedUser.companySize, + 'Est. Employees': updatedUser.companySize, }); } catch (error) { captureException(error); diff --git a/apps/api/src/app/shared/services/lead.service.ts b/apps/api/src/app/shared/services/lead.service.ts index 2d9ee2d5b..660e48a7f 100644 --- a/apps/api/src/app/shared/services/lead.service.ts +++ b/apps/api/src/app/shared/services/lead.service.ts @@ -8,16 +8,75 @@ interface ILeadInformation { 'Last Name': string; 'Lead Email': string; 'Signup Method': LEAD_SIGNUP_USING; - 'Mentioned Role': string; - 'Lead Source': string; - 'Company Size': string; + Role: string; + 'CRM Source': string; + 'Est. Employees': string; } @Injectable() export class LeadService { private log = process.env.NODE_ENV === 'local'; + private maAccessTokenDate: Date; + private maAccessToken: string; + + private async getMaAccessToken(): Promise { + if ( + this.maAccessToken && + this.maAccessTokenDate && + new Date().getTime() - this.maAccessTokenDate.getTime() < 3500000 + ) { + if (this.log) console.log('Using cached ma access token'); + + // 3500000 = 58 minutes + return this.maAccessToken; + } + if (process.env.LEAD_REFRESH_TOKEN && process.env.LEAD_CLIENT_ID && process.env.LEAD_CLIENT_SECRET) { + // eslint-disable-next-line max-len + const url = `https://accounts.zoho.com/oauth/v2/token?client_id=${process.env.LEAD_CLIENT_ID}&grant_type=refresh_token&client_secret=${process.env.LEAD_CLIENT_SECRET}&refresh_token=${process.env.LEAD_REFRESH_TOKEN}`; + if (this.log) console.log('Lead URL', url); + + const response = await axios.post(url); + this.maAccessTokenDate = new Date(); + this.maAccessToken = response.data.access_token; + if (this.log) console.log('New access token generated', this.maAccessToken); + + return response.data.access_token; + } + + return undefined; + } public async createLead(data: ILeadInformation): Promise { + const maAccessToken = await this.getMaAccessToken(); + if (maAccessToken) { + const leadData = JSON.stringify({ + 'First Name': data['First Name'], + 'Last Name': data['Last Name'], + 'Lead Email': data['Lead Email'], + Role: data.Role, + 'Est. Employees': data['Est. Employees'], + 'CRM Source': data['CRM Source'], + }); + // Add Lead to marketing automation + // eslint-disable-next-line max-len + const maUrl = `https://marketingautomation.zoho.com/api/v1/json/listsubscribe?listkey=${process.env.LEAD_LIST_KEY}&leadinfo=${leadData}&topic_id=${process.env.LEAD_TOPIC_ID}`; + if (this.log) console.log(maUrl); + + try { + const maResponse = await axios.post( + maUrl, + {}, + { + headers: { + Authorization: `Zoho-oauthtoken ${maAccessToken}`, + }, + } + ); + if (this.log) console.log('Lead created', maResponse.data); + } catch (error) { + captureException(error); + } + } if (process.env.LEAD_MAKE_WEBHOOK_URL) { try { await axios.post(process.env.LEAD_MAKE_WEBHOOK_URL, { @@ -25,9 +84,9 @@ export class LeadService { lastName: data['Last Name'], email: data['Lead Email'], signupMethod: data['Signup Method'], - mentionedRole: data['Mentioned Role'], - leadSource: data['Lead Source'], - companySize: data['Company Size'], + mentionedRole: data.Role, + leadSource: data['CRM Source'], + companySize: data['Est. Employees'], createdAt: new Date(), }); if (this.log) console.log('Lead data sent to Make.com webhook'); diff --git a/apps/api/src/app/team/usecase/accept-invitation/accept-invitation.usecase.ts b/apps/api/src/app/team/usecase/accept-invitation/accept-invitation.usecase.ts index 99bd881e4..cda8c8eaa 100644 --- a/apps/api/src/app/team/usecase/accept-invitation/accept-invitation.usecase.ts +++ b/apps/api/src/app/team/usecase/accept-invitation/accept-invitation.usecase.ts @@ -108,10 +108,10 @@ export class AcceptInvitation { 'First Name': user.firstName, 'Last Name': user.lastName, 'Lead Email': user.email, - 'Lead Source': 'Invitation', - 'Mentioned Role': user.role, + 'CRM Source': 'Invitation', + Role: user.role, 'Signup Method': LEAD_SIGNUP_USING.EMAIL, - 'Company Size': user.companySize, + 'Est. Employees': user.companySize, }); } catch (error) { captureException(error); diff --git a/apps/web/config/constants.config.ts b/apps/web/config/constants.config.ts index d6b461930..16a37155a 100644 --- a/apps/web/config/constants.config.ts +++ b/apps/web/config/constants.config.ts @@ -443,7 +443,7 @@ export const HOW_HEARD_ABOUT_US = [ { value: 'Google Search', label: 'Google Search' }, { value: 'Bubble.io', label: 'Bubble.io' }, { value: 'Colleague', label: 'Colleague' }, - { value: 'Linkdin', label: 'Linkdin' }, + { value: 'Linkedin', label: 'Linkedin' }, { value: 'Invitation', label: 'Invitation' }, { value: 'AI (ChatGPT, Perplexity, Claude ...)', label: 'AI (ChatGPT, Perplexity, Claude ...)' }, ];