@credal/actions 0.2.228 → 0.2.230
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/dist/actions/autogen/templates.js +158 -18
- package/dist/actions/autogen/types.d.ts +138 -11
- package/dist/actions/autogen/types.js +96 -13
- package/dist/actions/providers/zendesk/addCommentToTicket.js +5 -3
- package/dist/actions/providers/zendesk/assignTicket.js +4 -2
- package/dist/actions/providers/zendesk/createZendeskTicket.js +8 -6
- package/dist/actions/providers/zendesk/getTicketComments.d.ts +3 -0
- package/dist/actions/providers/zendesk/getTicketComments.js +80 -0
- package/dist/actions/providers/zendesk/getTicketDetails.js +4 -2
- package/dist/actions/providers/zendesk/listTickets.js +26 -16
- package/dist/actions/providers/zendesk/searchZendeskByQuery.js +6 -6
- package/dist/actions/providers/zendesk/searchZendeskTicketsByQuery.js +22 -16
- package/dist/actions/providers/zendesk/updateTicketStatus.js +4 -2
- package/dist/actions/providers/zendesk/utils/compactTicket.d.ts +22 -0
- package/dist/actions/providers/zendesk/utils/compactTicket.js +40 -0
- package/dist/actions/providers/zendesk/utils/getZendeskBaseUrl.d.ts +3 -0
- package/dist/actions/providers/zendesk/utils/getZendeskBaseUrl.js +7 -0
- package/dist/actions/providers/zendesk/utils/validateSubdomain.d.ts +1 -0
- package/dist/actions/providers/zendesk/utils/validateSubdomain.js +6 -0
- package/package.json +1 -1
|
@@ -4418,7 +4418,8 @@ export const zendeskCreateZendeskTicketDefinition = {
|
|
|
4418
4418
|
},
|
|
4419
4419
|
subdomain: {
|
|
4420
4420
|
type: "string",
|
|
4421
|
-
|
|
4421
|
+
pattern: "^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$",
|
|
4422
|
+
description: "The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix",
|
|
4422
4423
|
tags: ["recommend-predefined"],
|
|
4423
4424
|
},
|
|
4424
4425
|
groupId: {
|
|
@@ -4446,7 +4447,7 @@ export const zendeskCreateZendeskTicketDefinition = {
|
|
|
4446
4447
|
};
|
|
4447
4448
|
export const zendeskListZendeskTicketsDefinition = {
|
|
4448
4449
|
displayName: "List Zendesk tickets",
|
|
4449
|
-
description: "List
|
|
4450
|
+
description: "List compact ticket discovery records from Zendesk from the past 3 months. Use getTicketDetails to investigate selected tickets.",
|
|
4450
4451
|
scopes: [],
|
|
4451
4452
|
tags: [],
|
|
4452
4453
|
parameters: {
|
|
@@ -4455,29 +4456,99 @@ export const zendeskListZendeskTicketsDefinition = {
|
|
|
4455
4456
|
properties: {
|
|
4456
4457
|
subdomain: {
|
|
4457
4458
|
type: "string",
|
|
4458
|
-
|
|
4459
|
+
pattern: "^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$",
|
|
4460
|
+
description: "The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix",
|
|
4459
4461
|
tags: ["recommend-predefined"],
|
|
4460
4462
|
},
|
|
4461
4463
|
status: {
|
|
4462
4464
|
type: "string",
|
|
4465
|
+
enum: ["new", "open", "pending", "hold", "solved", "closed"],
|
|
4463
4466
|
description: "Filter tickets by status (new, open, pending, hold, solved, closed)",
|
|
4464
4467
|
},
|
|
4468
|
+
limit: {
|
|
4469
|
+
type: "integer",
|
|
4470
|
+
minimum: 1,
|
|
4471
|
+
maximum: 50,
|
|
4472
|
+
description: "Number of compact ticket records to return per page (optional, defaults to 20, maximum 50)",
|
|
4473
|
+
},
|
|
4474
|
+
page: {
|
|
4475
|
+
type: "integer",
|
|
4476
|
+
minimum: 1,
|
|
4477
|
+
description: "Offset page number to retrieve (optional, defaults to 1). Pass next_page from a previous response to continue.",
|
|
4478
|
+
},
|
|
4465
4479
|
},
|
|
4466
4480
|
},
|
|
4467
4481
|
output: {
|
|
4468
4482
|
type: "object",
|
|
4469
|
-
required: ["tickets", "count"],
|
|
4483
|
+
required: ["tickets", "count", "returned_count", "has_more"],
|
|
4470
4484
|
properties: {
|
|
4471
4485
|
tickets: {
|
|
4472
4486
|
type: "array",
|
|
4473
|
-
description: "
|
|
4487
|
+
description: "Small ticket records for choosing which IDs to fetch with getTicketDetails",
|
|
4474
4488
|
items: {
|
|
4475
4489
|
type: "object",
|
|
4490
|
+
required: ["id", "description_excerpt", "description_truncated"],
|
|
4491
|
+
properties: {
|
|
4492
|
+
id: {
|
|
4493
|
+
type: "integer",
|
|
4494
|
+
description: "Zendesk ticket ID",
|
|
4495
|
+
},
|
|
4496
|
+
subject: {
|
|
4497
|
+
type: "string",
|
|
4498
|
+
nullable: true,
|
|
4499
|
+
description: "Ticket subject",
|
|
4500
|
+
},
|
|
4501
|
+
status: {
|
|
4502
|
+
type: "string",
|
|
4503
|
+
nullable: true,
|
|
4504
|
+
description: "Ticket status category",
|
|
4505
|
+
},
|
|
4506
|
+
type: {
|
|
4507
|
+
type: "string",
|
|
4508
|
+
nullable: true,
|
|
4509
|
+
description: "Ticket type such as question, incident, problem, or task",
|
|
4510
|
+
},
|
|
4511
|
+
priority: {
|
|
4512
|
+
type: "string",
|
|
4513
|
+
nullable: true,
|
|
4514
|
+
description: "Ticket priority",
|
|
4515
|
+
},
|
|
4516
|
+
created_at: {
|
|
4517
|
+
type: "string",
|
|
4518
|
+
nullable: true,
|
|
4519
|
+
description: "Ticket creation timestamp",
|
|
4520
|
+
},
|
|
4521
|
+
updated_at: {
|
|
4522
|
+
type: "string",
|
|
4523
|
+
nullable: true,
|
|
4524
|
+
description: "Ticket update timestamp",
|
|
4525
|
+
},
|
|
4526
|
+
description_excerpt: {
|
|
4527
|
+
type: "string",
|
|
4528
|
+
description: "Up to the first 1,000 characters of the ticket description",
|
|
4529
|
+
},
|
|
4530
|
+
description_truncated: {
|
|
4531
|
+
type: "boolean",
|
|
4532
|
+
description: "Whether the full ticket description is longer than description_excerpt",
|
|
4533
|
+
},
|
|
4534
|
+
},
|
|
4476
4535
|
},
|
|
4477
4536
|
},
|
|
4478
4537
|
count: {
|
|
4479
4538
|
type: "number",
|
|
4480
|
-
description: "
|
|
4539
|
+
description: "Total number of tickets reported by Zendesk for the list query",
|
|
4540
|
+
},
|
|
4541
|
+
returned_count: {
|
|
4542
|
+
type: "number",
|
|
4543
|
+
description: "Number of compact ticket records returned in this response",
|
|
4544
|
+
},
|
|
4545
|
+
has_more: {
|
|
4546
|
+
type: "boolean",
|
|
4547
|
+
description: "Whether another page of tickets is available",
|
|
4548
|
+
},
|
|
4549
|
+
next_page: {
|
|
4550
|
+
type: "integer",
|
|
4551
|
+
description: "Page number to pass on the next call when has_more is true",
|
|
4481
4552
|
},
|
|
4482
4553
|
},
|
|
4483
4554
|
},
|
|
@@ -4486,7 +4557,7 @@ export const zendeskListZendeskTicketsDefinition = {
|
|
|
4486
4557
|
};
|
|
4487
4558
|
export const zendeskGetTicketDetailsDefinition = {
|
|
4488
4559
|
displayName: "Get ticket details",
|
|
4489
|
-
description: "Get
|
|
4560
|
+
description: "Get the full ticket object for a selected Zendesk ticket.",
|
|
4490
4561
|
scopes: [],
|
|
4491
4562
|
tags: [],
|
|
4492
4563
|
parameters: {
|
|
@@ -4499,7 +4570,8 @@ export const zendeskGetTicketDetailsDefinition = {
|
|
|
4499
4570
|
},
|
|
4500
4571
|
subdomain: {
|
|
4501
4572
|
type: "string",
|
|
4502
|
-
|
|
4573
|
+
pattern: "^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$",
|
|
4574
|
+
description: "The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix",
|
|
4503
4575
|
tags: ["recommend-predefined"],
|
|
4504
4576
|
},
|
|
4505
4577
|
},
|
|
@@ -4532,7 +4604,8 @@ export const zendeskUpdateTicketStatusDefinition = {
|
|
|
4532
4604
|
},
|
|
4533
4605
|
subdomain: {
|
|
4534
4606
|
type: "string",
|
|
4535
|
-
|
|
4607
|
+
pattern: "^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$",
|
|
4608
|
+
description: "The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix",
|
|
4536
4609
|
tags: ["recommend-predefined"],
|
|
4537
4610
|
},
|
|
4538
4611
|
status: {
|
|
@@ -4559,7 +4632,8 @@ export const zendeskAddCommentToTicketDefinition = {
|
|
|
4559
4632
|
},
|
|
4560
4633
|
subdomain: {
|
|
4561
4634
|
type: "string",
|
|
4562
|
-
|
|
4635
|
+
pattern: "^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$",
|
|
4636
|
+
description: "The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix",
|
|
4563
4637
|
tags: ["recommend-predefined"],
|
|
4564
4638
|
},
|
|
4565
4639
|
body: {
|
|
@@ -4604,7 +4678,8 @@ export const zendeskAssignTicketDefinition = {
|
|
|
4604
4678
|
},
|
|
4605
4679
|
subdomain: {
|
|
4606
4680
|
type: "string",
|
|
4607
|
-
|
|
4681
|
+
pattern: "^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$",
|
|
4682
|
+
description: "The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix",
|
|
4608
4683
|
tags: ["recommend-predefined"],
|
|
4609
4684
|
},
|
|
4610
4685
|
assigneeEmail: {
|
|
@@ -4627,7 +4702,8 @@ export const zendeskSearchZendeskByQueryDefinition = {
|
|
|
4627
4702
|
properties: {
|
|
4628
4703
|
subdomain: {
|
|
4629
4704
|
type: "string",
|
|
4630
|
-
|
|
4705
|
+
pattern: "^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$",
|
|
4706
|
+
description: "The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix",
|
|
4631
4707
|
tags: ["recommend-predefined"],
|
|
4632
4708
|
},
|
|
4633
4709
|
query: {
|
|
@@ -4667,7 +4743,7 @@ export const zendeskSearchZendeskByQueryDefinition = {
|
|
|
4667
4743
|
};
|
|
4668
4744
|
export const zendeskSearchZendeskTicketsByQueryDefinition = {
|
|
4669
4745
|
displayName: "Search Zendesk tickets with a query",
|
|
4670
|
-
description: "Search Zendesk
|
|
4746
|
+
description: "Search compact Zendesk ticket discovery records with flexible filtering options. Only returns tickets. Use getTicketDetails to investigate selected tickets.",
|
|
4671
4747
|
scopes: [],
|
|
4672
4748
|
tags: [],
|
|
4673
4749
|
parameters: {
|
|
@@ -4685,25 +4761,89 @@ export const zendeskSearchZendeskTicketsByQueryDefinition = {
|
|
|
4685
4761
|
description: 'Search query string that can include filters like status, priority, tags, assignee, etc. Examples - status:open, priority:high, tags:bug, assignee:user@example.com, or combination like "status:open priority:high". The search is always restricted to tickets, so any type filter in the query is ignored.',
|
|
4686
4762
|
},
|
|
4687
4763
|
limit: {
|
|
4688
|
-
type: "
|
|
4689
|
-
|
|
4764
|
+
type: "integer",
|
|
4765
|
+
minimum: 1,
|
|
4766
|
+
maximum: 50,
|
|
4767
|
+
description: "Number of compact ticket records to return per page (optional, defaults to 20, maximum 50)",
|
|
4768
|
+
},
|
|
4769
|
+
page: {
|
|
4770
|
+
type: "integer",
|
|
4771
|
+
minimum: 1,
|
|
4772
|
+
description: "Offset page number to retrieve (optional, defaults to 1). Pass next_page from a previous response to continue.",
|
|
4690
4773
|
},
|
|
4691
4774
|
},
|
|
4692
4775
|
},
|
|
4693
4776
|
output: {
|
|
4694
4777
|
type: "object",
|
|
4695
|
-
required: ["results", "count"],
|
|
4778
|
+
required: ["results", "count", "returned_count", "has_more"],
|
|
4696
4779
|
properties: {
|
|
4697
4780
|
results: {
|
|
4698
4781
|
type: "array",
|
|
4699
|
-
description: "
|
|
4782
|
+
description: "Small ticket records for choosing which IDs to fetch with getTicketDetails",
|
|
4700
4783
|
items: {
|
|
4701
4784
|
type: "object",
|
|
4785
|
+
required: ["id", "description_excerpt", "description_truncated"],
|
|
4786
|
+
properties: {
|
|
4787
|
+
id: {
|
|
4788
|
+
type: "integer",
|
|
4789
|
+
description: "Zendesk ticket ID",
|
|
4790
|
+
},
|
|
4791
|
+
subject: {
|
|
4792
|
+
type: "string",
|
|
4793
|
+
nullable: true,
|
|
4794
|
+
description: "Ticket subject",
|
|
4795
|
+
},
|
|
4796
|
+
status: {
|
|
4797
|
+
type: "string",
|
|
4798
|
+
nullable: true,
|
|
4799
|
+
description: "Ticket status category",
|
|
4800
|
+
},
|
|
4801
|
+
type: {
|
|
4802
|
+
type: "string",
|
|
4803
|
+
nullable: true,
|
|
4804
|
+
description: "Ticket type such as question, incident, problem, or task",
|
|
4805
|
+
},
|
|
4806
|
+
priority: {
|
|
4807
|
+
type: "string",
|
|
4808
|
+
nullable: true,
|
|
4809
|
+
description: "Ticket priority",
|
|
4810
|
+
},
|
|
4811
|
+
created_at: {
|
|
4812
|
+
type: "string",
|
|
4813
|
+
nullable: true,
|
|
4814
|
+
description: "Ticket creation timestamp",
|
|
4815
|
+
},
|
|
4816
|
+
updated_at: {
|
|
4817
|
+
type: "string",
|
|
4818
|
+
nullable: true,
|
|
4819
|
+
description: "Ticket update timestamp",
|
|
4820
|
+
},
|
|
4821
|
+
description_excerpt: {
|
|
4822
|
+
type: "string",
|
|
4823
|
+
description: "Up to the first 1,000 characters of the ticket description",
|
|
4824
|
+
},
|
|
4825
|
+
description_truncated: {
|
|
4826
|
+
type: "boolean",
|
|
4827
|
+
description: "Whether the full ticket description is longer than description_excerpt",
|
|
4828
|
+
},
|
|
4829
|
+
},
|
|
4702
4830
|
},
|
|
4703
4831
|
},
|
|
4704
4832
|
count: {
|
|
4705
4833
|
type: "number",
|
|
4706
|
-
description: "
|
|
4834
|
+
description: "Total number of matching tickets reported by Zendesk",
|
|
4835
|
+
},
|
|
4836
|
+
returned_count: {
|
|
4837
|
+
type: "number",
|
|
4838
|
+
description: "Number of compact ticket records returned in this response",
|
|
4839
|
+
},
|
|
4840
|
+
has_more: {
|
|
4841
|
+
type: "boolean",
|
|
4842
|
+
description: "Whether another page of matching tickets is available",
|
|
4843
|
+
},
|
|
4844
|
+
next_page: {
|
|
4845
|
+
type: "integer",
|
|
4846
|
+
description: "Page number to pass on the next call when has_more is true",
|
|
4707
4847
|
},
|
|
4708
4848
|
},
|
|
4709
4849
|
},
|
|
@@ -4520,24 +4520,89 @@ export type zendeskCreateZendeskTicketOutputType = z.infer<typeof zendeskCreateZ
|
|
|
4520
4520
|
export type zendeskCreateZendeskTicketFunction = ActionFunction<zendeskCreateZendeskTicketParamsType, AuthParamsType, zendeskCreateZendeskTicketOutputType>;
|
|
4521
4521
|
export declare const zendeskListZendeskTicketsParamsSchema: z.ZodObject<{
|
|
4522
4522
|
subdomain: z.ZodString;
|
|
4523
|
-
status: z.ZodOptional<z.
|
|
4523
|
+
status: z.ZodOptional<z.ZodEnum<["new", "open", "pending", "hold", "solved", "closed"]>>;
|
|
4524
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
4525
|
+
page: z.ZodOptional<z.ZodNumber>;
|
|
4524
4526
|
}, "strip", z.ZodTypeAny, {
|
|
4525
4527
|
subdomain: string;
|
|
4526
|
-
status?:
|
|
4528
|
+
status?: "new" | "open" | "pending" | "hold" | "solved" | "closed" | undefined;
|
|
4529
|
+
limit?: number | undefined;
|
|
4530
|
+
page?: number | undefined;
|
|
4527
4531
|
}, {
|
|
4528
4532
|
subdomain: string;
|
|
4529
|
-
status?:
|
|
4533
|
+
status?: "new" | "open" | "pending" | "hold" | "solved" | "closed" | undefined;
|
|
4534
|
+
limit?: number | undefined;
|
|
4535
|
+
page?: number | undefined;
|
|
4530
4536
|
}>;
|
|
4531
4537
|
export type zendeskListZendeskTicketsParamsType = z.infer<typeof zendeskListZendeskTicketsParamsSchema>;
|
|
4532
4538
|
export declare const zendeskListZendeskTicketsOutputSchema: z.ZodObject<{
|
|
4533
|
-
tickets: z.ZodArray<z.ZodObject<{
|
|
4539
|
+
tickets: z.ZodArray<z.ZodObject<{
|
|
4540
|
+
id: z.ZodNumber;
|
|
4541
|
+
subject: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
4542
|
+
status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
4543
|
+
type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
4544
|
+
priority: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
4545
|
+
created_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
4546
|
+
updated_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
4547
|
+
description_excerpt: z.ZodString;
|
|
4548
|
+
description_truncated: z.ZodBoolean;
|
|
4549
|
+
}, "strip", z.ZodTypeAny, {
|
|
4550
|
+
id: number;
|
|
4551
|
+
description_excerpt: string;
|
|
4552
|
+
description_truncated: boolean;
|
|
4553
|
+
type?: string | null | undefined;
|
|
4554
|
+
status?: string | null | undefined;
|
|
4555
|
+
created_at?: string | null | undefined;
|
|
4556
|
+
subject?: string | null | undefined;
|
|
4557
|
+
priority?: string | null | undefined;
|
|
4558
|
+
updated_at?: string | null | undefined;
|
|
4559
|
+
}, {
|
|
4560
|
+
id: number;
|
|
4561
|
+
description_excerpt: string;
|
|
4562
|
+
description_truncated: boolean;
|
|
4563
|
+
type?: string | null | undefined;
|
|
4564
|
+
status?: string | null | undefined;
|
|
4565
|
+
created_at?: string | null | undefined;
|
|
4566
|
+
subject?: string | null | undefined;
|
|
4567
|
+
priority?: string | null | undefined;
|
|
4568
|
+
updated_at?: string | null | undefined;
|
|
4569
|
+
}>, "many">;
|
|
4534
4570
|
count: z.ZodNumber;
|
|
4571
|
+
returned_count: z.ZodNumber;
|
|
4572
|
+
has_more: z.ZodBoolean;
|
|
4573
|
+
next_page: z.ZodOptional<z.ZodNumber>;
|
|
4535
4574
|
}, "strip", z.ZodTypeAny, {
|
|
4536
4575
|
count: number;
|
|
4537
|
-
tickets:
|
|
4576
|
+
tickets: {
|
|
4577
|
+
id: number;
|
|
4578
|
+
description_excerpt: string;
|
|
4579
|
+
description_truncated: boolean;
|
|
4580
|
+
type?: string | null | undefined;
|
|
4581
|
+
status?: string | null | undefined;
|
|
4582
|
+
created_at?: string | null | undefined;
|
|
4583
|
+
subject?: string | null | undefined;
|
|
4584
|
+
priority?: string | null | undefined;
|
|
4585
|
+
updated_at?: string | null | undefined;
|
|
4586
|
+
}[];
|
|
4587
|
+
returned_count: number;
|
|
4588
|
+
has_more: boolean;
|
|
4589
|
+
next_page?: number | undefined;
|
|
4538
4590
|
}, {
|
|
4539
4591
|
count: number;
|
|
4540
|
-
tickets:
|
|
4592
|
+
tickets: {
|
|
4593
|
+
id: number;
|
|
4594
|
+
description_excerpt: string;
|
|
4595
|
+
description_truncated: boolean;
|
|
4596
|
+
type?: string | null | undefined;
|
|
4597
|
+
status?: string | null | undefined;
|
|
4598
|
+
created_at?: string | null | undefined;
|
|
4599
|
+
subject?: string | null | undefined;
|
|
4600
|
+
priority?: string | null | undefined;
|
|
4601
|
+
updated_at?: string | null | undefined;
|
|
4602
|
+
}[];
|
|
4603
|
+
returned_count: number;
|
|
4604
|
+
has_more: boolean;
|
|
4605
|
+
next_page?: number | undefined;
|
|
4541
4606
|
}>;
|
|
4542
4607
|
export type zendeskListZendeskTicketsOutputType = z.infer<typeof zendeskListZendeskTicketsOutputSchema>;
|
|
4543
4608
|
export type zendeskListZendeskTicketsFunction = ActionFunction<zendeskListZendeskTicketsParamsType, AuthParamsType, zendeskListZendeskTicketsOutputType>;
|
|
@@ -4661,25 +4726,87 @@ export declare const zendeskSearchZendeskTicketsByQueryParamsSchema: z.ZodObject
|
|
|
4661
4726
|
subdomain: z.ZodString;
|
|
4662
4727
|
query: z.ZodString;
|
|
4663
4728
|
limit: z.ZodOptional<z.ZodNumber>;
|
|
4729
|
+
page: z.ZodOptional<z.ZodNumber>;
|
|
4664
4730
|
}, "strip", z.ZodTypeAny, {
|
|
4665
4731
|
query: string;
|
|
4666
4732
|
subdomain: string;
|
|
4667
4733
|
limit?: number | undefined;
|
|
4734
|
+
page?: number | undefined;
|
|
4668
4735
|
}, {
|
|
4669
4736
|
query: string;
|
|
4670
4737
|
subdomain: string;
|
|
4671
4738
|
limit?: number | undefined;
|
|
4739
|
+
page?: number | undefined;
|
|
4672
4740
|
}>;
|
|
4673
4741
|
export type zendeskSearchZendeskTicketsByQueryParamsType = z.infer<typeof zendeskSearchZendeskTicketsByQueryParamsSchema>;
|
|
4674
4742
|
export declare const zendeskSearchZendeskTicketsByQueryOutputSchema: z.ZodObject<{
|
|
4675
|
-
results: z.ZodArray<z.ZodObject<{
|
|
4743
|
+
results: z.ZodArray<z.ZodObject<{
|
|
4744
|
+
id: z.ZodNumber;
|
|
4745
|
+
subject: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
4746
|
+
status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
4747
|
+
type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
4748
|
+
priority: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
4749
|
+
created_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
4750
|
+
updated_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
4751
|
+
description_excerpt: z.ZodString;
|
|
4752
|
+
description_truncated: z.ZodBoolean;
|
|
4753
|
+
}, "strip", z.ZodTypeAny, {
|
|
4754
|
+
id: number;
|
|
4755
|
+
description_excerpt: string;
|
|
4756
|
+
description_truncated: boolean;
|
|
4757
|
+
type?: string | null | undefined;
|
|
4758
|
+
status?: string | null | undefined;
|
|
4759
|
+
created_at?: string | null | undefined;
|
|
4760
|
+
subject?: string | null | undefined;
|
|
4761
|
+
priority?: string | null | undefined;
|
|
4762
|
+
updated_at?: string | null | undefined;
|
|
4763
|
+
}, {
|
|
4764
|
+
id: number;
|
|
4765
|
+
description_excerpt: string;
|
|
4766
|
+
description_truncated: boolean;
|
|
4767
|
+
type?: string | null | undefined;
|
|
4768
|
+
status?: string | null | undefined;
|
|
4769
|
+
created_at?: string | null | undefined;
|
|
4770
|
+
subject?: string | null | undefined;
|
|
4771
|
+
priority?: string | null | undefined;
|
|
4772
|
+
updated_at?: string | null | undefined;
|
|
4773
|
+
}>, "many">;
|
|
4676
4774
|
count: z.ZodNumber;
|
|
4775
|
+
returned_count: z.ZodNumber;
|
|
4776
|
+
has_more: z.ZodBoolean;
|
|
4777
|
+
next_page: z.ZodOptional<z.ZodNumber>;
|
|
4677
4778
|
}, "strip", z.ZodTypeAny, {
|
|
4678
|
-
results:
|
|
4779
|
+
results: {
|
|
4780
|
+
id: number;
|
|
4781
|
+
description_excerpt: string;
|
|
4782
|
+
description_truncated: boolean;
|
|
4783
|
+
type?: string | null | undefined;
|
|
4784
|
+
status?: string | null | undefined;
|
|
4785
|
+
created_at?: string | null | undefined;
|
|
4786
|
+
subject?: string | null | undefined;
|
|
4787
|
+
priority?: string | null | undefined;
|
|
4788
|
+
updated_at?: string | null | undefined;
|
|
4789
|
+
}[];
|
|
4679
4790
|
count: number;
|
|
4791
|
+
returned_count: number;
|
|
4792
|
+
has_more: boolean;
|
|
4793
|
+
next_page?: number | undefined;
|
|
4680
4794
|
}, {
|
|
4681
|
-
results:
|
|
4795
|
+
results: {
|
|
4796
|
+
id: number;
|
|
4797
|
+
description_excerpt: string;
|
|
4798
|
+
description_truncated: boolean;
|
|
4799
|
+
type?: string | null | undefined;
|
|
4800
|
+
status?: string | null | undefined;
|
|
4801
|
+
created_at?: string | null | undefined;
|
|
4802
|
+
subject?: string | null | undefined;
|
|
4803
|
+
priority?: string | null | undefined;
|
|
4804
|
+
updated_at?: string | null | undefined;
|
|
4805
|
+
}[];
|
|
4682
4806
|
count: number;
|
|
4807
|
+
returned_count: number;
|
|
4808
|
+
has_more: boolean;
|
|
4809
|
+
next_page?: number | undefined;
|
|
4683
4810
|
}>;
|
|
4684
4811
|
export type zendeskSearchZendeskTicketsByQueryOutputType = z.infer<typeof zendeskSearchZendeskTicketsByQueryOutputSchema>;
|
|
4685
4812
|
export type zendeskSearchZendeskTicketsByQueryFunction = ActionFunction<zendeskSearchZendeskTicketsByQueryParamsType, AuthParamsType, zendeskSearchZendeskTicketsByQueryOutputType>;
|
|
@@ -10273,21 +10400,21 @@ export declare const githubListCommitsParamsSchema: z.ZodObject<{
|
|
|
10273
10400
|
}, "strip", z.ZodTypeAny, {
|
|
10274
10401
|
repositoryOwner: string;
|
|
10275
10402
|
repositoryName: string;
|
|
10403
|
+
page?: number | undefined;
|
|
10276
10404
|
branch?: string | undefined;
|
|
10277
10405
|
author?: string | undefined;
|
|
10278
10406
|
since?: string | undefined;
|
|
10279
10407
|
until?: string | undefined;
|
|
10280
10408
|
perPage?: number | undefined;
|
|
10281
|
-
page?: number | undefined;
|
|
10282
10409
|
}, {
|
|
10283
10410
|
repositoryOwner: string;
|
|
10284
10411
|
repositoryName: string;
|
|
10412
|
+
page?: number | undefined;
|
|
10285
10413
|
branch?: string | undefined;
|
|
10286
10414
|
author?: string | undefined;
|
|
10287
10415
|
since?: string | undefined;
|
|
10288
10416
|
until?: string | undefined;
|
|
10289
10417
|
perPage?: number | undefined;
|
|
10290
|
-
page?: number | undefined;
|
|
10291
10418
|
}>;
|
|
10292
10419
|
export type githubListCommitsParamsType = z.infer<typeof githubListCommitsParamsSchema>;
|
|
10293
10420
|
export declare const githubListCommitsOutputSchema: z.ZodObject<{
|
|
@@ -1596,7 +1596,10 @@ export const bingGetTopNSearchResultUrlsOutputSchema = z.object({
|
|
|
1596
1596
|
export const zendeskCreateZendeskTicketParamsSchema = z.object({
|
|
1597
1597
|
subject: z.string().describe("The subject of the ticket"),
|
|
1598
1598
|
body: z.string().describe("The body of the ticket").optional(),
|
|
1599
|
-
subdomain: z
|
|
1599
|
+
subdomain: z
|
|
1600
|
+
.string()
|
|
1601
|
+
.regex(new RegExp("^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$"))
|
|
1602
|
+
.describe("The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix"),
|
|
1600
1603
|
groupId: z.coerce.number().describe("The ID of the group to assign the ticket to").optional(),
|
|
1601
1604
|
});
|
|
1602
1605
|
export const zendeskCreateZendeskTicketOutputSchema = z.object({
|
|
@@ -1604,23 +1607,65 @@ export const zendeskCreateZendeskTicketOutputSchema = z.object({
|
|
|
1604
1607
|
ticketUrl: z.string().describe("The URL of the ticket created").optional(),
|
|
1605
1608
|
});
|
|
1606
1609
|
export const zendeskListZendeskTicketsParamsSchema = z.object({
|
|
1607
|
-
subdomain: z
|
|
1608
|
-
|
|
1610
|
+
subdomain: z
|
|
1611
|
+
.string()
|
|
1612
|
+
.regex(new RegExp("^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$"))
|
|
1613
|
+
.describe("The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix"),
|
|
1614
|
+
status: z
|
|
1615
|
+
.enum(["new", "open", "pending", "hold", "solved", "closed"])
|
|
1616
|
+
.describe("Filter tickets by status (new, open, pending, hold, solved, closed)")
|
|
1617
|
+
.optional(),
|
|
1618
|
+
limit: z.coerce
|
|
1619
|
+
.number()
|
|
1620
|
+
.int()
|
|
1621
|
+
.gte(1)
|
|
1622
|
+
.lte(50)
|
|
1623
|
+
.describe("Number of compact ticket records to return per page (optional, defaults to 20, maximum 50)")
|
|
1624
|
+
.optional(),
|
|
1625
|
+
page: z.coerce
|
|
1626
|
+
.number()
|
|
1627
|
+
.int()
|
|
1628
|
+
.gte(1)
|
|
1629
|
+
.describe("Offset page number to retrieve (optional, defaults to 1). Pass next_page from a previous response to continue.")
|
|
1630
|
+
.optional(),
|
|
1609
1631
|
});
|
|
1610
1632
|
export const zendeskListZendeskTicketsOutputSchema = z.object({
|
|
1611
|
-
tickets: z
|
|
1612
|
-
|
|
1633
|
+
tickets: z
|
|
1634
|
+
.array(z.object({
|
|
1635
|
+
id: z.coerce.number().int().describe("Zendesk ticket ID"),
|
|
1636
|
+
subject: z.string().nullable().describe("Ticket subject").optional(),
|
|
1637
|
+
status: z.string().nullable().describe("Ticket status category").optional(),
|
|
1638
|
+
type: z.string().nullable().describe("Ticket type such as question, incident, problem, or task").optional(),
|
|
1639
|
+
priority: z.string().nullable().describe("Ticket priority").optional(),
|
|
1640
|
+
created_at: z.string().nullable().describe("Ticket creation timestamp").optional(),
|
|
1641
|
+
updated_at: z.string().nullable().describe("Ticket update timestamp").optional(),
|
|
1642
|
+
description_excerpt: z.string().describe("Up to the first 1,000 characters of the ticket description"),
|
|
1643
|
+
description_truncated: z
|
|
1644
|
+
.boolean()
|
|
1645
|
+
.describe("Whether the full ticket description is longer than description_excerpt"),
|
|
1646
|
+
}))
|
|
1647
|
+
.describe("Small ticket records for choosing which IDs to fetch with getTicketDetails"),
|
|
1648
|
+
count: z.coerce.number().describe("Total number of tickets reported by Zendesk for the list query"),
|
|
1649
|
+
returned_count: z.coerce.number().describe("Number of compact ticket records returned in this response"),
|
|
1650
|
+
has_more: z.boolean().describe("Whether another page of tickets is available"),
|
|
1651
|
+
next_page: z.coerce.number().int().describe("Page number to pass on the next call when has_more is true").optional(),
|
|
1613
1652
|
});
|
|
1614
1653
|
export const zendeskGetTicketDetailsParamsSchema = z.object({
|
|
1615
1654
|
ticketId: z.string().describe("The ID of the ticket"),
|
|
1616
|
-
subdomain: z
|
|
1655
|
+
subdomain: z
|
|
1656
|
+
.string()
|
|
1657
|
+
.regex(new RegExp("^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$"))
|
|
1658
|
+
.describe("The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix"),
|
|
1617
1659
|
});
|
|
1618
1660
|
export const zendeskGetTicketDetailsOutputSchema = z.object({
|
|
1619
1661
|
ticket: z.object({}).catchall(z.any()).describe("The details of the ticket"),
|
|
1620
1662
|
});
|
|
1621
1663
|
export const zendeskUpdateTicketStatusParamsSchema = z.object({
|
|
1622
1664
|
ticketId: z.string().describe("The ID of the ticket to update"),
|
|
1623
|
-
subdomain: z
|
|
1665
|
+
subdomain: z
|
|
1666
|
+
.string()
|
|
1667
|
+
.regex(new RegExp("^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$"))
|
|
1668
|
+
.describe("The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix"),
|
|
1624
1669
|
status: z
|
|
1625
1670
|
.string()
|
|
1626
1671
|
.describe('The state of the ticket. If your account has activated custom ticket statuses, this is the ticket\'s status category. Allowed values are "new", "open", "pending", "hold", "solved", or "closed".'),
|
|
@@ -1628,7 +1673,10 @@ export const zendeskUpdateTicketStatusParamsSchema = z.object({
|
|
|
1628
1673
|
export const zendeskUpdateTicketStatusOutputSchema = z.void();
|
|
1629
1674
|
export const zendeskAddCommentToTicketParamsSchema = z.object({
|
|
1630
1675
|
ticketId: z.string().describe("The ID of the ticket to update"),
|
|
1631
|
-
subdomain: z
|
|
1676
|
+
subdomain: z
|
|
1677
|
+
.string()
|
|
1678
|
+
.regex(new RegExp("^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$"))
|
|
1679
|
+
.describe("The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix"),
|
|
1632
1680
|
body: z.string().describe("The body of the comment"),
|
|
1633
1681
|
public: z.boolean().describe("Whether the comment should be public (defaults to true)").optional(),
|
|
1634
1682
|
});
|
|
@@ -1638,12 +1686,18 @@ export const zendeskAddCommentToTicketOutputSchema = z.object({
|
|
|
1638
1686
|
});
|
|
1639
1687
|
export const zendeskAssignTicketParamsSchema = z.object({
|
|
1640
1688
|
ticketId: z.string().describe("The ID of the ticket to update"),
|
|
1641
|
-
subdomain: z
|
|
1689
|
+
subdomain: z
|
|
1690
|
+
.string()
|
|
1691
|
+
.regex(new RegExp("^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$"))
|
|
1692
|
+
.describe("The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix"),
|
|
1642
1693
|
assigneeEmail: z.string().describe("The email address of the agent to assign the ticket to"),
|
|
1643
1694
|
});
|
|
1644
1695
|
export const zendeskAssignTicketOutputSchema = z.void();
|
|
1645
1696
|
export const zendeskSearchZendeskByQueryParamsSchema = z.object({
|
|
1646
|
-
subdomain: z
|
|
1697
|
+
subdomain: z
|
|
1698
|
+
.string()
|
|
1699
|
+
.regex(new RegExp("^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$"))
|
|
1700
|
+
.describe("The hostname-label subdomain of the Zendesk account, without a protocol, path, or .zendesk.com suffix"),
|
|
1647
1701
|
query: z
|
|
1648
1702
|
.string()
|
|
1649
1703
|
.describe('Search query string that can include filters like status, priority, tags, assignee, etc. Examples - status:open, priority:high, tags:bug, assignee:user@example.com, or combination like "status:open priority:high"'),
|
|
@@ -1665,11 +1719,40 @@ export const zendeskSearchZendeskTicketsByQueryParamsSchema = z.object({
|
|
|
1665
1719
|
query: z
|
|
1666
1720
|
.string()
|
|
1667
1721
|
.describe('Search query string that can include filters like status, priority, tags, assignee, etc. Examples - status:open, priority:high, tags:bug, assignee:user@example.com, or combination like "status:open priority:high". The search is always restricted to tickets, so any type filter in the query is ignored.'),
|
|
1668
|
-
limit: z.coerce
|
|
1722
|
+
limit: z.coerce
|
|
1723
|
+
.number()
|
|
1724
|
+
.int()
|
|
1725
|
+
.gte(1)
|
|
1726
|
+
.lte(50)
|
|
1727
|
+
.describe("Number of compact ticket records to return per page (optional, defaults to 20, maximum 50)")
|
|
1728
|
+
.optional(),
|
|
1729
|
+
page: z.coerce
|
|
1730
|
+
.number()
|
|
1731
|
+
.int()
|
|
1732
|
+
.gte(1)
|
|
1733
|
+
.describe("Offset page number to retrieve (optional, defaults to 1). Pass next_page from a previous response to continue.")
|
|
1734
|
+
.optional(),
|
|
1669
1735
|
});
|
|
1670
1736
|
export const zendeskSearchZendeskTicketsByQueryOutputSchema = z.object({
|
|
1671
|
-
results: z
|
|
1672
|
-
|
|
1737
|
+
results: z
|
|
1738
|
+
.array(z.object({
|
|
1739
|
+
id: z.coerce.number().int().describe("Zendesk ticket ID"),
|
|
1740
|
+
subject: z.string().nullable().describe("Ticket subject").optional(),
|
|
1741
|
+
status: z.string().nullable().describe("Ticket status category").optional(),
|
|
1742
|
+
type: z.string().nullable().describe("Ticket type such as question, incident, problem, or task").optional(),
|
|
1743
|
+
priority: z.string().nullable().describe("Ticket priority").optional(),
|
|
1744
|
+
created_at: z.string().nullable().describe("Ticket creation timestamp").optional(),
|
|
1745
|
+
updated_at: z.string().nullable().describe("Ticket update timestamp").optional(),
|
|
1746
|
+
description_excerpt: z.string().describe("Up to the first 1,000 characters of the ticket description"),
|
|
1747
|
+
description_truncated: z
|
|
1748
|
+
.boolean()
|
|
1749
|
+
.describe("Whether the full ticket description is longer than description_excerpt"),
|
|
1750
|
+
}))
|
|
1751
|
+
.describe("Small ticket records for choosing which IDs to fetch with getTicketDetails"),
|
|
1752
|
+
count: z.coerce.number().describe("Total number of matching tickets reported by Zendesk"),
|
|
1753
|
+
returned_count: z.coerce.number().describe("Number of compact ticket records returned in this response"),
|
|
1754
|
+
has_more: z.boolean().describe("Whether another page of matching tickets is available"),
|
|
1755
|
+
next_page: z.coerce.number().int().describe("Page number to pass on the next call when has_more is true").optional(),
|
|
1673
1756
|
});
|
|
1674
1757
|
export const linkedinCreateShareLinkedinPostUrlParamsSchema = z.object({
|
|
1675
1758
|
text: z.string().describe("The text for the linkedin post").optional(),
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
2
2
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
3
|
+
import { getZendeskBaseUrl } from "./utils/getZendeskBaseUrl.js";
|
|
3
4
|
const addCommentToTicket = async ({ params, authParams, }) => {
|
|
4
5
|
const { authToken } = authParams;
|
|
5
6
|
const { subdomain, ticketId, body, public: isPublic } = params;
|
|
6
|
-
const url = `https://${subdomain}.zendesk.com/api/v2/tickets/${ticketId}.json`;
|
|
7
7
|
if (!authToken) {
|
|
8
8
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
9
9
|
}
|
|
10
|
+
const zendeskBaseUrl = getZendeskBaseUrl({ subdomain });
|
|
11
|
+
const apiEndpoint = new URL(`/api/v2/tickets/${ticketId}.json`, zendeskBaseUrl);
|
|
10
12
|
const axiosClient = createAxiosClientWithRetries({ timeout: 20000, retryCount: 5 });
|
|
11
13
|
try {
|
|
12
14
|
await axiosClient.request({
|
|
13
|
-
url:
|
|
15
|
+
url: apiEndpoint.toString(),
|
|
14
16
|
method: "PUT",
|
|
15
17
|
headers: {
|
|
16
18
|
"Content-Type": "application/json",
|
|
@@ -27,7 +29,7 @@ const addCommentToTicket = async ({ params, authParams, }) => {
|
|
|
27
29
|
});
|
|
28
30
|
return {
|
|
29
31
|
success: true,
|
|
30
|
-
ticketUrl:
|
|
32
|
+
ticketUrl: new URL(`/agent/tickets/${ticketId}`, zendeskBaseUrl).toString(),
|
|
31
33
|
};
|
|
32
34
|
}
|
|
33
35
|
catch (error) {
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
2
2
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
3
|
+
import { getZendeskBaseUrl } from "./utils/getZendeskBaseUrl.js";
|
|
3
4
|
const updateTicketStatus = async ({ params, authParams, }) => {
|
|
4
5
|
const { authToken } = authParams;
|
|
5
6
|
const { subdomain, ticketId, assigneeEmail } = params;
|
|
6
|
-
const url = `https://${subdomain}.zendesk.com/api/v2/tickets/${ticketId}.json`;
|
|
7
7
|
if (!authToken) {
|
|
8
8
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
9
9
|
}
|
|
10
|
+
const zendeskBaseUrl = getZendeskBaseUrl({ subdomain });
|
|
11
|
+
const apiEndpoint = new URL(`/api/v2/tickets/${ticketId}.json`, zendeskBaseUrl);
|
|
10
12
|
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
11
13
|
await axiosClient.request({
|
|
12
|
-
url:
|
|
14
|
+
url: apiEndpoint.toString(),
|
|
13
15
|
method: "PUT",
|
|
14
16
|
headers: {
|
|
15
17
|
"Content-Type": "application/json",
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
2
2
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
3
|
+
import { getZendeskBaseUrl } from "./utils/getZendeskBaseUrl.js";
|
|
3
4
|
const createZendeskTicket = async ({ params, authParams, }) => {
|
|
4
5
|
const { authToken } = authParams;
|
|
5
6
|
const { subdomain, subject, body, groupId } = params;
|
|
6
|
-
|
|
7
|
+
if (!authToken) {
|
|
8
|
+
throw new Error(MISSING_AUTH_TOKEN);
|
|
9
|
+
}
|
|
10
|
+
const zendeskBaseUrl = getZendeskBaseUrl({ subdomain });
|
|
11
|
+
const apiEndpoint = new URL("/api/v2/tickets.json", zendeskBaseUrl);
|
|
7
12
|
const payload = {
|
|
8
13
|
ticket: {
|
|
9
14
|
subject,
|
|
@@ -13,11 +18,8 @@ const createZendeskTicket = async ({ params, authParams, }) => {
|
|
|
13
18
|
group_id: groupId,
|
|
14
19
|
},
|
|
15
20
|
};
|
|
16
|
-
if (!authToken) {
|
|
17
|
-
throw new Error(MISSING_AUTH_TOKEN);
|
|
18
|
-
}
|
|
19
21
|
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
20
|
-
const response = await axiosClient.post(
|
|
22
|
+
const response = await axiosClient.post(apiEndpoint.toString(), payload, {
|
|
21
23
|
headers: {
|
|
22
24
|
"Content-Type": "application/json",
|
|
23
25
|
Authorization: `Bearer ${authToken}`,
|
|
@@ -25,7 +27,7 @@ const createZendeskTicket = async ({ params, authParams, }) => {
|
|
|
25
27
|
});
|
|
26
28
|
return {
|
|
27
29
|
ticketId: response.data.ticket.id,
|
|
28
|
-
ticketUrl:
|
|
30
|
+
ticketUrl: new URL(`/requests/${response.data.ticket.id}`, zendeskBaseUrl).toString(),
|
|
29
31
|
};
|
|
30
32
|
};
|
|
31
33
|
export default createZendeskTicket;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
2
|
+
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
3
|
+
import { getZendeskBaseUrl } from "./utils/getZendeskBaseUrl.js";
|
|
4
|
+
const getTicketComments = async ({ params, authParams, }) => {
|
|
5
|
+
const { authToken } = authParams;
|
|
6
|
+
const { subdomain, ticketId, limit = 10, cursor, sortOrder = "asc", maxBodyCharacters = 5000 } = params;
|
|
7
|
+
if (!authToken) {
|
|
8
|
+
throw new Error(MISSING_AUTH_TOKEN);
|
|
9
|
+
}
|
|
10
|
+
const zendeskBaseUrl = getZendeskBaseUrl({ subdomain });
|
|
11
|
+
const apiEndpoint = new URL(`/api/v2/tickets/${encodeURIComponent(ticketId)}/comments.json`, zendeskBaseUrl);
|
|
12
|
+
apiEndpoint.searchParams.set("page[size]", limit.toString());
|
|
13
|
+
apiEndpoint.searchParams.set("sort", sortOrder === "desc" ? "-created_at" : "created_at");
|
|
14
|
+
if (cursor) {
|
|
15
|
+
apiEndpoint.searchParams.set("page[after]", cursor);
|
|
16
|
+
}
|
|
17
|
+
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
18
|
+
const response = await axiosClient.get(apiEndpoint.toString(), {
|
|
19
|
+
headers: {
|
|
20
|
+
"Content-Type": "application/json",
|
|
21
|
+
Authorization: `Bearer ${authToken}`,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
const rawComments = Array.isArray(response.data.comments) ? response.data.comments : [];
|
|
25
|
+
const comments = rawComments.flatMap(comment => {
|
|
26
|
+
if (!isRecord(comment) || typeof comment.id !== "number") {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const rawComment = comment;
|
|
30
|
+
const fullBody = typeof rawComment.plain_body === "string"
|
|
31
|
+
? rawComment.plain_body
|
|
32
|
+
: typeof rawComment.body === "string"
|
|
33
|
+
? rawComment.body
|
|
34
|
+
: "";
|
|
35
|
+
const channel = isRecord(rawComment.via) && typeof rawComment.via.channel === "string" ? rawComment.via.channel : undefined;
|
|
36
|
+
const attachments = compactAttachments(rawComment.attachments);
|
|
37
|
+
return [
|
|
38
|
+
{
|
|
39
|
+
id: comment.id,
|
|
40
|
+
author_id: typeof rawComment.author_id === "number" ? rawComment.author_id : null,
|
|
41
|
+
created_at: typeof rawComment.created_at === "string" ? rawComment.created_at : null,
|
|
42
|
+
public: rawComment.public === true,
|
|
43
|
+
type: typeof rawComment.type === "string" ? rawComment.type : null,
|
|
44
|
+
body: fullBody.slice(0, maxBodyCharacters),
|
|
45
|
+
body_truncated: fullBody.length > maxBodyCharacters,
|
|
46
|
+
...(channel ? { via: { channel } } : {}),
|
|
47
|
+
...(attachments.length > 0 ? { attachments } : {}),
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
});
|
|
51
|
+
const hasMore = response.data.meta?.has_more === true;
|
|
52
|
+
const afterCursor = response.data.meta?.after_cursor;
|
|
53
|
+
return {
|
|
54
|
+
comments,
|
|
55
|
+
returned_count: comments.length,
|
|
56
|
+
has_more: hasMore,
|
|
57
|
+
...(hasMore && typeof afterCursor === "string" ? { next_cursor: afterCursor } : {}),
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
function compactAttachments(value) {
|
|
61
|
+
if (!Array.isArray(value))
|
|
62
|
+
return [];
|
|
63
|
+
return value.flatMap(attachment => {
|
|
64
|
+
if (!isRecord(attachment))
|
|
65
|
+
return [];
|
|
66
|
+
return [
|
|
67
|
+
{
|
|
68
|
+
...(typeof attachment.id === "number" ? { id: attachment.id } : {}),
|
|
69
|
+
...(typeof attachment.file_name === "string" ? { file_name: attachment.file_name } : {}),
|
|
70
|
+
...(typeof attachment.content_type === "string" ? { content_type: attachment.content_type } : {}),
|
|
71
|
+
...(typeof attachment.size === "number" ? { size: attachment.size } : {}),
|
|
72
|
+
...(typeof attachment.content_url === "string" ? { content_url: attachment.content_url } : {}),
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function isRecord(value) {
|
|
78
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
79
|
+
}
|
|
80
|
+
export default getTicketComments;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
2
2
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
3
|
+
import { getZendeskBaseUrl } from "./utils/getZendeskBaseUrl.js";
|
|
3
4
|
const getZendeskTicketDetails = async ({ params, authParams, }) => {
|
|
4
5
|
const { authToken } = authParams;
|
|
5
6
|
const { subdomain, ticketId } = params;
|
|
6
|
-
const url = `https://${subdomain}.zendesk.com/api/v2/tickets/${ticketId}.json`;
|
|
7
7
|
if (!authToken) {
|
|
8
8
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
9
9
|
}
|
|
10
|
+
const zendeskBaseUrl = getZendeskBaseUrl({ subdomain });
|
|
11
|
+
const apiEndpoint = new URL(`/api/v2/tickets/${ticketId}.json`, zendeskBaseUrl);
|
|
10
12
|
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
11
13
|
const response = await axiosClient.request({
|
|
12
|
-
url:
|
|
14
|
+
url: apiEndpoint.toString(),
|
|
13
15
|
method: "GET",
|
|
14
16
|
headers: {
|
|
15
17
|
"Content-Type": "application/json",
|
|
@@ -1,33 +1,43 @@
|
|
|
1
1
|
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
2
2
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
3
|
+
import { compactZendeskTickets, isZendeskTicketSearchResult } from "./utils/compactTicket.js";
|
|
4
|
+
import { getZendeskBaseUrl } from "./utils/getZendeskBaseUrl.js";
|
|
3
5
|
const listZendeskTickets = async ({ params, authParams, }) => {
|
|
4
6
|
const { authToken } = authParams;
|
|
5
|
-
const { subdomain, status } = params;
|
|
7
|
+
const { subdomain, status, limit = 20, page = 1 } = params;
|
|
6
8
|
// Calculate date 3 months ago from now
|
|
7
9
|
const threeMonthsAgo = new Date();
|
|
8
10
|
threeMonthsAgo.setMonth(threeMonthsAgo.getMonth() - 3);
|
|
9
11
|
const formattedDate = threeMonthsAgo.toISOString().split("T")[0];
|
|
10
|
-
// Endpoint for getting tickets
|
|
11
|
-
const url = `https://${subdomain}.zendesk.com/api/v2/tickets.json`;
|
|
12
12
|
if (!authToken) {
|
|
13
13
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
14
14
|
}
|
|
15
|
+
const zendeskBaseUrl = getZendeskBaseUrl({ subdomain });
|
|
16
|
+
const apiEndpoint = new URL("/api/v2/search.json", zendeskBaseUrl);
|
|
15
17
|
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
},
|
|
18
|
+
const query = [`type:ticket`, `created>${formattedDate}`, ...(status ? [`status:${status}`] : [])].join(" ");
|
|
19
|
+
apiEndpoint.searchParams.set("query", query);
|
|
20
|
+
apiEndpoint.searchParams.set("per_page", limit.toString());
|
|
21
|
+
apiEndpoint.searchParams.set("page", page.toString());
|
|
22
|
+
const headers = {
|
|
23
|
+
"Content-Type": "application/json",
|
|
24
|
+
Authorization: `Bearer ${authToken}`,
|
|
25
|
+
};
|
|
26
|
+
const response = await axiosClient.get(apiEndpoint.toString(), {
|
|
27
|
+
headers,
|
|
27
28
|
});
|
|
29
|
+
const rawTickets = Array.isArray(response.data.results)
|
|
30
|
+
? response.data.results.filter(isZendeskTicketSearchResult)
|
|
31
|
+
: [];
|
|
32
|
+
const tickets = compactZendeskTickets(rawTickets);
|
|
33
|
+
const count = typeof response.data.count === "number" ? response.data.count : rawTickets.length;
|
|
34
|
+
const hasMore = typeof response.data.next_page === "string" && response.data.next_page.length > 0;
|
|
28
35
|
return {
|
|
29
|
-
tickets
|
|
30
|
-
count
|
|
36
|
+
tickets,
|
|
37
|
+
count,
|
|
38
|
+
returned_count: tickets.length,
|
|
39
|
+
has_more: hasMore,
|
|
40
|
+
...(hasMore ? { next_page: page + 1 } : {}),
|
|
31
41
|
};
|
|
32
42
|
};
|
|
33
43
|
export default listZendeskTickets;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
2
2
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
3
|
+
import { getZendeskBaseUrl } from "./utils/getZendeskBaseUrl.js";
|
|
3
4
|
const searchZendeskByQuery = async ({ params, authParams, }) => {
|
|
4
5
|
const { authToken } = authParams;
|
|
5
6
|
const { subdomain, query, objectType = "ticket", limit = 100 } = params;
|
|
6
|
-
// Endpoint for searching Zendesk objects
|
|
7
|
-
const url = `https://${subdomain}.zendesk.com/api/v2/search.json`;
|
|
8
7
|
if (!authToken) {
|
|
9
8
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
10
9
|
}
|
|
10
|
+
const zendeskBaseUrl = getZendeskBaseUrl({ subdomain });
|
|
11
|
+
const apiEndpoint = new URL("/api/v2/search.json", zendeskBaseUrl);
|
|
11
12
|
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
12
13
|
// Build search query parameters
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const response = await axiosClient.get(`${url}?${queryParams.toString()}`, {
|
|
14
|
+
apiEndpoint.searchParams.set("query", `type:${objectType} ${query}`);
|
|
15
|
+
apiEndpoint.searchParams.set("per_page", limit.toString());
|
|
16
|
+
const response = await axiosClient.get(apiEndpoint.toString(), {
|
|
17
17
|
headers: {
|
|
18
18
|
"Content-Type": "application/json",
|
|
19
19
|
Authorization: `Bearer ${authToken}`,
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
2
2
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
3
|
-
|
|
3
|
+
import { compactZendeskTickets, isZendeskTicketSearchResult } from "./utils/compactTicket.js";
|
|
4
|
+
import { getZendeskBaseUrl } from "./utils/getZendeskBaseUrl.js";
|
|
4
5
|
const searchZendeskTicketsByQuery = async ({ params, authParams, }) => {
|
|
5
6
|
const { authToken } = authParams;
|
|
6
|
-
const { subdomain, query, limit =
|
|
7
|
+
const { subdomain, query, limit = 20, page = 1 } = params;
|
|
7
8
|
if (!authToken) {
|
|
8
9
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
const url = new URL(`https://${subdomain}.zendesk.com/api/v2/search.json`);
|
|
11
|
+
const zendeskBaseUrl = getZendeskBaseUrl({ subdomain });
|
|
12
|
+
const apiEndpoint = new URL("/api/v2/search.json", zendeskBaseUrl);
|
|
14
13
|
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
15
14
|
// Strip any type: filters from the incoming query so it can't target other resource types,
|
|
16
15
|
// then force the search to tickets only
|
|
@@ -18,22 +17,29 @@ const searchZendeskTicketsByQuery = async ({ params, authParams, }) => {
|
|
|
18
17
|
.replace(/\btype:\S+/gi, "")
|
|
19
18
|
.replace(/\s+/g, " ")
|
|
20
19
|
.trim();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
apiEndpoint.searchParams.set("query", `type:ticket ${sanitizedQuery}`.trim());
|
|
21
|
+
apiEndpoint.searchParams.set("per_page", limit.toString());
|
|
22
|
+
apiEndpoint.searchParams.set("page", page.toString());
|
|
23
|
+
const headers = {
|
|
24
|
+
"Content-Type": "application/json",
|
|
25
|
+
Authorization: `Bearer ${authToken}`,
|
|
26
|
+
};
|
|
27
|
+
const response = await axiosClient.get(apiEndpoint.toString(), {
|
|
28
|
+
headers,
|
|
28
29
|
});
|
|
29
30
|
// Defense in depth: only return results Zendesk marks as tickets
|
|
30
|
-
const
|
|
31
|
-
? response.data.results.filter(
|
|
31
|
+
const rawResults = Array.isArray(response.data.results)
|
|
32
|
+
? response.data.results.filter(isZendeskTicketSearchResult)
|
|
32
33
|
: [];
|
|
33
|
-
const
|
|
34
|
+
const results = compactZendeskTickets(rawResults);
|
|
35
|
+
const count = typeof response.data.count === "number" ? response.data.count : rawResults.length;
|
|
36
|
+
const hasMore = typeof response.data.next_page === "string" && response.data.next_page.length > 0;
|
|
34
37
|
return {
|
|
35
38
|
results,
|
|
36
39
|
count,
|
|
40
|
+
returned_count: results.length,
|
|
41
|
+
has_more: hasMore,
|
|
42
|
+
...(hasMore ? { next_page: page + 1 } : {}),
|
|
37
43
|
};
|
|
38
44
|
};
|
|
39
45
|
export default searchZendeskTicketsByQuery;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
2
2
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
3
|
+
import { getZendeskBaseUrl } from "./utils/getZendeskBaseUrl.js";
|
|
3
4
|
const updateTicketStatus = async ({ params, authParams, }) => {
|
|
4
5
|
const { authToken } = authParams;
|
|
5
6
|
const { subdomain, ticketId, status } = params;
|
|
6
|
-
const url = `https://${subdomain}.zendesk.com/api/v2/tickets/${ticketId}.json`;
|
|
7
7
|
if (!authToken) {
|
|
8
8
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
9
9
|
}
|
|
10
|
+
const zendeskBaseUrl = getZendeskBaseUrl({ subdomain });
|
|
11
|
+
const apiEndpoint = new URL(`/api/v2/tickets/${ticketId}.json`, zendeskBaseUrl);
|
|
10
12
|
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
11
13
|
await axiosClient.request({
|
|
12
|
-
url:
|
|
14
|
+
url: apiEndpoint.toString(),
|
|
13
15
|
method: "PUT",
|
|
14
16
|
headers: {
|
|
15
17
|
"Content-Type": "application/json",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { zendeskListZendeskTicketsOutputType } from "../../../autogen/types.js";
|
|
2
|
+
type CompactTicket = zendeskListZendeskTicketsOutputType["tickets"][number];
|
|
3
|
+
export interface ZendeskTicketSearchResult {
|
|
4
|
+
id: number;
|
|
5
|
+
result_type: "ticket";
|
|
6
|
+
subject?: string | null;
|
|
7
|
+
status?: string | null;
|
|
8
|
+
type?: string | null;
|
|
9
|
+
priority?: string | null;
|
|
10
|
+
created_at?: string | null;
|
|
11
|
+
updated_at?: string | null;
|
|
12
|
+
description?: string | null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Narrows an unknown Zendesk Search API result to the ticket fields used for discovery.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isZendeskTicketSearchResult(value: unknown): value is ZendeskTicketSearchResult;
|
|
18
|
+
/**
|
|
19
|
+
* Projects Zendesk tickets into small records for choosing which IDs to fetch with getTicketDetails.
|
|
20
|
+
*/
|
|
21
|
+
export declare function compactZendeskTickets(tickets: ZendeskTicketSearchResult[]): CompactTicket[];
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const DESCRIPTION_EXCERPT_CHARACTERS = 1000;
|
|
2
|
+
/**
|
|
3
|
+
* Narrows an unknown Zendesk Search API result to the ticket fields used for discovery.
|
|
4
|
+
*/
|
|
5
|
+
export function isZendeskTicketSearchResult(value) {
|
|
6
|
+
if (typeof value !== "object" || value === null)
|
|
7
|
+
return false;
|
|
8
|
+
const result = value;
|
|
9
|
+
return (typeof result.id === "number" &&
|
|
10
|
+
result.result_type === "ticket" &&
|
|
11
|
+
isOptionalNullableString(result.subject) &&
|
|
12
|
+
isOptionalNullableString(result.status) &&
|
|
13
|
+
isOptionalNullableString(result.type) &&
|
|
14
|
+
isOptionalNullableString(result.priority) &&
|
|
15
|
+
isOptionalNullableString(result.created_at) &&
|
|
16
|
+
isOptionalNullableString(result.updated_at) &&
|
|
17
|
+
isOptionalNullableString(result.description));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Projects Zendesk tickets into small records for choosing which IDs to fetch with getTicketDetails.
|
|
21
|
+
*/
|
|
22
|
+
export function compactZendeskTickets(tickets) {
|
|
23
|
+
return tickets.map(ticket => {
|
|
24
|
+
const description = ticket.description ?? "";
|
|
25
|
+
return {
|
|
26
|
+
id: ticket.id,
|
|
27
|
+
subject: ticket.subject ?? null,
|
|
28
|
+
status: ticket.status ?? null,
|
|
29
|
+
type: ticket.type ?? null,
|
|
30
|
+
priority: ticket.priority ?? null,
|
|
31
|
+
created_at: ticket.created_at ?? null,
|
|
32
|
+
updated_at: ticket.updated_at ?? null,
|
|
33
|
+
description_excerpt: description.slice(0, DESCRIPTION_EXCERPT_CHARACTERS),
|
|
34
|
+
description_truncated: description.length > DESCRIPTION_EXCERPT_CHARACTERS,
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function isOptionalNullableString(value) {
|
|
39
|
+
return value === undefined || value === null || typeof value === "string";
|
|
40
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const ZENDESK_SUBDOMAIN_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;
|
|
2
|
+
export const getZendeskBaseUrl = ({ subdomain }) => {
|
|
3
|
+
if (!ZENDESK_SUBDOMAIN_PATTERN.test(subdomain)) {
|
|
4
|
+
throw new Error("Invalid Zendesk subdomain");
|
|
5
|
+
}
|
|
6
|
+
return new URL(`https://${subdomain}.zendesk.com/`);
|
|
7
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const validateZendeskSubdomain: (subdomain: string) => void;
|