-
Notifications
You must be signed in to change notification settings - Fork 195
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1901c94
commit 83eb00a
Showing
3 changed files
with
777 additions
and
0 deletions.
There are no files selected for viewing
297 changes: 297 additions & 0 deletions
297
packages/api/src/crm/engagement/services/leadsquared/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,297 @@ | ||
import { EncryptionService } from '@@core/@core-services/encryption/encryption.service'; | ||
import { LoggerService } from '@@core/@core-services/logger/logger.service'; | ||
import { PrismaService } from '@@core/@core-services/prisma/prisma.service'; | ||
import { ApiResponse } from '@@core/utils/types'; | ||
import { SyncParam } from '@@core/utils/types/interface'; | ||
import { CrmObject } from '@crm/@lib/@types'; | ||
import { IEngagementService } from '@crm/engagement/types'; | ||
import { Injectable } from '@nestjs/common'; | ||
import axios from 'axios'; | ||
import { ServiceRegistry } from '../registry.service'; | ||
import { | ||
LeadSquaredEngagementCallInput, | ||
LeadSquaredEngagementEmailInput, | ||
LeadSquaredEngagementEmailOutput, | ||
LeadSquaredEngagementInput, | ||
LeadSquaredEngagementMeetingInput, | ||
LeadSquaredEngagementMeetingOutput, | ||
LeadSquaredEngagementOutput, | ||
} from './types'; | ||
|
||
@Injectable() | ||
export class LeadSquaredService implements IEngagementService { | ||
constructor( | ||
private prisma: PrismaService, | ||
private logger: LoggerService, | ||
private cryptoService: EncryptionService, | ||
private registry: ServiceRegistry, | ||
) { | ||
this.logger.setContext( | ||
CrmObject.engagement.toUpperCase() + ':' + LeadSquaredService.name, | ||
); | ||
this.registry.registerService('leadsquared', this); | ||
} | ||
|
||
formatDate(date: Date): string { | ||
const year = date.getUTCFullYear(); | ||
const month = date.getUTCMonth(); | ||
const currentDate = date.getUTCDate(); | ||
const hours = date.getUTCHours(); | ||
const minutes = date.getUTCMinutes(); | ||
const seconds = date.getUTCSeconds(); | ||
return `${year}-${month}-${currentDate} ${hours}:${minutes}:${seconds}`; | ||
} | ||
|
||
async addEngagement( | ||
engagementData: LeadSquaredEngagementInput, | ||
linkedUserId: string, | ||
engagement_type: string, | ||
): Promise<ApiResponse<LeadSquaredEngagementOutput>> { | ||
try { | ||
switch (engagement_type) { | ||
case 'CALL': | ||
return this.addCall( | ||
engagementData as LeadSquaredEngagementCallInput, | ||
linkedUserId, | ||
); | ||
case 'MEETING': | ||
return this.addMeeting( | ||
engagementData as LeadSquaredEngagementMeetingInput, | ||
linkedUserId, | ||
); | ||
case 'EMAIL': | ||
return this.addEmail( | ||
engagementData as LeadSquaredEngagementEmailInput, | ||
linkedUserId, | ||
); | ||
default: | ||
break; | ||
} | ||
} catch (error) { | ||
throw error; | ||
} | ||
} | ||
|
||
private async addCall( | ||
engagementData: LeadSquaredEngagementCallInput, | ||
linkedUserId: string, | ||
): Promise<ApiResponse<any>> { | ||
try { | ||
const connection = await this.prisma.connections.findFirst({ | ||
where: { | ||
id_linked_user: linkedUserId, | ||
provider_slug: 'leadsquared', | ||
vertical: 'crm', | ||
}, | ||
}); | ||
|
||
const headers = { | ||
'Content-Type': 'application/json', | ||
'x-LSQ-AccessKey': this.cryptoService.decrypt(connection.access_token), | ||
'x-LSQ-SecretKey': this.cryptoService.decrypt(connection.secret_token), | ||
}; | ||
|
||
const resp = await axios.post( | ||
`${connection.account_url}/v2/Telephony.svc/LogCall`, | ||
engagementData, | ||
{ | ||
headers, | ||
}, | ||
); | ||
return { | ||
data: resp.data, | ||
message: 'LeadSquared call created', | ||
statusCode: 201, | ||
}; | ||
} catch (error) { | ||
throw error; | ||
} | ||
} | ||
|
||
private async addMeeting( | ||
engagementData: LeadSquaredEngagementMeetingInput, | ||
linkedUserId: string, | ||
): Promise<ApiResponse<LeadSquaredEngagementMeetingOutput>> { | ||
try { | ||
const connection = await this.prisma.connections.findFirst({ | ||
where: { | ||
id_linked_user: linkedUserId, | ||
provider_slug: 'leadsquared', | ||
vertical: 'crm', | ||
}, | ||
}); | ||
|
||
const headers = { | ||
'Content-Type': 'application/json', | ||
'x-LSQ-AccessKey': this.cryptoService.decrypt(connection.access_token), | ||
'x-LSQ-SecretKey': this.cryptoService.decrypt(connection.secret_token), | ||
}; | ||
|
||
const resp = await axios.post( | ||
`${connection.account_url}/v2/Task.svc/Create`, | ||
engagementData, | ||
{ | ||
headers, | ||
}, | ||
); | ||
const taskId = resp.data['Message']['Id']; | ||
const taskResponse = await axios.get( | ||
`${connection.account_url}/v2/Task.svc/Retrieve.GetById?id=${taskId}`, | ||
{ | ||
headers, | ||
}, | ||
); | ||
return { | ||
data: taskResponse.data[0], | ||
message: 'Leadsquared meeting created', | ||
statusCode: 201, | ||
}; | ||
} catch (e) { | ||
throw e; | ||
} | ||
} | ||
|
||
private async addEmail( | ||
engagementData: LeadSquaredEngagementEmailInput, | ||
linkedUserId: string, | ||
): Promise<ApiResponse<LeadSquaredEngagementEmailOutput>> { | ||
try { | ||
const connection = await this.prisma.connections.findFirst({ | ||
where: { | ||
id_linked_user: linkedUserId, | ||
provider_slug: 'leadsquared', | ||
vertical: 'crm', | ||
}, | ||
}); | ||
const headers = { | ||
'Content-Type': 'application/json', | ||
'x-LSQ-AccessKey': this.cryptoService.decrypt(connection.access_token), | ||
'x-LSQ-SecretKey': this.cryptoService.decrypt(connection.secret_token), | ||
}; | ||
|
||
const resp = await axios.post( | ||
`${connection.account_url}/v2/EmailMarketing.svc/SendEmailToLead`, | ||
engagementData, | ||
{ | ||
headers, | ||
}, | ||
); | ||
return { | ||
data: resp.data, | ||
message: 'LeadSquared email created', | ||
statusCode: 201, | ||
}; | ||
} catch (error) { | ||
throw error; | ||
} | ||
} | ||
|
||
private async syncEmails(linkedUserId: string) { | ||
try { | ||
const connection = await this.prisma.connections.findFirst({ | ||
where: { | ||
id_linked_user: linkedUserId, | ||
provider_slug: 'leadsquared', | ||
vertical: 'crm', | ||
}, | ||
}); | ||
const headers = { | ||
'Content-Type': 'application/json', | ||
'x-LSQ-AccessKey': this.cryptoService.decrypt(connection.access_token), | ||
'x-LSQ-SecretKey': this.cryptoService.decrypt(connection.secret_token), | ||
}; | ||
const fromDate = this.formatDate(new Date(0)); | ||
const toDate = this.formatDate(new Date()); | ||
const requestBody = { | ||
Parameter: { | ||
FromDate: fromDate, | ||
ToDate: toDate, | ||
EmailEvent: 'Sent', | ||
}, | ||
}; | ||
const resp = await axios.get( | ||
`${connection.account_url}/v2/EmailMarketing.svc/RetrieveSentEmails`, | ||
requestBody, | ||
{ | ||
headers, | ||
}, | ||
); | ||
this.logger.log(`Synced leadsquared emails engagements !`); | ||
return { | ||
data: resp.data['Records'], | ||
message: 'LeadSquared engagements retrieved', | ||
statusCode: 200, | ||
}; | ||
} catch (error) { | ||
throw error; | ||
} | ||
} | ||
|
||
private async syncMeetings(linkedUserId: string) { | ||
try { | ||
const connection = await this.prisma.connections.findFirst({ | ||
where: { | ||
id_linked_user: linkedUserId, | ||
provider_slug: 'leadsquared', | ||
vertical: 'crm', | ||
}, | ||
}); | ||
|
||
const fromDate = this.formatDate(new Date(0)); | ||
const toDate = this.formatDate(new Date()); | ||
|
||
const payload = { | ||
FromDate: fromDate, | ||
ToDate: toDate, | ||
Users: [linkedUserId], | ||
}; | ||
|
||
const resp = await axios.post( | ||
`${connection.account_url}/v2/Task.svc/RetrieveAppointments/ByUserId`, | ||
payload, | ||
{ | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'x-LSQ-AccessKey': this.cryptoService.decrypt( | ||
connection.access_token, | ||
), | ||
'x-LSQ-SecretKey': this.cryptoService.decrypt( | ||
connection.secret_token, | ||
), | ||
}, | ||
}, | ||
); | ||
this.logger.log(`Synced leadsquared meetings !`); | ||
return { | ||
data: resp.data['List'], | ||
message: 'Leadsquared meetings retrieved', | ||
statusCode: 200, | ||
}; | ||
} catch (error) { | ||
throw error; | ||
} | ||
} | ||
|
||
async sync( | ||
data: SyncParam, | ||
): Promise<ApiResponse<LeadSquaredEngagementOutput[]>> { | ||
try { | ||
const { linkedUserId, engagement_type } = data; | ||
|
||
switch (engagement_type as string) { | ||
// there was no any endpoint to sync calls | ||
// case 'CALL': | ||
// return this.syncCalls(linkedUserId); | ||
case 'MEETING': | ||
return this.syncMeetings(linkedUserId); | ||
case 'EMAIL': | ||
return this.syncEmails(linkedUserId); | ||
|
||
default: | ||
break; | ||
} | ||
} catch (error) { | ||
throw error; | ||
} | ||
} | ||
} |
Oops, something went wrong.