1 | |
2 |
|
3 | export type DynSelect_object_type = string |
4 |
|
5 | |
6 | export async function object_type(auth: RT.Hubspot) { |
7 | const standard = [ |
8 | "contacts", |
9 | "companies", |
10 | "deals", |
11 | "tickets", |
12 | "line_items", |
13 | "products", |
14 | "quotes", |
15 | "leads", |
16 | "notes", |
17 | "tasks", |
18 | "meetings", |
19 | "calls", |
20 | "emails", |
21 | "communications", |
22 | ].map((o) => ({ value: o, label: o })) |
23 | const response = await fetch("https://api.hubapi.com/crm/v3/schemas", { |
24 | headers: { |
25 | Authorization: `Bearer ${auth.token}`, |
26 | Accept: "application/json", |
27 | }, |
28 | }) |
29 | |
30 | if (!response.ok) return standard |
31 | const { results } = (await response.json()) as { |
32 | results: { fullyQualifiedName: string; labels: { plural: string } }[] |
33 | } |
34 | return [ |
35 | ...standard, |
36 | ...results.map((s) => ({ |
37 | value: s.fullyQualifiedName, |
38 | label: `${s.labels.plural} (custom)`, |
39 | })), |
40 | ] |
41 | } |
42 |
|
43 | |
44 | * Create Meeting |
45 | * Log a meeting engagement, optionally attached to a contact, company, deal, ticket or other record. Times are ISO 8601. This records the meeting in the CRM; it does not send calendar invites. |
46 | */ |
47 | export async function main( |
48 | auth: RT.Hubspot, |
49 | title: string, |
50 | start_time: string, |
51 | to_object_type: DynSelect_object_type | undefined, |
52 | to_object_id: string | undefined, |
53 | end_time: string | undefined, |
54 | meeting_body: string | undefined, |
55 | location: string | undefined, |
56 | outcome: |
57 | | "SCHEDULED" |
58 | | "COMPLETED" |
59 | | "RESCHEDULED" |
60 | | "NO_SHOW" |
61 | | "CANCELED" |
62 | | undefined, |
63 | owner_id: string | undefined |
64 | ) { |
65 | const properties: { [key: string]: any } = { |
66 | hs_meeting_title: title, |
67 | hs_meeting_body: meeting_body, |
68 | hs_timestamp: start_time, |
69 | hs_meeting_start_time: start_time, |
70 | hs_meeting_end_time: end_time, |
71 | hs_meeting_location: location, |
72 | hs_meeting_outcome: outcome, |
73 | hubspot_owner_id: owner_id, |
74 | } |
75 | for (const key of Object.keys(properties)) { |
76 | if (properties[key] == null || properties[key] === "") |
77 | delete properties[key] |
78 | } |
79 |
|
80 | const response = await fetch( |
81 | "https://api.hubapi.com/crm/v3/objects/meetings", |
82 | { |
83 | method: "POST", |
84 | headers: { |
85 | Authorization: `Bearer ${auth.token}`, |
86 | "Content-Type": "application/json", |
87 | Accept: "application/json", |
88 | }, |
89 | body: JSON.stringify({ properties }), |
90 | } |
91 | ) |
92 |
|
93 | if (!response.ok) { |
94 | throw new Error(`${response.status} ${await response.text()}`) |
95 | } |
96 |
|
97 | const created = await response.json() |
98 | if (!to_object_type || !to_object_id) return created |
99 |
|
100 | const association = await fetch( |
101 | `https://api.hubapi.com/crm/v4/objects/meetings/${created.id}/associations/default/${to_object_type}/${to_object_id}`, |
102 | { |
103 | method: "PUT", |
104 | headers: { |
105 | Authorization: `Bearer ${auth.token}`, |
106 | Accept: "application/json", |
107 | }, |
108 | } |
109 | ) |
110 | if (!association.ok) { |
111 | throw new Error(`${association.status} ${await association.text()}`) |
112 | } |
113 |
|
114 | return { ...created, association: await association.json() } |
115 | } |
116 |
|