diff --git a/.env.appStore.example b/.env.appStore.example index 15f9fa42fb56d9..7ae87f9854bb55 100644 --- a/.env.appStore.example +++ b/.env.appStore.example @@ -128,7 +128,7 @@ ZOHOCRM_CLIENT_SECRET="" # - REVERT -# Used for the Pipedrive integration (via/ Revert (https://revert.dev)) +# Used for the CRM integrations (via/ Revert (https://revert.dev)) # @see https://github.com/calcom/cal.com/#obtaining-revert-api-keys REVERT_API_KEY= REVERT_PUBLIC_TOKEN= diff --git a/.env.example b/.env.example index a01ef6cc4d5def..086ed41fc48112 100644 --- a/.env.example +++ b/.env.example @@ -354,3 +354,9 @@ UNKEY_ROOT_KEY= # Used for Cal.ai Enterprise Voice AI Agents # https://retellai.com RETELL_AI_KEY= + +# - REVERT +# Used for the CRM integrations (via/ Revert (https://revert.dev)) +# @see https://github.com/calcom/cal.com/#obtaining-revert-api-keys +REVERT_API_KEY= +REVERT_PUBLIC_TOKEN= \ No newline at end of file diff --git a/packages/app-store/_utils/crms/RevertCRMAppService.ts b/packages/app-store/_utils/crms/RevertCRMAppService.ts new file mode 100644 index 00000000000000..d19415d2d1dcbd --- /dev/null +++ b/packages/app-store/_utils/crms/RevertCRMAppService.ts @@ -0,0 +1,171 @@ +import { getLocation } from "@calcom/lib/CalEventParser"; +import logger from "@calcom/lib/logger"; +import type { + Calendar, + CalendarEvent, + EventBusyDate, + IntegrationCalendar, + NewCalendarEventType, + Person, +} from "@calcom/types/Calendar"; +import type { CredentialPayload } from "@calcom/types/Credential"; + +export type ContactCreateResult = { + status: string; + result: { + id: string; + email: string; + firstName: string; + lastName: string; + name: string; + }; +}; + +export type ContactSearchResult = { + status: string; + results: Array<{ + id: string; + email: string; + firstName: string; + lastName: string; + name: string; + }>; +}; + +export default abstract class RevertCRMAppService implements Calendar { + protected log: typeof logger; + protected tenantId: string; + protected revertApiKey: string; + protected revertApiUrl: string; + protected appSlug: string; + + constructor(credential: CredentialPayload) { + this.revertApiKey = process.env.REVERT_API_KEY || ""; + this.revertApiUrl = process.env.REVERT_API_URL || "https://api.revert.dev/"; + this.tenantId = String(credential.teamId ? credential.teamId : credential.userId); + this.log = logger.getSubLogger({ prefix: [`[[lib]`] }); + this.appSlug = ""; + } + + protected createContacts = async (attendees: Person[]) => { + const result = attendees.map(async (attendee) => { + const headers = new Headers(); + headers.append("x-revert-api-token", this.revertApiKey); + headers.append("x-revert-t-id", this.tenantId); + headers.append("Content-Type", "application/json"); + + const [firstname, lastname] = !!attendee.name ? attendee.name.split(" ") : [attendee.email, "-"]; + const bodyRaw = JSON.stringify({ + firstName: firstname, + lastName: lastname || "-", + email: attendee.email, + }); + + const requestOptions = { + method: "POST", + headers: headers, + body: bodyRaw, + }; + + try { + const response = await fetch(`${this.revertApiUrl}crm/contacts`, requestOptions); + const result = (await response.json()) as ContactCreateResult; + return result; + } catch (error) { + return Promise.reject(error); + } + }); + return await Promise.all(result); + }; + + protected getMeetingBody = (event: CalendarEvent): string => { + return `${event.organizer.language.translate("invitee_timezone")}: ${ + event.attendees[0].timeZone + }

