@nightsquawktech/gohighlevel-mcp-server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMMERCIAL.md +35 -0
- package/LICENSE +661 -0
- package/README.md +172 -0
- package/dist/constants.d.ts +14 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +14 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/calendars.d.ts +185 -0
- package/dist/schemas/calendars.d.ts.map +1 -0
- package/dist/schemas/calendars.js +74 -0
- package/dist/schemas/calendars.js.map +1 -0
- package/dist/schemas/common.d.ts +10 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +33 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/contacts.d.ts +401 -0
- package/dist/schemas/contacts.d.ts.map +1 -0
- package/dist/schemas/contacts.js +132 -0
- package/dist/schemas/contacts.js.map +1 -0
- package/dist/schemas/conversations.d.ts +89 -0
- package/dist/schemas/conversations.d.ts.map +1 -0
- package/dist/schemas/conversations.js +39 -0
- package/dist/schemas/conversations.js.map +1 -0
- package/dist/schemas/custom-fields.d.ts +360 -0
- package/dist/schemas/custom-fields.d.ts.map +1 -0
- package/dist/schemas/custom-fields.js +154 -0
- package/dist/schemas/custom-fields.js.map +1 -0
- package/dist/schemas/custom-values.d.ts +87 -0
- package/dist/schemas/custom-values.d.ts.map +1 -0
- package/dist/schemas/custom-values.js +43 -0
- package/dist/schemas/custom-values.js.map +1 -0
- package/dist/schemas/locations.d.ts +30 -0
- package/dist/schemas/locations.d.ts.map +1 -0
- package/dist/schemas/locations.js +17 -0
- package/dist/schemas/locations.js.map +1 -0
- package/dist/schemas/opportunities.d.ts +196 -0
- package/dist/schemas/opportunities.d.ts.map +1 -0
- package/dist/schemas/opportunities.js +83 -0
- package/dist/schemas/opportunities.js.map +1 -0
- package/dist/schemas/tags.d.ts +81 -0
- package/dist/schemas/tags.d.ts.map +1 -0
- package/dist/schemas/tags.js +41 -0
- package/dist/schemas/tags.js.map +1 -0
- package/dist/services/config.d.ts +3 -0
- package/dist/services/config.d.ts.map +1 -0
- package/dist/services/config.js +26 -0
- package/dist/services/config.js.map +1 -0
- package/dist/services/errors.d.ts +2 -0
- package/dist/services/errors.d.ts.map +1 -0
- package/dist/services/errors.js +47 -0
- package/dist/services/errors.js.map +1 -0
- package/dist/services/gohighlevel-client.d.ts +13 -0
- package/dist/services/gohighlevel-client.d.ts.map +1 -0
- package/dist/services/gohighlevel-client.js +42 -0
- package/dist/services/gohighlevel-client.js.map +1 -0
- package/dist/tools/calendars.d.ts +4 -0
- package/dist/tools/calendars.d.ts.map +1 -0
- package/dist/tools/calendars.js +163 -0
- package/dist/tools/calendars.js.map +1 -0
- package/dist/tools/contacts.d.ts +4 -0
- package/dist/tools/contacts.d.ts.map +1 -0
- package/dist/tools/contacts.js +492 -0
- package/dist/tools/contacts.js.map +1 -0
- package/dist/tools/conversations.d.ts +4 -0
- package/dist/tools/conversations.d.ts.map +1 -0
- package/dist/tools/conversations.js +76 -0
- package/dist/tools/conversations.js.map +1 -0
- package/dist/tools/custom-fields.d.ts +4 -0
- package/dist/tools/custom-fields.d.ts.map +1 -0
- package/dist/tools/custom-fields.js +337 -0
- package/dist/tools/custom-fields.js.map +1 -0
- package/dist/tools/custom-values.d.ts +4 -0
- package/dist/tools/custom-values.d.ts.map +1 -0
- package/dist/tools/custom-values.js +121 -0
- package/dist/tools/custom-values.js.map +1 -0
- package/dist/tools/format.d.ts +9 -0
- package/dist/tools/format.d.ts.map +1 -0
- package/dist/tools/format.js +49 -0
- package/dist/tools/format.js.map +1 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +19 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/locations.d.ts +4 -0
- package/dist/tools/locations.d.ts.map +1 -0
- package/dist/tools/locations.js +43 -0
- package/dist/tools/locations.js.map +1 -0
- package/dist/tools/opportunities.d.ts +4 -0
- package/dist/tools/opportunities.d.ts.map +1 -0
- package/dist/tools/opportunities.js +182 -0
- package/dist/tools/opportunities.js.map +1 -0
- package/dist/tools/read-tools.d.ts +22 -0
- package/dist/tools/read-tools.d.ts.map +1 -0
- package/dist/tools/read-tools.js +68 -0
- package/dist/tools/read-tools.js.map +1 -0
- package/dist/tools/tags.d.ts +4 -0
- package/dist/tools/tags.d.ts.map +1 -0
- package/dist/tools/tags.js +113 -0
- package/dist/tools/tags.js.map +1 -0
- package/dist/types.d.ts +28 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
import { formatApiError } from "../services/errors.js";
|
|
2
|
+
import { ContactIdSchema, ContactCollectionSchema, ContactTagsSchema, ContactWorkflowSchema, CreateContactNoteSchema, CreateContactSchema, CreateContactTaskSchema, DeleteContactSchema, MergeContactsDeleteLoserSchema, RemoveContactTagsSchema, RemoveContactWorkflowSchema, SearchContactsSchema, UpdateContactSchema, UpsertContactSchema } from "../schemas/contacts.js";
|
|
3
|
+
import { formatResponse, makeToolResponse, mergeExtra, omitUndefined, requireConfirm, summarizeRecord } from "./format.js";
|
|
4
|
+
import { extractItems, registerCollectionReadTool } from "./read-tools.js";
|
|
5
|
+
export function registerContactTools(server, client) {
|
|
6
|
+
registerCollectionReadTool(server, client, {
|
|
7
|
+
name: "ghl_search_contacts",
|
|
8
|
+
title: "Search GoHighLevel Contacts",
|
|
9
|
+
description: "Search contacts with POST /contacts/search. This is the preferred read path over deprecated GET /contacts/.",
|
|
10
|
+
inputSchema: SearchContactsSchema.shape,
|
|
11
|
+
method: "post",
|
|
12
|
+
path: () => "/contacts/search",
|
|
13
|
+
body: (params) => omitUndefined({
|
|
14
|
+
locationId: resolveLocationId(client, params.location_id),
|
|
15
|
+
query: params.query,
|
|
16
|
+
filters: params.filters,
|
|
17
|
+
pageLimit: params.pageLimit,
|
|
18
|
+
startAfterId: params.start_after_id
|
|
19
|
+
}),
|
|
20
|
+
preferredFields: ["id", "contactName", "firstName", "lastName", "email", "phone"],
|
|
21
|
+
heading: "GoHighLevel Contacts",
|
|
22
|
+
collectionLabel: "contacts"
|
|
23
|
+
});
|
|
24
|
+
server.registerTool("ghl_get_contact", {
|
|
25
|
+
title: "Get GoHighLevel Contact",
|
|
26
|
+
description: "Get one GoHighLevel contact from /contacts/{contactId}.",
|
|
27
|
+
inputSchema: ContactIdSchema.shape,
|
|
28
|
+
annotations: {
|
|
29
|
+
readOnlyHint: true,
|
|
30
|
+
destructiveHint: false,
|
|
31
|
+
idempotentHint: true,
|
|
32
|
+
openWorldHint: true
|
|
33
|
+
}
|
|
34
|
+
}, async ({ contact_id, response_format }) => {
|
|
35
|
+
try {
|
|
36
|
+
const contact = await client.get(`/contacts/${encodeURIComponent(contact_id)}`);
|
|
37
|
+
const data = { contact };
|
|
38
|
+
const markdown = ["# GoHighLevel Contact", "", summarizeRecord(contact, ["id", "contactName", "firstName", "lastName", "email", "phone"])].join("\n");
|
|
39
|
+
return makeToolResponse(data, formatResponse(response_format, data, markdown));
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
const data = { error: formatApiError(error) };
|
|
43
|
+
return makeToolResponse(data, data.error, true);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
server.registerTool("ghl_create_contact", {
|
|
47
|
+
title: "Create GoHighLevel Contact",
|
|
48
|
+
description: "Create a contact with POST /contacts/. Write operation: do not run against live data without explicit approval.",
|
|
49
|
+
inputSchema: CreateContactSchema.shape,
|
|
50
|
+
annotations: {
|
|
51
|
+
readOnlyHint: false,
|
|
52
|
+
destructiveHint: false,
|
|
53
|
+
idempotentHint: false,
|
|
54
|
+
openWorldHint: true
|
|
55
|
+
}
|
|
56
|
+
}, async (params) => {
|
|
57
|
+
try {
|
|
58
|
+
const contact = await client.post("/contacts/", contactBody(client, params));
|
|
59
|
+
const data = { contact };
|
|
60
|
+
const markdown = ["# Created GoHighLevel Contact", "", summarizeRecord(contact, ["id", "contactName", "firstName", "lastName", "email", "phone"])].join("\n");
|
|
61
|
+
return makeToolResponse(data, formatResponse(params.response_format, data, markdown));
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
const data = { error: formatApiError(error) };
|
|
65
|
+
return makeToolResponse(data, data.error, true);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
server.registerTool("ghl_update_contact", {
|
|
69
|
+
title: "Update GoHighLevel Contact",
|
|
70
|
+
description: "Update a contact with PUT /contacts/{contactId}. Write operation: do not run against live data without explicit approval.",
|
|
71
|
+
inputSchema: UpdateContactSchema.shape,
|
|
72
|
+
annotations: {
|
|
73
|
+
readOnlyHint: false,
|
|
74
|
+
destructiveHint: false,
|
|
75
|
+
idempotentHint: true,
|
|
76
|
+
openWorldHint: true
|
|
77
|
+
}
|
|
78
|
+
}, async (params) => {
|
|
79
|
+
try {
|
|
80
|
+
const body = contactBody(client, params, false);
|
|
81
|
+
if (Object.keys(body).length === 0) {
|
|
82
|
+
const data = { error: "At least one contact property must be provided for update." };
|
|
83
|
+
return makeToolResponse(data, data.error, true);
|
|
84
|
+
}
|
|
85
|
+
const contact = await client.put(`/contacts/${encodeURIComponent(params.contact_id)}`, body);
|
|
86
|
+
const data = { contact };
|
|
87
|
+
const markdown = ["# Updated GoHighLevel Contact", "", summarizeRecord(contact, ["id", "contactName", "firstName", "lastName", "email", "phone"])].join("\n");
|
|
88
|
+
return makeToolResponse(data, formatResponse(params.response_format, data, markdown));
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
const data = { error: formatApiError(error) };
|
|
92
|
+
return makeToolResponse(data, data.error, true);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
server.registerTool("ghl_upsert_contact", {
|
|
96
|
+
title: "Upsert GoHighLevel Contact",
|
|
97
|
+
description: "Create or update a contact with POST /contacts/upsert. Write operation: do not run against live data without explicit approval.",
|
|
98
|
+
inputSchema: UpsertContactSchema.shape,
|
|
99
|
+
annotations: {
|
|
100
|
+
readOnlyHint: false,
|
|
101
|
+
destructiveHint: false,
|
|
102
|
+
idempotentHint: true,
|
|
103
|
+
openWorldHint: true
|
|
104
|
+
}
|
|
105
|
+
}, async (params) => {
|
|
106
|
+
try {
|
|
107
|
+
const contact = await client.post("/contacts/upsert", contactBody(client, params));
|
|
108
|
+
const data = { contact };
|
|
109
|
+
const markdown = ["# Upserted GoHighLevel Contact", "", summarizeRecord(contact, ["id", "contactName", "firstName", "lastName", "email", "phone"])].join("\n");
|
|
110
|
+
return makeToolResponse(data, formatResponse(params.response_format, data, markdown));
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
const data = { error: formatApiError(error) };
|
|
114
|
+
return makeToolResponse(data, data.error, true);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
server.registerTool("ghl_delete_contact", {
|
|
118
|
+
title: "Delete GoHighLevel Contact",
|
|
119
|
+
description: "Delete one GoHighLevel contact from /contacts/{contactId}. Requires confirm: true and owner approval before live execution.",
|
|
120
|
+
inputSchema: DeleteContactSchema.shape,
|
|
121
|
+
annotations: {
|
|
122
|
+
readOnlyHint: false,
|
|
123
|
+
destructiveHint: true,
|
|
124
|
+
idempotentHint: false,
|
|
125
|
+
openWorldHint: true
|
|
126
|
+
}
|
|
127
|
+
}, async ({ contact_id, confirm, response_format }) => {
|
|
128
|
+
const guard = requireConfirm(confirm);
|
|
129
|
+
if (guard) {
|
|
130
|
+
const data = { error: guard };
|
|
131
|
+
return makeToolResponse(data, data.error, true);
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
const result = await client.del(`/contacts/${encodeURIComponent(contact_id)}`);
|
|
135
|
+
const data = { contact_id, result };
|
|
136
|
+
const markdown = ["# Deleted GoHighLevel Contact", "", `Deleted contact ${contact_id}.`].join("\n");
|
|
137
|
+
return makeToolResponse(data, formatResponse(response_format, data, markdown));
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
const data = { error: formatApiError(error) };
|
|
141
|
+
return makeToolResponse(data, data.error, true);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
server.registerTool("ghl_merge_contacts_delete_loser", {
|
|
145
|
+
title: "Merge GoHighLevel Contacts By Deleting Loser",
|
|
146
|
+
description: "Preview or execute a guarded contact merge workaround: read both contacts, check loser history, delete loser, then update survivor with loser email. Requires confirm: true to execute.",
|
|
147
|
+
inputSchema: MergeContactsDeleteLoserSchema.shape,
|
|
148
|
+
annotations: {
|
|
149
|
+
readOnlyHint: false,
|
|
150
|
+
destructiveHint: true,
|
|
151
|
+
idempotentHint: false,
|
|
152
|
+
openWorldHint: true
|
|
153
|
+
}
|
|
154
|
+
}, async (params) => {
|
|
155
|
+
try {
|
|
156
|
+
if (params.survivor_contact_id === params.loser_contact_id) {
|
|
157
|
+
const data = { error: "survivor_contact_id and loser_contact_id must be different." };
|
|
158
|
+
return makeToolResponse(data, data.error, true);
|
|
159
|
+
}
|
|
160
|
+
const [survivorRaw, loserRaw] = await Promise.all([
|
|
161
|
+
client.get(`/contacts/${encodeURIComponent(params.survivor_contact_id)}`),
|
|
162
|
+
client.get(`/contacts/${encodeURIComponent(params.loser_contact_id)}`)
|
|
163
|
+
]);
|
|
164
|
+
const survivor = unwrapContact(survivorRaw);
|
|
165
|
+
const loser = unwrapContact(loserRaw);
|
|
166
|
+
const loserEmail = stringField(loser, "email");
|
|
167
|
+
const survivorEmail = stringField(survivor, "email");
|
|
168
|
+
const history = await getLoserHistory(client, params.loser_contact_id);
|
|
169
|
+
const hasHistory = history.notes.count > 0
|
|
170
|
+
|| history.tasks.count > 0
|
|
171
|
+
|| history.conversations.count > 0
|
|
172
|
+
|| history.opportunities.count > 0
|
|
173
|
+
|| history.errors.length > 0;
|
|
174
|
+
const plan = {
|
|
175
|
+
survivor_contact_id: params.survivor_contact_id,
|
|
176
|
+
loser_contact_id: params.loser_contact_id,
|
|
177
|
+
operation: "delete_loser_then_update_survivor_email",
|
|
178
|
+
loser_email: loserEmail,
|
|
179
|
+
survivor_current_email: survivorEmail,
|
|
180
|
+
history,
|
|
181
|
+
will_delete_loser: params.confirm === true && !hasHistory,
|
|
182
|
+
will_update_survivor_email: params.confirm === true && !hasHistory && !!loserEmail,
|
|
183
|
+
history_policy: "skip_if_loser_has_notes_tasks_conversations_opportunities_or_check_errors",
|
|
184
|
+
caveat: "This is not GoHighLevel's native UI merge. Deleting the loser does not preserve loser history."
|
|
185
|
+
};
|
|
186
|
+
if (!loserEmail) {
|
|
187
|
+
const data = { error: "Loser contact has no email to copy.", plan };
|
|
188
|
+
return makeToolResponse(data, formatResponse(params.response_format, data, data.error), true);
|
|
189
|
+
}
|
|
190
|
+
if (params.expected_loser_email && params.expected_loser_email.toLowerCase() !== loserEmail.toLowerCase()) {
|
|
191
|
+
const data = { error: "Loser email did not match expected_loser_email.", plan };
|
|
192
|
+
return makeToolResponse(data, formatResponse(params.response_format, data, data.error), true);
|
|
193
|
+
}
|
|
194
|
+
if (params.confirm !== true) {
|
|
195
|
+
const data = { executed: false, reason: "Preview only. Re-run with confirm: true to execute delete-then-update.", plan };
|
|
196
|
+
const markdown = mergeMarkdown(data.executed, data.reason, plan);
|
|
197
|
+
return makeToolResponse(data, formatResponse(params.response_format, data, markdown));
|
|
198
|
+
}
|
|
199
|
+
if (hasHistory) {
|
|
200
|
+
const data = { error: "Loser contact has history or history checks failed; merge skipped without deleting.", plan };
|
|
201
|
+
return makeToolResponse(data, formatResponse(params.response_format, data, data.error), true);
|
|
202
|
+
}
|
|
203
|
+
const deleteResult = await client.del(`/contacts/${encodeURIComponent(params.loser_contact_id)}`);
|
|
204
|
+
let updateResult;
|
|
205
|
+
try {
|
|
206
|
+
updateResult = await client.put(`/contacts/${encodeURIComponent(params.survivor_contact_id)}`, { email: loserEmail });
|
|
207
|
+
}
|
|
208
|
+
catch (updateError) {
|
|
209
|
+
const data = {
|
|
210
|
+
error: formatApiError(updateError),
|
|
211
|
+
executed: true,
|
|
212
|
+
loser_deleted: true,
|
|
213
|
+
survivor_updated: false,
|
|
214
|
+
deleteResult,
|
|
215
|
+
plan
|
|
216
|
+
};
|
|
217
|
+
return makeToolResponse(data, formatResponse(params.response_format, data, data.error), true);
|
|
218
|
+
}
|
|
219
|
+
const data = {
|
|
220
|
+
executed: true,
|
|
221
|
+
loser_deleted: true,
|
|
222
|
+
survivor_updated: true,
|
|
223
|
+
survivor_contact_id: params.survivor_contact_id,
|
|
224
|
+
loser_contact_id: params.loser_contact_id,
|
|
225
|
+
deleteResult,
|
|
226
|
+
updateResult,
|
|
227
|
+
plan
|
|
228
|
+
};
|
|
229
|
+
const markdown = mergeMarkdown(true, "Deleted loser and updated survivor email.", plan);
|
|
230
|
+
return makeToolResponse(data, formatResponse(params.response_format, data, markdown));
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
const data = { error: formatApiError(error) };
|
|
234
|
+
return makeToolResponse(data, data.error, true);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
server.registerTool("ghl_add_contact_tags", {
|
|
238
|
+
title: "Add GoHighLevel Contact Tags",
|
|
239
|
+
description: "Add tags to a contact with POST /contacts/{contactId}/tags. Write operation: do not run against live data without explicit approval.",
|
|
240
|
+
inputSchema: ContactTagsSchema.shape,
|
|
241
|
+
annotations: {
|
|
242
|
+
readOnlyHint: false,
|
|
243
|
+
destructiveHint: false,
|
|
244
|
+
idempotentHint: false,
|
|
245
|
+
openWorldHint: true
|
|
246
|
+
}
|
|
247
|
+
}, async ({ contact_id, tags, response_format }) => {
|
|
248
|
+
try {
|
|
249
|
+
const result = await client.post(`/contacts/${encodeURIComponent(contact_id)}/tags`, { tags });
|
|
250
|
+
const data = { contact_id, tags, result };
|
|
251
|
+
const markdown = ["# Added GoHighLevel Contact Tags", "", `Added ${tags.length} tags to contact ${contact_id}.`].join("\n");
|
|
252
|
+
return makeToolResponse(data, formatResponse(response_format, data, markdown));
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
const data = { error: formatApiError(error) };
|
|
256
|
+
return makeToolResponse(data, data.error, true);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
server.registerTool("ghl_remove_contact_tags", {
|
|
260
|
+
title: "Remove GoHighLevel Contact Tags",
|
|
261
|
+
description: "Remove tags from a contact with DELETE /contacts/{contactId}/tags. Requires confirm: true and owner approval before live execution.",
|
|
262
|
+
inputSchema: RemoveContactTagsSchema.shape,
|
|
263
|
+
annotations: {
|
|
264
|
+
readOnlyHint: false,
|
|
265
|
+
destructiveHint: true,
|
|
266
|
+
idempotentHint: false,
|
|
267
|
+
openWorldHint: true
|
|
268
|
+
}
|
|
269
|
+
}, async ({ contact_id, tags, confirm, response_format }) => {
|
|
270
|
+
const guard = requireConfirm(confirm);
|
|
271
|
+
if (guard) {
|
|
272
|
+
const data = { error: guard };
|
|
273
|
+
return makeToolResponse(data, data.error, true);
|
|
274
|
+
}
|
|
275
|
+
try {
|
|
276
|
+
const result = await client.del(`/contacts/${encodeURIComponent(contact_id)}/tags`, undefined, { tags });
|
|
277
|
+
const data = { contact_id, tags, result };
|
|
278
|
+
const markdown = ["# Removed GoHighLevel Contact Tags", "", `Removed ${tags.length} tags from contact ${contact_id}.`].join("\n");
|
|
279
|
+
return makeToolResponse(data, formatResponse(response_format, data, markdown));
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
const data = { error: formatApiError(error) };
|
|
283
|
+
return makeToolResponse(data, data.error, true);
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
server.registerTool("ghl_add_contact_to_workflow", {
|
|
287
|
+
title: "Add GoHighLevel Contact To Workflow",
|
|
288
|
+
description: "Add a contact to a workflow with POST /contacts/{contactId}/workflow/{workflowId}. Write operation: do not run against live data without explicit approval.",
|
|
289
|
+
inputSchema: ContactWorkflowSchema.shape,
|
|
290
|
+
annotations: {
|
|
291
|
+
readOnlyHint: false,
|
|
292
|
+
destructiveHint: false,
|
|
293
|
+
idempotentHint: false,
|
|
294
|
+
openWorldHint: true
|
|
295
|
+
}
|
|
296
|
+
}, async ({ contact_id, workflow_id, response_format }) => {
|
|
297
|
+
try {
|
|
298
|
+
const result = await client.post(`/contacts/${encodeURIComponent(contact_id)}/workflow/${encodeURIComponent(workflow_id)}`, {});
|
|
299
|
+
const data = { contact_id, workflow_id, result };
|
|
300
|
+
const markdown = ["# Added GoHighLevel Contact To Workflow", "", `Added contact ${contact_id} to workflow ${workflow_id}.`].join("\n");
|
|
301
|
+
return makeToolResponse(data, formatResponse(response_format, data, markdown));
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
const data = { error: formatApiError(error) };
|
|
305
|
+
return makeToolResponse(data, data.error, true);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
server.registerTool("ghl_remove_contact_from_workflow", {
|
|
309
|
+
title: "Remove GoHighLevel Contact From Workflow",
|
|
310
|
+
description: "Remove a contact from a workflow with DELETE /contacts/{contactId}/workflow/{workflowId}. Requires confirm: true and owner approval before live execution.",
|
|
311
|
+
inputSchema: RemoveContactWorkflowSchema.shape,
|
|
312
|
+
annotations: {
|
|
313
|
+
readOnlyHint: false,
|
|
314
|
+
destructiveHint: true,
|
|
315
|
+
idempotentHint: false,
|
|
316
|
+
openWorldHint: true
|
|
317
|
+
}
|
|
318
|
+
}, async ({ contact_id, workflow_id, confirm, response_format }) => {
|
|
319
|
+
const guard = requireConfirm(confirm);
|
|
320
|
+
if (guard) {
|
|
321
|
+
const data = { error: guard };
|
|
322
|
+
return makeToolResponse(data, data.error, true);
|
|
323
|
+
}
|
|
324
|
+
try {
|
|
325
|
+
const result = await client.del(`/contacts/${encodeURIComponent(contact_id)}/workflow/${encodeURIComponent(workflow_id)}`);
|
|
326
|
+
const data = { contact_id, workflow_id, result };
|
|
327
|
+
const markdown = ["# Removed GoHighLevel Contact From Workflow", "", `Removed contact ${contact_id} from workflow ${workflow_id}.`].join("\n");
|
|
328
|
+
return makeToolResponse(data, formatResponse(response_format, data, markdown));
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
const data = { error: formatApiError(error) };
|
|
332
|
+
return makeToolResponse(data, data.error, true);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
registerCollectionReadTool(server, client, {
|
|
336
|
+
name: "ghl_get_contact_notes",
|
|
337
|
+
title: "Get GoHighLevel Contact Notes",
|
|
338
|
+
description: "List notes for a contact from /contacts/{contactId}/notes.",
|
|
339
|
+
inputSchema: ContactCollectionSchema.shape,
|
|
340
|
+
path: (params) => `/contacts/${encodeURIComponent(String(params.contact_id))}/notes`,
|
|
341
|
+
preferredFields: ["id", "body", "userId", "dateAdded"],
|
|
342
|
+
heading: "GoHighLevel Contact Notes",
|
|
343
|
+
collectionLabel: "notes"
|
|
344
|
+
});
|
|
345
|
+
server.registerTool("ghl_create_contact_note", {
|
|
346
|
+
title: "Create GoHighLevel Contact Note",
|
|
347
|
+
description: "Create a note for a contact with POST /contacts/{contactId}/notes. Write operation: do not run against live data without explicit approval.",
|
|
348
|
+
inputSchema: CreateContactNoteSchema.shape,
|
|
349
|
+
annotations: {
|
|
350
|
+
readOnlyHint: false,
|
|
351
|
+
destructiveHint: false,
|
|
352
|
+
idempotentHint: false,
|
|
353
|
+
openWorldHint: true
|
|
354
|
+
}
|
|
355
|
+
}, async ({ contact_id, body, userId, extra, response_format }) => {
|
|
356
|
+
try {
|
|
357
|
+
const note = await client.post(`/contacts/${encodeURIComponent(contact_id)}/notes`, mergeExtra({ body, userId }, extra));
|
|
358
|
+
const data = { note };
|
|
359
|
+
const markdown = ["# Created GoHighLevel Contact Note", "", summarizeRecord(note, ["id", "body", "userId", "dateAdded"])].join("\n");
|
|
360
|
+
return makeToolResponse(data, formatResponse(response_format, data, markdown));
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
const data = { error: formatApiError(error) };
|
|
364
|
+
return makeToolResponse(data, data.error, true);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
registerCollectionReadTool(server, client, {
|
|
368
|
+
name: "ghl_get_contact_tasks",
|
|
369
|
+
title: "Get GoHighLevel Contact Tasks",
|
|
370
|
+
description: "List tasks for a contact from /contacts/{contactId}/tasks.",
|
|
371
|
+
inputSchema: ContactCollectionSchema.shape,
|
|
372
|
+
path: (params) => `/contacts/${encodeURIComponent(String(params.contact_id))}/tasks`,
|
|
373
|
+
preferredFields: ["id", "title", "body", "dueDate", "assignedTo", "completed"],
|
|
374
|
+
heading: "GoHighLevel Contact Tasks",
|
|
375
|
+
collectionLabel: "tasks"
|
|
376
|
+
});
|
|
377
|
+
server.registerTool("ghl_create_contact_task", {
|
|
378
|
+
title: "Create GoHighLevel Contact Task",
|
|
379
|
+
description: "Create a task for a contact with POST /contacts/{contactId}/tasks. Write operation: do not run against live data without explicit approval.",
|
|
380
|
+
inputSchema: CreateContactTaskSchema.shape,
|
|
381
|
+
annotations: {
|
|
382
|
+
readOnlyHint: false,
|
|
383
|
+
destructiveHint: false,
|
|
384
|
+
idempotentHint: false,
|
|
385
|
+
openWorldHint: true
|
|
386
|
+
}
|
|
387
|
+
}, async ({ contact_id, title, body, dueDate, assignedTo, completed, extra, response_format }) => {
|
|
388
|
+
try {
|
|
389
|
+
const task = await client.post(`/contacts/${encodeURIComponent(contact_id)}/tasks`, mergeExtra({ title, body, dueDate, assignedTo, completed }, extra));
|
|
390
|
+
const data = { task };
|
|
391
|
+
const markdown = ["# Created GoHighLevel Contact Task", "", summarizeRecord(task, ["id", "title", "body", "dueDate", "assignedTo", "completed"])].join("\n");
|
|
392
|
+
return makeToolResponse(data, formatResponse(response_format, data, markdown));
|
|
393
|
+
}
|
|
394
|
+
catch (error) {
|
|
395
|
+
const data = { error: formatApiError(error) };
|
|
396
|
+
return makeToolResponse(data, data.error, true);
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
function resolveLocationId(client, locationId) {
|
|
401
|
+
return typeof locationId === "string" && locationId.length > 0 ? locationId : client.defaultLocationId;
|
|
402
|
+
}
|
|
403
|
+
function contactBody(client, params, includeLocationId = true) {
|
|
404
|
+
return mergeExtra({
|
|
405
|
+
...(includeLocationId ? { locationId: resolveLocationId(client, "location_id" in params ? params.location_id : undefined) } : {}),
|
|
406
|
+
firstName: params.firstName,
|
|
407
|
+
lastName: params.lastName,
|
|
408
|
+
name: params.name,
|
|
409
|
+
email: params.email,
|
|
410
|
+
phone: params.phone,
|
|
411
|
+
address1: params.address1,
|
|
412
|
+
city: params.city,
|
|
413
|
+
state: params.state,
|
|
414
|
+
country: params.country,
|
|
415
|
+
postalCode: params.postalCode,
|
|
416
|
+
companyName: params.companyName,
|
|
417
|
+
website: params.website,
|
|
418
|
+
source: params.source,
|
|
419
|
+
assignedTo: params.assignedTo,
|
|
420
|
+
dnd: params.dnd,
|
|
421
|
+
tags: params.tags,
|
|
422
|
+
customFields: params.customFields
|
|
423
|
+
}, params.extra);
|
|
424
|
+
}
|
|
425
|
+
function unwrapContact(raw) {
|
|
426
|
+
if (raw && typeof raw === "object") {
|
|
427
|
+
const source = raw;
|
|
428
|
+
if (source.contact && typeof source.contact === "object") {
|
|
429
|
+
return source.contact;
|
|
430
|
+
}
|
|
431
|
+
return source;
|
|
432
|
+
}
|
|
433
|
+
return {};
|
|
434
|
+
}
|
|
435
|
+
function stringField(source, key) {
|
|
436
|
+
const value = source[key];
|
|
437
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
438
|
+
}
|
|
439
|
+
async function getLoserHistory(client, loserContactId) {
|
|
440
|
+
const history = {
|
|
441
|
+
notes: { count: 0, checked: false },
|
|
442
|
+
tasks: { count: 0, checked: false },
|
|
443
|
+
conversations: { count: 0, checked: false },
|
|
444
|
+
opportunities: { count: 0, checked: false },
|
|
445
|
+
errors: []
|
|
446
|
+
};
|
|
447
|
+
await setHistoryCount(history, "notes", async () => client.get(`/contacts/${encodeURIComponent(loserContactId)}/notes`));
|
|
448
|
+
await setHistoryCount(history, "tasks", async () => client.get(`/contacts/${encodeURIComponent(loserContactId)}/tasks`));
|
|
449
|
+
await setHistoryCount(history, "conversations", async () => client.get("/conversations/search", {
|
|
450
|
+
locationId: client.defaultLocationId,
|
|
451
|
+
contactId: loserContactId,
|
|
452
|
+
limit: 1
|
|
453
|
+
}));
|
|
454
|
+
await setHistoryCount(history, "opportunities", async () => client.get("/opportunities/search", {
|
|
455
|
+
location_id: client.defaultLocationId,
|
|
456
|
+
contact_id: loserContactId,
|
|
457
|
+
limit: 1
|
|
458
|
+
}));
|
|
459
|
+
return history;
|
|
460
|
+
}
|
|
461
|
+
async function setHistoryCount(history, key, read) {
|
|
462
|
+
try {
|
|
463
|
+
const raw = await read();
|
|
464
|
+
history[key] = {
|
|
465
|
+
count: extractItems(raw).length,
|
|
466
|
+
checked: true
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
catch (error) {
|
|
470
|
+
history.errors.push(`${key}: ${formatApiError(error)}`);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
function mergeMarkdown(executed, reason, plan) {
|
|
474
|
+
const history = plan.history;
|
|
475
|
+
return [
|
|
476
|
+
"# GoHighLevel Contact Merge Workaround",
|
|
477
|
+
"",
|
|
478
|
+
`- Executed: ${executed}`,
|
|
479
|
+
`- Result: ${reason}`,
|
|
480
|
+
`- Survivor: ${String(plan.survivor_contact_id)}`,
|
|
481
|
+
`- Loser: ${String(plan.loser_contact_id)}`,
|
|
482
|
+
`- Loser email to copy: ${String(plan.loser_email ?? "")}`,
|
|
483
|
+
`- Loser notes: ${history.notes.count}`,
|
|
484
|
+
`- Loser tasks: ${history.tasks.count}`,
|
|
485
|
+
`- Loser conversations: ${history.conversations.count}`,
|
|
486
|
+
`- Loser opportunities: ${history.opportunities.count}`,
|
|
487
|
+
`- History check errors: ${history.errors.length}`,
|
|
488
|
+
"",
|
|
489
|
+
"Caveat: this is delete-the-loser then update-the-survivor, not native GoHighLevel UI merge."
|
|
490
|
+
].join("\n");
|
|
491
|
+
}
|
|
492
|
+
//# sourceMappingURL=contacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contacts.js","sourceRoot":"","sources":["../../src/tools/contacts.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,8BAA8B,EAC9B,uBAAuB,EACvB,2BAA2B,EAC3B,oBAAoB,EAepB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3H,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAE3E,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,MAAyB;IAC/E,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE;QACzC,IAAI,EAAE,qBAAqB;QAC3B,KAAK,EAAE,6BAA6B;QACpC,WAAW,EAAE,6GAA6G;QAC1H,WAAW,EAAE,oBAAoB,CAAC,KAAK;QACvC,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,GAAG,EAAE,CAAC,kBAAkB;QAC9B,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC;YAC9B,UAAU,EAAE,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC;YACzD,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,YAAY,EAAE,MAAM,CAAC,cAAc;SACpC,CAAC;QACF,eAAe,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC;QACjF,OAAO,EAAE,sBAAsB;QAC/B,eAAe,EAAE,UAAU;KAC5B,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE,yDAAyD;QACtE,WAAW,EAAE,eAAe,CAAC,KAAK;QAClC,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,eAAe,EAAkB,EAAE,EAAE;QACxD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,GAAG,CAAU,aAAa,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YACzF,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,CAAC,uBAAuB,EAAE,EAAE,EAAE,eAAe,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtJ,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,4BAA4B;QACnC,WAAW,EAAE,iHAAiH;QAC9H,WAAW,EAAE,mBAAmB,CAAC,KAAK;QACtC,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,MAA0B,EAAE,EAAE;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAU,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;YACtF,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,CAAC,+BAA+B,EAAE,EAAE,EAAE,eAAe,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9J,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACxF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,4BAA4B;QACnC,WAAW,EAAE,2HAA2H;QACxI,WAAW,EAAE,mBAAmB,CAAC,KAAK;QACtC,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,MAA0B,EAAE,EAAE;QACnC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YAChD,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACnC,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,4DAA4D,EAAE,CAAC;gBACrF,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAClD,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,GAAG,CAAU,aAAa,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACtG,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,CAAC,+BAA+B,EAAE,EAAE,EAAE,eAAe,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9J,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACxF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,4BAA4B;QACnC,WAAW,EAAE,iIAAiI;QAC9I,WAAW,EAAE,mBAAmB,CAAC,KAAK;QACtC,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,MAA0B,EAAE,EAAE;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAU,kBAAkB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;YAC5F,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,CAAC,gCAAgC,EAAE,EAAE,EAAE,eAAe,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/J,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACxF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,4BAA4B;QACnC,WAAW,EAAE,6HAA6H;QAC1I,WAAW,EAAE,mBAAmB,CAAC,KAAK;QACtC,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAsB,EAAE,EAAE;QACrE,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YAC9B,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAU,aAAa,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YACxF,MAAM,IAAI,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,CAAC,+BAA+B,EAAE,EAAE,EAAE,mBAAmB,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpG,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,iCAAiC,EACjC;QACE,KAAK,EAAE,8CAA8C;QACrD,WAAW,EAAE,yLAAyL;QACtM,WAAW,EAAE,8BAA8B,CAAC,KAAK;QACjD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,MAAqC,EAAE,EAAE;QAC9C,IAAI,CAAC;YACH,IAAI,MAAM,CAAC,mBAAmB,KAAK,MAAM,CAAC,gBAAgB,EAAE,CAAC;gBAC3D,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,6DAA6D,EAAE,CAAC;gBACtF,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAClD,CAAC;YAED,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAChD,MAAM,CAAC,GAAG,CAAU,aAAa,kBAAkB,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBAClF,MAAM,CAAC,GAAG,CAAU,aAAa,kBAAkB,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC;aAChF,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;YAC5C,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;YACtC,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAC/C,MAAM,aAAa,GAAG,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACvE,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC;mBACrC,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC;mBACvB,OAAO,CAAC,aAAa,CAAC,KAAK,GAAG,CAAC;mBAC/B,OAAO,CAAC,aAAa,CAAC,KAAK,GAAG,CAAC;mBAC/B,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YAE/B,MAAM,IAAI,GAAG;gBACX,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;gBAC/C,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;gBACzC,SAAS,EAAE,yCAAyC;gBACpD,WAAW,EAAE,UAAU;gBACvB,sBAAsB,EAAE,aAAa;gBACrC,OAAO;gBACP,iBAAiB,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,UAAU;gBACzD,0BAA0B,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU;gBAClF,cAAc,EAAE,2EAA2E;gBAC3F,MAAM,EAAE,gGAAgG;aACzG,CAAC;YAEF,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,qCAAqC,EAAE,IAAI,EAAE,CAAC;gBACpE,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;YAChG,CAAC;YAED,IAAI,MAAM,CAAC,oBAAoB,IAAI,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC1G,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,iDAAiD,EAAE,IAAI,EAAE,CAAC;gBAChF,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;YAChG,CAAC;YAED,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBAC5B,MAAM,IAAI,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,wEAAwE,EAAE,IAAI,EAAE,CAAC;gBACzH,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACjE,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;YACxF,CAAC;YAED,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,qFAAqF,EAAE,IAAI,EAAE,CAAC;gBACpH,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;YAChG,CAAC;YAED,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,GAAG,CAAU,aAAa,kBAAkB,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YAC3G,IAAI,YAAqB,CAAC;YAC1B,IAAI,CAAC;gBACH,YAAY,GAAG,MAAM,MAAM,CAAC,GAAG,CAAU,aAAa,kBAAkB,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;YACjI,CAAC;YAAC,OAAO,WAAW,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG;oBACX,KAAK,EAAE,cAAc,CAAC,WAAW,CAAC;oBAClC,QAAQ,EAAE,IAAI;oBACd,aAAa,EAAE,IAAI;oBACnB,gBAAgB,EAAE,KAAK;oBACvB,YAAY;oBACZ,IAAI;iBACL,CAAC;gBACF,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;YAChG,CAAC;YAED,MAAM,IAAI,GAAG;gBACX,QAAQ,EAAE,IAAI;gBACd,aAAa,EAAE,IAAI;gBACnB,gBAAgB,EAAE,IAAI;gBACtB,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;gBAC/C,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;gBACzC,YAAY;gBACZ,YAAY;gBACZ,IAAI;aACL,CAAC;YACF,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,EAAE,2CAA2C,EAAE,IAAI,CAAC,CAAC;YACxF,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACxF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,8BAA8B;QACrC,WAAW,EAAE,sIAAsI;QACnJ,WAAW,EAAE,iBAAiB,CAAC,KAAK;QACpC,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAoB,EAAE,EAAE;QAChE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAU,aAAa,kBAAkB,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YACxG,MAAM,IAAI,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,CAAC,kCAAkC,EAAE,EAAE,EAAE,SAAS,IAAI,CAAC,MAAM,oBAAoB,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5H,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,KAAK,EAAE,iCAAiC;QACxC,WAAW,EAAE,qIAAqI;QAClJ,WAAW,EAAE,uBAAuB,CAAC,KAAK;QAC1C,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAA0B,EAAE,EAAE;QAC/E,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YAC9B,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAU,aAAa,kBAAkB,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAClH,MAAM,IAAI,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,CAAC,oCAAoC,EAAE,EAAE,EAAE,WAAW,IAAI,CAAC,MAAM,sBAAsB,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClI,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,6BAA6B,EAC7B;QACE,KAAK,EAAE,qCAAqC;QAC5C,WAAW,EAAE,6JAA6J;QAC1K,WAAW,EAAE,qBAAqB,CAAC,KAAK;QACxC,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAwB,EAAE,EAAE;QAC3E,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAU,aAAa,kBAAkB,CAAC,UAAU,CAAC,aAAa,kBAAkB,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACzI,MAAM,IAAI,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;YACjD,MAAM,QAAQ,GAAG,CAAC,yCAAyC,EAAE,EAAE,EAAE,iBAAiB,UAAU,gBAAgB,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvI,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,kCAAkC,EAClC;QACE,KAAK,EAAE,0CAA0C;QACjD,WAAW,EAAE,4JAA4J;QACzK,WAAW,EAAE,2BAA2B,CAAC,KAAK;QAC9C,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,EAA8B,EAAE,EAAE;QAC1F,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YAC9B,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAU,aAAa,kBAAkB,CAAC,UAAU,CAAC,aAAa,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YACpI,MAAM,IAAI,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;YACjD,MAAM,QAAQ,GAAG,CAAC,6CAA6C,EAAE,EAAE,EAAE,mBAAmB,UAAU,kBAAkB,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/I,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE;QACzC,IAAI,EAAE,uBAAuB;QAC7B,KAAK,EAAE,+BAA+B;QACtC,WAAW,EAAE,4DAA4D;QACzE,WAAW,EAAE,uBAAuB,CAAC,KAAK;QAC1C,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ;QACpF,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC;QACtD,OAAO,EAAE,2BAA2B;QACpC,eAAe,EAAE,OAAO;KACzB,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,KAAK,EAAE,iCAAiC;QACxC,WAAW,EAAE,6IAA6I;QAC1J,WAAW,EAAE,uBAAuB,CAAC,KAAK;QAC1C,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAA0B,EAAE,EAAE;QACrF,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAU,aAAa,kBAAkB,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;YAClI,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,CAAC,oCAAoC,EAAE,EAAE,EAAE,eAAe,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrI,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE;QACzC,IAAI,EAAE,uBAAuB;QAC7B,KAAK,EAAE,+BAA+B;QACtC,WAAW,EAAE,4DAA4D;QACzE,WAAW,EAAE,uBAAuB,CAAC,KAAK;QAC1C,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ;QACpF,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,CAAC;QAC9E,OAAO,EAAE,2BAA2B;QACpC,eAAe,EAAE,OAAO;KACzB,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,KAAK,EAAE,iCAAiC;QACxC,WAAW,EAAE,6IAA6I;QAC1J,WAAW,EAAE,uBAAuB,CAAC,KAAK;QAC1C,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAA0B,EAAE,EAAE;QACpH,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAU,aAAa,kBAAkB,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;YACjK,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,CAAC,oCAAoC,EAAE,EAAE,EAAE,eAAe,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7J,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAyB,EAAE,UAAmB;IACvE,OAAO,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;AACzG,CAAC;AAED,SAAS,WAAW,CAClB,MAAyB,EACzB,MAAoE,EACpE,iBAAiB,GAAG,IAAI;IAExB,OAAO,UAAU,CAAC;QAChB,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,iBAAiB,CAAC,MAAM,EAAE,aAAa,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjI,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,YAAY,EAAE,MAAM,CAAC,YAAY;KAClC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,aAAa,CAAC,GAAY;IACjC,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,GAA8B,CAAC;QAC9C,IAAI,MAAM,CAAC,OAAO,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACzD,OAAO,MAAM,CAAC,OAAkC,CAAC;QACnD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,WAAW,CAAC,MAA+B,EAAE,GAAW;IAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACzF,CAAC;AAeD,KAAK,UAAU,eAAe,CAAC,MAAyB,EAAE,cAAsB;IAC9E,MAAM,OAAO,GAAiB;QAC5B,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE;QACnC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE;QACnC,aAAa,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE;QAC3C,aAAa,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE;QAC3C,MAAM,EAAE,EAAE;KACX,CAAC;IAEF,MAAM,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAU,aAAa,kBAAkB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClI,MAAM,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAU,aAAa,kBAAkB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClI,MAAM,eAAe,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAU,uBAAuB,EAAE;QACvG,UAAU,EAAE,MAAM,CAAC,iBAAiB;QACpC,SAAS,EAAE,cAAc;QACzB,KAAK,EAAE,CAAC;KACT,CAAC,CAAC,CAAC;IACJ,MAAM,eAAe,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAU,uBAAuB,EAAE;QACvG,WAAW,EAAE,MAAM,CAAC,iBAAiB;QACrC,UAAU,EAAE,cAAc;QAC1B,KAAK,EAAE,CAAC;KACT,CAAC,CAAC,CAAC;IAEJ,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,OAAqB,EACrB,GAAuC,EACvC,IAA4B;IAE5B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,IAAI,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,GAAG;YACb,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM;YAC/B,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,QAAiB,EAAE,MAAc,EAAE,IAA6B;IACrF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAuB,CAAC;IAC7C,OAAO;QACL,wCAAwC;QACxC,EAAE;QACF,eAAe,QAAQ,EAAE;QACzB,aAAa,MAAM,EAAE;QACrB,eAAe,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE;QACjD,YAAY,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE;QAC3C,0BAA0B,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE;QAC1D,kBAAkB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE;QACvC,kBAAkB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE;QACvC,0BAA0B,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE;QACvD,0BAA0B,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE;QACvD,2BAA2B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE;QAClD,EAAE;QACF,6FAA6F;KAC9F,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { GoHighLevelClient } from "../services/gohighlevel-client.js";
|
|
3
|
+
export declare function registerConversationTools(server: McpServer, client: GoHighLevelClient): void;
|
|
4
|
+
//# sourceMappingURL=conversations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../../src/tools/conversations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAW3E,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAyE5F"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { formatApiError } from "../services/errors.js";
|
|
2
|
+
import { ConversationMessagesSchema, SearchConversationsSchema, SendMessageSchema } from "../schemas/conversations.js";
|
|
3
|
+
import { formatResponse, makeToolResponse, mergeExtra, omitUndefined, requireConfirm, summarizeRecord } from "./format.js";
|
|
4
|
+
import { registerCollectionReadTool } from "./read-tools.js";
|
|
5
|
+
export function registerConversationTools(server, client) {
|
|
6
|
+
registerCollectionReadTool(server, client, {
|
|
7
|
+
name: "ghl_search_conversations",
|
|
8
|
+
title: "Search GoHighLevel Conversations",
|
|
9
|
+
description: "Search conversations with GET /conversations/search.",
|
|
10
|
+
inputSchema: SearchConversationsSchema.shape,
|
|
11
|
+
path: () => "/conversations/search",
|
|
12
|
+
query: (params) => ({
|
|
13
|
+
...omitUndefined({
|
|
14
|
+
locationId: resolveLocationId(client, params.location_id),
|
|
15
|
+
contactId: params.contactId,
|
|
16
|
+
assignedTo: params.assignedTo,
|
|
17
|
+
lastMessageType: params.lastMessageType
|
|
18
|
+
}),
|
|
19
|
+
...(params.extra_query ?? {})
|
|
20
|
+
}),
|
|
21
|
+
preferredFields: ["id", "contactId", "fullName", "lastMessageBody", "lastMessageType", "unreadCount"],
|
|
22
|
+
heading: "GoHighLevel Conversations",
|
|
23
|
+
collectionLabel: "conversations"
|
|
24
|
+
});
|
|
25
|
+
registerCollectionReadTool(server, client, {
|
|
26
|
+
name: "ghl_get_conversation_messages",
|
|
27
|
+
title: "Get GoHighLevel Conversation Messages",
|
|
28
|
+
description: "List messages for a conversation with GET /conversations/{conversationId}/messages.",
|
|
29
|
+
inputSchema: ConversationMessagesSchema.shape,
|
|
30
|
+
path: (params) => `/conversations/${encodeURIComponent(String(params.conversation_id))}/messages`,
|
|
31
|
+
query: (params) => params.extra_query ?? undefined,
|
|
32
|
+
preferredFields: ["id", "messageId", "type", "direction", "body", "message", "dateAdded"],
|
|
33
|
+
heading: "GoHighLevel Conversation Messages",
|
|
34
|
+
collectionLabel: "messages"
|
|
35
|
+
});
|
|
36
|
+
server.registerTool("ghl_send_message", {
|
|
37
|
+
title: "Send GoHighLevel Message",
|
|
38
|
+
description: "Send an outward-facing message with POST /conversations/messages. Requires confirm: true and owner approval before live execution.",
|
|
39
|
+
inputSchema: SendMessageSchema.shape,
|
|
40
|
+
annotations: {
|
|
41
|
+
readOnlyHint: false,
|
|
42
|
+
destructiveHint: true,
|
|
43
|
+
idempotentHint: false,
|
|
44
|
+
openWorldHint: true
|
|
45
|
+
}
|
|
46
|
+
}, async (params) => {
|
|
47
|
+
const guard = requireConfirm(params.confirm);
|
|
48
|
+
if (guard) {
|
|
49
|
+
const data = { error: guard };
|
|
50
|
+
return makeToolResponse(data, data.error, true);
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const result = await client.post("/conversations/messages", mergeExtra({
|
|
54
|
+
type: params.type,
|
|
55
|
+
contactId: params.contactId,
|
|
56
|
+
conversationId: params.conversationId,
|
|
57
|
+
message: params.message,
|
|
58
|
+
attachments: params.attachments,
|
|
59
|
+
subject: params.subject,
|
|
60
|
+
fromEmail: params.fromEmail,
|
|
61
|
+
toEmail: params.toEmail
|
|
62
|
+
}, params.extra));
|
|
63
|
+
const data = { result };
|
|
64
|
+
const markdown = ["# Sent GoHighLevel Message", "", summarizeRecord(result, ["id", "messageId", "status", "conversationId", "contactId"])].join("\n");
|
|
65
|
+
return makeToolResponse(data, formatResponse(params.response_format, data, markdown));
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
const data = { error: formatApiError(error) };
|
|
69
|
+
return makeToolResponse(data, data.error, true);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function resolveLocationId(client, locationId) {
|
|
74
|
+
return typeof locationId === "string" && locationId.length > 0 ? locationId : client.defaultLocationId;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=conversations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversations.js","sourceRoot":"","sources":["../../src/tools/conversations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { GoHighLevelClient } from "../services/gohighlevel-client.js";
|
|
3
|
+
export declare function registerCustomFieldTools(server: McpServer, client: GoHighLevelClient): void;
|
|
4
|
+
//# sourceMappingURL=custom-fields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-fields.d.ts","sourceRoot":"","sources":["../../src/tools/custom-fields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AA+B3E,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,GAAG,IAAI,CA4V3F"}
|