@credal/actions 0.2.144 → 0.2.146
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/jira/getJiraTicketDetails.js +4 -4
- 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 +182 -250
- 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 : "",
|
|
@@ -45,16 +47,10 @@ class SlackUserCache {
|
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
49
|
/* ===================== Helpers ===================== */
|
|
48
|
-
function normalizeChannelOperand(ch) {
|
|
49
|
-
const s = ch.trim();
|
|
50
|
-
if (/^[CGD][A-Z0-9]/i.test(s))
|
|
51
|
-
return s;
|
|
52
|
-
return s.replace(/^#/, "");
|
|
53
|
-
}
|
|
54
50
|
function fmtDaysAgo(n) {
|
|
55
51
|
const d = new Date();
|
|
56
52
|
d.setDate(d.getDate() - n);
|
|
57
|
-
return d.toISOString().slice(0, 10);
|
|
53
|
+
return d.toISOString().slice(0, 10);
|
|
58
54
|
}
|
|
59
55
|
function timeFilter(range) {
|
|
60
56
|
switch (range) {
|
|
@@ -70,45 +66,44 @@ function timeFilter(range) {
|
|
|
70
66
|
return "";
|
|
71
67
|
}
|
|
72
68
|
}
|
|
73
|
-
function lookupUserIdsByEmail(client, emails,
|
|
69
|
+
function lookupUserIdsByEmail(client, emails, cache) {
|
|
74
70
|
return __awaiter(this, void 0, void 0, function* () {
|
|
75
71
|
const ids = [];
|
|
76
|
-
const
|
|
77
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
72
|
+
const settled = yield Promise.allSettled(emails.map((raw) => __awaiter(this, void 0, void 0, function* () {
|
|
73
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
78
74
|
const email = raw.trim();
|
|
79
75
|
if (!email)
|
|
80
76
|
return null;
|
|
81
77
|
const res = yield client.users.lookupByEmail({ email });
|
|
82
78
|
const id = (_a = res.user) === null || _a === void 0 ? void 0 : _a.id;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
slackUserCache.set(id, u);
|
|
79
|
+
if (id && res.user) {
|
|
80
|
+
cache.set(id, {
|
|
81
|
+
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 : "",
|
|
82
|
+
email: (_g = (_f = res.user.profile) === null || _f === void 0 ? void 0 : _f.email) !== null && _g !== void 0 ? _g : "",
|
|
83
|
+
});
|
|
89
84
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return null;
|
|
93
|
-
}));
|
|
94
|
-
const settled = yield Promise.allSettled(tasks);
|
|
85
|
+
return id !== null && id !== void 0 ? id : null;
|
|
86
|
+
})));
|
|
95
87
|
for (const r of settled)
|
|
96
88
|
if (r.status === "fulfilled" && r.value)
|
|
97
89
|
ids.push(r.value);
|
|
98
90
|
return ids;
|
|
99
91
|
});
|
|
100
92
|
}
|
|
101
|
-
function
|
|
93
|
+
function tryGetMPIMName(client, userIds) {
|
|
102
94
|
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
-
var _a, _b;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
95
|
+
var _a, _b, _c;
|
|
96
|
+
try {
|
|
97
|
+
const res = yield client.conversations.open({ users: userIds.join(",") });
|
|
98
|
+
const id = (_a = res.channel) === null || _a === void 0 ? void 0 : _a.id;
|
|
99
|
+
if (!id)
|
|
100
|
+
return null;
|
|
101
|
+
const info = yield client.conversations.info({ channel: id });
|
|
102
|
+
return (_c = (_b = info.channel) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : null;
|
|
103
|
+
}
|
|
104
|
+
catch (_d) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
112
107
|
});
|
|
113
108
|
}
|
|
114
109
|
function getPermalink(client, channel, ts) {
|
|
@@ -124,23 +119,15 @@ function getPermalink(client, channel, ts) {
|
|
|
124
119
|
}
|
|
125
120
|
function fetchOneMessage(client, channel, ts) {
|
|
126
121
|
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;
|
|
122
|
+
var _a;
|
|
123
|
+
const r = yield client.conversations.history({ channel, latest: ts, inclusive: true, limit: 1 });
|
|
124
|
+
return (_a = r.messages) === null || _a === void 0 ? void 0 : _a[0];
|
|
134
125
|
});
|
|
135
126
|
}
|
|
136
127
|
function fetchThread(client, channel, threadTs) {
|
|
137
128
|
return __awaiter(this, void 0, void 0, function* () {
|
|
138
129
|
var _a;
|
|
139
|
-
const r = yield client.conversations.replies({
|
|
140
|
-
channel,
|
|
141
|
-
ts: threadTs,
|
|
142
|
-
limit: 50,
|
|
143
|
-
});
|
|
130
|
+
const r = yield client.conversations.replies({ channel, ts: threadTs, limit: 50 });
|
|
144
131
|
return (_a = r.messages) !== null && _a !== void 0 ? _a : [];
|
|
145
132
|
});
|
|
146
133
|
}
|
|
@@ -151,232 +138,177 @@ function fetchContextWindow(client, channel, ts) {
|
|
|
151
138
|
const anchor = yield fetchOneMessage(client, channel, ts);
|
|
152
139
|
if (!anchor)
|
|
153
140
|
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());
|
|
141
|
+
const before = yield client.conversations.history({ channel, latest: ts, inclusive: false, limit: 4 });
|
|
142
|
+
out.push(...((_a = before.messages) !== null && _a !== void 0 ? _a : []).reverse());
|
|
161
143
|
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 : []));
|
|
144
|
+
const after = yield client.conversations.history({ channel, oldest: ts, inclusive: false, limit: 5 });
|
|
145
|
+
out.push(...((_b = after.messages) !== null && _b !== void 0 ? _b : []));
|
|
169
146
|
return out;
|
|
170
147
|
});
|
|
171
148
|
}
|
|
172
|
-
|
|
149
|
+
function hasOverlap(messages, ids, minOverlap) {
|
|
150
|
+
const participants = new Set(messages.map(m => m.user).filter(Boolean));
|
|
151
|
+
const overlap = ids.filter(id => participants.has(id)).length;
|
|
152
|
+
return overlap >= minOverlap;
|
|
153
|
+
}
|
|
154
|
+
function expandSlackEntities(client, cache, raw) {
|
|
155
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
156
|
+
let text = raw;
|
|
157
|
+
// resolve users
|
|
158
|
+
const userIds = new Set();
|
|
159
|
+
for (const m of raw.matchAll(MENTION_USER_RE))
|
|
160
|
+
userIds.add(m[1]);
|
|
161
|
+
const idToUser = {};
|
|
162
|
+
yield Promise.all([...userIds].map((id) => __awaiter(this, void 0, void 0, function* () {
|
|
163
|
+
const u = yield cache.get(id);
|
|
164
|
+
idToUser[id] = { name: u === null || u === void 0 ? void 0 : u.name };
|
|
165
|
+
})));
|
|
166
|
+
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}`; });
|
|
167
|
+
// channels
|
|
168
|
+
text = text.replace(MENTION_CHANNEL_RE, (_, id) => `#${id}`);
|
|
169
|
+
// special mentions
|
|
170
|
+
text = text.replace(SPECIAL_RE, (_, kind) => `@${kind}`);
|
|
171
|
+
// subteams
|
|
172
|
+
text = text.replace(SUBTEAM_RE, (_m, sid) => `@${sid}`);
|
|
173
|
+
// links
|
|
174
|
+
text = text.replace(/<([^>|]+)\|([^>]+)>/g, (_m, _url, label) => label);
|
|
175
|
+
text = text.replace(/<([^>|]+)>/g, (_m, url) => url);
|
|
176
|
+
return text;
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
function searchScoped(input) {
|
|
180
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
181
|
+
var _a, _b;
|
|
182
|
+
const { client, scope, topic, timeRange, limit } = input;
|
|
183
|
+
const parts = [`in:${scope}`];
|
|
184
|
+
if (topic === null || topic === void 0 ? void 0 : topic.trim())
|
|
185
|
+
parts.push(topic.trim());
|
|
186
|
+
const tf = timeFilter(timeRange);
|
|
187
|
+
if (tf)
|
|
188
|
+
parts.push(tf);
|
|
189
|
+
const query = parts.join(" ");
|
|
190
|
+
const searchRes = yield client.search.messages({ query, count: limit, highlight: true });
|
|
191
|
+
return (_b = (_a = searchRes.messages) === null || _a === void 0 ? void 0 : _a.matches) !== null && _b !== void 0 ? _b : [];
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
function searchByTopic(input) {
|
|
195
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
196
|
+
var _a, _b;
|
|
197
|
+
const { client, topic, timeRange, limit } = input;
|
|
198
|
+
const parts = [];
|
|
199
|
+
if (topic === null || topic === void 0 ? void 0 : topic.trim())
|
|
200
|
+
parts.push(topic.trim());
|
|
201
|
+
const tf = timeFilter(timeRange);
|
|
202
|
+
if (tf)
|
|
203
|
+
parts.push(tf);
|
|
204
|
+
const query = parts.join(" ");
|
|
205
|
+
const searchRes = yield client.search.messages({ query, count: limit, highlight: true });
|
|
206
|
+
return (_b = (_a = searchRes.messages) === null || _a === void 0 ? void 0 : _a.matches) !== null && _b !== void 0 ? _b : [];
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
function dedupeAndSort(results) {
|
|
210
|
+
const seen = new Set();
|
|
211
|
+
const out = [];
|
|
212
|
+
for (const r of results) {
|
|
213
|
+
const key = `${r.channelId}-${r.ts}`;
|
|
214
|
+
if (!seen.has(key)) {
|
|
215
|
+
seen.add(key);
|
|
216
|
+
out.push(r);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return out.sort((a, b) => Number(b.ts) - Number(a.ts));
|
|
220
|
+
}
|
|
221
|
+
/* ===================== MAIN EXPORT ===================== */
|
|
173
222
|
const searchSlack = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
|
|
174
|
-
|
|
175
|
-
if (!authParams.authToken) {
|
|
223
|
+
if (!authParams.authToken)
|
|
176
224
|
throw new Error(MISSING_AUTH_TOKEN);
|
|
177
|
-
}
|
|
178
225
|
const client = new WebClient(authParams.authToken);
|
|
179
|
-
const
|
|
180
|
-
const { emails,
|
|
181
|
-
const parts = [];
|
|
226
|
+
const cache = new SlackUserCache(client);
|
|
227
|
+
const { emails, topic, timeRange, limit = 20 } = params;
|
|
182
228
|
const { user_id: myUserId } = yield client.auth.test();
|
|
183
229
|
if (!myUserId)
|
|
184
230
|
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]}>`);
|
|
231
|
+
const me = myUserId ? yield cache.get(myUserId) : undefined;
|
|
232
|
+
const targetIds = (emails === null || emails === void 0 ? void 0 : emails.length) ? yield lookupUserIdsByEmail(client, emails, cache) : [];
|
|
233
|
+
const filteredTargetIds = targetIds.filter(id => id !== myUserId);
|
|
234
|
+
const allMatches = [];
|
|
235
|
+
// --- Scoped DM/MPIM searches ---
|
|
236
|
+
if (filteredTargetIds.length === 1) {
|
|
237
|
+
allMatches.push(...(yield searchScoped({ client, scope: `<@${filteredTargetIds[0]}>`, topic, timeRange, limit })));
|
|
238
|
+
}
|
|
239
|
+
else if (filteredTargetIds.length >= 2) {
|
|
240
|
+
const mpimName = yield tryGetMPIMName(client, filteredTargetIds);
|
|
241
|
+
if (mpimName) {
|
|
242
|
+
allMatches.push(...(yield searchScoped({ client, scope: mpimName, topic, timeRange, limit })));
|
|
198
243
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
parts.push(`in:${convoName}`);
|
|
244
|
+
for (const id of filteredTargetIds) {
|
|
245
|
+
allMatches.push(...(yield searchScoped({ client, scope: `<@${id}>`, topic, timeRange, limit })));
|
|
202
246
|
}
|
|
203
247
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const tf = timeFilter(timeRange);
|
|
210
|
-
if (tf)
|
|
211
|
-
parts.push(tf);
|
|
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* () {
|
|
248
|
+
// --- Topic-wide search ---
|
|
249
|
+
const topicMatches = yield searchByTopic({ client, topic, timeRange, limit });
|
|
250
|
+
allMatches.push(...topicMatches);
|
|
251
|
+
// --- Expand hits with context + filter overlap ---
|
|
252
|
+
const expanded = yield Promise.all(allMatches.map(m => limitHit(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
232
253
|
var _a, _b, _c, _d, _e, _f;
|
|
233
|
-
if (!
|
|
254
|
+
if (!m.ts || !((_a = m.channel) === null || _a === void 0 ? void 0 : _a.id))
|
|
234
255
|
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
|
-
}
|
|
256
|
+
const anchor = yield fetchOneMessage(client, m.channel.id, m.ts);
|
|
257
|
+
const rootTs = (anchor === null || anchor === void 0 ? void 0 : anchor.thread_ts) || m.ts;
|
|
258
|
+
let members = [];
|
|
259
|
+
// Check convo type (DM, MPIM, channel)
|
|
260
|
+
const convoInfo = yield client.conversations.info({ channel: m.channel.id });
|
|
261
|
+
const isIm = (_b = convoInfo.channel) === null || _b === void 0 ? void 0 : _b.is_im;
|
|
262
|
+
const isMpim = (_c = convoInfo.channel) === null || _c === void 0 ? void 0 : _c.is_mpim;
|
|
263
|
+
const [contextMsgs, permalink] = (anchor === null || anchor === void 0 ? void 0 : anchor.thread_ts)
|
|
264
|
+
? [yield fetchThread(client, m.channel.id, rootTs), yield getPermalink(client, m.channel.id, rootTs)]
|
|
265
|
+
: [yield fetchContextWindow(client, m.channel.id, m.ts), yield getPermalink(client, m.channel.id, m.ts)];
|
|
266
|
+
let passesFilter = false;
|
|
267
|
+
if (isIm || isMpim) {
|
|
268
|
+
// DM/MPIM: use members, not authorship
|
|
269
|
+
const membersRes = (_d = (yield client.conversations.members({ channel: m.channel.id })).members) !== null && _d !== void 0 ? _d : [];
|
|
270
|
+
members = yield Promise.all(membersRes.map((uid) => __awaiter(void 0, void 0, void 0, function* () {
|
|
271
|
+
const u = yield cache.get(uid);
|
|
272
|
+
return { userId: uid, userEmail: u === null || u === void 0 ? void 0 : u.email, userName: u === null || u === void 0 ? void 0 : u.name };
|
|
273
|
+
})));
|
|
274
|
+
const overlap = filteredTargetIds.filter(id => membersRes.includes(id)).length;
|
|
275
|
+
passesFilter = overlap >= 1;
|
|
302
276
|
}
|
|
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
|
-
};
|
|
277
|
+
else {
|
|
278
|
+
// Channel: use authorship
|
|
279
|
+
passesFilter = hasOverlap(contextMsgs, filteredTargetIds, 1);
|
|
313
280
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
281
|
+
if (filteredTargetIds.length && !passesFilter)
|
|
282
|
+
return null;
|
|
283
|
+
const context = yield Promise.all(contextMsgs.map((t) => __awaiter(void 0, void 0, void 0, function* () {
|
|
284
|
+
var _a, _b;
|
|
285
|
+
return ({
|
|
286
|
+
ts: t.ts,
|
|
287
|
+
text: t.text ? yield expandSlackEntities(client, cache, t.text) : undefined,
|
|
288
|
+
userEmail: t.user ? (_a = (yield cache.get(t.user))) === null || _a === void 0 ? void 0 : _a.email : undefined,
|
|
289
|
+
userName: t.user ? (_b = (yield cache.get(t.user))) === null || _b === void 0 ? void 0 : _b.name : undefined,
|
|
290
|
+
});
|
|
291
|
+
})));
|
|
292
|
+
return {
|
|
293
|
+
channelId: m.channel.id,
|
|
294
|
+
ts: rootTs,
|
|
295
|
+
text: (anchor === null || anchor === void 0 ? void 0 : anchor.text) ? yield expandSlackEntities(client, cache, anchor.text) : undefined,
|
|
296
|
+
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,
|
|
297
|
+
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,
|
|
298
|
+
context,
|
|
299
|
+
permalink,
|
|
300
|
+
members,
|
|
301
|
+
};
|
|
302
|
+
}))));
|
|
303
|
+
const results = dedupeAndSort(expanded.filter(h => h !== null));
|
|
321
304
|
return {
|
|
322
|
-
query,
|
|
305
|
+
query: topic !== null && topic !== void 0 ? topic : "",
|
|
323
306
|
results: results.map(r => ({
|
|
324
307
|
name: r.text || "Untitled",
|
|
325
308
|
url: r.permalink || "",
|
|
326
309
|
contents: r,
|
|
327
310
|
})),
|
|
328
|
-
currentUser,
|
|
311
|
+
currentUser: { userId: myUserId, userName: me === null || me === void 0 ? void 0 : me.name, userEmail: me === null || me === void 0 ? void 0 : me.email },
|
|
329
312
|
};
|
|
330
313
|
});
|
|
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
314
|
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;
|