${event.organizer.language.translate("share_additional_notes")}
${ + event.additionalNotes || "-" + }`; + }; + + protected abstract contactSearch( + event: CalendarEvent + ): Promise; + + protected abstract createCRMEvent( + event: CalendarEvent, + contacts: CalendarEvent["attendees"] + ): Promise; + + protected updateMeeting = async (uid: string, event: CalendarEvent) => { + const eventPayload = { + subject: event.title, + startDateTime: event.startTime, + endDateTime: event.endTime, + description: this.getMeetingBody(event), + location: getLocation(event), + }; + const headers = new Headers(); + headers.append("x-revert-api-token", this.revertApiKey); + headers.append("x-revert-t-id", this.tenantId); + headers.append("Content-Type", "application/json"); + + const eventBody = JSON.stringify(eventPayload); + const requestOptions = { + method: "PATCH", + headers: headers, + body: eventBody, + }; + + return await fetch(`${this.revertApiUrl}crm/events/${uid}`, requestOptions); + }; + + protected deleteMeeting = async (uid: string) => { + const headers = new Headers(); + headers.append("x-revert-api-token", this.revertApiKey); + headers.append("x-revert-t-id", this.tenantId); + + const requestOptions = { + method: "DELETE", + headers: headers, + }; + + return await fetch(`${this.revertApiUrl}crm/events/${uid}`, requestOptions); + }; + + protected async handleEventCreation(event: CalendarEvent, contacts: CalendarEvent["attendees"]) { + const meetingEvent = await (await this.createCRMEvent(event, contacts)).json(); + if (meetingEvent && meetingEvent.status === "ok") { + this.log.debug("event:creation:ok", { meetingEvent }); + + return Promise.resolve({ + uid: meetingEvent.result.id, + id: meetingEvent.result.id, + type: this.appSlug, + password: "", + url: "", + additionalInfo: { contacts, meetingEvent }, + }); + } + this.log.debug("meeting:creation:notOk", { meetingEvent, event, contacts }); + return Promise.reject("Something went wrong when creating a meeting"); + } + + async getAvailability( + _dateFrom: string, + _dateTo: string, + _selectedCalendars: IntegrationCalendar[] + ): Promise { + return Promise.resolve([]); + } + + async listCalendars(_event?: CalendarEvent): Promise { + return Promise.resolve([]); + } + + abstract createEvent(event: CalendarEvent): Promise; + + abstract updateEvent(uid: string, event: CalendarEvent): Promise; + + public async deleteEvent(uid: string): Promise { + await this.deleteMeeting(uid); + } +} diff --git a/packages/app-store/hubspot-revert/lib/CalendarService.ts b/packages/app-store/hubspot-revert/lib/CalendarService.ts index e82c0a1e8985b7..34f8cdcd4d94c2 100644 --- a/packages/app-store/hubspot-revert/lib/CalendarService.ts +++ b/packages/app-store/hubspot-revert/lib/CalendarService.ts @@ -1,83 +1,19 @@ import { getLocation } from "@calcom/lib/CalEventParser"; -import logger from "@calcom/lib/logger"; -import type { - Calendar, - CalendarEvent, - EventBusyDate, - IntegrationCalendar, - NewCalendarEventType, - Person, -} from "@calcom/types/Calendar"; +import type { CalendarEvent, NewCalendarEventType, Person } from "@calcom/types/Calendar"; import type { CredentialPayload } from "@calcom/types/Credential"; +import type { ContactSearchResult } from "../../_utils/crms/RevertCRMAppService"; +import RevertCRMAppService from "../../_utils/crms/RevertCRMAppService"; import appConfig from "../config.json"; -type ContactSearchResult = { - status: string; - results: Array<{ - id: string; - email: string; - firstName: string; - lastName: string; - name: string; - }>; -}; - -type ContactCreateResult = { - status: string; - result: { - id: string; - email: string; - firstName: string; - lastName: string; - name: string; - }; -}; - -export default class HubSpotRevertCalendarService implements Calendar { - private log: typeof logger; - private tenantId: string; - private revertApiKey: string; - private revertApiUrl: string; +export default class HubSpotAppService extends RevertCRMAppService { constructor(credential: CredentialPayload) { - this.revertApiKey = process.env.REVERT_API_KEY || ""; - this.revertApiUrl = process.env.REVERT_API_URL || "https://api.revert.dev/"; - this.tenantId = String(credential.teamId ? credential.teamId : credential.userId); // Question: Is this a reasonable assumption to be made? Get confirmation on the exact field to be used here. - this.log = logger.getSubLogger({ prefix: [`[[lib] ${appConfig.slug}`] }); + super(credential); + this.log = this.log.getSubLogger({ prefix: [appConfig.slug] }); + this.appSlug = appConfig.slug; } - private createContacts = async (attendees: Person[]) => { - const result = attendees.map(async (attendee) => { - const headers = new Headers(); - headers.append("x-revert-api-token", this.revertApiKey); - headers.append("x-revert-t-id", this.tenantId); - headers.append("Content-Type", "application/json"); - - const [firstname, lastname] = !!attendee.name ? attendee.name.split(" ") : [attendee.email, "-"]; - const bodyRaw = JSON.stringify({ - firstName: firstname, - lastName: lastname || "-", - email: attendee.email, - }); - - const requestOptions = { - method: "POST", - headers: headers, - body: bodyRaw, - }; - - try { - const response = await fetch(`${this.revertApiUrl}crm/contacts`, requestOptions); - const result = (await response.json()) as ContactCreateResult; - return result; - } catch (error) { - return Promise.reject(error); - } - }); - return await Promise.all(result); - }; - - private contactSearch = async (event: CalendarEvent) => { + protected contactSearch = async (event: CalendarEvent) => { const headers = new Headers(); headers.append("x-revert-api-token", this.revertApiKey); headers.append("x-revert-t-id", this.tenantId); @@ -112,15 +48,7 @@ export default class HubSpotRevertCalendarService implements Calendar { } }; - private getMeetingBody = (event: CalendarEvent): string => { - return `${event.organizer.language.translate("invitee_timezone")}: ${ - event.attendees[0].timeZone - }

${event.organizer.language.translate("share_additional_notes")}
${ - event.additionalNotes || "-" - }`; - }; - - private createHubSpotEvent = async (event: CalendarEvent, contacts: CalendarEvent["attendees"]) => { + protected createCRMEvent = async (event: CalendarEvent, contacts: CalendarEvent["attendees"]) => { const eventPayload = { subject: event.title, startDateTime: event.startTime, @@ -146,65 +74,12 @@ export default class HubSpotRevertCalendarService implements Calendar { return await fetch(`${this.revertApiUrl}crm/events`, requestOptions); }; - private updateMeeting = async (uid: string, event: CalendarEvent) => { - const eventPayload = { - subject: event.title, - startDateTime: event.startTime, - endDateTime: event.endTime, - description: this.getMeetingBody(event), - location: getLocation(event), - }; - const headers = new Headers(); - headers.append("x-revert-api-token", this.revertApiKey); - headers.append("x-revert-t-id", this.tenantId); - headers.append("Content-Type", "application/json"); - - const eventBody = JSON.stringify(eventPayload); - const requestOptions = { - method: "PATCH", - headers: headers, - body: eventBody, - }; - - return await fetch(`${this.revertApiUrl}crm/events/${uid}`, requestOptions); - }; - - private deleteMeeting = async (uid: string) => { - const headers = new Headers(); - headers.append("x-revert-api-token", this.revertApiKey); - headers.append("x-revert-t-id", this.tenantId); - - const requestOptions = { - method: "DELETE", - headers: headers, - }; - - return await fetch(`${this.revertApiUrl}crm/events/${uid}`, requestOptions); - }; - - async handleEventCreation(event: CalendarEvent, contacts: CalendarEvent["attendees"]) { - const meetingEvent = await (await this.createHubSpotEvent(event, contacts)).json(); - if (meetingEvent && meetingEvent.status === "ok") { - this.log.debug("event:creation:ok", { meetingEvent }); - return Promise.resolve({ - uid: meetingEvent.result.id, - id: meetingEvent.result.id, - type: appConfig.slug, - password: "", - url: "", - additionalInfo: { contacts, meetingEvent }, - }); - } - this.log.debug("meeting:creation:notOk", { meetingEvent, event, contacts }); - return Promise.reject("Something went wrong when creating a meeting in HubSpot CRM"); - } - async createEvent(event: CalendarEvent): Promise { const contacts = await this.contactSearch(event); if (contacts && contacts.results.length) { if (contacts.results.length === event.attendees.length) { - // all contacts are in hubspot CRM already. + // All contacts are in HubSpot CRM already. this.log.debug("contact:search:all", { event, contacts: contacts }); const existingPeople = contacts.results.map((c) => { return { @@ -222,7 +97,7 @@ export default class HubSpotRevertCalendarService implements Calendar { this.log.debug("contact:search:notAll", { event, contacts }); const existingContacts = contacts.results.map((contact) => contact.email); this.log.debug("contact:filter:existing", { existingContacts }); - // Get non existing contacts filtering out existing from attendees + // Get non-existing contacts filtering out existing from attendees const nonExistingContacts: Person[] = event.attendees.filter( (attendee) => !existingContacts.includes(attendee.email) ); @@ -230,7 +105,7 @@ export default class HubSpotRevertCalendarService implements Calendar { // Only create contacts in HubSpot CRM that were not present in the previous contact search const createdContacts = await this.createContacts(nonExistingContacts); this.log.debug("contact:created", { createdContacts }); - // Continue with event creation and association only when all contacts are present in hubspot + // Continue with event creation and association only when all contacts are present in HubSpot if (createdContacts[0] && createdContacts[0].status === "ok") { this.log.debug("contact:creation:ok"); const existingPeople = contacts.results.map((c) => { @@ -252,7 +127,7 @@ export default class HubSpotRevertCalendarService implements Calendar { }; }); const allContacts = existingPeople.concat(newlyCreatedPeople); - // ensure the order of attendees is maintained. + // Ensure the order of attendees is maintained. allContacts.sort((a, b) => { const indexA = event.attendees.findIndex((c) => c.email === a.email); const indexB = event.attendees.findIndex((c) => c.email === b.email); @@ -313,20 +188,4 @@ export default class HubSpotRevertCalendarService implements Calendar { this.log.debug("meeting:updation:notOk", { meetingEvent, event }); return Promise.reject("Something went wrong when updating a meeting in HubSpot CRM"); } - - async deleteEvent(uid: string): Promise { - await this.deleteMeeting(uid); - } - - async getAvailability( - _dateFrom: string, - _dateTo: string, - _selectedCalendars: IntegrationCalendar[] - ): Promise { - return Promise.resolve([]); - } - - async listCalendars(_event?: CalendarEvent): Promise { - return Promise.resolve([]); - } } diff --git a/packages/app-store/salesforce-revert/lib/CalendarService.ts b/packages/app-store/salesforce-revert/lib/CalendarService.ts index 4ef2294532a3ed..6c67592d9bd3fe 100644 --- a/packages/app-store/salesforce-revert/lib/CalendarService.ts +++ b/packages/app-store/salesforce-revert/lib/CalendarService.ts @@ -1,83 +1,19 @@ import { getLocation } from "@calcom/lib/CalEventParser"; -import logger from "@calcom/lib/logger"; -import type { - Calendar, - CalendarEvent, - EventBusyDate, - IntegrationCalendar, - NewCalendarEventType, - Person, -} from "@calcom/types/Calendar"; +import type { CalendarEvent, NewCalendarEventType, Person } from "@calcom/types/Calendar"; import type { CredentialPayload } from "@calcom/types/Credential"; +import type { ContactSearchResult } from "../../_utils/crms/RevertCRMAppService"; +import RevertCRMAppService from "../../_utils/crms/RevertCRMAppService"; import appConfig from "../config.json"; -type ContactSearchResult = { - status: string; - results: Array<{ - id: string; - email: string; - firstName: string; - lastName: string; - name: string; - }>; -}; - -type ContactCreateResult = { - status: string; - result: { - id: string; - email: string; - firstName: string; - lastName: string; - name: string; - }; -}; - -export default class SalesforceRevertCalendarService implements Calendar { - private log: typeof logger; - private tenantId: string; - private revertApiKey: string; - private revertApiUrl: string; +export default class SalesforceAppService extends RevertCRMAppService { constructor(credential: CredentialPayload) { - this.revertApiKey = process.env.REVERT_API_KEY || ""; - this.revertApiUrl = process.env.REVERT_API_URL || "https://api.revert.dev/"; - this.tenantId = String(credential.teamId ? credential.teamId : credential.userId); // Question: Is this a reasonable assumption to be made? Get confirmation on the exact field to be used here. - this.log = logger.getSubLogger({ prefix: [`[[lib] ${appConfig.slug}`] }); + super(credential); + this.log = this.log.getSubLogger({ prefix: [appConfig.slug] }); + this.appSlug = appConfig.slug; } - private createContacts = async (attendees: Person[]) => { - const result = attendees.map(async (attendee) => { - const headers = new Headers(); - headers.append("x-revert-api-token", this.revertApiKey); - headers.append("x-revert-t-id", this.tenantId); - headers.append("Content-Type", "application/json"); - - const [firstname, lastname] = !!attendee.name ? attendee.name.split(" ") : [attendee.email, "-"]; - const bodyRaw = JSON.stringify({ - firstName: firstname, - lastName: lastname || "-", - email: attendee.email, - }); - - const requestOptions = { - method: "POST", - headers: headers, - body: bodyRaw, - }; - - try { - const response = await fetch(`${this.revertApiUrl}crm/contacts`, requestOptions); - const result = (await response.json()) as ContactCreateResult; - return result; - } catch (error) { - return Promise.reject(error); - } - }); - return await Promise.all(result); - }; - - private contactSearch = async (event: CalendarEvent) => { + protected contactSearch = async (event: CalendarEvent) => { const result = event.attendees.map(async (attendee) => { const headers = new Headers(); headers.append("x-revert-api-token", this.revertApiKey); @@ -105,15 +41,7 @@ export default class SalesforceRevertCalendarService implements Calendar { return await Promise.all(result); }; - private getMeetingBody = (event: CalendarEvent): string => { - return `${event.organizer.language.translate("invitee_timezone")}: ${ - event.attendees[0].timeZone - }

${event.organizer.language.translate("share_additional_notes")}
${ - event.additionalNotes || "-" - }`; - }; - - private createSalesforceEvent = async (event: CalendarEvent, contacts: CalendarEvent["attendees"]) => { + protected createCRMEvent = async (event: CalendarEvent, contacts: CalendarEvent["attendees"]) => { const eventPayload = { subject: event.title, startDateTime: event.startTime, @@ -138,60 +66,6 @@ export default class SalesforceRevertCalendarService implements Calendar { return await fetch(`${this.revertApiUrl}crm/events`, requestOptions); }; - - private updateMeeting = async (uid: string, event: CalendarEvent) => { - const eventPayload = { - subject: event.title, - startDateTime: event.startTime, - endDateTime: event.endTime, - description: this.getMeetingBody(event), - location: getLocation(event), - }; - const headers = new Headers(); - headers.append("x-revert-api-token", this.revertApiKey); - headers.append("x-revert-t-id", this.tenantId); - headers.append("Content-Type", "application/json"); - - const eventBody = JSON.stringify(eventPayload); - const requestOptions = { - method: "PATCH", - headers: headers, - body: eventBody, - }; - - return await fetch(`${this.revertApiUrl}crm/events/${uid}`, requestOptions); - }; - - private deleteMeeting = async (uid: string) => { - const headers = new Headers(); - headers.append("x-revert-api-token", this.revertApiKey); - headers.append("x-revert-t-id", this.tenantId); - - const requestOptions = { - method: "DELETE", - headers: headers, - }; - - return await fetch(`${this.revertApiUrl}crm/events/${uid}`, requestOptions); - }; - - async handleEventCreation(event: CalendarEvent, contacts: CalendarEvent["attendees"]) { - const meetingEvent = await (await this.createSalesforceEvent(event, contacts)).json(); - if (meetingEvent && meetingEvent.status === "ok") { - this.log.debug("event:creation:ok", { meetingEvent }); - return Promise.resolve({ - uid: meetingEvent.result.id, - id: meetingEvent.result.id, - type: appConfig.slug, - password: "", - url: "", - additionalInfo: { contacts, meetingEvent }, - }); - } - this.log.debug("meeting:creation:notOk", { meetingEvent, event, contacts }); - return Promise.reject("Something went wrong when creating a meeting in SFDC"); - } - async createEvent(event: CalendarEvent): Promise { let contacts = await this.contactSearch(event); contacts = contacts.filter((c) => c.results.length >= 1); @@ -309,20 +183,4 @@ export default class SalesforceRevertCalendarService implements Calendar { this.log.debug("meeting:updation:notOk", { meetingEvent, event }); return Promise.reject("Something went wrong when updating a meeting in SFDC"); } - - async deleteEvent(uid: string): Promise { - await this.deleteMeeting(uid); - } - - async getAvailability( - _dateFrom: string, - _dateTo: string, - _selectedCalendars: IntegrationCalendar[] - ): Promise { - return Promise.resolve([]); - } - - async listCalendars(_event?: CalendarEvent): Promise { - return Promise.resolve([]); - } } diff --git a/packages/app-store/zohocrm-revert/lib/CalendarService.ts b/packages/app-store/zohocrm-revert/lib/CalendarService.ts index bb399a592a8c64..0efbc6c3b3ea75 100644 --- a/packages/app-store/zohocrm-revert/lib/CalendarService.ts +++ b/packages/app-store/zohocrm-revert/lib/CalendarService.ts @@ -1,84 +1,19 @@ import { getLocation } from "@calcom/lib/CalEventParser"; -import logger from "@calcom/lib/logger"; -import type { - Calendar, - CalendarEvent, - EventBusyDate, - IntegrationCalendar, - NewCalendarEventType, - Person, -} from "@calcom/types/Calendar"; +import type { CalendarEvent, NewCalendarEventType, Person } from "@calcom/types/Calendar"; import type { CredentialPayload } from "@calcom/types/Credential"; +import type { ContactSearchResult } from "../../_utils/crms/RevertCRMAppService"; +import RevertCRMAppService from "../../_utils/crms/RevertCRMAppService"; import appConfig from "../config.json"; -type ContactSearchResult = { - status: string; - results: Array<{ - id: string; - email: string; - firstName: string; - lastName: string; - name: string; - }>; - error?: string; -}; - -type ContactCreateResult = { - status: string; - result: { - id: string; - email: string; - firstName: string; - lastName: string; - name: string; - }; -}; - -export default class ZohoCRMRevertCalendarService implements Calendar { - private log: typeof logger; - private tenantId: string; - private revertApiKey: string; - private revertApiUrl: string; +export default class ZohoCRMAppService extends RevertCRMAppService { constructor(credential: CredentialPayload) { - this.revertApiKey = process.env.REVERT_API_KEY || ""; - this.revertApiUrl = process.env.REVERT_API_URL || "https://api.revert.dev/"; - this.tenantId = String(credential.teamId ? credential.teamId : credential.userId); // Question: Is this a reasonable assumption to be made? Get confirmation on the exact field to be used here. - this.log = logger.getSubLogger({ prefix: [`[[lib] ${appConfig.slug}`] }); + super(credential); + this.log = this.log.getSubLogger({ prefix: [appConfig.slug] }); + this.appSlug = appConfig.slug; } - private createContacts = async (attendees: Person[]) => { - const result = attendees.map(async (attendee) => { - const headers = new Headers(); - headers.append("x-revert-api-token", this.revertApiKey); - headers.append("x-revert-t-id", this.tenantId); - headers.append("Content-Type", "application/json"); - - const [firstname, lastname] = !!attendee.name ? attendee.name.split(" ") : [attendee.email, "-"]; - const bodyRaw = JSON.stringify({ - firstName: firstname, - lastName: lastname || "-", - email: attendee.email, - }); - - const requestOptions = { - method: "POST", - headers: headers, - body: bodyRaw, - }; - - try { - const response = await fetch(`${this.revertApiUrl}crm/contacts`, requestOptions); - const result = (await response.json()) as ContactCreateResult; - return result; - } catch (error) { - return Promise.reject(error); - } - }); - return await Promise.all(result); - }; - - private contactSearch = async (event: CalendarEvent) => { + protected contactSearch = async (event: CalendarEvent) => { const result = event.attendees.map(async (attendee) => { const headers = new Headers(); headers.append("x-revert-api-token", this.revertApiKey); @@ -106,15 +41,7 @@ export default class ZohoCRMRevertCalendarService implements Calendar { return await Promise.all(result); }; - private getMeetingBody = (event: CalendarEvent): string => { - return `${event.organizer.language.translate("invitee_timezone")}: ${ - event.attendees[0].timeZone - }

${event.organizer.language.translate("share_additional_notes")}
${ - event.additionalNotes || "-" - }`; - }; - - private createZohoCRMEvent = async (event: CalendarEvent, contacts: CalendarEvent["attendees"]) => { + protected createCRMEvent = async (event: CalendarEvent, contacts: CalendarEvent["attendees"]) => { const eventPayload = { subject: event.title, startDateTime: event.startTime, @@ -140,64 +67,10 @@ export default class ZohoCRMRevertCalendarService implements Calendar { return await fetch(`${this.revertApiUrl}crm/events`, requestOptions); }; - private updateMeeting = async (uid: string, event: CalendarEvent) => { - const eventPayload = { - subject: event.title, - startDateTime: event.startTime, - endDateTime: event.endTime, - description: this.getMeetingBody(event), - location: getLocation(event), - }; - const headers = new Headers(); - headers.append("x-revert-api-token", this.revertApiKey); - headers.append("x-revert-t-id", this.tenantId); - headers.append("Content-Type", "application/json"); - - const eventBody = JSON.stringify(eventPayload); - const requestOptions = { - method: "PATCH", - headers: headers, - body: eventBody, - }; - - return await fetch(`${this.revertApiUrl}crm/events/${uid}`, requestOptions); - }; - - private deleteMeeting = async (uid: string) => { - const headers = new Headers(); - headers.append("x-revert-api-token", this.revertApiKey); - headers.append("x-revert-t-id", this.tenantId); - - const requestOptions = { - method: "DELETE", - headers: headers, - }; - - return await fetch(`${this.revertApiUrl}crm/events/${uid}`, requestOptions); - }; - - async handleEventCreation(event: CalendarEvent, contacts: CalendarEvent["attendees"]) { - const meetingEvent = await (await this.createZohoCRMEvent(event, contacts)).json(); - if (meetingEvent && meetingEvent.status === "ok") { - this.log.debug("event:creation:ok", { meetingEvent }); - - return Promise.resolve({ - uid: meetingEvent.result.details.id, - id: meetingEvent.result.details.id, - type: appConfig.slug, - password: "", - url: "", - additionalInfo: { contacts, meetingEvent }, - }); - } - this.log.debug("meeting:creation:notOk", { meetingEvent, event, contacts }); - return Promise.reject("Something went wrong when creating a meeting in ZOHO CRM"); - } - async createEvent(event: CalendarEvent): Promise { let contacts = await this.contactSearch(event); - contacts = contacts.filter((c) => !c.error && c.results && c.results.length >= 1); + contacts = contacts.filter((c) => c.status !== "error" && c.results && c.results.length >= 1); if (contacts && contacts.length >= 1 && contacts[0].results) { if (contacts.length === event.attendees.length) { @@ -313,20 +186,4 @@ export default class ZohoCRMRevertCalendarService implements Calendar { this.log.debug("meeting:updation:notOk", { meetingEvent, event }); return Promise.reject("Something went wrong when updating a meeting in ZOHO CRM"); } - - async deleteEvent(uid: string): Promise { - await this.deleteMeeting(uid); - } - - async getAvailability( - _dateFrom: string, - _dateTo: string, - _selectedCalendars: IntegrationCalendar[] - ): Promise { - return Promise.resolve([]); - } - - async listCalendars(_event?: CalendarEvent): Promise { - return Promise.resolve([]); - } }