HubSpot app improvement: create contacts (#3502)
* WIP * Last changes * Create non-existing contacts from attendees * Adding list of features * Removing unneeded code * Missing error when creating contacts Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>pull/3523/head^2
parent
43a6e3f5ce
commit
82d8db5f70
|
@ -261,7 +261,7 @@ export default function Success(props: SuccessProps) {
|
|||
data-testid="success-page">
|
||||
{userIsOwner && !isEmbed && (
|
||||
<div className="mt-2 ml-4 -mb-4">
|
||||
<Link href={eventType.recurringEvent?.count ? "/bookings/recurring" : "/bookings"}>
|
||||
<Link href={eventType.recurringEvent?.count ? "/bookings/recurring" : "/bookings/upcoming"}>
|
||||
<a className="mt-2 inline-flex px-1 py-2 text-sm text-gray-500 hover:bg-gray-100 hover:text-gray-800">
|
||||
<ChevronLeftIcon className="h-5 w-5" /> {t("back_to_bookings")}
|
||||
</a>
|
||||
|
|
|
@ -6,3 +6,7 @@ items:
|
|||
<Slider items={items} />
|
||||
|
||||
HubSpot is a cloud-based CRM designed to help align sales and marketing teams, foster sales enablement, boost ROI and optimize your inbound marketing strategy to generate more, qualified leads.
|
||||
|
||||
Features:
|
||||
- Creates a meeting in HubSpot for one or many attendees
|
||||
- Attendees that don't exist in HubSpot, gets created first to associate them in the meeting
|
||||
|
|
|
@ -15,6 +15,7 @@ import type {
|
|||
EventBusyDate,
|
||||
IntegrationCalendar,
|
||||
NewCalendarEventType,
|
||||
Person,
|
||||
} from "@calcom/types/Calendar";
|
||||
|
||||
import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
|
||||
|
@ -38,6 +39,22 @@ export default class HubspotOtherCalendarService implements Calendar {
|
|||
this.log = logger.getChildLogger({ prefix: [`[[lib] ${this.integrationName}`] });
|
||||
}
|
||||
|
||||
private hubspotContactCreate = async (attendees: Person[]) => {
|
||||
const simplePublicObjectInputs: SimplePublicObjectInput[] = attendees.map((attendee) => {
|
||||
const [firstname, lastname] = attendee.name ? attendee.name.split(" ") : [attendee.email, ""];
|
||||
return {
|
||||
properties: {
|
||||
firstname,
|
||||
lastname,
|
||||
email: attendee.email,
|
||||
},
|
||||
};
|
||||
});
|
||||
return Promise.all(
|
||||
simplePublicObjectInputs.map((contact) => hubspotClient.crm.contacts.basicApi.create(contact))
|
||||
);
|
||||
};
|
||||
|
||||
private hubspotContactSearch = async (event: CalendarEvent) => {
|
||||
const publicObjectSearchRequest: PublicObjectSearchRequest = {
|
||||
filterGroups: event.attendees.map((attendee) => ({
|
||||
|
@ -168,29 +185,56 @@ export default class HubspotOtherCalendarService implements Calendar {
|
|||
};
|
||||
};
|
||||
|
||||
async handleMeetingCreation(event: CalendarEvent, contacts: SimplePublicObjectInput[]) {
|
||||
const meetingEvent = await this.hubspotCreateMeeting(event);
|
||||
if (meetingEvent) {
|
||||
const associatedMeeting = await this.hubspotAssociate(meetingEvent, contacts);
|
||||
if (associatedMeeting) {
|
||||
return Promise.resolve({
|
||||
uid: meetingEvent.id,
|
||||
id: meetingEvent.id,
|
||||
type: "hubspot_other_calendar",
|
||||
password: "",
|
||||
url: "",
|
||||
additionalInfo: { contacts, associatedMeeting },
|
||||
});
|
||||
}
|
||||
return Promise.reject("Something went wrong when associating the meeting and attendees in HubSpot");
|
||||
}
|
||||
return Promise.reject("Something went wrong when creating a meeting in HubSpot");
|
||||
}
|
||||
|
||||
async createEvent(event: CalendarEvent): Promise<NewCalendarEventType> {
|
||||
const auth = await this.auth;
|
||||
await auth.getToken();
|
||||
const contacts = await this.hubspotContactSearch(event);
|
||||
if (contacts) {
|
||||
const meetingEvent = await this.hubspotCreateMeeting(event);
|
||||
if (meetingEvent) {
|
||||
const associatedMeeting = await this.hubspotAssociate(meetingEvent, contacts);
|
||||
if (associatedMeeting) {
|
||||
return Promise.resolve({
|
||||
uid: meetingEvent.id,
|
||||
id: meetingEvent.id,
|
||||
type: "hubspot_other_calendar",
|
||||
password: "",
|
||||
url: "",
|
||||
additionalInfo: { contacts, associatedMeeting },
|
||||
});
|
||||
if (contacts.length) {
|
||||
if (contacts.length == event.attendees.length) {
|
||||
// All attendees do exist in HubSpot
|
||||
return await this.handleMeetingCreation(event, contacts);
|
||||
} else {
|
||||
// Some attendees don't exist in HubSpot
|
||||
// Get the existing contacts' email to filter out
|
||||
const existingContacts = contacts.map((contact) => contact.properties.email);
|
||||
// Get non existing contacts filtering out existing from attendees
|
||||
const nonExistingContacts = event.attendees.filter(
|
||||
(attendee) => !existingContacts.includes(attendee.email)
|
||||
);
|
||||
// Only create contacts in HubSpot that were not present in the previous contact search
|
||||
const createContacts = await this.hubspotContactCreate(nonExistingContacts);
|
||||
// Continue with meeting creation and association only when all contacts are present in HubSpot
|
||||
if (createContacts.length) {
|
||||
return await this.handleMeetingCreation(event, createContacts.concat(contacts));
|
||||
}
|
||||
return Promise.reject("Something went wrong when associating the meeting and attendees in HubSpot");
|
||||
return Promise.reject("Something went wrong when creating non-existing attendees in HubSpot");
|
||||
}
|
||||
} else {
|
||||
const createContacts = await this.hubspotContactCreate(event.attendees);
|
||||
if (createContacts.length) {
|
||||
return await this.handleMeetingCreation(event, createContacts);
|
||||
}
|
||||
return Promise.reject("Something went wrong when creating a meeting in HubSpot");
|
||||
}
|
||||
return Promise.reject("Something went wrong when searching the atendee in HubSpot");
|
||||
return Promise.reject("Something went wrong when searching/creating the attendees in HubSpot");
|
||||
}
|
||||
|
||||
async updateEvent(uid: string, event: CalendarEvent): Promise<any> {
|
||||
|
|
Loading…
Reference in New Issue