@credal/actions 0.2.149 → 0.2.151
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.
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { type KnownBlock } from "@slack/web-api";
|
|
1
2
|
import { type slackUserSearchSlackFunction } from "../../autogen/types.js";
|
|
3
|
+
import type { Attachment } from "@slack/web-api/dist/types/response/ChannelsHistoryResponse.js";
|
|
2
4
|
export type TimeRange = "latest" | "today" | "yesterday" | "last_7d" | "last_30d" | "all";
|
|
3
5
|
export interface SlackSearchMessage {
|
|
4
6
|
channelId: string;
|
|
@@ -14,10 +16,23 @@ export interface SlackSearchMessage {
|
|
|
14
16
|
userName?: string;
|
|
15
17
|
}>;
|
|
16
18
|
members?: Array<{
|
|
17
|
-
userId: string
|
|
18
|
-
userEmail
|
|
19
|
-
userName
|
|
19
|
+
userId: string;
|
|
20
|
+
userEmail?: string;
|
|
21
|
+
userName?: string;
|
|
20
22
|
}>;
|
|
21
23
|
}
|
|
24
|
+
interface SlackMessage {
|
|
25
|
+
ts?: string;
|
|
26
|
+
text?: string;
|
|
27
|
+
user?: string;
|
|
28
|
+
username?: string;
|
|
29
|
+
thread_ts?: string;
|
|
30
|
+
blocks?: KnownBlock[];
|
|
31
|
+
attachments?: Attachment[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Extracts all visible text from a Slack message
|
|
35
|
+
*/
|
|
36
|
+
export declare function extractMessageText(m: SlackMessage | undefined): string | undefined;
|
|
22
37
|
declare const searchSlack: slackUserSearchSlackFunction;
|
|
23
38
|
export default searchSlack;
|
|
@@ -11,7 +11,7 @@ import { WebClient } from "@slack/web-api";
|
|
|
11
11
|
import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
|
|
12
12
|
import pLimit from "p-limit";
|
|
13
13
|
/* ===================== Constants ===================== */
|
|
14
|
-
const HIT_ENRICH_POOL =
|
|
14
|
+
const HIT_ENRICH_POOL = 2; // keep concurrency conservative to avoid 429s
|
|
15
15
|
const limitHit = pLimit(HIT_ENRICH_POOL);
|
|
16
16
|
const MENTION_USER_RE = /<@([UW][A-Z0-9]+)(?:\|[^>]+)?>/g;
|
|
17
17
|
const MENTION_CHANNEL_RE = /<#(C[A-Z0-9]+)(?:\|[^>]+)?>/g;
|
|
@@ -22,36 +22,39 @@ class SlackUserCache {
|
|
|
22
22
|
constructor(client) {
|
|
23
23
|
this.client = client;
|
|
24
24
|
this.cache = new Map();
|
|
25
|
-
this.
|
|
26
|
-
|
|
25
|
+
this.pending = new Map();
|
|
26
|
+
}
|
|
27
|
+
getSync(id) {
|
|
28
|
+
return this.cache.get(id);
|
|
27
29
|
}
|
|
28
30
|
get(id) {
|
|
29
31
|
return __awaiter(this, void 0, void 0, function* () {
|
|
30
32
|
const cached = this.cache.get(id);
|
|
31
33
|
if (cached)
|
|
32
34
|
return cached;
|
|
33
|
-
const pending = this.
|
|
35
|
+
const pending = this.pending.get(id);
|
|
34
36
|
if (pending)
|
|
35
37
|
return pending;
|
|
38
|
+
// fallback to users.info only if we have to
|
|
36
39
|
const promise = (() => __awaiter(this, void 0, void 0, function* () {
|
|
37
|
-
var _a, _b, _c, _d, _e
|
|
40
|
+
var _a, _b, _c, _d, _e;
|
|
38
41
|
try {
|
|
39
42
|
const res = yield this.client.users.info({ user: id });
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
if ((_a = res.user) === null || _a === void 0 ? void 0 : _a.id) {
|
|
44
|
+
const u = {
|
|
45
|
+
name: (_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,
|
|
46
|
+
email: (_e = res.user.profile) === null || _e === void 0 ? void 0 : _e.email,
|
|
47
|
+
};
|
|
45
48
|
this.cache.set(id, u);
|
|
46
49
|
return u;
|
|
47
50
|
}
|
|
48
51
|
return undefined;
|
|
49
52
|
}
|
|
50
53
|
finally {
|
|
51
|
-
this.
|
|
54
|
+
this.pending.delete(id);
|
|
52
55
|
}
|
|
53
56
|
}))();
|
|
54
|
-
this.
|
|
57
|
+
this.pending.set(id, promise);
|
|
55
58
|
return promise;
|
|
56
59
|
});
|
|
57
60
|
}
|
|
@@ -60,6 +63,164 @@ class SlackUserCache {
|
|
|
60
63
|
}
|
|
61
64
|
}
|
|
62
65
|
/* ===================== Helpers ===================== */
|
|
66
|
+
/* ===================== Helpers ===================== */
|
|
67
|
+
/**
|
|
68
|
+
* Extracts all visible text from a Slack message
|
|
69
|
+
*/
|
|
70
|
+
export function extractMessageText(m) {
|
|
71
|
+
var _a, _b, _c, _d;
|
|
72
|
+
if (!m)
|
|
73
|
+
return undefined;
|
|
74
|
+
const pieces = [];
|
|
75
|
+
// ---- Rich text helpers ----
|
|
76
|
+
const walkRichTextInline = (el) => {
|
|
77
|
+
var _a;
|
|
78
|
+
const blockPieces = [];
|
|
79
|
+
switch (el.type) {
|
|
80
|
+
case "text":
|
|
81
|
+
blockPieces.push(el.text);
|
|
82
|
+
break;
|
|
83
|
+
case "link":
|
|
84
|
+
blockPieces.push(el.text || el.url);
|
|
85
|
+
break;
|
|
86
|
+
case "user":
|
|
87
|
+
blockPieces.push(`<@${el.user_id}>`);
|
|
88
|
+
break;
|
|
89
|
+
case "channel":
|
|
90
|
+
blockPieces.push(`<#${el.channel_id}>`);
|
|
91
|
+
break;
|
|
92
|
+
case "emoji":
|
|
93
|
+
blockPieces.push(`:${el.name}:`);
|
|
94
|
+
break;
|
|
95
|
+
case "broadcast":
|
|
96
|
+
blockPieces.push(`@${el.range}`);
|
|
97
|
+
break;
|
|
98
|
+
case "date":
|
|
99
|
+
blockPieces.push((_a = el.fallback) !== null && _a !== void 0 ? _a : `<date:${el.timestamp}>`);
|
|
100
|
+
break;
|
|
101
|
+
case "team":
|
|
102
|
+
blockPieces.push(`<team:${el.team_id}>`);
|
|
103
|
+
break;
|
|
104
|
+
case "usergroup":
|
|
105
|
+
blockPieces.push(`<usergroup:${el.usergroup_id}>`);
|
|
106
|
+
break;
|
|
107
|
+
case "color":
|
|
108
|
+
// Usually formatting only, skip
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
return blockPieces;
|
|
112
|
+
};
|
|
113
|
+
const walkRichTextElement = (el) => {
|
|
114
|
+
const result = [];
|
|
115
|
+
switch (el.type) {
|
|
116
|
+
case "rich_text_section":
|
|
117
|
+
case "rich_text_quote":
|
|
118
|
+
result.push(el.elements.map(walkRichTextInline).join("\n"));
|
|
119
|
+
break;
|
|
120
|
+
case "rich_text_list":
|
|
121
|
+
result.push(el.elements.map(section => section.elements.map(walkRichTextInline).join("\n")).join("\n"));
|
|
122
|
+
break;
|
|
123
|
+
case "rich_text_preformatted":
|
|
124
|
+
result.push(el.elements.map(walkRichTextInline).join("\n"));
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
return result;
|
|
128
|
+
};
|
|
129
|
+
// ---- Block helpers ----
|
|
130
|
+
const walkBlock = (block) => {
|
|
131
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
132
|
+
const blockPieces = [];
|
|
133
|
+
switch (block.type) {
|
|
134
|
+
case "section":
|
|
135
|
+
if ((_a = block.text) === null || _a === void 0 ? void 0 : _a.text)
|
|
136
|
+
blockPieces.push(block.text.text);
|
|
137
|
+
if (block.fields) {
|
|
138
|
+
for (const f of block.fields)
|
|
139
|
+
if (f.text)
|
|
140
|
+
blockPieces.push(f.text);
|
|
141
|
+
}
|
|
142
|
+
if (block.accessory && "text" in block.accessory && block.accessory.text) {
|
|
143
|
+
blockPieces.push(block.accessory.text.text);
|
|
144
|
+
}
|
|
145
|
+
break;
|
|
146
|
+
case "context":
|
|
147
|
+
if (Array.isArray(block.elements)) {
|
|
148
|
+
block.elements.forEach(el => {
|
|
149
|
+
if ("text" in el && el.text)
|
|
150
|
+
blockPieces.push(el.text);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
case "header":
|
|
155
|
+
if ((_b = block.text) === null || _b === void 0 ? void 0 : _b.text)
|
|
156
|
+
blockPieces.push(block.text.text);
|
|
157
|
+
break;
|
|
158
|
+
case "rich_text":
|
|
159
|
+
blockPieces.push(block.elements.map(walkRichTextElement).join("\n"));
|
|
160
|
+
break;
|
|
161
|
+
case "markdown":
|
|
162
|
+
if (block.text)
|
|
163
|
+
blockPieces.push(block.text);
|
|
164
|
+
break;
|
|
165
|
+
case "video":
|
|
166
|
+
if ((_c = block.title) === null || _c === void 0 ? void 0 : _c.text)
|
|
167
|
+
blockPieces.push(block.title.text);
|
|
168
|
+
if ((_d = block.description) === null || _d === void 0 ? void 0 : _d.text)
|
|
169
|
+
blockPieces.push(block.description.text);
|
|
170
|
+
break;
|
|
171
|
+
case "image":
|
|
172
|
+
if ((_e = block.title) === null || _e === void 0 ? void 0 : _e.text)
|
|
173
|
+
blockPieces.push(block.title.text);
|
|
174
|
+
break;
|
|
175
|
+
case "input":
|
|
176
|
+
if ((_f = block.label) === null || _f === void 0 ? void 0 : _f.text)
|
|
177
|
+
blockPieces.push(block.label.text);
|
|
178
|
+
if ((_g = block.hint) === null || _g === void 0 ? void 0 : _g.text)
|
|
179
|
+
blockPieces.push(block.hint.text);
|
|
180
|
+
break;
|
|
181
|
+
// divider, file, actions, input don’t contribute visible text
|
|
182
|
+
case "divider":
|
|
183
|
+
case "file":
|
|
184
|
+
case "actions":
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
return blockPieces;
|
|
188
|
+
};
|
|
189
|
+
let blockText = "";
|
|
190
|
+
if (Array.isArray(m.blocks)) {
|
|
191
|
+
const blockPieces = m.blocks.map(b => walkBlock(b));
|
|
192
|
+
blockText = blockPieces.join("\n");
|
|
193
|
+
}
|
|
194
|
+
if (blockText) {
|
|
195
|
+
pieces.push(blockText);
|
|
196
|
+
}
|
|
197
|
+
else if (m.text) {
|
|
198
|
+
pieces.push(m.text);
|
|
199
|
+
}
|
|
200
|
+
// 3. Attachments
|
|
201
|
+
if (m.attachments) {
|
|
202
|
+
for (const att of m.attachments) {
|
|
203
|
+
if (att.pretext)
|
|
204
|
+
pieces.push(att.pretext);
|
|
205
|
+
if (att.title)
|
|
206
|
+
pieces.push(att.title);
|
|
207
|
+
if (att.text)
|
|
208
|
+
pieces.push(att.text);
|
|
209
|
+
if (att.fields) {
|
|
210
|
+
for (const f of att.fields) {
|
|
211
|
+
const title = (_b = (_a = f.title) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : "";
|
|
212
|
+
const value = (_d = (_c = f.value) === null || _c === void 0 ? void 0 : _c.trim()) !== null && _d !== void 0 ? _d : "";
|
|
213
|
+
if (title || value) {
|
|
214
|
+
pieces.push(title && value ? `${title}: ${value}` : title || value);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Deduplicate and join
|
|
221
|
+
const out = Array.from(new Set(pieces.map(s => s.trim()).filter(Boolean))).join("\n");
|
|
222
|
+
return out || undefined;
|
|
223
|
+
}
|
|
63
224
|
function normalizeChannelOperand(ch) {
|
|
64
225
|
const s = ch.trim();
|
|
65
226
|
if (/^[CGD][A-Z0-9]/i.test(s))
|
|
@@ -89,7 +250,7 @@ function lookupUserIdsByEmail(client, emails, cache) {
|
|
|
89
250
|
return __awaiter(this, void 0, void 0, function* () {
|
|
90
251
|
const ids = [];
|
|
91
252
|
const settled = yield Promise.allSettled(emails.map((raw) => __awaiter(this, void 0, void 0, function* () {
|
|
92
|
-
var _a, _b, _c, _d, _e
|
|
253
|
+
var _a, _b, _c, _d, _e;
|
|
93
254
|
const email = raw.trim();
|
|
94
255
|
if (!email)
|
|
95
256
|
return null;
|
|
@@ -97,8 +258,8 @@ function lookupUserIdsByEmail(client, emails, cache) {
|
|
|
97
258
|
const id = (_a = res.user) === null || _a === void 0 ? void 0 : _a.id;
|
|
98
259
|
if (id && res.user) {
|
|
99
260
|
cache.set(id, {
|
|
100
|
-
name: (
|
|
101
|
-
email: (
|
|
261
|
+
name: (_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,
|
|
262
|
+
email: (_e = res.user.profile) === null || _e === void 0 ? void 0 : _e.email,
|
|
102
263
|
});
|
|
103
264
|
}
|
|
104
265
|
return id !== null && id !== void 0 ? id : null;
|
|
@@ -136,18 +297,32 @@ function getPermalink(client, channel, ts) {
|
|
|
136
297
|
}
|
|
137
298
|
});
|
|
138
299
|
}
|
|
300
|
+
function transformToSlackMessage(message) {
|
|
301
|
+
return {
|
|
302
|
+
ts: message.ts,
|
|
303
|
+
text: message.text,
|
|
304
|
+
user: message.user,
|
|
305
|
+
username: message.username,
|
|
306
|
+
thread_ts: message.thread_ts,
|
|
307
|
+
blocks: message.blocks,
|
|
308
|
+
attachments: message.attachments,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
139
311
|
function fetchOneMessage(client, channel, ts) {
|
|
140
312
|
return __awaiter(this, void 0, void 0, function* () {
|
|
141
313
|
var _a;
|
|
142
314
|
const r = yield client.conversations.history({ channel, latest: ts, inclusive: true, limit: 1 });
|
|
143
|
-
|
|
315
|
+
const message = (_a = r.messages) === null || _a === void 0 ? void 0 : _a[0];
|
|
316
|
+
if (!message)
|
|
317
|
+
return undefined;
|
|
318
|
+
return transformToSlackMessage(message);
|
|
144
319
|
});
|
|
145
320
|
}
|
|
146
321
|
function fetchThread(client, channel, threadTs) {
|
|
147
322
|
return __awaiter(this, void 0, void 0, function* () {
|
|
148
|
-
var _a;
|
|
149
|
-
const r = yield client.conversations.replies({ channel, ts: threadTs, limit:
|
|
150
|
-
return (_a = r.messages) !== null &&
|
|
323
|
+
var _a, _b;
|
|
324
|
+
const r = yield client.conversations.replies({ channel, ts: threadTs, limit: 20 });
|
|
325
|
+
return (_b = (_a = r.messages) === null || _a === void 0 ? void 0 : _a.map(transformToSlackMessage)) !== null && _b !== void 0 ? _b : [];
|
|
151
326
|
});
|
|
152
327
|
}
|
|
153
328
|
function fetchContextWindow(client, channel, ts) {
|
|
@@ -157,11 +332,13 @@ function fetchContextWindow(client, channel, ts) {
|
|
|
157
332
|
const anchor = yield fetchOneMessage(client, channel, ts);
|
|
158
333
|
if (!anchor)
|
|
159
334
|
return out;
|
|
160
|
-
const before = yield client.conversations.history({ channel, latest: ts, inclusive: false, limit:
|
|
161
|
-
|
|
335
|
+
const before = yield client.conversations.history({ channel, latest: ts, inclusive: false, limit: 3 });
|
|
336
|
+
const beforeMessages = (_a = before.messages) === null || _a === void 0 ? void 0 : _a.map(transformToSlackMessage);
|
|
337
|
+
out.push(...(beforeMessages !== null && beforeMessages !== void 0 ? beforeMessages : []).reverse());
|
|
162
338
|
out.push(anchor);
|
|
163
|
-
const after = yield client.conversations.history({ channel, oldest: ts, inclusive: false, limit:
|
|
164
|
-
|
|
339
|
+
const after = yield client.conversations.history({ channel, oldest: ts, inclusive: false, limit: 3 });
|
|
340
|
+
const afterMessages = (_b = after.messages) === null || _b === void 0 ? void 0 : _b.map(transformToSlackMessage);
|
|
341
|
+
out.push(...(afterMessages !== null && afterMessages !== void 0 ? afterMessages : []));
|
|
165
342
|
return out;
|
|
166
343
|
});
|
|
167
344
|
}
|
|
@@ -170,26 +347,21 @@ function hasOverlap(messages, ids, minOverlap) {
|
|
|
170
347
|
const overlap = ids.filter(id => participants.has(id)).length;
|
|
171
348
|
return overlap >= minOverlap;
|
|
172
349
|
}
|
|
173
|
-
function expandSlackEntities(
|
|
350
|
+
function expandSlackEntities(cache, raw) {
|
|
174
351
|
return __awaiter(this, void 0, void 0, function* () {
|
|
175
352
|
let text = raw;
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
idToUser[id] = { name: u === null || u === void 0 ? void 0 : u.name };
|
|
353
|
+
const userIds = [...raw.matchAll(MENTION_USER_RE)].map(m => m[1]);
|
|
354
|
+
// resolve all in parallel: prefer cache, else users.info
|
|
355
|
+
const idToName = {};
|
|
356
|
+
yield Promise.all(userIds.map((id) => __awaiter(this, void 0, void 0, function* () {
|
|
357
|
+
const u = yield cache.get(id); // get() will call users.info if missing
|
|
358
|
+
if (u === null || u === void 0 ? void 0 : u.name)
|
|
359
|
+
idToName[id] = u.name;
|
|
184
360
|
})));
|
|
185
|
-
text = text.replace(MENTION_USER_RE, (_, id) => { var _a
|
|
186
|
-
// channels
|
|
361
|
+
text = text.replace(MENTION_USER_RE, (_, id) => { var _a; return `@${(_a = idToName[id]) !== null && _a !== void 0 ? _a : id}`; });
|
|
187
362
|
text = text.replace(MENTION_CHANNEL_RE, (_, id) => `#${id}`);
|
|
188
|
-
// special mentions
|
|
189
363
|
text = text.replace(SPECIAL_RE, (_, kind) => `@${kind}`);
|
|
190
|
-
// subteams
|
|
191
364
|
text = text.replace(SUBTEAM_RE, (_m, sid) => `@${sid}`);
|
|
192
|
-
// links
|
|
193
365
|
text = text.replace(/<([^>|]+)\|([^>]+)>/g, (_m, _url, label) => label);
|
|
194
366
|
text = text.replace(/<([^>|]+)>/g, (_m, url) => url);
|
|
195
367
|
return text;
|
|
@@ -247,96 +419,102 @@ const searchSlack = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params,
|
|
|
247
419
|
const { user_id: myUserId } = yield client.auth.test();
|
|
248
420
|
if (!myUserId)
|
|
249
421
|
throw new Error("Failed to get my user ID.");
|
|
250
|
-
|
|
422
|
+
// preload myself
|
|
423
|
+
const meInfo = yield cache.get(myUserId);
|
|
424
|
+
// resolve targets by email
|
|
251
425
|
const targetIds = (emails === null || emails === void 0 ? void 0 : emails.length) ? yield lookupUserIdsByEmail(client, emails, cache) : [];
|
|
252
426
|
const filteredTargetIds = targetIds.filter(id => id !== myUserId);
|
|
253
427
|
const allMatches = [];
|
|
254
|
-
// --- Parallel search execution for better performance ---
|
|
255
428
|
const searchPromises = [];
|
|
256
|
-
// Scoped DM/MPIM searches
|
|
257
429
|
if (filteredTargetIds.length === 1) {
|
|
258
430
|
searchPromises.push(searchScoped({ client, scope: `<@${filteredTargetIds[0]}>`, topic, timeRange, limit }));
|
|
259
431
|
}
|
|
260
432
|
else if (filteredTargetIds.length >= 2) {
|
|
261
|
-
// Run MPIM lookup and individual DM searches in parallel
|
|
262
433
|
const searchMPIM = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
263
434
|
const mpimName = yield tryGetMPIMName(client, filteredTargetIds);
|
|
264
435
|
return mpimName ? searchScoped({ client, scope: mpimName, topic, timeRange, limit }) : [];
|
|
265
436
|
});
|
|
266
437
|
searchPromises.push(searchMPIM());
|
|
267
|
-
// Add individual DM searches
|
|
268
438
|
searchPromises.push(...filteredTargetIds.map(id => searchScoped({ client, scope: `<@${id}>`, topic, timeRange, limit })));
|
|
269
439
|
}
|
|
270
440
|
else if (channel) {
|
|
271
441
|
searchPromises.push(searchScoped({ client, scope: normalizeChannelOperand(channel), topic, timeRange, limit }));
|
|
272
442
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
443
|
+
if (topic) {
|
|
444
|
+
searchPromises.push(searchByTopic({ client, topic, timeRange, limit }));
|
|
445
|
+
}
|
|
276
446
|
const searchResults = yield Promise.all(searchPromises);
|
|
277
447
|
searchResults.forEach(matches => allMatches.push(...matches));
|
|
278
|
-
// --- Expand hits with context + filter overlap ---
|
|
279
|
-
// Create a channel info cache to avoid redundant API calls
|
|
280
448
|
const channelInfoCache = new Map();
|
|
281
449
|
const expanded = yield Promise.all(allMatches.map(m => limitHit(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
282
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
450
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
283
451
|
if (!m.ts || !((_a = m.channel) === null || _a === void 0 ? void 0 : _a.id))
|
|
284
452
|
return null;
|
|
285
453
|
const anchor = yield fetchOneMessage(client, m.channel.id, m.ts);
|
|
286
454
|
const rootTs = (anchor === null || anchor === void 0 ? void 0 : anchor.thread_ts) || m.ts;
|
|
287
|
-
|
|
288
|
-
// Check convo type (DM, MPIM, channel) with caching
|
|
455
|
+
// channel info
|
|
289
456
|
let channelInfo = channelInfoCache.get(m.channel.id);
|
|
290
457
|
if (!channelInfo) {
|
|
291
458
|
const convoInfo = yield client.conversations.info({ channel: m.channel.id });
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
459
|
+
const isIm = (_c = (_b = convoInfo.channel) === null || _b === void 0 ? void 0 : _b.is_im) !== null && _c !== void 0 ? _c : false;
|
|
460
|
+
const isMpim = (_e = (_d = convoInfo.channel) === null || _d === void 0 ? void 0 : _d.is_mpim) !== null && _e !== void 0 ? _e : false;
|
|
461
|
+
let members = [];
|
|
462
|
+
if (isIm || isMpim) {
|
|
463
|
+
const res = yield client.conversations.members({ channel: m.channel.id });
|
|
464
|
+
members = (_f = res.members) !== null && _f !== void 0 ? _f : [];
|
|
465
|
+
}
|
|
466
|
+
channelInfo = { isIm, isMpim, members };
|
|
296
467
|
channelInfoCache.set(m.channel.id, channelInfo);
|
|
297
468
|
}
|
|
298
|
-
|
|
469
|
+
// context + permalink
|
|
299
470
|
const [contextMsgs, permalink] = (anchor === null || anchor === void 0 ? void 0 : anchor.thread_ts)
|
|
300
|
-
? [
|
|
301
|
-
|
|
471
|
+
? [
|
|
472
|
+
yield fetchThread(client, m.channel.id, rootTs),
|
|
473
|
+
(_g = m.permalink) !== null && _g !== void 0 ? _g : (yield getPermalink(client, m.channel.id, rootTs)),
|
|
474
|
+
]
|
|
475
|
+
: [
|
|
476
|
+
yield fetchContextWindow(client, m.channel.id, m.ts),
|
|
477
|
+
(_h = m.permalink) !== null && _h !== void 0 ? _h : (yield getPermalink(client, m.channel.id, m.ts)),
|
|
478
|
+
];
|
|
479
|
+
// filter logic
|
|
302
480
|
let passesFilter = false;
|
|
303
|
-
if (isIm || isMpim) {
|
|
304
|
-
|
|
305
|
-
const membersRes = (_f = (yield client.conversations.members({ channel: m.channel.id })).members) !== null && _f !== void 0 ? _f : [];
|
|
306
|
-
members = yield Promise.all(membersRes.map((uid) => __awaiter(void 0, void 0, void 0, function* () {
|
|
307
|
-
const u = yield cache.get(uid);
|
|
308
|
-
return { userId: uid, userEmail: u === null || u === void 0 ? void 0 : u.email, userName: u === null || u === void 0 ? void 0 : u.name };
|
|
309
|
-
})));
|
|
310
|
-
const overlap = filteredTargetIds.filter(id => membersRes.includes(id)).length;
|
|
481
|
+
if (channelInfo.isIm || channelInfo.isMpim) {
|
|
482
|
+
const overlap = filteredTargetIds.filter(id => channelInfo.members.includes(id)).length;
|
|
311
483
|
passesFilter = overlap >= 1;
|
|
312
484
|
}
|
|
313
485
|
else {
|
|
314
|
-
// Channel: use authorship
|
|
315
486
|
passesFilter = hasOverlap(contextMsgs, filteredTargetIds, 1);
|
|
316
487
|
}
|
|
317
488
|
if (filteredTargetIds.length && !passesFilter)
|
|
318
489
|
return null;
|
|
319
490
|
const context = yield Promise.all(contextMsgs.map((t) => __awaiter(void 0, void 0, void 0, function* () {
|
|
320
|
-
var _a
|
|
321
|
-
|
|
491
|
+
var _a;
|
|
492
|
+
const u = t.user ? yield cache.get(t.user) : undefined;
|
|
493
|
+
const rawText = extractMessageText(t);
|
|
494
|
+
return {
|
|
322
495
|
ts: t.ts,
|
|
323
|
-
text:
|
|
324
|
-
userEmail:
|
|
325
|
-
userName:
|
|
326
|
-
}
|
|
496
|
+
text: rawText ? yield expandSlackEntities(cache, rawText) : undefined,
|
|
497
|
+
userEmail: u === null || u === void 0 ? void 0 : u.email,
|
|
498
|
+
userName: (_a = u === null || u === void 0 ? void 0 : u.name) !== null && _a !== void 0 ? _a : t.username,
|
|
499
|
+
};
|
|
327
500
|
})));
|
|
501
|
+
const anchorUser = (anchor === null || anchor === void 0 ? void 0 : anchor.user) ? yield cache.get(anchor.user) : undefined;
|
|
502
|
+
const anchorText = extractMessageText(anchor);
|
|
328
503
|
return {
|
|
329
504
|
channelId: m.channel.id,
|
|
330
505
|
ts: rootTs,
|
|
331
|
-
text:
|
|
332
|
-
userEmail:
|
|
333
|
-
userName: (
|
|
506
|
+
text: anchorText ? yield expandSlackEntities(cache, anchorText) : undefined,
|
|
507
|
+
userEmail: anchorUser === null || anchorUser === void 0 ? void 0 : anchorUser.email,
|
|
508
|
+
userName: (_j = anchorUser === null || anchorUser === void 0 ? void 0 : anchorUser.name) !== null && _j !== void 0 ? _j : anchor === null || anchor === void 0 ? void 0 : anchor.username,
|
|
334
509
|
context,
|
|
335
|
-
permalink,
|
|
336
|
-
members
|
|
510
|
+
permalink: (_k = m.permalink) !== null && _k !== void 0 ? _k : permalink,
|
|
511
|
+
members: ((_l = channelInfo.members) !== null && _l !== void 0 ? _l : []).map(uid => {
|
|
512
|
+
const u = cache.getSync(uid);
|
|
513
|
+
return { userId: uid, userEmail: u === null || u === void 0 ? void 0 : u.email, userName: u === null || u === void 0 ? void 0 : u.name };
|
|
514
|
+
}),
|
|
337
515
|
};
|
|
338
516
|
}))));
|
|
339
|
-
const results = dedupeAndSort(expanded.filter(
|
|
517
|
+
const results = dedupeAndSort(expanded.filter(Boolean));
|
|
340
518
|
return {
|
|
341
519
|
query: topic !== null && topic !== void 0 ? topic : "",
|
|
342
520
|
results: results.map(r => ({
|
|
@@ -344,7 +522,7 @@ const searchSlack = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params,
|
|
|
344
522
|
url: r.permalink || "",
|
|
345
523
|
contents: r,
|
|
346
524
|
})),
|
|
347
|
-
currentUser: { userId: myUserId, userName:
|
|
525
|
+
currentUser: { userId: myUserId, userName: meInfo === null || meInfo === void 0 ? void 0 : meInfo.name, userEmail: meInfo === null || meInfo === void 0 ? void 0 : meInfo.email },
|
|
348
526
|
};
|
|
349
527
|
});
|
|
350
528
|
export default searchSlack;
|