@credal/actions 0.2.108 → 0.2.110
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/actionMapper.js +9 -1
- package/dist/actions/autogen/templates.d.ts +1 -0
- package/dist/actions/autogen/templates.js +156 -0
- package/dist/actions/autogen/types.d.ts +154 -20
- package/dist/actions/autogen/types.js +60 -0
- package/dist/actions/providers/confluence/updatePage.js +15 -14
- package/dist/actions/providers/google-oauth/scheduleCalendarMeeting.d.ts +1 -0
- package/dist/actions/providers/google-oauth/scheduleCalendarMeeting.js +48 -4
- package/dist/actions/providers/jamf/types.d.ts +8 -0
- package/dist/actions/providers/jamf/types.js +7 -0
- package/dist/actions/providers/slackUser/searchSlack.d.ts +17 -0
- package/dist/actions/providers/slackUser/searchSlack.js +219 -0
- package/dist/actions/providers/zendesk/addCommentToTicket.js +2 -1
- package/dist/actions/providers/zendesk/assignTicket.js +2 -1
- package/dist/actions/providers/zendesk/createZendeskTicket.js +2 -1
- package/dist/actions/providers/zendesk/getTicketDetails.js +3 -2
- package/dist/actions/providers/zendesk/listTickets.js +2 -1
- package/dist/actions/providers/zendesk/searchZendeskByQuery.js +2 -1
- package/dist/actions/providers/zendesk/updateTicketStatus.js +2 -1
- package/dist/actions/util/axiosClient.d.ts +4 -1
- package/dist/actions/util/axiosClient.js +7 -3
- package/package.json +1 -1
- package/dist/actions/providers/generic/fillTemplateAction.d.ts +0 -7
- package/dist/actions/providers/generic/fillTemplateAction.js +0 -18
- package/dist/actions/providers/generic/genericApiCall.d.ts +0 -3
- package/dist/actions/providers/generic/genericApiCall.js +0 -38
- package/dist/actions/providers/google-oauth/getDriveContentById.d.ts +0 -3
- package/dist/actions/providers/google-oauth/getDriveContentById.js +0 -161
- package/dist/actions/providers/google-oauth/searchAndGetDriveContentByKeywords.d.ts +0 -3
- package/dist/actions/providers/google-oauth/searchAndGetDriveContentByKeywords.js +0 -47
- package/dist/actions/providers/google-oauth/searchDriveAndGetContentByKeywords.d.ts +0 -3
- package/dist/actions/providers/google-oauth/searchDriveAndGetContentByKeywords.js +0 -110
- package/dist/actions/providers/google-oauth/searchDriveAndGetContentByQuery.d.ts +0 -3
- package/dist/actions/providers/google-oauth/searchDriveAndGetContentByQuery.js +0 -78
- package/dist/actions/providers/google-oauth/utils/extractContentFromDriveFileId.d.ts +0 -15
- package/dist/actions/providers/google-oauth/utils/extractContentFromDriveFileId.js +0 -129
- package/dist/actions/providers/googlemaps/nearbysearch.d.ts +0 -3
- package/dist/actions/providers/googlemaps/nearbysearch.js +0 -96
- package/dist/actions/providers/snowflake/runSnowflakeQueryWriteResultsToS3.d.ts +0 -3
- package/dist/actions/providers/snowflake/runSnowflakeQueryWriteResultsToS3.js +0 -154
- package/dist/actions/providers/x/scrapeTweetDataWithNitter.d.ts +0 -3
- package/dist/actions/providers/x/scrapeTweetDataWithNitter.js +0 -45
|
@@ -5,6 +5,7 @@ export var ProviderName;
|
|
|
5
5
|
ProviderName["PERPLEXITY"] = "perplexity";
|
|
6
6
|
ProviderName["ASANA"] = "asana";
|
|
7
7
|
ProviderName["SLACK"] = "slack";
|
|
8
|
+
ProviderName["SLACKUSER"] = "slackUser";
|
|
8
9
|
ProviderName["MATH"] = "math";
|
|
9
10
|
ProviderName["CONFLUENCE"] = "confluence";
|
|
10
11
|
ProviderName["JIRA"] = "jira";
|
|
@@ -274,6 +275,48 @@ export const slackGetChannelMessagesOutputSchema = z.object({
|
|
|
274
275
|
.describe("A message in the channel"))
|
|
275
276
|
.describe("The messages in the channel"),
|
|
276
277
|
});
|
|
278
|
+
export const slackUserSearchSlackParamsSchema = z.object({
|
|
279
|
+
emails: z
|
|
280
|
+
.array(z.string().email())
|
|
281
|
+
.describe("Participants identified strictly by email (one email = 1:1 DM, multiple = MPIM).")
|
|
282
|
+
.optional(),
|
|
283
|
+
channel: z.string().describe('Channel name or ID. Examples - "#eng-updates", "eng-updates", "C01234567".').optional(),
|
|
284
|
+
topic: z.string().describe('Keyword(s) to search for (e.g., "jogging decision").').optional(),
|
|
285
|
+
timeRange: z
|
|
286
|
+
.enum(["latest", "today", "yesterday", "last_7d", "last_30d", "all"])
|
|
287
|
+
.describe("Optional time filter applied to the search.")
|
|
288
|
+
.default("latest"),
|
|
289
|
+
limit: z
|
|
290
|
+
.number()
|
|
291
|
+
.int()
|
|
292
|
+
.gte(1)
|
|
293
|
+
.lte(100)
|
|
294
|
+
.describe("Max matches to request (passed to Slack search; results are then hydrated and sorted newest-first).")
|
|
295
|
+
.default(50),
|
|
296
|
+
});
|
|
297
|
+
export const slackUserSearchSlackOutputSchema = z.object({
|
|
298
|
+
query: z.string().describe("The exact query string sent to Slack’s search API after resolving inputs."),
|
|
299
|
+
results: z
|
|
300
|
+
.array(z.object({
|
|
301
|
+
channelId: z.string().describe("Slack channel/conversation ID (C…/G…/D… or name)."),
|
|
302
|
+
ts: z.string().describe("Slack message timestamp of the hit (or thread root when hydrated as thread)."),
|
|
303
|
+
text: z.string().describe("Message text of the anchor (hit or thread root).").optional(),
|
|
304
|
+
userId: z.string().describe("User ID of the anchor message’s author (if available).").optional(),
|
|
305
|
+
permalink: z
|
|
306
|
+
.string()
|
|
307
|
+
.describe("A Slack permalink to the anchor (message or thread root), if resolvable.")
|
|
308
|
+
.optional(),
|
|
309
|
+
context: z
|
|
310
|
+
.array(z.object({
|
|
311
|
+
ts: z.string().describe("Timestamp of the contextual message."),
|
|
312
|
+
text: z.string().describe("Text of the contextual message.").optional(),
|
|
313
|
+
userId: z.string().describe("Author user ID of the contextual message.").optional(),
|
|
314
|
+
}))
|
|
315
|
+
.describe("When a hit is in a thread, this is the full thread (root first). Otherwise, a small surrounding context window (~3 before, 5 after).")
|
|
316
|
+
.optional(),
|
|
317
|
+
}))
|
|
318
|
+
.describe("Hydrated search results (threads or small context windows), sorted by ts desc."),
|
|
319
|
+
});
|
|
277
320
|
export const mathAddParamsSchema = z.object({
|
|
278
321
|
a: z.number().describe("The first number to add"),
|
|
279
322
|
b: z.number().describe("The second number to add"),
|
|
@@ -1541,6 +1584,23 @@ export const googleOauthScheduleCalendarMeetingParamsSchema = z.object({
|
|
|
1541
1584
|
.string()
|
|
1542
1585
|
.describe("The time zone for the meeting, IANA Time Zone identifier (e.g., 'America/New_York')")
|
|
1543
1586
|
.optional(),
|
|
1587
|
+
recurrence: z
|
|
1588
|
+
.object({
|
|
1589
|
+
frequency: z.enum(["DAILY", "WEEKLY", "MONTHLY", "YEARLY"]).describe("How often the meeting repeats").optional(),
|
|
1590
|
+
interval: z.number().int().gte(1).describe("The interval between recurrences (e.g., every 2 weeks)").optional(),
|
|
1591
|
+
count: z.number().int().gte(1).describe("Number of occurrences after which to stop the recurrence").optional(),
|
|
1592
|
+
until: z.string().describe("End date for the recurrence in RFC3339 format (YYYY-MM-DD)").optional(),
|
|
1593
|
+
byDay: z
|
|
1594
|
+
.array(z.enum(["MO", "TU", "WE", "TH", "FR", "SA", "SU"]))
|
|
1595
|
+
.describe("Days of the week when the meeting occurs (for WEEKLY frequency)")
|
|
1596
|
+
.optional(),
|
|
1597
|
+
byMonthDay: z
|
|
1598
|
+
.array(z.number().int().gte(1).lte(31))
|
|
1599
|
+
.describe("Days of the month when the meeting occurs (for MONTHLY frequency)")
|
|
1600
|
+
.optional(),
|
|
1601
|
+
})
|
|
1602
|
+
.describe("Recurring meeting configuration. If not provided, creates a one-time meeting.")
|
|
1603
|
+
.optional(),
|
|
1544
1604
|
});
|
|
1545
1605
|
export const googleOauthScheduleCalendarMeetingOutputSchema = z.object({
|
|
1546
1606
|
success: z.boolean().describe("Whether the meeting was scheduled successfully"),
|
|
@@ -8,28 +8,30 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
+
const axios_1 = __importDefault(require("axios"));
|
|
16
|
+
function getConfluenceApi(baseUrl, username, apiToken) {
|
|
17
|
+
const api = axios_1.default.create({
|
|
15
18
|
baseURL: baseUrl,
|
|
16
19
|
headers: {
|
|
17
20
|
Accept: "application/json",
|
|
21
|
+
// Tokens are associated with a specific user.
|
|
18
22
|
Authorization: `Basic ${Buffer.from(`${username}:${apiToken}`).toString("base64")}`,
|
|
19
23
|
},
|
|
20
|
-
};
|
|
24
|
+
});
|
|
25
|
+
return api;
|
|
21
26
|
}
|
|
22
27
|
const confluenceUpdatePage = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
23
|
-
const { pageId, content, title } = params;
|
|
24
|
-
const { baseUrl, authToken
|
|
25
|
-
|
|
26
|
-
throw new Error("Missing required authentication information");
|
|
27
|
-
}
|
|
28
|
-
const config = getConfluenceRequestConfig(baseUrl, username, authToken);
|
|
28
|
+
const { pageId, username, content, title } = params;
|
|
29
|
+
const { baseUrl, authToken } = authParams;
|
|
30
|
+
const api = getConfluenceApi(baseUrl, username, authToken);
|
|
29
31
|
// Get current version number
|
|
30
|
-
const response = yield
|
|
32
|
+
const response = yield api.get(`/api/v2/pages/${pageId}`);
|
|
31
33
|
const currVersion = response.data.version.number;
|
|
32
|
-
|
|
34
|
+
yield api.put(`/api/v2/pages/${pageId}`, {
|
|
33
35
|
id: pageId,
|
|
34
36
|
status: "current",
|
|
35
37
|
title,
|
|
@@ -40,7 +42,6 @@ const confluenceUpdatePage = (_a) => __awaiter(void 0, [_a], void 0, function* (
|
|
|
40
42
|
version: {
|
|
41
43
|
number: currVersion + 1,
|
|
42
44
|
},
|
|
43
|
-
};
|
|
44
|
-
yield axiosClient_1.axiosClient.put(`/api/v2/pages/${pageId}`, payload, config);
|
|
45
|
+
});
|
|
45
46
|
});
|
|
46
47
|
exports.default = confluenceUpdatePage;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { googleOauthScheduleCalendarMeetingFunction } from "../../autogen/types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Creates a new Google calendar event using OAuth authentication
|
|
4
|
+
* Supports both one-time and recurring meetings
|
|
4
5
|
*/
|
|
5
6
|
declare const scheduleCalendarMeeting: googleOauthScheduleCalendarMeetingFunction;
|
|
6
7
|
export default scheduleCalendarMeeting;
|
|
@@ -11,20 +11,50 @@ import { v4 } from "uuid";
|
|
|
11
11
|
import { axiosClient } from "../../util/axiosClient.js";
|
|
12
12
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
13
13
|
import { getDayOfWeek } from "../../../utils/datetime.js";
|
|
14
|
+
/**
|
|
15
|
+
* Generates a recurrence rule (RRULE) based on the recurrence parameters
|
|
16
|
+
*/
|
|
17
|
+
function generateRecurrenceRule(recurrence) {
|
|
18
|
+
let rrule = `RRULE:FREQ=${recurrence.frequency}`;
|
|
19
|
+
if (recurrence.interval) {
|
|
20
|
+
rrule += `;INTERVAL=${recurrence.interval}`;
|
|
21
|
+
}
|
|
22
|
+
if (recurrence.count) {
|
|
23
|
+
rrule += `;COUNT=${recurrence.count}`;
|
|
24
|
+
}
|
|
25
|
+
if (recurrence.until) {
|
|
26
|
+
const date = new Date(recurrence.until);
|
|
27
|
+
const year = date.getUTCFullYear();
|
|
28
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, "0");
|
|
29
|
+
const day = String(date.getUTCDate()).padStart(2, "0");
|
|
30
|
+
const hour = String(date.getUTCHours()).padStart(2, "0");
|
|
31
|
+
const minute = String(date.getUTCMinutes()).padStart(2, "0");
|
|
32
|
+
const second = String(date.getUTCSeconds()).padStart(2, "0");
|
|
33
|
+
rrule += `;UNTIL=${year}${month}${day}T${hour}${minute}${second}Z`; // trufflehog:ignore
|
|
34
|
+
}
|
|
35
|
+
if (recurrence.byDay && recurrence.byDay.length > 0) {
|
|
36
|
+
rrule += `;BYDAY=${recurrence.byDay.join(",")}`;
|
|
37
|
+
}
|
|
38
|
+
if (recurrence.byMonthDay && recurrence.byMonthDay.length > 0) {
|
|
39
|
+
rrule += `;BYMONTHDAY=${recurrence.byMonthDay.join(",")}`;
|
|
40
|
+
}
|
|
41
|
+
return rrule;
|
|
42
|
+
}
|
|
14
43
|
/**
|
|
15
44
|
* Creates a new Google calendar event using OAuth authentication
|
|
45
|
+
* Supports both one-time and recurring meetings
|
|
16
46
|
*/
|
|
17
47
|
const scheduleCalendarMeeting = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
18
48
|
if (!authParams.authToken) {
|
|
19
49
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
20
50
|
}
|
|
21
|
-
const { calendarId, name, start, end, description, attendees, useGoogleMeet, timeZone } = params;
|
|
51
|
+
const { calendarId, name, start, end, description, attendees, useGoogleMeet, timeZone, recurrence } = params;
|
|
22
52
|
// https://developers.google.com/calendar/api/v3/reference/events/insert
|
|
23
|
-
let createEventApiUrl = `https://www.googleapis.com/calendar/v3/calendars/${calendarId}/events`;
|
|
53
|
+
let createEventApiUrl = `https://www.googleapis.com/calendar/v3/calendars/${encodeURIComponent(calendarId)}/events`;
|
|
24
54
|
const data = {
|
|
25
55
|
summary: name,
|
|
26
|
-
start: Object.assign({ dateTime: start }, (timeZone
|
|
27
|
-
end: Object.assign({ dateTime: end }, (timeZone
|
|
56
|
+
start: Object.assign({ dateTime: start }, (timeZone ? { timeZone } : { timeZone: "UTC" })),
|
|
57
|
+
end: Object.assign({ dateTime: end }, (timeZone ? { timeZone } : { timeZone: "UTC" })),
|
|
28
58
|
};
|
|
29
59
|
if (description) {
|
|
30
60
|
data.description = description;
|
|
@@ -40,6 +70,20 @@ const scheduleCalendarMeeting = (_a) => __awaiter(void 0, [_a], void 0, function
|
|
|
40
70
|
},
|
|
41
71
|
};
|
|
42
72
|
}
|
|
73
|
+
// Add recurrence rule if specified
|
|
74
|
+
if (recurrence) {
|
|
75
|
+
try {
|
|
76
|
+
const rrule = generateRecurrenceRule(recurrence);
|
|
77
|
+
data.recurrence = [rrule];
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.error("Error generating recurrence rule", error);
|
|
81
|
+
return {
|
|
82
|
+
success: false,
|
|
83
|
+
error: "Invalid recurrence configuration: " + (error instanceof Error ? error.message : "Unknown error"),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
43
87
|
try {
|
|
44
88
|
const response = yield axiosClient.post(createEventApiUrl, data, {
|
|
45
89
|
headers: {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type slackUserSearchSlackFunction } from "../../autogen/types.js";
|
|
2
|
+
export type TimeRange = "latest" | "today" | "yesterday" | "last_7d" | "last_30d" | "all";
|
|
3
|
+
export interface SlackSearchMessage {
|
|
4
|
+
channelId: string;
|
|
5
|
+
ts: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
userId?: string;
|
|
8
|
+
permalink?: string;
|
|
9
|
+
/** If thread: full thread (root first). If not thread: small context window around the hit. */
|
|
10
|
+
context?: Array<{
|
|
11
|
+
ts: string;
|
|
12
|
+
text?: string;
|
|
13
|
+
userId?: string;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
declare const searchSlack: slackUserSearchSlackFunction;
|
|
17
|
+
export default searchSlack;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { WebClient } from "@slack/web-api";
|
|
11
|
+
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
12
|
+
/* ===================== Helpers ===================== */
|
|
13
|
+
function normalizeChannelOperand(ch) {
|
|
14
|
+
const s = ch.trim();
|
|
15
|
+
if (/^[CGD][A-Z0-9]/i.test(s))
|
|
16
|
+
return s;
|
|
17
|
+
return s.replace(/^#/, "");
|
|
18
|
+
}
|
|
19
|
+
function timeFilter(range) {
|
|
20
|
+
switch (range) {
|
|
21
|
+
case "today":
|
|
22
|
+
return "after:today";
|
|
23
|
+
case "yesterday":
|
|
24
|
+
return "after:yesterday";
|
|
25
|
+
case "last_7d":
|
|
26
|
+
return "after:7 days ago";
|
|
27
|
+
case "last_30d":
|
|
28
|
+
return "after:30 days ago";
|
|
29
|
+
default:
|
|
30
|
+
return "";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function lookupUserIdsByEmail(client, emails) {
|
|
34
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
var _a;
|
|
36
|
+
const ids = [];
|
|
37
|
+
for (const raw of emails) {
|
|
38
|
+
const email = raw.trim();
|
|
39
|
+
if (!email)
|
|
40
|
+
continue;
|
|
41
|
+
const res = yield client.users.lookupByEmail({ email });
|
|
42
|
+
const id = (_a = res.user) === null || _a === void 0 ? void 0 : _a.id;
|
|
43
|
+
if (id)
|
|
44
|
+
ids.push(id);
|
|
45
|
+
}
|
|
46
|
+
return ids;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function getMPIMName(client, userIds) {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
var _a, _b;
|
|
52
|
+
const res = yield client.conversations.open({ users: userIds.join(",") });
|
|
53
|
+
const id = (_a = res.channel) === null || _a === void 0 ? void 0 : _a.id;
|
|
54
|
+
if (!id)
|
|
55
|
+
throw new Error("Failed to open conversation for provided users.");
|
|
56
|
+
const info = yield client.conversations.info({ channel: id });
|
|
57
|
+
if (!((_b = info.channel) === null || _b === void 0 ? void 0 : _b.name))
|
|
58
|
+
throw new Error("Failed to open conversation for provided users.");
|
|
59
|
+
return info.channel.name;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function getPermalink(client, channel, ts) {
|
|
63
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
try {
|
|
65
|
+
const res = yield client.chat.getPermalink({ channel, message_ts: ts });
|
|
66
|
+
return res.permalink;
|
|
67
|
+
}
|
|
68
|
+
catch (_a) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function fetchOneMessage(client, channel, ts) {
|
|
74
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
+
const r = yield client.conversations.history({
|
|
76
|
+
channel,
|
|
77
|
+
latest: ts,
|
|
78
|
+
inclusive: true,
|
|
79
|
+
limit: 1,
|
|
80
|
+
});
|
|
81
|
+
return (r.messages && r.messages[0]) || undefined;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function fetchThread(client, channel, threadTs) {
|
|
85
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
+
var _a;
|
|
87
|
+
const r = yield client.conversations.replies({
|
|
88
|
+
channel,
|
|
89
|
+
ts: threadTs,
|
|
90
|
+
limit: 50,
|
|
91
|
+
});
|
|
92
|
+
return (_a = r.messages) !== null && _a !== void 0 ? _a : [];
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function fetchContextWindow(client, channel, ts) {
|
|
96
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
var _a, _b;
|
|
98
|
+
const out = [];
|
|
99
|
+
const anchor = yield fetchOneMessage(client, channel, ts);
|
|
100
|
+
if (!anchor)
|
|
101
|
+
return out;
|
|
102
|
+
const beforeRes = yield client.conversations.history({
|
|
103
|
+
channel,
|
|
104
|
+
latest: ts,
|
|
105
|
+
inclusive: false,
|
|
106
|
+
limit: 4,
|
|
107
|
+
});
|
|
108
|
+
out.push(...((_a = beforeRes.messages) !== null && _a !== void 0 ? _a : []).reverse());
|
|
109
|
+
out.push(anchor);
|
|
110
|
+
const afterRes = yield client.conversations.history({
|
|
111
|
+
channel,
|
|
112
|
+
oldest: ts,
|
|
113
|
+
inclusive: false,
|
|
114
|
+
limit: 5,
|
|
115
|
+
});
|
|
116
|
+
out.push(...((_b = afterRes.messages) !== null && _b !== void 0 ? _b : []));
|
|
117
|
+
return out;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/* ===================== Main Export ===================== */
|
|
121
|
+
const searchSlack = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
122
|
+
var _b, _c, _d, _e, _f, _g;
|
|
123
|
+
if (!authParams.authToken) {
|
|
124
|
+
throw new Error(MISSING_AUTH_TOKEN);
|
|
125
|
+
}
|
|
126
|
+
const client = new WebClient(authParams.authToken);
|
|
127
|
+
const { emails, channel, topic, timeRange, limit } = params;
|
|
128
|
+
const parts = [];
|
|
129
|
+
if (emails === null || emails === void 0 ? void 0 : emails.length) {
|
|
130
|
+
const userIds = yield lookupUserIdsByEmail(client, emails);
|
|
131
|
+
if (userIds.length === 0)
|
|
132
|
+
throw new Error("No users resolved from emails.");
|
|
133
|
+
if (userIds.length == 1) {
|
|
134
|
+
parts.push(`in:<@${userIds[0]}>`);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const convoName = yield getMPIMName(client, userIds);
|
|
138
|
+
parts.push(`in:${convoName}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else if (channel) {
|
|
142
|
+
parts.push(`in:${normalizeChannelOperand(channel)}`);
|
|
143
|
+
}
|
|
144
|
+
if (topic && topic.trim())
|
|
145
|
+
parts.push(topic.trim());
|
|
146
|
+
const tf = timeFilter(timeRange);
|
|
147
|
+
if (tf)
|
|
148
|
+
parts.push(tf);
|
|
149
|
+
const query = parts.join(" ").trim();
|
|
150
|
+
if (!query)
|
|
151
|
+
throw new Error("No query built — provide emails, channel, or topic.");
|
|
152
|
+
const count = Math.max(1, Math.min(100, limit));
|
|
153
|
+
const searchRes = yield client.search.messages({ query, count, highlight: true });
|
|
154
|
+
const matches = (_c = (_b = searchRes.messages) === null || _b === void 0 ? void 0 : _b.matches) !== null && _c !== void 0 ? _c : [];
|
|
155
|
+
const hits = matches.slice(0, limit).map(m => {
|
|
156
|
+
var _a, _b;
|
|
157
|
+
return ({
|
|
158
|
+
channelId: ((_a = m.channel) === null || _a === void 0 ? void 0 : _a.id) || ((_b = m.channel) === null || _b === void 0 ? void 0 : _b.name) || "",
|
|
159
|
+
ts: m.ts,
|
|
160
|
+
text: m.text,
|
|
161
|
+
userId: m.user,
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
const results = [];
|
|
165
|
+
for (const h of hits) {
|
|
166
|
+
if (!h.ts)
|
|
167
|
+
continue;
|
|
168
|
+
try {
|
|
169
|
+
const anchor = yield fetchOneMessage(client, h.channelId, h.ts);
|
|
170
|
+
const rootTs = (anchor === null || anchor === void 0 ? void 0 : anchor.thread_ts) || h.ts;
|
|
171
|
+
if (anchor === null || anchor === void 0 ? void 0 : anchor.thread_ts) {
|
|
172
|
+
const thread = yield fetchThread(client, h.channelId, rootTs);
|
|
173
|
+
const normalizedThreads = [];
|
|
174
|
+
for (const t of thread) {
|
|
175
|
+
if (!t.ts)
|
|
176
|
+
continue;
|
|
177
|
+
normalizedThreads.push({ ts: t.ts, text: t.text, userId: t.user });
|
|
178
|
+
}
|
|
179
|
+
results.push({
|
|
180
|
+
channelId: h.channelId,
|
|
181
|
+
ts: rootTs,
|
|
182
|
+
text: (_d = anchor.text) !== null && _d !== void 0 ? _d : h.text,
|
|
183
|
+
userId: (_e = anchor.user) !== null && _e !== void 0 ? _e : h.userId,
|
|
184
|
+
context: normalizedThreads,
|
|
185
|
+
permalink: yield getPermalink(client, h.channelId, rootTs),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const ctx = yield fetchContextWindow(client, h.channelId, h.ts);
|
|
190
|
+
const normalizedThreads = [];
|
|
191
|
+
for (const t of ctx) {
|
|
192
|
+
if (!t.ts)
|
|
193
|
+
continue;
|
|
194
|
+
normalizedThreads.push({ ts: t.ts, text: t.text, userId: t.user });
|
|
195
|
+
}
|
|
196
|
+
results.push({
|
|
197
|
+
channelId: h.channelId,
|
|
198
|
+
ts: h.ts,
|
|
199
|
+
text: (_f = anchor === null || anchor === void 0 ? void 0 : anchor.text) !== null && _f !== void 0 ? _f : h.text,
|
|
200
|
+
userId: (_g = anchor === null || anchor === void 0 ? void 0 : anchor.user) !== null && _g !== void 0 ? _g : h.userId,
|
|
201
|
+
context: normalizedThreads,
|
|
202
|
+
permalink: yield getPermalink(client, h.channelId, h.ts),
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch (_h) {
|
|
207
|
+
results.push({
|
|
208
|
+
channelId: h.channelId,
|
|
209
|
+
ts: h.ts,
|
|
210
|
+
text: h.text,
|
|
211
|
+
userId: h.userId,
|
|
212
|
+
permalink: yield getPermalink(client, h.channelId, h.ts),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
results.sort((a, b) => Number(b.ts) - Number(a.ts));
|
|
217
|
+
return { query, results };
|
|
218
|
+
});
|
|
219
|
+
export default searchSlack;
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
10
|
+
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
11
11
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
12
12
|
const addCommentToTicket = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
13
13
|
const { authToken } = authParams;
|
|
@@ -16,6 +16,7 @@ const addCommentToTicket = (_a) => __awaiter(void 0, [_a], void 0, function* ({
|
|
|
16
16
|
if (!authToken) {
|
|
17
17
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
18
18
|
}
|
|
19
|
+
const axiosClient = createAxiosClientWithRetries({ timeout: 20000, retryCount: 5 });
|
|
19
20
|
try {
|
|
20
21
|
const response = yield axiosClient.request({
|
|
21
22
|
url: url,
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
10
|
+
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
11
11
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
12
12
|
const updateTicketStatus = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
13
13
|
const { authToken } = authParams;
|
|
@@ -16,6 +16,7 @@ const updateTicketStatus = (_a) => __awaiter(void 0, [_a], void 0, function* ({
|
|
|
16
16
|
if (!authToken) {
|
|
17
17
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
18
18
|
}
|
|
19
|
+
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
19
20
|
yield axiosClient.request({
|
|
20
21
|
url: url,
|
|
21
22
|
method: "PUT",
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
10
|
+
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
11
11
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
12
12
|
const createZendeskTicket = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
13
13
|
const { authToken } = authParams;
|
|
@@ -24,6 +24,7 @@ const createZendeskTicket = (_a) => __awaiter(void 0, [_a], void 0, function* ({
|
|
|
24
24
|
if (!authToken) {
|
|
25
25
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
26
26
|
}
|
|
27
|
+
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
27
28
|
const response = yield axiosClient.post(url, payload, {
|
|
28
29
|
headers: {
|
|
29
30
|
"Content-Type": "application/json",
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
10
|
+
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
11
11
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
12
12
|
const getZendeskTicketDetails = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
13
13
|
const { authToken } = authParams;
|
|
@@ -16,7 +16,8 @@ const getZendeskTicketDetails = (_a) => __awaiter(void 0, [_a], void 0, function
|
|
|
16
16
|
if (!authToken) {
|
|
17
17
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
18
18
|
}
|
|
19
|
-
const
|
|
19
|
+
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
20
|
+
const response = yield axiosClient.request({
|
|
20
21
|
url: url,
|
|
21
22
|
method: "GET",
|
|
22
23
|
headers: {
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
10
|
+
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
11
11
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
12
12
|
const listZendeskTickets = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
13
13
|
const { authToken } = authParams;
|
|
@@ -21,6 +21,7 @@ const listZendeskTickets = (_a) => __awaiter(void 0, [_a], void 0, function* ({
|
|
|
21
21
|
if (!authToken) {
|
|
22
22
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
23
23
|
}
|
|
24
|
+
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
24
25
|
// Add query parameters for filtering
|
|
25
26
|
const queryParams = new URLSearchParams();
|
|
26
27
|
queryParams.append("created_after", formattedDate);
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
10
|
+
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
11
11
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
12
12
|
const searchZendeskByQuery = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
13
13
|
const { authToken } = authParams;
|
|
@@ -17,6 +17,7 @@ const searchZendeskByQuery = (_a) => __awaiter(void 0, [_a], void 0, function* (
|
|
|
17
17
|
if (!authToken) {
|
|
18
18
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
19
19
|
}
|
|
20
|
+
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
20
21
|
// Build search query parameters
|
|
21
22
|
const queryParams = new URLSearchParams();
|
|
22
23
|
queryParams.append("query", `type:${objectType} ${query}`);
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
10
|
+
import { createAxiosClientWithRetries } from "../../util/axiosClient.js";
|
|
11
11
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
12
12
|
const updateTicketStatus = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
13
13
|
const { authToken } = authParams;
|
|
@@ -16,6 +16,7 @@ const updateTicketStatus = (_a) => __awaiter(void 0, [_a], void 0, function* ({
|
|
|
16
16
|
if (!authToken) {
|
|
17
17
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
18
18
|
}
|
|
19
|
+
const axiosClient = createAxiosClientWithRetries({ timeout: 10000, retryCount: 4 });
|
|
19
20
|
yield axiosClient.request({
|
|
20
21
|
url: url,
|
|
21
22
|
method: "PUT",
|
|
@@ -7,4 +7,7 @@ export declare class ApiError extends Error {
|
|
|
7
7
|
export declare function isAxiosTimeoutError(error: unknown): boolean;
|
|
8
8
|
export declare const axiosClient: AxiosInstance;
|
|
9
9
|
export declare function createAxiosClientWithTimeout(timeout: number): AxiosInstance;
|
|
10
|
-
export declare
|
|
10
|
+
export declare function createAxiosClientWithRetries(args: {
|
|
11
|
+
timeout: number;
|
|
12
|
+
retryCount: number;
|
|
13
|
+
}): AxiosInstance;
|
|
@@ -45,10 +45,11 @@ export const axiosClient = createAxiosClient();
|
|
|
45
45
|
export function createAxiosClientWithTimeout(timeout) {
|
|
46
46
|
return createAxiosClient(timeout);
|
|
47
47
|
}
|
|
48
|
-
function createAxiosClientWithRetries(
|
|
48
|
+
export function createAxiosClientWithRetries(args) {
|
|
49
|
+
const { timeout, retryCount } = args;
|
|
49
50
|
const instance = createAxiosClient(timeout);
|
|
50
51
|
axiosRetry(instance, {
|
|
51
|
-
retries:
|
|
52
|
+
retries: retryCount,
|
|
52
53
|
retryDelay: axiosRetry.exponentialDelay,
|
|
53
54
|
retryCondition: error => {
|
|
54
55
|
if (axiosRetry.isNetworkError(error) || !error.response)
|
|
@@ -56,7 +57,10 @@ function createAxiosClientWithRetries(timeout) {
|
|
|
56
57
|
const status = error.response.status;
|
|
57
58
|
return status === 408 || status === 429 || status >= 500;
|
|
58
59
|
},
|
|
60
|
+
onRetry: (retryCount, error) => {
|
|
61
|
+
var _a, _b;
|
|
62
|
+
console.log(`Retry ${retryCount}: ${((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) || "Network Error"} - ${(_b = error.config) === null || _b === void 0 ? void 0 : _b.url}`);
|
|
63
|
+
},
|
|
59
64
|
});
|
|
60
65
|
return instance;
|
|
61
66
|
}
|
|
62
|
-
export const axiosClientWithRetries = createAxiosClientWithRetries();
|
package/package.json
CHANGED