From 1f036bf35e8cbd2260563e97bfa5b9c60e70bf8d Mon Sep 17 00:00:00 2001 From: Jatin Sandilya <7681067+jatinsandilya@users.noreply.github.com> Date: Fri, 29 Dec 2023 15:25:26 +0530 Subject: [PATCH] feat: pipedrive crm app on cal (#12316) * add pipedrive crm app w/ revert api * update lockfile * fix issues highlighted by codacy * get pipedrive `client_id` & `client_secret` from db * update readme with instructions to add credentials * Fix yarn.lock * fix `turbo.json` --------- Co-authored-by: Hariom --- .env.appStore.example | 8 + README.md | 4 + .../app-store/apps.keys-schemas.generated.ts | 2 + packages/app-store/apps.metadata.generated.ts | 2 + packages/app-store/apps.schemas.generated.ts | 2 + packages/app-store/apps.server.generated.ts | 1 + packages/app-store/index.ts | 1 + .../app-store/pipedrive-crm/DESCRIPTION.md | 6 + packages/app-store/pipedrive-crm/README.md | 19 + packages/app-store/pipedrive-crm/api/add.ts | 35 + .../app-store/pipedrive-crm/api/callback.ts | 19 + packages/app-store/pipedrive-crm/api/index.ts | 2 + packages/app-store/pipedrive-crm/config.json | 17 + packages/app-store/pipedrive-crm/index.ts | 2 + .../pipedrive-crm/lib/CalendarService.ts | 313 +++++ packages/app-store/pipedrive-crm/lib/index.ts | 1 + packages/app-store/pipedrive-crm/package.json | 14 + .../app-store/pipedrive-crm/static/icon.svg | 23 + .../static/pipedrive-banner.jpeg | Bin 0 -> 65706 bytes packages/app-store/pipedrive-crm/zod.ts | 8 + turbo.json | 3 + yarn.lock | 1111 +++++++---------- 22 files changed, 953 insertions(+), 640 deletions(-) create mode 100644 packages/app-store/pipedrive-crm/DESCRIPTION.md create mode 100644 packages/app-store/pipedrive-crm/README.md create mode 100644 packages/app-store/pipedrive-crm/api/add.ts create mode 100644 packages/app-store/pipedrive-crm/api/callback.ts create mode 100644 packages/app-store/pipedrive-crm/api/index.ts create mode 100644 packages/app-store/pipedrive-crm/config.json create mode 100644 packages/app-store/pipedrive-crm/index.ts create mode 100644 packages/app-store/pipedrive-crm/lib/CalendarService.ts create mode 100644 packages/app-store/pipedrive-crm/lib/index.ts create mode 100644 packages/app-store/pipedrive-crm/package.json create mode 100644 packages/app-store/pipedrive-crm/static/icon.svg create mode 100644 packages/app-store/pipedrive-crm/static/pipedrive-banner.jpeg create mode 100644 packages/app-store/pipedrive-crm/zod.ts diff --git a/.env.appStore.example b/.env.appStore.example index 1b51680e41..15f9fa42fb 100644 --- a/.env.appStore.example +++ b/.env.appStore.example @@ -127,4 +127,12 @@ ZOHOCRM_CLIENT_ID="" ZOHOCRM_CLIENT_SECRET="" +# - REVERT +# Used for the Pipedrive integration (via/ Revert (https://revert.dev)) +# @see https://github.com/calcom/cal.com/#obtaining-revert-api-keys +REVERT_API_KEY= +REVERT_PUBLIC_TOKEN= + +# NOTE: If you're self hosting Revert, update this URL to point to your own instance. +REVERT_API_URL=https://api.revert.dev/ # ********************************************************************************************************* diff --git a/README.md b/README.md index aafcd72975..2092be150a 100644 --- a/README.md +++ b/README.md @@ -554,6 +554,10 @@ following [Follow these steps](./packages/app-store/zoho-bigin/) +### Obtaining Pipedrive Client ID and Secret + +[Follow these steps](./packages/app-store/pipedrive-crm/) + ## Workflows ### Setting up SendGrid for Email reminders diff --git a/packages/app-store/apps.keys-schemas.generated.ts b/packages/app-store/apps.keys-schemas.generated.ts index 0d8f1c1f24..541bb55bd3 100644 --- a/packages/app-store/apps.keys-schemas.generated.ts +++ b/packages/app-store/apps.keys-schemas.generated.ts @@ -20,6 +20,7 @@ import { appKeysSchema as metapixel_zod_ts } from "./metapixel/zod"; import { appKeysSchema as office365calendar_zod_ts } from "./office365calendar/zod"; import { appKeysSchema as office365video_zod_ts } from "./office365video/zod"; import { appKeysSchema as paypal_zod_ts } from "./paypal/zod"; +import { appKeysSchema as pipedrive_crm_zod_ts } from "./pipedrive-crm/zod"; import { appKeysSchema as plausible_zod_ts } from "./plausible/zod"; import { appKeysSchema as qr_code_zod_ts } from "./qr_code/zod"; import { appKeysSchema as routing_forms_zod_ts } from "./routing-forms/zod"; @@ -57,6 +58,7 @@ export const appKeysSchemas = { office365calendar: office365calendar_zod_ts, office365video: office365video_zod_ts, paypal: paypal_zod_ts, + "pipedrive-crm": pipedrive_crm_zod_ts, plausible: plausible_zod_ts, qr_code: qr_code_zod_ts, "routing-forms": routing_forms_zod_ts, diff --git a/packages/app-store/apps.metadata.generated.ts b/packages/app-store/apps.metadata.generated.ts index cb252d45f8..e2c9f3e978 100644 --- a/packages/app-store/apps.metadata.generated.ts +++ b/packages/app-store/apps.metadata.generated.ts @@ -42,6 +42,7 @@ import office365video_config_json from "./office365video/config.json"; import paypal_config_json from "./paypal/config.json"; import ping_config_json from "./ping/config.json"; import pipedream_config_json from "./pipedream/config.json"; +import pipedrive_crm_config_json from "./pipedrive-crm/config.json"; import plausible_config_json from "./plausible/config.json"; import qr_code_config_json from "./qr_code/config.json"; import raycast_config_json from "./raycast/config.json"; @@ -120,6 +121,7 @@ export const appStoreMetadata = { paypal: paypal_config_json, ping: ping_config_json, pipedream: pipedream_config_json, + "pipedrive-crm": pipedrive_crm_config_json, plausible: plausible_config_json, qr_code: qr_code_config_json, raycast: raycast_config_json, diff --git a/packages/app-store/apps.schemas.generated.ts b/packages/app-store/apps.schemas.generated.ts index 505f91ed99..3e1e37634e 100644 --- a/packages/app-store/apps.schemas.generated.ts +++ b/packages/app-store/apps.schemas.generated.ts @@ -20,6 +20,7 @@ import { appDataSchema as metapixel_zod_ts } from "./metapixel/zod"; import { appDataSchema as office365calendar_zod_ts } from "./office365calendar/zod"; import { appDataSchema as office365video_zod_ts } from "./office365video/zod"; import { appDataSchema as paypal_zod_ts } from "./paypal/zod"; +import { appDataSchema as pipedrive_crm_zod_ts } from "./pipedrive-crm/zod"; import { appDataSchema as plausible_zod_ts } from "./plausible/zod"; import { appDataSchema as qr_code_zod_ts } from "./qr_code/zod"; import { appDataSchema as routing_forms_zod_ts } from "./routing-forms/zod"; @@ -57,6 +58,7 @@ export const appDataSchemas = { office365calendar: office365calendar_zod_ts, office365video: office365video_zod_ts, paypal: paypal_zod_ts, + "pipedrive-crm": pipedrive_crm_zod_ts, plausible: plausible_zod_ts, qr_code: qr_code_zod_ts, "routing-forms": routing_forms_zod_ts, diff --git a/packages/app-store/apps.server.generated.ts b/packages/app-store/apps.server.generated.ts index aa68d01ec1..55d544efdc 100644 --- a/packages/app-store/apps.server.generated.ts +++ b/packages/app-store/apps.server.generated.ts @@ -42,6 +42,7 @@ export const apiHandlers = { paypal: import("./paypal/api"), ping: import("./ping/api"), pipedream: import("./pipedream/api"), + "pipedrive-crm": import("./pipedrive-crm/api"), plausible: import("./plausible/api"), qr_code: import("./qr_code/api"), raycast: import("./raycast/api"), diff --git a/packages/app-store/index.ts b/packages/app-store/index.ts index 2a90955403..940e644994 100644 --- a/packages/app-store/index.ts +++ b/packages/app-store/index.ts @@ -16,6 +16,7 @@ const appStore = { office365video: () => import("./office365video"), plausible: () => import("./plausible"), paypal: () => import("./paypal"), + "pipedrive-crm": () => import("./pipedrive-crm"), salesforce: () => import("./salesforce"), zohocrm: () => import("./zohocrm"), sendgrid: () => import("./sendgrid"), diff --git a/packages/app-store/pipedrive-crm/DESCRIPTION.md b/packages/app-store/pipedrive-crm/DESCRIPTION.md new file mode 100644 index 0000000000..1ace85dd67 --- /dev/null +++ b/packages/app-store/pipedrive-crm/DESCRIPTION.md @@ -0,0 +1,6 @@ +--- +items: +- pipedrive-banner.jpeg +--- + +{DESCRIPTION} diff --git a/packages/app-store/pipedrive-crm/README.md b/packages/app-store/pipedrive-crm/README.md new file mode 100644 index 0000000000..ac053cab04 --- /dev/null +++ b/packages/app-store/pipedrive-crm/README.md @@ -0,0 +1,19 @@ +## Pipedrive Integration via Revert + +#### Obtaining Pipedrive Client ID and Secret + +* Open [Pipedrive Developers Corner](https://developers.pipedrive.com/) and sign in to your account, or create a new one +* Go to Settings > (company name) Developer Hub +* Create a Pipedrive app, using the steps mentioned [here](https://pipedrive.readme.io/docs/marketplace-creating-a-proper-app#create-an-app-in-5-simple-steps) + * You can skip this step and use the default revert Pipedrive app +* Set `https://app.revert.dev/oauth-callback/pipedrive` as a callback url for your app +* **Get your client\_id and client\_secret**: + * Go to the "OAuth & access scopes" tab of your app + * Copy your client\_id and client\_secret + +#### Obtaining Revert API keys + +* Create an account on Revert if you don't already have one. (https://app.revert.dev/sign-up) +* Login to your revert dashboard (https://app.revert.dev/sign-in) and click on `Customize your apps` - `Pipedrive` +* Enter the `client_id` and `client_secret` you copied in the previous step +* Enter the `client_id` and `client_secret` previously copied to `Settings > Admin > Apps > CRM > Pipedrive` by clicking the `Edit` button on the app settings. diff --git a/packages/app-store/pipedrive-crm/api/add.ts b/packages/app-store/pipedrive-crm/api/add.ts new file mode 100644 index 0000000000..a5e06acf01 --- /dev/null +++ b/packages/app-store/pipedrive-crm/api/add.ts @@ -0,0 +1,35 @@ +import type { NextApiRequest, NextApiResponse } from "next"; + +import { createDefaultInstallation } from "@calcom/app-store/_utils/installation"; +import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; +import { HttpError } from "@calcom/lib/http-error"; + +import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug"; +import appConfig from "../config.json"; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + if (req.method !== "GET") return res.status(405).json({ message: "Method not allowed" }); + const appKeys = await getAppKeysFromSlug(appConfig.slug); + let client_id = ""; + if (typeof appKeys.client_id === "string") client_id = appKeys.client_id; + if (!client_id) return res.status(400).json({ message: "pipedrive client id missing." }); + // Check that user is authenticated + req.session = await getServerSession({ req, res }); + const { teamId } = req.query; + const userId = req.session?.user.id; + if (!userId) { + throw new HttpError({ statusCode: 401, message: "You must be logged in to do this" }); + } + await createDefaultInstallation({ + appType: `${appConfig.slug}_other_calendar`, + userId: userId, + slug: appConfig.slug, + key: {}, + teamId: Number(teamId), + }); + const tenantId = teamId ? teamId : userId; + res.status(200).json({ + url: `https://oauth.pipedrive.com/oauth/authorize?client_id=${appKeys.client_id}&redirect_uri=https://app.revert.dev/oauth-callback/pipedrive&state={%22tenantId%22:%22${tenantId}%22,%22revertPublicToken%22:%22${process.env.REVERT_PUBLIC_TOKEN}%22}`, + newTab: true, + }); +} diff --git a/packages/app-store/pipedrive-crm/api/callback.ts b/packages/app-store/pipedrive-crm/api/callback.ts new file mode 100644 index 0000000000..46e1433328 --- /dev/null +++ b/packages/app-store/pipedrive-crm/api/callback.ts @@ -0,0 +1,19 @@ +import type { NextApiRequest, NextApiResponse } from "next"; + +import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; + +import getInstalledAppPath from "../../_utils/getInstalledAppPath"; +import { decodeOAuthState } from "../../_utils/oauth/decodeOAuthState"; +import appConfig from "../config.json"; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + if (!req.session?.user?.id) { + return res.status(401).json({ message: "You must be logged in to do this" }); + } + + const state = decodeOAuthState(req); + res.redirect( + getSafeRedirectUrl(state?.returnTo) ?? + getInstalledAppPath({ variant: appConfig.variant, slug: appConfig.slug }) + ); +} diff --git a/packages/app-store/pipedrive-crm/api/index.ts b/packages/app-store/pipedrive-crm/api/index.ts new file mode 100644 index 0000000000..eb12c1b4ed --- /dev/null +++ b/packages/app-store/pipedrive-crm/api/index.ts @@ -0,0 +1,2 @@ +export { default as add } from "./add"; +export { default as callback } from "./callback"; diff --git a/packages/app-store/pipedrive-crm/config.json b/packages/app-store/pipedrive-crm/config.json new file mode 100644 index 0000000000..ff390101ba --- /dev/null +++ b/packages/app-store/pipedrive-crm/config.json @@ -0,0 +1,17 @@ +{ + "/*": "Don't modify slug - If required, do it using cli edit command", + "name": "Pipedrive CRM", + "slug": "pipedrive-crm", + "type": "pipedrive-crm_other_calendar", + "logo": "icon.svg", + "url": "https://revert.dev", + "variant": "crm", + "categories": ["crm"], + "publisher": "Revert.dev ", + "email": "jatin@revert.dev", + "description": "Founded in 2010, Pipedrive is an easy and effective sales CRM that drives small business growth.\r\rToday, Pipedrive is used by revenue teams at more than 100,000 companies worldwide. Pipedrive is headquartered in New York and has offices across Europe and the US.\r\rThe company is backed by majority holder Vista Equity Partners, Bessemer Venture Partners, Insight Partners, Atomico, and DTCP.\r\rLearn more at www.pipedrive.com.", + "isTemplate": false, + "__createdUsingCli": true, + "__template": "basic", + "dirName": "pipedrive-crm" +} diff --git a/packages/app-store/pipedrive-crm/index.ts b/packages/app-store/pipedrive-crm/index.ts new file mode 100644 index 0000000000..e2e9d7b029 --- /dev/null +++ b/packages/app-store/pipedrive-crm/index.ts @@ -0,0 +1,2 @@ +export * as api from "./api"; +export * as lib from "./lib"; diff --git a/packages/app-store/pipedrive-crm/lib/CalendarService.ts b/packages/app-store/pipedrive-crm/lib/CalendarService.ts new file mode 100644 index 0000000000..a3c80cd0a7 --- /dev/null +++ b/packages/app-store/pipedrive-crm/lib/CalendarService.ts @@ -0,0 +1,313 @@ +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"; + +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 PipedriveCalendarService implements Calendar { + private log: typeof logger; + private tenantId: string; + private revertApiKey: string; + private revertApiUrl: 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); // 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}`] }); + } + + 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) => { + const result = event.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 bodyRaw = JSON.stringify({ searchCriteria: attendee.email }); + + const requestOptions = { + method: "POST", + headers: headers, + body: bodyRaw, + }; + + try { + const response = await fetch(`${this.revertApiUrl}crm/contacts/search`, requestOptions); + const result = (await response.json()) as ContactSearchResult; + return result; + } catch (error) { + return { status: "error", results: [] }; + } + }); + 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 createPipedriveEvent = async (event: CalendarEvent, contacts: CalendarEvent["attendees"]) => { + const eventPayload = { + subject: event.title, + startDateTime: event.startTime, + endDateTime: event.endTime, + description: this.getMeetingBody(event), + location: getLocation(event), + associations: { + contactId: String(contacts[0].id), + }, + }; + 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: "POST", + headers: headers, + body: eventBody, + }; + + 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.createPipedriveEvent(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 PipedriveCRM"); + } + + async createEvent(event: CalendarEvent): Promise { + let contacts = await this.contactSearch(event); + contacts = contacts.filter((c) => c.results.length >= 1); + if (contacts && contacts.length) { + if (contacts.length === event.attendees.length) { + // all contacts are in Pipedrive CRM already. + this.log.debug("contact:search:all", { event, contacts: contacts }); + const existingPeople = contacts.map((c) => { + return { + id: Number(c.results[0].id), + name: `${c.results[0].firstName} ${c.results[0].lastName}`, + email: c.results[0].email, + timeZone: event.attendees[0].timeZone, + language: event.attendees[0].language, + }; + }); + return await this.handleEventCreation(event, existingPeople); + } else { + // Some attendees don't exist in PipedriveCRM + // Get the existing contacts' email to filter out + this.log.debug("contact:search:notAll", { event, contacts }); + const existingContacts = contacts.map((contact) => contact.results[0].email); + this.log.debug("contact:filter:existing", { existingContacts }); + // Get non existing contacts filtering out existing from attendees + const nonExistingContacts: Person[] = event.attendees.filter( + (attendee) => !existingContacts.includes(attendee.email) + ); + this.log.debug("contact:filter:nonExisting", { nonExistingContacts }); + // Only create contacts in PipedriveCRM 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 Pipedrive + if (createdContacts[0] && createdContacts[0].status === "ok") { + this.log.debug("contact:creation:ok"); + const existingPeople = contacts.map((c) => { + return { + id: Number(c.results[0].id), + name: c.results[0].name, + email: c.results[0].email, + timeZone: nonExistingContacts[0].timeZone, + language: nonExistingContacts[0].language, + }; + }); + const newlyCreatedPeople = createdContacts.map((c) => { + return { + id: Number(c.result.id), + name: c.result.name, + email: c.result.email, + timeZone: nonExistingContacts[0].timeZone, + language: nonExistingContacts[0].language, + }; + }); + const allContacts = existingPeople.concat(newlyCreatedPeople); + // 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); + return indexA - indexB; + }); + return await this.handleEventCreation(event, allContacts); + } + return Promise.reject({ + calError: "Something went wrong when creating non-existing attendees in PipedriveCRM", + }); + } + } else { + this.log.debug("contact:search:none", { event, contacts }); + const createdContacts = await this.createContacts(event.attendees); + this.log.debug("contact:created", { createdContacts }); + if (createdContacts[0] && createdContacts[0].status === "ok") { + this.log.debug("contact:creation:ok"); + const newContacts = createdContacts.map((c) => { + return { + id: Number(c.result.id), + name: c.result.name, + email: c.result.email, + timeZone: event.attendees[0].timeZone, + language: event.attendees[0].language, + }; + }); + return await this.handleEventCreation(event, newContacts); + } + } + return Promise.reject({ + calError: "Something went wrong when searching/creating the attendees in PipedriveCRM", + }); + } + + async updateEvent(uid: string, event: CalendarEvent): Promise { + const meetingEvent = await (await this.updateMeeting(uid, event)).json(); + if (meetingEvent && meetingEvent.status === "ok") { + this.log.debug("event:updation:ok", { meetingEvent }); + return Promise.resolve({ + uid: meetingEvent.result.id, + id: meetingEvent.result.id, + type: appConfig.slug, + password: "", + url: "", + additionalInfo: { meetingEvent }, + }); + } + this.log.debug("meeting:updation:notOk", { meetingEvent, event }); + return Promise.reject("Something went wrong when updating a meeting in PipedriveCRM"); + } + + 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/pipedrive-crm/lib/index.ts b/packages/app-store/pipedrive-crm/lib/index.ts new file mode 100644 index 0000000000..e168c149df --- /dev/null +++ b/packages/app-store/pipedrive-crm/lib/index.ts @@ -0,0 +1 @@ +export { default as CalendarService } from "./CalendarService"; diff --git a/packages/app-store/pipedrive-crm/package.json b/packages/app-store/pipedrive-crm/package.json new file mode 100644 index 0000000000..5d8130acf0 --- /dev/null +++ b/packages/app-store/pipedrive-crm/package.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json.schemastore.org/package.json", + "private": true, + "name": "@calcom/pipedrive-crm", + "version": "0.0.0", + "main": "./index.ts", + "dependencies": { + "@calcom/lib": "*" + }, + "devDependencies": { + "@calcom/types": "*" + }, + "description": "Founded in 2010, Pipedrive is an easy and effective sales CRM that drives small business growth.\r\rToday, Pipedrive is used by revenue teams at more than 100,000 companies worldwide. Pipedrive is headquartered in New York and has offices across Europe and the US.\r\rThe company is backed by majority holder Vista Equity Partners, Bessemer Venture Partners, Insight Partners, Atomico, and DTCP.\r\rLearn more at www.pipedrive.com." +} diff --git a/packages/app-store/pipedrive-crm/static/icon.svg b/packages/app-store/pipedrive-crm/static/icon.svg new file mode 100644 index 0000000000..689c4cd337 --- /dev/null +++ b/packages/app-store/pipedrive-crm/static/icon.svg @@ -0,0 +1,23 @@ + + + + Pipedrive_letter_logo_light@1,5x + + + Created with Sketch. + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/app-store/pipedrive-crm/static/pipedrive-banner.jpeg b/packages/app-store/pipedrive-crm/static/pipedrive-banner.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..0d07a67795d191e5d5be5693dd1a87a9a4b2b8d9 GIT binary patch literal 65706 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.11 <=16" - checksum: 7b622944823fa12a77ea490656121a77e1a1daf08114a6a0b027922113f4481d95f4fe380a5de369a51657ef777d35757dc31f63e41071c21f3e97ca47e4205a + checksum: c5bfdeb6d06f528e2222e71bf830b2f4f3e5b95419453d3b650cef9fe012e0126f121e4858d950edf3db1fb209a056b592643751624d1bc1fc71ecbe546d53d5 languageName: node linkType: hard @@ -22375,9 +22210,9 @@ __metadata: linkType: hard "gsap@npm:^3.11.0": - version: 3.12.2 - resolution: "gsap@npm:3.12.2" - checksum: e3e9709f9ca60cee0ef7fd91f45a232a48b550f95b6df090dfffe2511fccc651408476de575b69c1c2ce80b6089b6ad0d4854beb58ea427f14e51a30b0640a70 + version: 3.12.4 + resolution: "gsap@npm:3.12.4" + checksum: 7b78fb46b3250c09a1856da32109bae16091be41bd3ec3a17ce2b6dea444fbecd2c57b9c677a09c6b4c022d3024e9ae39d377fab5f63302417a88a6b43231381 languageName: node linkType: hard @@ -22949,14 +22784,7 @@ __metadata: languageName: node linkType: hard -"http-cache-semantics@npm:^4.0.0": - version: 4.1.0 - resolution: "http-cache-semantics@npm:4.1.0" - checksum: 974de94a81c5474be07f269f9fd8383e92ebb5a448208223bfb39e172a9dbc26feff250192ecc23b9593b3f92098e010406b0f24bd4d588d631f80214648ed42 - languageName: node - linkType: hard - -"http-cache-semantics@npm:^4.1.0": +"http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.0": version: 4.1.1 resolution: "http-cache-semantics@npm:4.1.1" checksum: 83ac0bc60b17a3a36f9953e7be55e5c8f41acc61b22583060e8dedc9dd5e3607c823a88d0926f9150e571f90946835c7fe150732801010845c72cd8bbff1a236 @@ -23280,9 +23108,9 @@ __metadata: linkType: hard "iframe-resizer@npm:^4.3.0": - version: 4.3.7 - resolution: "iframe-resizer@npm:4.3.7" - checksum: 252f459d0350223f3db6ec01649f79c51088653cf2d8edf932542fe92fab79b2a968403cc685af253ea168097f102dbc5ac8c579ece772e05be83fa39a6026bc + version: 4.3.9 + resolution: "iframe-resizer@npm:4.3.9" + checksum: 8f40a6e9bf27bf60682d9a80f12c60d96a3b724f5e9ef5bdbcf5f2ac58b1b17f6924e34cfc54210a0a065d305380e77d79e28c551f54bd3b1dac1da2624a2144 languageName: node linkType: hard @@ -23303,9 +23131,9 @@ __metadata: linkType: hard "ignore@npm:^5.2.4": - version: 5.2.4 - resolution: "ignore@npm:5.2.4" - checksum: 3d4c309c6006e2621659311783eaea7ebcd41fe4ca1d78c91c473157ad6666a57a2df790fe0d07a12300d9aac2888204d7be8d59f9aaf665b1c7fcdb432517ef + version: 5.3.0 + resolution: "ignore@npm:5.3.0" + checksum: 2736da6621f14ced652785cb05d86301a66d70248597537176612bd0c8630893564bd5f6421f8806b09e8472e75c591ef01672ab8059c07c6eb2c09cefe04bf9 languageName: node linkType: hard @@ -24434,7 +24262,7 @@ __metadata: languageName: node linkType: hard -"isomorphic-ws@npm:5.0.0, isomorphic-ws@npm:^5.0.0": +"isomorphic-ws@npm:^5.0.0": version: 5.0.0 resolution: "isomorphic-ws@npm:5.0.0" peerDependencies: @@ -24689,7 +24517,16 @@ __metadata: languageName: node linkType: hard -"jiti@npm:^1.17.1, jiti@npm:^1.18.2": +"jiti@npm:^1.17.1": + version: 1.21.0 + resolution: "jiti@npm:1.21.0" + bin: + jiti: bin/jiti.js + checksum: a7bd5d63921c170eaec91eecd686388181c7828e1fa0657ab374b9372bfc1f383cf4b039e6b272383d5cb25607509880af814a39abdff967322459cca41f2961 + languageName: node + linkType: hard + +"jiti@npm:^1.18.2": version: 1.20.0 resolution: "jiti@npm:1.20.0" bin: @@ -24698,16 +24535,16 @@ __metadata: languageName: node linkType: hard -"joi@npm:^17.7.0": - version: 17.10.2 - resolution: "joi@npm:17.10.2" +"joi@npm:^17.11.0": + version: 17.11.0 + resolution: "joi@npm:17.11.0" dependencies: "@hapi/hoek": ^9.0.0 "@hapi/topo": ^5.0.0 "@sideway/address": ^4.1.3 "@sideway/formula": ^3.0.1 "@sideway/pinpoint": ^2.0.0 - checksum: 2fac59e83b35465d04ffcd33a937c39795264bdd3d392bebee8034710f84631a400cd320a3bb0bb736e70ce930abb1ea551bc3ffbeca023b53417d864eb216a4 + checksum: 3a4e9ecba345cdafe585e7ed8270a44b39718e11dff3749aa27e0001a63d578b75100c062be28e6f48f960b594864034e7a13833f33fbd7ad56d5ce6b617f9bf languageName: node linkType: hard @@ -24739,6 +24576,13 @@ __metadata: languageName: node linkType: hard +"jose@npm:^5.0.0": + version: 5.1.3 + resolution: "jose@npm:5.1.3" + checksum: c0225c3408b1c3fcfc40c68161e5e14d554c606ffa428250e0db618469df52f4ce32c69918e296c8c299db1081981638096be838426f61d926269d35602fd814 + languageName: node + linkType: hard + "jpeg-js@npm:0.4.2": version: 0.4.2 resolution: "jpeg-js@npm:0.4.2" @@ -24957,7 +24801,7 @@ __metadata: languageName: node linkType: hard -"json-buffer@npm:3.0.1, json-buffer@npm:~3.0.1": +"json-buffer@npm:3.0.1": version: 3.0.1 resolution: "json-buffer@npm:3.0.1" checksum: 9026b03edc2847eefa2e37646c579300a1f3a4586cfb62bf857832b60c852042d0d6ae55d1afb8926163fa54c2b01d83ae24705f34990348bdac6273a29d4581 @@ -25030,11 +24874,14 @@ __metadata: linkType: hard "json-stable-stringify@npm:^1.0.1": - version: 1.0.2 - resolution: "json-stable-stringify@npm:1.0.2" + version: 1.1.0 + resolution: "json-stable-stringify@npm:1.1.0" dependencies: + call-bind: ^1.0.5 + isarray: ^2.0.5 jsonify: ^0.0.1 - checksum: ec10863493fb728481ed7576551382768a173d5b884758db530def00523b862083a3fd70fee24b39e2f47f5f502e22f9a1489dd66da3535b63bf6241dbfca800 + object-keys: ^1.1.1 + checksum: 98e74dd45d3e93aa7cb5351b9f55475e15a8a7b57f401897373a1a1bbe41a6757f8b8d24f2bff0594893eccde616efe71bbaea2c1fdc1f67e8c39bcb9ee993e2 languageName: node linkType: hard @@ -25288,12 +25135,11 @@ __metadata: linkType: hard "keyv@npm:^4.0.0": - version: 4.3.3 - resolution: "keyv@npm:4.3.3" + version: 4.5.4 + resolution: "keyv@npm:4.5.4" dependencies: - compress-brotli: ^1.3.8 json-buffer: 3.0.1 - checksum: bcc946eeec3407fb3b42d831ce985357162113c5f07a8c45c12ede39704ba2d99be4c3dded76d2d2d2a2366627e42440bdde24393216164156928399949c12a1 + checksum: 74a24395b1c34bd44ad5cb2b49140d087553e170625240b86755a6604cd65aa16efdbdeae5cdb17ba1284a0fbb25ad06263755dbc71b8d8b06f74232ce3cdd72 languageName: node linkType: hard @@ -27824,7 +27670,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.1.0, minimist@npm:^1.2.3, minimist@npm:^1.2.7": +"minimist@npm:^1.1.0, minimist@npm:^1.2.3, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 @@ -30483,11 +30329,11 @@ __metadata: linkType: hard "playwright-core@npm:^1.38.1": - version: 1.38.1 - resolution: "playwright-core@npm:1.38.1" + version: 1.40.1 + resolution: "playwright-core@npm:1.40.1" bin: playwright-core: cli.js - checksum: 66e83fe040f309b13ad94ba39dea40ac207bfcbbc22de13141af88dbdedd64e1c4e3ce1d0cb070d4efd8050d7e579953ec3681dd8a0acf2c1cc738d9c50e545e + checksum: 84d92fb9b86e3c225b16b6886bf858eb5059b4e60fa1205ff23336e56a06dcb2eac62650992dede72f406c8e70a7b6a5303e511f9b4bc0b85022ede356a01ee0 languageName: node linkType: hard @@ -31172,9 +31018,9 @@ __metadata: linkType: hard "property-information@npm:^6.0.0": - version: 6.3.0 - resolution: "property-information@npm:6.3.0" - checksum: bf0a15dec097fd4324a42163cabd96b90819e48ef0d8d98756ef0420b2c579bf33646fe0b6e04aa9e79f5a2b5b5860ef11655a79cd8969d8eda58df23c4f96c9 + version: 6.4.0 + resolution: "property-information@npm:6.4.0" + checksum: b5aed9a40e87730995f3ceed29839f137fa73b2a4cccfb8ed72ab8bddb8881cad05c3487c4aa168d7cb49a53db8089790c9f00f59d15b8380d2bb5383cdd1f24 languageName: node linkType: hard @@ -31314,7 +31160,7 @@ __metadata: languageName: node linkType: hard -"pvtsutils@npm:^1.3.2": +"pvtsutils@npm:^1.3.2, pvtsutils@npm:^1.3.5": version: 1.3.5 resolution: "pvtsutils@npm:1.3.5" dependencies: @@ -31818,12 +31664,12 @@ __metadata: linkType: hard "react-fast-marquee@npm:^1.3.5": - version: 1.6.1 - resolution: "react-fast-marquee@npm:1.6.1" + version: 1.6.2 + resolution: "react-fast-marquee@npm:1.6.2" peerDependencies: react: ">= 16.8.0 || 18.0.0" react-dom: ">= 16.8.0 || 18.0.0" - checksum: 35cb639d516ed87d950757ac80ca1ef84b63b64be8400802514225b4566870ead21a6cddcfe1bdd805724a0e173718dde4a9a4162efbabbfee6b6adc490a6eab + checksum: 5bdd2115f042a734c97317f45237450116665db999ed6fc63326c6b9f34dd93a06ea601c7a9a8157960b5da22fcd3516e75fe28ecb296631b24de94f22ad1efc languageName: node linkType: hard @@ -33029,9 +32875,9 @@ __metadata: linkType: hard "remeda@npm:^1.24.1": - version: 1.27.0 - resolution: "remeda@npm:1.27.0" - checksum: 0298aba3ade1d5694bf5a8ca592c735f5ed17325d1f1ee8e4bfc5d80384de47cf6cc42093167f8c512dc4e453896f0ac59685598222328545d7c047c990120a4 + version: 1.33.0 + resolution: "remeda@npm:1.33.0" + checksum: 3d07b191e10b67bb9a008646b98031c12bd20caba25f280a7f491de4c9db7e10150f1243f831669586bb65c3829dfe3319e08c1a5a90414b3fd040c83f2034bf languageName: node linkType: hard @@ -33578,7 +33424,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.0.0, rxjs@npm:^7.8.0": +"rxjs@npm:^7.0.0, rxjs@npm:^7.8.1": version: 7.8.1 resolution: "rxjs@npm:7.8.1" dependencies: @@ -35212,11 +35058,11 @@ __metadata: linkType: hard "superjson@npm:^1.9.1": - version: 1.13.1 - resolution: "superjson@npm:1.13.1" + version: 1.13.3 + resolution: "superjson@npm:1.13.3" dependencies: copy-anything: ^3.0.2 - checksum: 9c8c664a924ce097250112428805ccc8b500018b31a91042e953d955108b8481c156005d836b413940c9fa5f124a3195f55f3a518fe76510a254a59f9151a204 + checksum: f5aeb010f24163cb871a4bc402d9164112201c059afc247a75b03131c274aea6eec9cf08be9e4a9465fe4961689009a011584528531d52f7cc91c077e07e5c75 languageName: node linkType: hard @@ -36344,7 +36190,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2, tslib@npm:^2.4.1, tslib@npm:^2.6.1": +"tslib@npm:^2, tslib@npm:^2.4.1, tslib@npm:^2.6.1, tslib@npm:^2.6.2": version: 2.6.2 resolution: "tslib@npm:2.6.2" checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad @@ -36817,9 +36663,9 @@ __metadata: linkType: hard "ua-parser-js@npm:^1.0.33, ua-parser-js@npm:^1.0.35": - version: 1.0.36 - resolution: "ua-parser-js@npm:1.0.36" - checksum: 5b2c8a5e3443dfbba7624421805de946457c26ae167cb2275781a2729d1518f7067c9d5c74c3b0acac4b9ff3278cae4eace08ca6eecb63848bc3b2f6a63cc975 + version: 1.0.37 + resolution: "ua-parser-js@npm:1.0.37" + checksum: 4d481c720d523366d7762dc8a46a1b58967d979aacf786f9ceceb1cd767de069f64a4bdffb63956294f1c0696eb465ddb950f28ba90571709e33521b4bd75e07 languageName: node linkType: hard @@ -36885,11 +36731,11 @@ __metadata: linkType: hard "undici@npm:^5.12.0": - version: 5.25.2 - resolution: "undici@npm:5.25.2" + version: 5.28.2 + resolution: "undici@npm:5.28.2" dependencies: - busboy: ^1.6.0 - checksum: 1177a9c4fc9a1ddb765508d0f69ae61c166559badce8d797aaa92beef70ec5ac8fdc420b643f5d8d40b9a37891ba5536e2070d86a9c54a128aec67ad0c862d06 + "@fastify/busboy": ^2.0.0 + checksum: f9e9335803f962fff07c3c11c6d50bbc76248bacf97035047155adb29c3622a65bd6bff23a22218189740133149d22e63b68131d8c40e78ac6cb4b6d686a6dfa languageName: node linkType: hard @@ -37871,17 +37717,17 @@ __metadata: linkType: hard "wait-on@npm:^7.0.1": - version: 7.0.1 - resolution: "wait-on@npm:7.0.1" + version: 7.2.0 + resolution: "wait-on@npm:7.2.0" dependencies: - axios: ^0.27.2 - joi: ^17.7.0 + axios: ^1.6.1 + joi: ^17.11.0 lodash: ^4.17.21 - minimist: ^1.2.7 - rxjs: ^7.8.0 + minimist: ^1.2.8 + rxjs: ^7.8.1 bin: wait-on: bin/wait-on - checksum: 1e8a17d8ee6436f71d3ab82781ce31267481fcd7bbccde49b0f8124871e6e40a1acac3401f04f775ba6203853a5813352fa131620fc139914351f3b2894d573f + checksum: 69ec1432bb4479363fdd71f2f3f501a98aa356a562781108a4a89ef8fdf1e3d5fd0c2fd56c4cc5902abbb662065f1f22d4e436a1e6fc9331ce8b575eb023325e languageName: node linkType: hard @@ -38344,21 +38190,6 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.14.1": - version: 8.14.1 - resolution: "ws@npm:8.14.1" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 9e310be2b0ff69e1f87d8c6d093ecd17a1ed4c37f281d17c35e8c30e2bd116401775b3d503249651374e6e0e1e9905db62fff096b694371c77561aee06bc3466 - languageName: node - linkType: hard - "ws@npm:^6.1.0": version: 6.2.2 resolution: "ws@npm:6.2.2" @@ -38398,9 +38229,9 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.12.0": - version: 8.14.2 - resolution: "ws@npm:8.14.2" +"ws@npm:^8.12.0, ws@npm:^8.15.0": + version: 8.15.1 + resolution: "ws@npm:8.15.1" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -38409,7 +38240,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 3ca0dad26e8cc6515ff392b622a1467430814c463b3368b0258e33696b1d4bed7510bc7030f7b72838b9fdeb8dbd8839cbf808367d6aae2e1d668ce741d4308b + checksum: 8c67365f6e6134278ad635d558bfce466d7ef7543a043baea333aaa430429f0af8a130c0c36e7dd78f918d68167a659ba9b5067330b77c4b279e91533395952b languageName: node linkType: hard @@ -38683,9 +38514,9 @@ __metadata: linkType: hard "yaml@npm:^2.3.1": - version: 2.3.2 - resolution: "yaml@npm:2.3.2" - checksum: acd80cc24df12c808c6dec8a0176d404ef9e6f08ad8786f746ecc9d8974968c53c6e8a67fdfabcc5f99f3dc59b6bb0994b95646ff03d18e9b1dcd59eccc02146 + version: 2.3.4 + resolution: "yaml@npm:2.3.4" + checksum: e6d1dae1c6383bcc8ba11796eef3b8c02d5082911c6723efeeb5ba50fc8e881df18d645e64de68e421b577296000bea9c75d6d9097c2f6699da3ae0406c030d8 languageName: node linkType: hard