@credal/actions 0.2.145 → 0.2.147
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/README.md +1 -1
- package/dist/actions/autogen/templates.js +22 -1
- package/dist/actions/autogen/types.d.ts +43 -0
- package/dist/actions/autogen/types.js +9 -1
- package/dist/actions/groups.d.ts +6 -0
- package/dist/actions/groups.js +261 -0
- package/dist/actions/providers/confluence/updatePage.d.ts +3 -0
- package/dist/actions/providers/confluence/updatePage.js +47 -0
- package/dist/actions/providers/credal/callCopilot.d.ts +3 -0
- package/dist/actions/providers/credal/callCopilot.js +36 -0
- package/dist/actions/providers/gitlab/getFileContent.js +4 -1
- package/dist/actions/providers/gitlab/searchGroup.js +1 -27
- package/dist/actions/providers/gitlab/utils.d.ts +3 -0
- package/dist/actions/providers/gitlab/utils.js +37 -0
- package/dist/actions/providers/jamf/types.d.ts +8 -0
- package/dist/actions/providers/jamf/types.js +7 -0
- package/dist/actions/providers/math/index.d.ts +1 -0
- package/dist/actions/providers/math/index.js +37 -0
- package/dist/actions/providers/slack/archiveChannel.d.ts +3 -0
- package/dist/actions/providers/slack/archiveChannel.js +42 -0
- package/dist/actions/providers/slack/index.d.ts +1 -0
- package/dist/actions/providers/slack/index.js +37 -0
- package/dist/actions/providers/slack/listConversations.d.ts +3 -0
- package/dist/actions/providers/slack/listConversations.js +41 -0
- package/dist/actions/providers/slackUser/searchSlack.d.ts +6 -1
- package/dist/actions/providers/slackUser/searchSlack.js +183 -242
- package/package.json +1 -1
- package/dist/actions/providers/jira/updateServiceDeskRequest.d.ts +0 -3
- package/dist/actions/providers/jira/updateServiceDeskRequest.js +0 -72
|
@@ -10,12 +10,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { WebClient } from "@slack/web-api";
|
|
11
11
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
12
12
|
import pLimit from "p-limit";
|
|
13
|
+
/* ===================== Constants ===================== */
|
|
13
14
|
const HIT_ENRICH_POOL = 5;
|
|
14
15
|
const limitHit = pLimit(HIT_ENRICH_POOL);
|
|
15
16
|
const MENTION_USER_RE = /<@([UW][A-Z0-9]+)(?:\|[^>]+)?>/g;
|
|
16
17
|
const MENTION_CHANNEL_RE = /<#(C[A-Z0-9]+)(?:\|[^>]+)?>/g;
|
|
17
18
|
const SPECIAL_RE = /<!(channel|here|everyone)>/g;
|
|
18
|
-
const SUBTEAM_RE = /<!subteam\^([A-Z0-9]+)(?:\|[^>]+)?>/g;
|
|
19
|
+
const SUBTEAM_RE = /<!subteam\^([A-Z0-9]+)(?:\|[^>]+)?>/g;
|
|
20
|
+
/* ===================== Cache ===================== */
|
|
19
21
|
class SlackUserCache {
|
|
20
22
|
constructor(client) {
|
|
21
23
|
this.client = client;
|
|
@@ -25,9 +27,9 @@ class SlackUserCache {
|
|
|
25
27
|
get(id) {
|
|
26
28
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27
29
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
28
|
-
const
|
|
29
|
-
if (
|
|
30
|
-
return
|
|
30
|
+
const cached = this.cache.get(id);
|
|
31
|
+
if (cached)
|
|
32
|
+
return cached;
|
|
31
33
|
const res = yield this.client.users.info({ user: id });
|
|
32
34
|
const u = {
|
|
33
35
|
name: (_g = (_e = (_c = (_b = (_a = res.user) === null || _a === void 0 ? void 0 : _a.profile) === null || _b === void 0 ? void 0 : _b.display_name) !== null && _c !== void 0 ? _c : (_d = res.user) === null || _d === void 0 ? void 0 : _d.real_name) !== null && _e !== void 0 ? _e : (_f = res.user) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : "",
|
|
@@ -54,7 +56,7 @@ function normalizeChannelOperand(ch) {
|
|
|
54
56
|
function fmtDaysAgo(n) {
|
|
55
57
|
const d = new Date();
|
|
56
58
|
d.setDate(d.getDate() - n);
|
|
57
|
-
return d.toISOString().slice(0, 10);
|
|
59
|
+
return d.toISOString().slice(0, 10);
|
|
58
60
|
}
|
|
59
61
|
function timeFilter(range) {
|
|
60
62
|
switch (range) {
|
|
@@ -70,45 +72,44 @@ function timeFilter(range) {
|
|
|
70
72
|
return "";
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
|
-
function lookupUserIdsByEmail(client, emails,
|
|
75
|
+
function lookupUserIdsByEmail(client, emails, cache) {
|
|
74
76
|
return __awaiter(this, void 0, void 0, function* () {
|
|
75
77
|
const ids = [];
|
|
76
|
-
const
|
|
77
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
78
|
+
const settled = yield Promise.allSettled(emails.map((raw) => __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
78
80
|
const email = raw.trim();
|
|
79
81
|
if (!email)
|
|
80
82
|
return null;
|
|
81
83
|
const res = yield client.users.lookupByEmail({ email });
|
|
82
84
|
const id = (_a = res.user) === null || _a === void 0 ? void 0 : _a.id;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
slackUserCache.set(id, u);
|
|
85
|
+
if (id && res.user) {
|
|
86
|
+
cache.set(id, {
|
|
87
|
+
name: (_e = (_d = (_c = (_b = res.user.profile) === null || _b === void 0 ? void 0 : _b.display_name) !== null && _c !== void 0 ? _c : res.user.real_name) !== null && _d !== void 0 ? _d : res.user.name) !== null && _e !== void 0 ? _e : "",
|
|
88
|
+
email: (_g = (_f = res.user.profile) === null || _f === void 0 ? void 0 : _f.email) !== null && _g !== void 0 ? _g : "",
|
|
89
|
+
});
|
|
89
90
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return null;
|
|
93
|
-
}));
|
|
94
|
-
const settled = yield Promise.allSettled(tasks);
|
|
91
|
+
return id !== null && id !== void 0 ? id : null;
|
|
92
|
+
})));
|
|
95
93
|
for (const r of settled)
|
|
96
94
|
if (r.status === "fulfilled" && r.value)
|
|
97
95
|
ids.push(r.value);
|
|
98
96
|
return ids;
|
|
99
97
|
});
|
|
100
98
|
}
|
|
101
|
-
function
|
|
99
|
+
function tryGetMPIMName(client, userIds) {
|
|
102
100
|
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
-
var _a, _b;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
101
|
+
var _a, _b, _c;
|
|
102
|
+
try {
|
|
103
|
+
const res = yield client.conversations.open({ users: userIds.join(",") });
|
|
104
|
+
const id = (_a = res.channel) === null || _a === void 0 ? void 0 : _a.id;
|
|
105
|
+
if (!id)
|
|
106
|
+
return null;
|
|
107
|
+
const info = yield client.conversations.info({ channel: id });
|
|
108
|
+
return (_c = (_b = info.channel) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : null;
|
|
109
|
+
}
|
|
110
|
+
catch (_d) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
112
113
|
});
|
|
113
114
|
}
|
|
114
115
|
function getPermalink(client, channel, ts) {
|
|
@@ -124,23 +125,15 @@ function getPermalink(client, channel, ts) {
|
|
|
124
125
|
}
|
|
125
126
|
function fetchOneMessage(client, channel, ts) {
|
|
126
127
|
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
inclusive: true,
|
|
131
|
-
limit: 1,
|
|
132
|
-
});
|
|
133
|
-
return (r.messages && r.messages[0]) || undefined;
|
|
128
|
+
var _a;
|
|
129
|
+
const r = yield client.conversations.history({ channel, latest: ts, inclusive: true, limit: 1 });
|
|
130
|
+
return (_a = r.messages) === null || _a === void 0 ? void 0 : _a[0];
|
|
134
131
|
});
|
|
135
132
|
}
|
|
136
133
|
function fetchThread(client, channel, threadTs) {
|
|
137
134
|
return __awaiter(this, void 0, void 0, function* () {
|
|
138
135
|
var _a;
|
|
139
|
-
const r = yield client.conversations.replies({
|
|
140
|
-
channel,
|
|
141
|
-
ts: threadTs,
|
|
142
|
-
limit: 50,
|
|
143
|
-
});
|
|
136
|
+
const r = yield client.conversations.replies({ channel, ts: threadTs, limit: 50 });
|
|
144
137
|
return (_a = r.messages) !== null && _a !== void 0 ? _a : [];
|
|
145
138
|
});
|
|
146
139
|
}
|
|
@@ -151,232 +144,180 @@ function fetchContextWindow(client, channel, ts) {
|
|
|
151
144
|
const anchor = yield fetchOneMessage(client, channel, ts);
|
|
152
145
|
if (!anchor)
|
|
153
146
|
return out;
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
latest: ts,
|
|
157
|
-
inclusive: false,
|
|
158
|
-
limit: 4,
|
|
159
|
-
});
|
|
160
|
-
out.push(...((_a = beforeRes.messages) !== null && _a !== void 0 ? _a : []).reverse());
|
|
147
|
+
const before = yield client.conversations.history({ channel, latest: ts, inclusive: false, limit: 4 });
|
|
148
|
+
out.push(...((_a = before.messages) !== null && _a !== void 0 ? _a : []).reverse());
|
|
161
149
|
out.push(anchor);
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
oldest: ts,
|
|
165
|
-
inclusive: false,
|
|
166
|
-
limit: 5,
|
|
167
|
-
});
|
|
168
|
-
out.push(...((_b = afterRes.messages) !== null && _b !== void 0 ? _b : []));
|
|
150
|
+
const after = yield client.conversations.history({ channel, oldest: ts, inclusive: false, limit: 5 });
|
|
151
|
+
out.push(...((_b = after.messages) !== null && _b !== void 0 ? _b : []));
|
|
169
152
|
return out;
|
|
170
153
|
});
|
|
171
154
|
}
|
|
172
|
-
|
|
155
|
+
function hasOverlap(messages, ids, minOverlap) {
|
|
156
|
+
const participants = new Set(messages.map(m => m.user).filter(Boolean));
|
|
157
|
+
const overlap = ids.filter(id => participants.has(id)).length;
|
|
158
|
+
return overlap >= minOverlap;
|
|
159
|
+
}
|
|
160
|
+
function expandSlackEntities(client, cache, raw) {
|
|
161
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
162
|
+
let text = raw;
|
|
163
|
+
// resolve users
|
|
164
|
+
const userIds = new Set();
|
|
165
|
+
for (const m of raw.matchAll(MENTION_USER_RE))
|
|
166
|
+
userIds.add(m[1]);
|
|
167
|
+
const idToUser = {};
|
|
168
|
+
yield Promise.all([...userIds].map((id) => __awaiter(this, void 0, void 0, function* () {
|
|
169
|
+
const u = yield cache.get(id);
|
|
170
|
+
idToUser[id] = { name: u === null || u === void 0 ? void 0 : u.name };
|
|
171
|
+
})));
|
|
172
|
+
text = text.replace(MENTION_USER_RE, (_, id) => { var _a, _b; return `@${(_b = (_a = idToUser[id]) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : id}`; });
|
|
173
|
+
// channels
|
|
174
|
+
text = text.replace(MENTION_CHANNEL_RE, (_, id) => `#${id}`);
|
|
175
|
+
// special mentions
|
|
176
|
+
text = text.replace(SPECIAL_RE, (_, kind) => `@${kind}`);
|
|
177
|
+
// subteams
|
|
178
|
+
text = text.replace(SUBTEAM_RE, (_m, sid) => `@${sid}`);
|
|
179
|
+
// links
|
|
180
|
+
text = text.replace(/<([^>|]+)\|([^>]+)>/g, (_m, _url, label) => label);
|
|
181
|
+
text = text.replace(/<([^>|]+)>/g, (_m, url) => url);
|
|
182
|
+
return text;
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
function searchScoped(input) {
|
|
186
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
187
|
+
var _a, _b;
|
|
188
|
+
const { client, scope, topic, timeRange, limit } = input;
|
|
189
|
+
const parts = [`in:${scope}`];
|
|
190
|
+
if (topic === null || topic === void 0 ? void 0 : topic.trim())
|
|
191
|
+
parts.push(topic.trim());
|
|
192
|
+
const tf = timeFilter(timeRange);
|
|
193
|
+
if (tf)
|
|
194
|
+
parts.push(tf);
|
|
195
|
+
const query = parts.join(" ");
|
|
196
|
+
const searchRes = yield client.search.messages({ query, count: limit, highlight: true });
|
|
197
|
+
return (_b = (_a = searchRes.messages) === null || _a === void 0 ? void 0 : _a.matches) !== null && _b !== void 0 ? _b : [];
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
function searchByTopic(input) {
|
|
201
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
202
|
+
var _a, _b;
|
|
203
|
+
const { client, topic, timeRange, limit } = input;
|
|
204
|
+
const parts = [];
|
|
205
|
+
if (topic === null || topic === void 0 ? void 0 : topic.trim())
|
|
206
|
+
parts.push(topic.trim());
|
|
207
|
+
const tf = timeFilter(timeRange);
|
|
208
|
+
if (tf)
|
|
209
|
+
parts.push(tf);
|
|
210
|
+
const query = parts.join(" ");
|
|
211
|
+
const searchRes = yield client.search.messages({ query, count: limit, highlight: true });
|
|
212
|
+
return (_b = (_a = searchRes.messages) === null || _a === void 0 ? void 0 : _a.matches) !== null && _b !== void 0 ? _b : [];
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function dedupeAndSort(results) {
|
|
216
|
+
const seen = new Set();
|
|
217
|
+
const out = [];
|
|
218
|
+
for (const r of results) {
|
|
219
|
+
const key = `${r.channelId}-${r.ts}`;
|
|
220
|
+
if (!seen.has(key)) {
|
|
221
|
+
seen.add(key);
|
|
222
|
+
out.push(r);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return out.sort((a, b) => Number(b.ts) - Number(a.ts));
|
|
226
|
+
}
|
|
227
|
+
/* ===================== MAIN EXPORT ===================== */
|
|
173
228
|
const searchSlack = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
174
|
-
|
|
175
|
-
if (!authParams.authToken) {
|
|
229
|
+
if (!authParams.authToken)
|
|
176
230
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
177
|
-
}
|
|
178
231
|
const client = new WebClient(authParams.authToken);
|
|
179
|
-
const
|
|
180
|
-
const { emails,
|
|
181
|
-
const parts = [];
|
|
232
|
+
const cache = new SlackUserCache(client);
|
|
233
|
+
const { emails, topic, timeRange, limit = 20, channel } = params;
|
|
182
234
|
const { user_id: myUserId } = yield client.auth.test();
|
|
183
235
|
if (!myUserId)
|
|
184
236
|
throw new Error("Failed to get my user ID.");
|
|
185
|
-
const me = yield
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
parts.push(`in:<@${userIdsWithoutMe[0]}>`);
|
|
237
|
+
const me = myUserId ? yield cache.get(myUserId) : undefined;
|
|
238
|
+
const targetIds = (emails === null || emails === void 0 ? void 0 : emails.length) ? yield lookupUserIdsByEmail(client, emails, cache) : [];
|
|
239
|
+
const filteredTargetIds = targetIds.filter(id => id !== myUserId);
|
|
240
|
+
const allMatches = [];
|
|
241
|
+
// --- Scoped DM/MPIM searches ---
|
|
242
|
+
if (filteredTargetIds.length === 1) {
|
|
243
|
+
allMatches.push(...(yield searchScoped({ client, scope: `<@${filteredTargetIds[0]}>`, topic, timeRange, limit })));
|
|
244
|
+
}
|
|
245
|
+
else if (filteredTargetIds.length >= 2) {
|
|
246
|
+
const mpimName = yield tryGetMPIMName(client, filteredTargetIds);
|
|
247
|
+
if (mpimName) {
|
|
248
|
+
allMatches.push(...(yield searchScoped({ client, scope: mpimName, topic, timeRange, limit })));
|
|
198
249
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
parts.push(`in:${convoName}`);
|
|
250
|
+
for (const id of filteredTargetIds) {
|
|
251
|
+
allMatches.push(...(yield searchScoped({ client, scope: `<@${id}>`, topic, timeRange, limit })));
|
|
202
252
|
}
|
|
203
253
|
}
|
|
204
254
|
else if (channel) {
|
|
205
|
-
|
|
255
|
+
allMatches.push(...(yield searchScoped({ client, scope: normalizeChannelOperand(channel), topic, timeRange, limit })));
|
|
206
256
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
const query = parts.join(" ").trim();
|
|
213
|
-
if (!query)
|
|
214
|
-
throw new Error("No query built — provide emails, channel, or topic.");
|
|
215
|
-
const count = Math.max(1, Math.min(100, limit));
|
|
216
|
-
const searchRes = yield client.search.messages({ query, count, highlight: true });
|
|
217
|
-
const matches = (_c = (_b = searchRes.messages) === null || _b === void 0 ? void 0 : _b.matches) !== null && _c !== void 0 ? _c : [];
|
|
218
|
-
const hitsPromises = matches.slice(0, limit).map((m) => __awaiter(void 0, void 0, void 0, function* () {
|
|
219
|
-
var _a, _b, _c, _d;
|
|
220
|
-
const user = m.user ? yield slackUserCache.get(m.user) : undefined;
|
|
221
|
-
const prettyText = m.text ? yield expandSlackEntities(client, slackUserCache, m.text) : undefined;
|
|
222
|
-
return {
|
|
223
|
-
channelId: ((_a = m.channel) === null || _a === void 0 ? void 0 : _a.id) || ((_b = m.channel) === null || _b === void 0 ? void 0 : _b.name) || "",
|
|
224
|
-
ts: m.ts,
|
|
225
|
-
text: prettyText,
|
|
226
|
-
userEmail: (_c = user === null || user === void 0 ? void 0 : user.email) !== null && _c !== void 0 ? _c : undefined,
|
|
227
|
-
userName: (_d = user === null || user === void 0 ? void 0 : user.name) !== null && _d !== void 0 ? _d : undefined,
|
|
228
|
-
};
|
|
229
|
-
}));
|
|
230
|
-
const hits = yield Promise.all(hitsPromises);
|
|
231
|
-
const tasks = hits.map(h => limitHit(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
257
|
+
// --- Topic-wide search ---
|
|
258
|
+
const topicMatches = topic ? yield searchByTopic({ client, topic, timeRange, limit }) : [];
|
|
259
|
+
allMatches.push(...topicMatches);
|
|
260
|
+
// --- Expand hits with context + filter overlap ---
|
|
261
|
+
const expanded = yield Promise.all(allMatches.map(m => limitHit(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
232
262
|
var _a, _b, _c, _d, _e, _f;
|
|
233
|
-
if (!
|
|
263
|
+
if (!m.ts || !((_a = m.channel) === null || _a === void 0 ? void 0 : _a.id))
|
|
234
264
|
return null;
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
};
|
|
256
|
-
}));
|
|
257
|
-
const context = yield Promise.all(contextPromises);
|
|
258
|
-
const user = anchor.user ? yield slackUserCache.get(anchor.user) : undefined;
|
|
259
|
-
const textResponse = (_a = anchor.text) !== null && _a !== void 0 ? _a : h.text;
|
|
260
|
-
const prettyText = textResponse ? yield expandSlackEntities(client, slackUserCache, textResponse) : undefined;
|
|
261
|
-
return {
|
|
262
|
-
channelId: h.channelId,
|
|
263
|
-
ts: rootTs,
|
|
264
|
-
text: prettyText,
|
|
265
|
-
userEmail: (_b = user === null || user === void 0 ? void 0 : user.email) !== null && _b !== void 0 ? _b : h.userEmail,
|
|
266
|
-
userName: (_c = user === null || user === void 0 ? void 0 : user.name) !== null && _c !== void 0 ? _c : h.userName,
|
|
267
|
-
context,
|
|
268
|
-
permalink,
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
// not a thread: fetch context window + permalink concurrently
|
|
273
|
-
const [ctx, permalink] = yield Promise.all([
|
|
274
|
-
fetchContextWindow(client, h.channelId, h.ts),
|
|
275
|
-
getPermalink(client, h.channelId, h.ts),
|
|
276
|
-
]);
|
|
277
|
-
const contextPromises = ctx
|
|
278
|
-
.filter(t => t.ts)
|
|
279
|
-
.map((t) => __awaiter(void 0, void 0, void 0, function* () {
|
|
280
|
-
var _a, _b;
|
|
281
|
-
const user = t.user ? yield slackUserCache.get(t.user) : undefined;
|
|
282
|
-
const prettyText = t.text ? yield expandSlackEntities(client, slackUserCache, t.text) : undefined;
|
|
283
|
-
return {
|
|
284
|
-
ts: t.ts,
|
|
285
|
-
text: prettyText,
|
|
286
|
-
userEmail: (_a = user === null || user === void 0 ? void 0 : user.email) !== null && _a !== void 0 ? _a : undefined,
|
|
287
|
-
userName: (_b = user === null || user === void 0 ? void 0 : user.name) !== null && _b !== void 0 ? _b : undefined,
|
|
288
|
-
};
|
|
289
|
-
}));
|
|
290
|
-
const context = yield Promise.all(contextPromises);
|
|
291
|
-
const user = (anchor === null || anchor === void 0 ? void 0 : anchor.user) ? yield slackUserCache.get(anchor.user) : undefined;
|
|
292
|
-
return {
|
|
293
|
-
channelId: h.channelId,
|
|
294
|
-
ts: h.ts,
|
|
295
|
-
text: (_d = anchor === null || anchor === void 0 ? void 0 : anchor.text) !== null && _d !== void 0 ? _d : h.text,
|
|
296
|
-
userEmail: (_e = user === null || user === void 0 ? void 0 : user.email) !== null && _e !== void 0 ? _e : h.userEmail,
|
|
297
|
-
userName: (_f = user === null || user === void 0 ? void 0 : user.name) !== null && _f !== void 0 ? _f : h.userName,
|
|
298
|
-
context,
|
|
299
|
-
permalink,
|
|
300
|
-
};
|
|
301
|
-
}
|
|
265
|
+
const anchor = yield fetchOneMessage(client, m.channel.id, m.ts);
|
|
266
|
+
const rootTs = (anchor === null || anchor === void 0 ? void 0 : anchor.thread_ts) || m.ts;
|
|
267
|
+
let members = [];
|
|
268
|
+
// Check convo type (DM, MPIM, channel)
|
|
269
|
+
const convoInfo = yield client.conversations.info({ channel: m.channel.id });
|
|
270
|
+
const isIm = (_b = convoInfo.channel) === null || _b === void 0 ? void 0 : _b.is_im;
|
|
271
|
+
const isMpim = (_c = convoInfo.channel) === null || _c === void 0 ? void 0 : _c.is_mpim;
|
|
272
|
+
const [contextMsgs, permalink] = (anchor === null || anchor === void 0 ? void 0 : anchor.thread_ts)
|
|
273
|
+
? [yield fetchThread(client, m.channel.id, rootTs), yield getPermalink(client, m.channel.id, rootTs)]
|
|
274
|
+
: [yield fetchContextWindow(client, m.channel.id, m.ts), yield getPermalink(client, m.channel.id, m.ts)];
|
|
275
|
+
let passesFilter = false;
|
|
276
|
+
if (isIm || isMpim) {
|
|
277
|
+
// DM/MPIM: use members, not authorship
|
|
278
|
+
const membersRes = (_d = (yield client.conversations.members({ channel: m.channel.id })).members) !== null && _d !== void 0 ? _d : [];
|
|
279
|
+
members = yield Promise.all(membersRes.map((uid) => __awaiter(void 0, void 0, void 0, function* () {
|
|
280
|
+
const u = yield cache.get(uid);
|
|
281
|
+
return { userId: uid, userEmail: u === null || u === void 0 ? void 0 : u.email, userName: u === null || u === void 0 ? void 0 : u.name };
|
|
282
|
+
})));
|
|
283
|
+
const overlap = filteredTargetIds.filter(id => membersRes.includes(id)).length;
|
|
284
|
+
passesFilter = overlap >= 1;
|
|
302
285
|
}
|
|
303
|
-
|
|
304
|
-
//
|
|
305
|
-
|
|
306
|
-
channelId: h.channelId,
|
|
307
|
-
ts: h.ts,
|
|
308
|
-
text: h.text ? yield expandSlackEntities(client, slackUserCache, h.text) : undefined,
|
|
309
|
-
userEmail: h.userEmail,
|
|
310
|
-
userName: h.userName,
|
|
311
|
-
permalink: yield getPermalink(client, h.channelId, h.ts),
|
|
312
|
-
};
|
|
286
|
+
else {
|
|
287
|
+
// Channel: use authorship
|
|
288
|
+
passesFilter = hasOverlap(contextMsgs, filteredTargetIds, 1);
|
|
313
289
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
290
|
+
if (filteredTargetIds.length && !passesFilter)
|
|
291
|
+
return null;
|
|
292
|
+
const context = yield Promise.all(contextMsgs.map((t) => __awaiter(void 0, void 0, void 0, function* () {
|
|
293
|
+
var _a, _b;
|
|
294
|
+
return ({
|
|
295
|
+
ts: t.ts,
|
|
296
|
+
text: t.text ? yield expandSlackEntities(client, cache, t.text) : undefined,
|
|
297
|
+
userEmail: t.user ? (_a = (yield cache.get(t.user))) === null || _a === void 0 ? void 0 : _a.email : undefined,
|
|
298
|
+
userName: t.user ? (_b = (yield cache.get(t.user))) === null || _b === void 0 ? void 0 : _b.name : undefined,
|
|
299
|
+
});
|
|
300
|
+
})));
|
|
301
|
+
return {
|
|
302
|
+
channelId: m.channel.id,
|
|
303
|
+
ts: rootTs,
|
|
304
|
+
text: (anchor === null || anchor === void 0 ? void 0 : anchor.text) ? yield expandSlackEntities(client, cache, anchor.text) : undefined,
|
|
305
|
+
userEmail: (anchor === null || anchor === void 0 ? void 0 : anchor.user) ? (_e = (yield cache.get(anchor.user))) === null || _e === void 0 ? void 0 : _e.email : undefined,
|
|
306
|
+
userName: (anchor === null || anchor === void 0 ? void 0 : anchor.user) ? (_f = (yield cache.get(anchor.user))) === null || _f === void 0 ? void 0 : _f.name : undefined,
|
|
307
|
+
context,
|
|
308
|
+
permalink,
|
|
309
|
+
members,
|
|
310
|
+
};
|
|
311
|
+
}))));
|
|
312
|
+
const results = dedupeAndSort(expanded.filter(h => h !== null));
|
|
321
313
|
return {
|
|
322
|
-
query,
|
|
314
|
+
query: topic !== null && topic !== void 0 ? topic : "",
|
|
323
315
|
results: results.map(r => ({
|
|
324
316
|
name: r.text || "Untitled",
|
|
325
317
|
url: r.permalink || "",
|
|
326
318
|
contents: r,
|
|
327
319
|
})),
|
|
328
|
-
currentUser,
|
|
320
|
+
currentUser: { userId: myUserId, userName: me === null || me === void 0 ? void 0 : me.name, userEmail: me === null || me === void 0 ? void 0 : me.email },
|
|
329
321
|
};
|
|
330
322
|
});
|
|
331
|
-
function expandSlackEntities(client_1, cache_1, raw_1) {
|
|
332
|
-
return __awaiter(this, arguments, void 0, function* (client, cache, raw, { includeEmail = false } = {}) {
|
|
333
|
-
let text = raw;
|
|
334
|
-
// 1) Users: <@U12345> -> @Name (or @Name <email>)
|
|
335
|
-
const userIds = new Set();
|
|
336
|
-
for (const m of raw.matchAll(MENTION_USER_RE))
|
|
337
|
-
userIds.add(m[1]);
|
|
338
|
-
const idToUser = {};
|
|
339
|
-
yield Promise.all([...userIds].map((id) => __awaiter(this, void 0, void 0, function* () {
|
|
340
|
-
try {
|
|
341
|
-
const u = yield cache.get(id);
|
|
342
|
-
idToUser[id] = { name: u === null || u === void 0 ? void 0 : u.name, email: u === null || u === void 0 ? void 0 : u.email };
|
|
343
|
-
}
|
|
344
|
-
catch (_a) {
|
|
345
|
-
idToUser[id] = {};
|
|
346
|
-
}
|
|
347
|
-
})));
|
|
348
|
-
text = text.replace(MENTION_USER_RE, (_, id) => {
|
|
349
|
-
const u = idToUser[id];
|
|
350
|
-
if (u === null || u === void 0 ? void 0 : u.name) {
|
|
351
|
-
return includeEmail && u.email ? `@${u.name} <${u.email}>` : `@${u.name}`;
|
|
352
|
-
}
|
|
353
|
-
// fallback: keep original token if we can't resolve
|
|
354
|
-
return `@${id}`;
|
|
355
|
-
});
|
|
356
|
-
// 2) Channels: <#C12345|name> -> #name (fallback to #C12345)
|
|
357
|
-
const channelIds = new Set();
|
|
358
|
-
for (const m of raw.matchAll(MENTION_CHANNEL_RE))
|
|
359
|
-
channelIds.add(m[1]);
|
|
360
|
-
const idToChannel = {};
|
|
361
|
-
yield Promise.all([...channelIds].map((id) => __awaiter(this, void 0, void 0, function* () {
|
|
362
|
-
var _a, _b;
|
|
363
|
-
try {
|
|
364
|
-
const info = yield client.conversations.info({ channel: id });
|
|
365
|
-
idToChannel[id] = (_b = (_a = info.channel) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : undefined;
|
|
366
|
-
}
|
|
367
|
-
catch (_c) {
|
|
368
|
-
idToChannel[id] = undefined;
|
|
369
|
-
}
|
|
370
|
-
})));
|
|
371
|
-
text = text.replace(MENTION_CHANNEL_RE, (_, id) => { var _a; return `#${(_a = idToChannel[id]) !== null && _a !== void 0 ? _a : id}`; });
|
|
372
|
-
// 3) Special mentions: <!here>, <!channel>, <!everyone>
|
|
373
|
-
text = text.replace(SPECIAL_RE, (_, kind) => `@${kind}`);
|
|
374
|
-
// 4) User groups: <!subteam^S123|@group> -> @group (fallback to @S123)
|
|
375
|
-
text = text.replace(SUBTEAM_RE, (_m, sid) => `@${sid}`);
|
|
376
|
-
// 5) Slack links: <https://x|label> -> label (or the URL)
|
|
377
|
-
text = text.replace(/<([^>|]+)\|([^>]+)>/g, (_m, _url, label) => label); // keep label
|
|
378
|
-
text = text.replace(/<([^>|]+)>/g, (_m, url) => url); // bare <https://…>
|
|
379
|
-
return text;
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
323
|
export default searchSlack;
|
package/package.json
CHANGED
|
@@ -1,72 +0,0 @@
|
|
|
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 { axiosClient } from "../../util/axiosClient.js";
|
|
11
|
-
const updateServiceDeskRequest = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
12
|
-
const { issueId, requestTypeId, summary, description, priority, customFields } = params;
|
|
13
|
-
const { authToken, cloudId, baseUrl } = authParams;
|
|
14
|
-
if (!cloudId || !authToken) {
|
|
15
|
-
throw new Error("Valid Cloud ID and auth token are required to update service desk request");
|
|
16
|
-
}
|
|
17
|
-
// Use the regular Jira API for updating service desk requests as they are still Jira issues
|
|
18
|
-
const apiUrl = `https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3/issue/${issueId}`;
|
|
19
|
-
const formattedDescription = description
|
|
20
|
-
? {
|
|
21
|
-
type: "doc",
|
|
22
|
-
version: 1,
|
|
23
|
-
content: [
|
|
24
|
-
{
|
|
25
|
-
type: "paragraph",
|
|
26
|
-
content: [
|
|
27
|
-
{
|
|
28
|
-
type: "text",
|
|
29
|
-
text: description,
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
}
|
|
35
|
-
: undefined;
|
|
36
|
-
const payload = {
|
|
37
|
-
fields: Object.assign(Object.assign(Object.assign(Object.assign({}, (summary && { summary })), (formattedDescription && { description: formattedDescription })), (priority && { priority: { name: priority } })), (customFields && Object.assign({}, customFields))),
|
|
38
|
-
};
|
|
39
|
-
try {
|
|
40
|
-
yield axiosClient.put(apiUrl, payload, {
|
|
41
|
-
headers: {
|
|
42
|
-
Authorization: `Bearer ${authToken}`,
|
|
43
|
-
Accept: "application/json",
|
|
44
|
-
"Content-Type": "application/json",
|
|
45
|
-
},
|
|
46
|
-
});
|
|
47
|
-
// Get the updated issue details to return current status and web link
|
|
48
|
-
const getResponse = yield axiosClient.get(apiUrl, {
|
|
49
|
-
headers: {
|
|
50
|
-
Authorization: `Bearer ${authToken}`,
|
|
51
|
-
Accept: "application/json",
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
const issueKey = getResponse.data.key;
|
|
55
|
-
const currentStatus = getResponse.data.fields.status.name;
|
|
56
|
-
const webLink = `${baseUrl}/browse/${issueKey}`;
|
|
57
|
-
return {
|
|
58
|
-
success: true,
|
|
59
|
-
issueKey,
|
|
60
|
-
webLink,
|
|
61
|
-
currentStatus,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
console.error("Error updating service desk request:", error);
|
|
66
|
-
return {
|
|
67
|
-
success: false,
|
|
68
|
-
error: error instanceof Error ? error.message : "Unknown error",
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
export default updateServiceDeskRequest;
|