alvin-bot 5.7.0 → 5.8.0

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.
Files changed (136) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/claude.js +1 -102
  3. package/dist/config.js +1 -96
  4. package/dist/engine.js +1 -90
  5. package/dist/find-claude-binary.js +1 -98
  6. package/dist/handlers/async-agent-chunk-handler.js +1 -50
  7. package/dist/handlers/background-bypass.js +1 -75
  8. package/dist/handlers/commands.js +1 -2336
  9. package/dist/handlers/cron-progress.js +1 -52
  10. package/dist/handlers/document.js +1 -194
  11. package/dist/handlers/message.js +1 -959
  12. package/dist/handlers/photo.js +1 -154
  13. package/dist/handlers/platform-message.js +1 -360
  14. package/dist/handlers/stuck-timer.js +1 -54
  15. package/dist/handlers/video.js +1 -237
  16. package/dist/handlers/voice.js +1 -148
  17. package/dist/i18n.js +1 -805
  18. package/dist/index.js +1 -697
  19. package/dist/init-data-dir.js +1 -98
  20. package/dist/middleware/auth.js +1 -233
  21. package/dist/migrate.js +1 -162
  22. package/dist/paths.js +1 -146
  23. package/dist/platforms/discord.js +1 -175
  24. package/dist/platforms/index.js +1 -130
  25. package/dist/platforms/signal.js +1 -205
  26. package/dist/platforms/slack-slash-parser.js +1 -32
  27. package/dist/platforms/slack.js +1 -501
  28. package/dist/platforms/telegram.js +1 -111
  29. package/dist/platforms/types.js +1 -8
  30. package/dist/platforms/whatsapp-auth-helpers.js +1 -53
  31. package/dist/platforms/whatsapp.js +1 -707
  32. package/dist/providers/claude-sdk-provider.js +1 -565
  33. package/dist/providers/codex-cli-provider.js +1 -134
  34. package/dist/providers/index.js +1 -7
  35. package/dist/providers/ollama-provider.js +1 -32
  36. package/dist/providers/openai-compatible.js +1 -406
  37. package/dist/providers/registry.js +1 -352
  38. package/dist/providers/runtime-header.js +1 -45
  39. package/dist/providers/tool-executor.js +1 -475
  40. package/dist/providers/types.js +1 -227
  41. package/dist/services/access.js +1 -144
  42. package/dist/services/allowed-users-gate.js +1 -56
  43. package/dist/services/alvin-dispatch.js +1 -174
  44. package/dist/services/alvin-mcp-tools.js +1 -104
  45. package/dist/services/asset-index.js +1 -224
  46. package/dist/services/async-agent-parser.js +1 -418
  47. package/dist/services/async-agent-watcher.js +1 -583
  48. package/dist/services/auto-diagnostic.js +1 -228
  49. package/dist/services/broadcast.js +1 -52
  50. package/dist/services/browser-manager.js +1 -562
  51. package/dist/services/browser-webfetch.js +1 -127
  52. package/dist/services/browser.js +1 -121
  53. package/dist/services/cdp-bootstrap.js +1 -357
  54. package/dist/services/compaction.js +1 -144
  55. package/dist/services/critical-notify.js +1 -203
  56. package/dist/services/cron-resolver.js +1 -58
  57. package/dist/services/cron-scheduling.js +1 -310
  58. package/dist/services/cron.js +1 -861
  59. package/dist/services/custom-tools.js +1 -317
  60. package/dist/services/delivery-queue.js +1 -173
  61. package/dist/services/delivery-registry.js +1 -21
  62. package/dist/services/disk-cleanup.js +1 -203
  63. package/dist/services/elevenlabs.js +1 -58
  64. package/dist/services/embeddings/auto-detect.js +1 -74
  65. package/dist/services/embeddings/fts5.js +1 -108
  66. package/dist/services/embeddings/gemini.js +1 -65
  67. package/dist/services/embeddings/index.js +1 -496
  68. package/dist/services/embeddings/ollama.js +1 -78
  69. package/dist/services/embeddings/openai.js +1 -49
  70. package/dist/services/embeddings/provider.js +1 -22
  71. package/dist/services/embeddings/vector-base.js +1 -113
  72. package/dist/services/embeddings-migration.js +1 -193
  73. package/dist/services/embeddings.js +1 -9
  74. package/dist/services/env-file.js +1 -50
  75. package/dist/services/exec-guard.js +1 -71
  76. package/dist/services/fallback-order.js +1 -154
  77. package/dist/services/file-permissions.js +1 -93
  78. package/dist/services/heartbeat-file.js +1 -65
  79. package/dist/services/heartbeat.js +1 -313
  80. package/dist/services/hooks.js +1 -44
  81. package/dist/services/imagegen.js +1 -72
  82. package/dist/services/language-detect.js +1 -154
  83. package/dist/services/markdown.js +1 -63
  84. package/dist/services/mcp.js +1 -263
  85. package/dist/services/memory-extractor.js +1 -178
  86. package/dist/services/memory-inject-mode.js +1 -43
  87. package/dist/services/memory-layers.js +1 -156
  88. package/dist/services/memory.js +1 -146
  89. package/dist/services/ollama-manager.js +1 -339
  90. package/dist/services/permissions-wizard.js +1 -291
  91. package/dist/services/personality.js +1 -376
  92. package/dist/services/plugins.js +1 -171
  93. package/dist/services/preflight.js +1 -292
  94. package/dist/services/process-manager.js +1 -291
  95. package/dist/services/release-highlights.js +1 -79
  96. package/dist/services/reminders.js +1 -97
  97. package/dist/services/restart.js +1 -48
  98. package/dist/services/security-audit.js +1 -74
  99. package/dist/services/self-diagnosis.js +1 -272
  100. package/dist/services/self-search.js +1 -129
  101. package/dist/services/session-persistence.js +1 -237
  102. package/dist/services/session.js +1 -282
  103. package/dist/services/skills.js +1 -290
  104. package/dist/services/ssrf-guard.js +1 -162
  105. package/dist/services/standing-orders.js +1 -29
  106. package/dist/services/steer-channel.js +1 -46
  107. package/dist/services/stop-controller.js +1 -52
  108. package/dist/services/subagent-dedup.js +1 -86
  109. package/dist/services/subagent-delivery.js +1 -452
  110. package/dist/services/subagent-stats.js +1 -123
  111. package/dist/services/subagents.js +1 -814
  112. package/dist/services/sudo.js +1 -329
  113. package/dist/services/telegram.js +1 -158
  114. package/dist/services/timing-safe-bearer.js +1 -51
  115. package/dist/services/tool-discovery.js +1 -214
  116. package/dist/services/trends.js +1 -580
  117. package/dist/services/updater.js +1 -291
  118. package/dist/services/usage-tracker.js +1 -144
  119. package/dist/services/users.js +1 -271
  120. package/dist/services/voice.js +1 -104
  121. package/dist/services/watchdog-brake.js +1 -154
  122. package/dist/services/watchdog.js +1 -311
  123. package/dist/services/workspaces.js +1 -276
  124. package/dist/tui/index.js +1 -667
  125. package/dist/util/console-formatter.js +1 -109
  126. package/dist/util/debounce.js +1 -24
  127. package/dist/util/telegram-error-filter.js +1 -62
  128. package/dist/version.js +1 -24
  129. package/dist/web/bind-strategy.js +1 -42
  130. package/dist/web/canvas.js +1 -30
  131. package/dist/web/doctor-api.js +1 -604
  132. package/dist/web/openai-compat.js +1 -252
  133. package/dist/web/server.js +1 -1902
  134. package/dist/web/setup-api.js +1 -1101
  135. package/package.json +5 -2
  136. package/dist/.metadata_never_index +0 -0
@@ -1,501 +1 @@
1
- /**
2
- * Slack Platform Adapter
3
- *
4
- * Uses @slack/bolt (Socket Mode) for real-time messaging.
5
- * Optional dependency — only loaded if SLACK_BOT_TOKEN + SLACK_APP_TOKEN are set.
6
- *
7
- * Socket Mode = no public URL needed. Works behind NAT/firewalls.
8
- *
9
- * Setup:
10
- * 1. Create a Slack App at https://api.slack.com/apps
11
- * 2. Enable Socket Mode (Settings → Socket Mode → Enable)
12
- * 3. Generate an App-Level Token with connections:write scope → SLACK_APP_TOKEN (xapp-...)
13
- * 4. Install to workspace → Bot User OAuth Token → SLACK_BOT_TOKEN (xoxb-...)
14
- * 5. Add Bot Token Scopes: chat:write, channels:history, groups:history, im:history,
15
- * mpim:history, app_mentions:read, files:write, reactions:write
16
- * 6. Subscribe to events: message.im, message.groups, message.channels, app_mention
17
- * 7. Set env vars and restart bot
18
- */
19
- import fs from "fs";
20
- import { parseSlackSlashCommand } from "./slack-slash-parser.js";
21
- import { config } from "../config.js";
22
- /**
23
- * v4.20.2 — Slack caller allowlist. When SLACK_ALLOWED_USERS is set in the
24
- * environment (comma-separated Slack user IDs), only those users get past
25
- * this gate. When the list is empty, fall back to legacy behaviour: any
26
- * member of the workspace can talk to the bot. The empty-list case is safe
27
- * iff the workspace is private to the operator.
28
- *
29
- * Slack user IDs are workspace-scoped (e.g. "U0ABC123"); rotate the list if
30
- * you migrate workspaces.
31
- */
32
- function isSlackUserAllowed(userId) {
33
- if (config.slackAllowedUsers.length === 0) {
34
- // No allowlist set — log each unique caller once so the operator can
35
- // copy a known ID into SLACK_ALLOWED_USERS and lock the bot down.
36
- if (userId && !discoveredCallers.has(userId)) {
37
- discoveredCallers.add(userId);
38
- console.warn(`[slack] caller discovered: user=${userId} — to lock the bot to specific users, ` +
39
- `add to .env: SLACK_ALLOWED_USERS=${userId}` +
40
- (discoveredCallers.size > 1 ? ` (or comma-separate multiple)` : ""));
41
- }
42
- return true;
43
- }
44
- return config.slackAllowedUsers.includes(userId);
45
- }
46
- const discoveredCallers = new Set();
47
- let _slackState = {
48
- status: "disconnected",
49
- botName: null,
50
- botId: null,
51
- teamName: null,
52
- connectedAt: null,
53
- error: null,
54
- };
55
- export function getSlackState() {
56
- return { ..._slackState };
57
- }
58
- // ── Adapter ────────────────────────────────────────────────────────────────
59
- export class SlackAdapter {
60
- platform = "slack";
61
- handler = null;
62
- app = null; // Bolt App instance
63
- botUserId = "";
64
- botToken;
65
- appToken;
66
- /** v4.12.0 — channelId → channelName cache, refreshed on miss via conversations.info */
67
- channelNameCache = new Map();
68
- constructor(botToken, appToken) {
69
- this.botToken = botToken;
70
- this.appToken = appToken;
71
- }
72
- async start() {
73
- _slackState = {
74
- status: "connecting", botName: null, botId: null,
75
- teamName: null, connectedAt: null, error: null,
76
- };
77
- let bolt;
78
- try {
79
- bolt = await import("@slack/bolt");
80
- }
81
- catch {
82
- const msg = "@slack/bolt not installed. Run: npm install @slack/bolt";
83
- _slackState = { ..._slackState, status: "error", error: msg };
84
- console.error(`\u274C Slack: ${msg}`);
85
- throw new Error(msg);
86
- }
87
- const { App } = bolt;
88
- try {
89
- this.app = new App({
90
- token: this.botToken,
91
- appToken: this.appToken,
92
- socketMode: true,
93
- // Suppress Bolt's default logging (we log ourselves)
94
- logLevel: "ERROR",
95
- });
96
- // Get bot identity
97
- const authResult = await this.app.client.auth.test({ token: this.botToken });
98
- this.botUserId = authResult.user_id || "";
99
- _slackState.botName = authResult.user || null;
100
- _slackState.botId = authResult.user_id || null;
101
- _slackState.teamName = authResult.team || null;
102
- // Handle all messages (DMs + channels where bot is mentioned)
103
- this.app.message(async ({ message, say, client }) => {
104
- await this.handleMessage(message, say, client);
105
- });
106
- // Handle @mentions explicitly (app_mention event)
107
- this.app.event("app_mention", async ({ event, say, client }) => {
108
- await this.handleMention(event, say, client);
109
- });
110
- // v4.13.2 — Handle the /alvin slash command.
111
- //
112
- // Slack sends slash commands as their own "command" event type
113
- // (not as regular messages), so without this handler users who
114
- // type /status see "Not a valid command" from Slack's built-in
115
- // /status (which sets their user status). We register /alvin as
116
- // a namespaced parent and parse the subcommand from command.text.
117
- //
118
- // CRITICAL: Slack requires ack() within 3 seconds or the user
119
- // sees "/alvin didn't respond". We ack FIRST, then do the work
120
- // asynchronously via the normal handler pipeline.
121
- //
122
- // Defensive: older/mocked Bolt versions might not expose .command().
123
- // Skip registration silently rather than crashing start().
124
- if (typeof this.app.command === "function") {
125
- this.app.command("/alvin", async ({ command, ack }) => {
126
- await ack();
127
- try {
128
- await this.handleSlashCommand(command);
129
- }
130
- catch (err) {
131
- console.error("[slack] /alvin command failed:", err);
132
- }
133
- });
134
- }
135
- await this.app.start();
136
- _slackState.status = "connected";
137
- _slackState.connectedAt = Date.now();
138
- console.log(`\uD83D\uDCAC Slack connected (${_slackState.botName} @ ${_slackState.teamName})`);
139
- // v4.14 — Register this adapter with the delivery registry so the
140
- // async-agent watcher can deliver background sub-agent results
141
- // back to Slack. The registry accepts string channel IDs directly.
142
- try {
143
- const { registerDeliveryAdapter } = await import("../services/delivery-registry.js");
144
- registerDeliveryAdapter({
145
- platform: "slack",
146
- sendText: async (chatId, text) => {
147
- await this.sendText(String(chatId), text);
148
- },
149
- });
150
- }
151
- catch (err) {
152
- console.warn("[slack] failed to register delivery adapter:", err);
153
- }
154
- }
155
- catch (err) {
156
- _slackState.status = "error";
157
- _slackState.error = err instanceof Error ? err.message : String(err);
158
- console.error("\u274C Slack adapter failed:", _slackState.error);
159
- throw err;
160
- }
161
- }
162
- // ── Message Handling ───────────────────────────────────────────────────────
163
- async handleMessage(message, _say, client) {
164
- if (!this.handler)
165
- return;
166
- // Skip bot messages (including own), message_changed, etc.
167
- if (message.subtype)
168
- return;
169
- if (message.bot_id)
170
- return;
171
- if (!message.text && !message.files)
172
- return;
173
- const text = (message.text || "").trim();
174
- const userId = message.user || "";
175
- const channelId = message.channel || "";
176
- const messageId = message.ts || "";
177
- // v4.20.2 — caller allowlist. If SLACK_ALLOWED_USERS is set, silently
178
- // ignore anyone not on the list. Empty list = legacy behaviour
179
- // (any workspace member can talk to the bot — safe iff the workspace
180
- // is private to the operator).
181
- if (!isSlackUserAllowed(userId)) {
182
- return;
183
- }
184
- // Determine channel type
185
- // DMs (im) have channel_type "im", group DMs are "mpim", channels are "channel"/"group"
186
- const channelType = message.channel_type || "";
187
- const isDM = channelType === "im";
188
- const isGroup = !isDM;
189
- // In channels: only respond to @mentions (handled by app_mention event)
190
- // But message event also fires for DMs, so we handle DMs here
191
- if (isGroup)
192
- return; // Channel messages handled by app_mention
193
- // Resolve user name
194
- let userName = userId;
195
- try {
196
- const userInfo = await client.users.info({ user: userId });
197
- userName = userInfo.user?.real_name || userInfo.user?.name || userId;
198
- }
199
- catch { /* fallback to userId */ }
200
- // Check for file attachments
201
- let media = undefined;
202
- if (message.files && message.files.length > 0) {
203
- const file = message.files[0];
204
- media = this.parseSlackFile(file);
205
- }
206
- // Check for thread/reply context
207
- let replyToText;
208
- if (message.thread_ts && message.thread_ts !== message.ts) {
209
- try {
210
- const thread = await client.conversations.replies({
211
- channel: channelId,
212
- ts: message.thread_ts,
213
- limit: 1,
214
- });
215
- const parent = thread.messages?.[0];
216
- if (parent?.text) {
217
- replyToText = parent.text.length > 500 ? parent.text.slice(0, 500) + "..." : parent.text;
218
- }
219
- }
220
- catch { /* ignore */ }
221
- }
222
- const incoming = {
223
- platform: "slack",
224
- messageId,
225
- chatId: channelId,
226
- userId,
227
- userName,
228
- text,
229
- isGroup: false,
230
- isMention: false,
231
- isReplyToBot: false,
232
- replyToText,
233
- media,
234
- };
235
- await this.handler(incoming);
236
- }
237
- /**
238
- * v4.13.2 — Handle /alvin slash command.
239
- *
240
- * Slack delivers these with command.text containing the part after
241
- * "/alvin " (so "/alvin status" arrives with text="status"). We
242
- * translate into a platform-agnostic "/<sub>[ args]" string and
243
- * forward through the normal message handler — handlePlatformCommand
244
- * picks it up since it starts with "/".
245
- *
246
- * The response goes back via the same sendText path as regular
247
- * messages (chat.postMessage in command.channel_id). Slack allows
248
- * this in addition to the slash-command-native respond() mechanism,
249
- * and it keeps the codepath identical to message.im responses.
250
- */
251
- async handleSlashCommand(command) {
252
- if (!this.handler)
253
- return;
254
- const translated = parseSlackSlashCommand(command.text || "");
255
- const channelId = command.channel_id || "";
256
- const userId = command.user_id || "";
257
- const userName = command.user_name || userId;
258
- // v4.20.2 — caller allowlist for slash commands.
259
- if (!isSlackUserAllowed(userId)) {
260
- return;
261
- }
262
- const incoming = {
263
- platform: "slack",
264
- messageId: `cmd-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
265
- chatId: channelId,
266
- userId,
267
- userName,
268
- text: translated,
269
- // Slack slash commands are always issued 1:1 in the sense of
270
- // "one user invoking". isGroup reflects the CHANNEL context
271
- // (channel_name=directmessage is a DM, otherwise channel/group).
272
- isGroup: command.channel_name && command.channel_name !== "directmessage",
273
- isMention: false,
274
- isReplyToBot: false,
275
- };
276
- await this.handler(incoming);
277
- }
278
- async handleMention(event, _say, client) {
279
- if (!this.handler)
280
- return;
281
- if (event.bot_id)
282
- return;
283
- let text = (event.text || "").trim();
284
- const userId = event.user || "";
285
- const channelId = event.channel || "";
286
- const messageId = event.ts || "";
287
- // v4.20.2 — same caller allowlist as DMs.
288
- if (!isSlackUserAllowed(userId)) {
289
- return;
290
- }
291
- // Strip the @mention from text
292
- text = text.replace(new RegExp(`<@${this.botUserId}>`, "g"), "").trim();
293
- if (!text)
294
- return;
295
- // Resolve user name
296
- let userName = userId;
297
- try {
298
- const userInfo = await client.users.info({ user: userId });
299
- userName = userInfo.user?.real_name || userInfo.user?.name || userId;
300
- }
301
- catch { /* fallback */ }
302
- // File attachments
303
- let media = undefined;
304
- if (event.files && event.files.length > 0) {
305
- media = this.parseSlackFile(event.files[0]);
306
- }
307
- const incoming = {
308
- platform: "slack",
309
- messageId,
310
- chatId: channelId,
311
- userId,
312
- userName,
313
- text,
314
- isGroup: true,
315
- isMention: true,
316
- isReplyToBot: false,
317
- media,
318
- };
319
- await this.handler(incoming);
320
- }
321
- parseSlackFile(file) {
322
- if (!file)
323
- return undefined;
324
- const mime = file.mimetype || "";
325
- if (mime.startsWith("image/")) {
326
- return { type: "photo", url: file.url_private, mimeType: mime, fileName: file.name };
327
- }
328
- if (mime.startsWith("audio/")) {
329
- return { type: "voice", url: file.url_private, mimeType: mime, fileName: file.name };
330
- }
331
- if (mime.startsWith("video/")) {
332
- return { type: "video", url: file.url_private, mimeType: mime, fileName: file.name };
333
- }
334
- return { type: "document", url: file.url_private, mimeType: mime, fileName: file.name };
335
- }
336
- // ── Sending ──────────────────────────────────────────────────────────────
337
- async sendText(chatId, text, options) {
338
- if (!this.app)
339
- return;
340
- // Slack block limit is ~3000 chars for text blocks, message limit ~40000
341
- // But keep it practical — split at 3800 like Telegram
342
- const chunks = text.length > 3800
343
- ? text.match(/.{1,3800}/gs) || [text]
344
- : [text];
345
- let lastTs;
346
- for (const chunk of chunks) {
347
- const result = await this.app.client.chat.postMessage({
348
- token: this.botToken,
349
- channel: chatId,
350
- text: chunk,
351
- // Thread reply if replyTo is set
352
- ...(options?.replyTo ? { thread_ts: options.replyTo } : {}),
353
- // Convert markdown bold/italic to Slack mrkdwn
354
- mrkdwn: true,
355
- });
356
- if (result?.ts)
357
- lastTs = result.ts;
358
- }
359
- return lastTs;
360
- }
361
- /** Edit a previously-sent message (for progress tickers on long queries).
362
- * Fail-silent: ticker UX shouldn't crash the query. */
363
- async editMessage(chatId, messageId, newText) {
364
- if (!this.app)
365
- return messageId;
366
- try {
367
- const safeText = newText.length > 3800 ? newText.slice(0, 3800) + "..." : newText;
368
- await this.app.client.chat.update({
369
- token: this.botToken,
370
- channel: chatId,
371
- ts: messageId,
372
- text: safeText,
373
- mrkdwn: true,
374
- });
375
- }
376
- catch {
377
- // Silent failure — ticker UX shouldn't crash the query
378
- }
379
- return messageId;
380
- }
381
- async sendPhoto(chatId, photo, caption) {
382
- if (!this.app)
383
- return;
384
- if (typeof photo === "string") {
385
- // File path
386
- await this.app.client.filesUploadV2({
387
- token: this.botToken,
388
- channel_id: chatId,
389
- file: fs.createReadStream(photo),
390
- filename: "image.png",
391
- initial_comment: caption,
392
- });
393
- }
394
- else {
395
- // Buffer
396
- await this.app.client.filesUploadV2({
397
- token: this.botToken,
398
- channel_id: chatId,
399
- file_uploads: [{
400
- file: photo,
401
- filename: "image.png",
402
- }],
403
- initial_comment: caption,
404
- });
405
- }
406
- }
407
- async sendDocument(chatId, doc, fileName, caption) {
408
- if (!this.app)
409
- return;
410
- if (typeof doc === "string") {
411
- await this.app.client.filesUploadV2({
412
- token: this.botToken,
413
- channel_id: chatId,
414
- file: fs.createReadStream(doc),
415
- filename: fileName,
416
- initial_comment: caption,
417
- });
418
- }
419
- else {
420
- await this.app.client.filesUploadV2({
421
- token: this.botToken,
422
- channel_id: chatId,
423
- file_uploads: [{
424
- file: doc,
425
- filename: fileName,
426
- }],
427
- initial_comment: caption,
428
- });
429
- }
430
- }
431
- async react(chatId, messageId, emoji) {
432
- if (!this.app)
433
- return;
434
- try {
435
- // Slack emoji names don't include colons
436
- const name = emoji.replace(/^:|:$/g, "");
437
- await this.app.client.reactions.add({
438
- token: this.botToken,
439
- channel: chatId,
440
- timestamp: messageId,
441
- name,
442
- });
443
- }
444
- catch { /* ignore — emoji might not exist */ }
445
- }
446
- async setTyping(chatId) {
447
- if (!this.app)
448
- return;
449
- // v4.12.0 — Slack's official "is thinking" API for bots is
450
- // assistant.threads.setStatus which shows "Alvin is thinking…" under
451
- // the message. Only works in assistant-enabled channels (scope:
452
- // assistant:write) — silently no-ops in channels where the bot
453
- // isn't enabled as an assistant.
454
- try {
455
- await this.app.client.apiCall("assistant.threads.setStatus", {
456
- channel_id: chatId,
457
- status: "is thinking…",
458
- });
459
- }
460
- catch {
461
- // Not every channel supports assistant threads — that's fine
462
- }
463
- }
464
- /** v4.12.0 — Look up a Slack channel's name by ID, using a small in-memory
465
- * cache. Used by platform-message.ts for workspace resolution. */
466
- async getChannelName(channelId) {
467
- if (!this.app)
468
- return undefined;
469
- const cached = this.channelNameCache.get(channelId);
470
- if (cached)
471
- return cached;
472
- try {
473
- const result = await this.app.client.conversations.info({
474
- token: this.botToken,
475
- channel: channelId,
476
- });
477
- const name = result?.channel?.name;
478
- if (name) {
479
- this.channelNameCache.set(channelId, name);
480
- return name;
481
- }
482
- }
483
- catch {
484
- // IM channels return channel_not_found here — that's expected
485
- }
486
- return undefined;
487
- }
488
- async stop() {
489
- if (this.app) {
490
- try {
491
- await this.app.stop();
492
- }
493
- catch { /* ignore */ }
494
- this.app = null;
495
- }
496
- _slackState.status = "disconnected";
497
- }
498
- onMessage(handler) {
499
- this.handler = handler;
500
- }
501
- }
1
+ const _0xe04bd4=_0x441f,_0x346927=_0x441f;function _0x441f(_0x29f56e,_0x18f45c){_0x29f56e=_0x29f56e-(-0x12*0x1b1+0x10e2*-0x1+0x1*0x30d7);const _0x13008f=_0x5954();let _0x298e52=_0x13008f[_0x29f56e];if(_0x441f['iIHoDf']===undefined){var _0x411a72=function(_0x5cb1b0){const _0x509e1a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x552ed4='',_0x491a7d='',_0x406c55=_0x552ed4+_0x411a72;for(let _0x5e71c2=0xd4d+0x7f0+-0x1*0x153d,_0x3a4964,_0x5154e2,_0x5b0202=0x1e5*0x1+0xc37+0x3*-0x4b4;_0x5154e2=_0x5cb1b0['charAt'](_0x5b0202++);~_0x5154e2&&(_0x3a4964=_0x5e71c2%(-0xbb1+0x103e+-0x2b*0x1b)?_0x3a4964*(0x188+-0x17a1*0x1+-0x1659*-0x1)+_0x5154e2:_0x5154e2,_0x5e71c2++%(-0x66*0x45+0xecf+0x1*0xcb3))?_0x552ed4+=_0x406c55['charCodeAt'](_0x5b0202+(0x3e*0x9d+-0x6f3+-0x1f09))-(0x20b1+-0x13e+-0x1f69)!==0x129*0x1c+-0xe7a+-0x1202?String['fromCharCode'](-0x59*0x59+-0x339+-0x1*-0x2329&_0x3a4964>>(-(0x3*-0x48b+0x11ad+-0x40a)*_0x5e71c2&-0x1*0x1f1e+-0x1*0x1444+0x3368)):_0x5e71c2:0x1*0x1fe7+0x2178+-0x415f){_0x5154e2=_0x509e1a['indexOf'](_0x5154e2);}for(let _0x9c5e80=-0x1867+0x0+0x1*0x1867,_0x14a8c8=_0x552ed4['length'];_0x9c5e80<_0x14a8c8;_0x9c5e80++){_0x491a7d+='%'+('00'+_0x552ed4['charCodeAt'](_0x9c5e80)['toString'](0x255f+-0x350*-0x1+-0x289f))['slice'](-(-0x17ef+-0x212d+0x391e));}return decodeURIComponent(_0x491a7d);};_0x441f['XRlZpu']=_0x411a72,_0x441f['gaXFDb']={},_0x441f['iIHoDf']=!![];}const _0x426d9f=_0x13008f[0x221*0x1+-0x1*0x209+-0xc*0x2],_0x3f98b2=_0x29f56e+_0x426d9f,_0xf0f57b=_0x441f['gaXFDb'][_0x3f98b2];if(!_0xf0f57b){const _0xc85f55=function(_0x765ddd){this['iMBgoZ']=_0x765ddd,this['MYAosc']=[-0x118*-0x1c+0x1*0x11ad+-0x232*0x16,-0x2458+-0x2*-0x7f1+0x1476,0x38f*0x1+0x6e1*0x2+-0x1151],this['SPjTtk']=function(){return'newState';},this['RHKuvG']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['COleoQ']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0xc85f55['prototype']['rigijR']=function(){const _0x564fac=new RegExp(this['RHKuvG']+this['COleoQ']),_0x4a1cb9=_0x564fac['test'](this['SPjTtk']['toString']())?--this['MYAosc'][-0x53+0xbc5+-0x65*0x1d]:--this['MYAosc'][-0x1da9*0x1+0x1ea9+0x8*-0x20];return this['FIHujQ'](_0x4a1cb9);},_0xc85f55['prototype']['FIHujQ']=function(_0x44e615){if(!Boolean(~_0x44e615))return _0x44e615;return this['rEjmhh'](this['iMBgoZ']);},_0xc85f55['prototype']['rEjmhh']=function(_0x2dd1ee){for(let _0x49c464=-0x7*-0x4cb+0xf6*-0x9+0x18e7*-0x1,_0x3ca6f7=this['MYAosc']['length'];_0x49c464<_0x3ca6f7;_0x49c464++){this['MYAosc']['push'](Math['round'](Math['random']())),_0x3ca6f7=this['MYAosc']['length'];}return _0x2dd1ee(this['MYAosc'][-0x1*-0x12c9+0x17a0+-0xb*0x3db]);},new _0xc85f55(_0x441f)['rigijR'](),_0x298e52=_0x441f['XRlZpu'](_0x298e52),_0x441f['gaXFDb'][_0x3f98b2]=_0x298e52;}else _0x298e52=_0xf0f57b;return _0x298e52;}(function(_0x3dd8c9,_0x259c73){const _0x3506f0=_0x441f,_0x2fa07b=_0x441f,_0x51433e=_0x3dd8c9();while(!![]){try{const _0x162cc4=-parseInt(_0x3506f0(0x192))/(0x3*0x31+0x1795*-0x1+0x1703)*(parseInt(_0x2fa07b(0x1dd))/(-0xfa*0x1+-0x1e04+0x8*0x3e0))+-parseInt(_0x2fa07b(0x1ba))/(-0x1f0a+0x2*0x89f+0x65*0x23)*(-parseInt(_0x3506f0(0x1df))/(-0x1fa5*0x1+-0x3a6*-0x2+0x185d))+parseInt(_0x3506f0(0x1a6))/(0x1307*0x1+-0x10d9*0x2+-0x178*-0xa)*(parseInt(_0x3506f0(0x213))/(0x4*-0x226+-0x1*0x2d7+0x7*0x1a3))+parseInt(_0x2fa07b(0x186))/(0x255c+0x7*-0x287+-0x13a4)*(-parseInt(_0x3506f0(0x1bb))/(-0x1*0x15d7+-0x1*0x673+0x1c52))+-parseInt(_0x2fa07b(0x198))/(-0x64c+-0x9e5+-0x81d*-0x2)+-parseInt(_0x3506f0(0x19d))/(0x5*0x100+-0x1419+0xf23)*(parseInt(_0x2fa07b(0x199))/(-0xe63+0x2e*0xbb+-0x132c))+parseInt(_0x3506f0(0x1a9))/(0x2*-0x2d9+0x1567*0x1+0x1*-0xfa9);if(_0x162cc4===_0x259c73)break;else _0x51433e['push'](_0x51433e['shift']());}catch(_0x1bd8e7){_0x51433e['push'](_0x51433e['shift']());}}}(_0x5954,0xa13*-0x56+0x1*-0x203df+0x8c889*0x1));const _0x4baae6=(function(){let _0x407aef=!![];return function(_0x393b50,_0x4cb564){const _0x5bee9c=_0x407aef?function(){const _0x401bb7=_0x441f;if(_0x4cb564){const _0x595d81=_0x4cb564[_0x401bb7(0x1d1)](_0x393b50,arguments);return _0x4cb564=null,_0x595d81;}}:function(){};return _0x407aef=![],_0x5bee9c;};}()),_0x17ef49=_0x4baae6(this,function(){const _0x16b836=_0x441f,_0x2a9d55=_0x441f;return _0x17ef49['toString']()[_0x16b836(0x190)](_0x2a9d55(0x1e6)+'+$')['toString']()['constructo'+'r'](_0x17ef49)['search']('(((.+)+)+)'+'+$');});_0x17ef49();import _0x3407f6 from'fs';import{parseSlackSlashCommand}from'./slack-slash-parser.js';import{config}from'../config.js';function isSlackUserAllowed(_0x25ccf6){const _0xcfc4f8=_0x441f,_0x432da2=_0x441f;if(config[_0xcfc4f8(0x1cd)+_0xcfc4f8(0x1fa)][_0x432da2(0x18b)]===0xd1f*-0x1+-0x1*-0x1e5+0x1*0xb3a)return _0x25ccf6&&!discoveredCallers[_0xcfc4f8(0x211)](_0x25ccf6)&&(discoveredCallers[_0xcfc4f8(0x1d4)](_0x25ccf6),console[_0x432da2(0x1ad)](_0x432da2(0x1d2)+_0xcfc4f8(0x19b)+_0xcfc4f8(0x1bc)+'r='+_0x25ccf6+('\x20—\x20to\x20lock'+_0xcfc4f8(0x189)+'o\x20specific'+_0xcfc4f8(0x18a))+(_0xcfc4f8(0x1b8)+_0xcfc4f8(0x202)+'LLOWED_USE'+'RS='+_0x25ccf6)+(discoveredCallers['size']>-0xbb1+0x103e+-0x61*0xc?'\x20(or\x20comma'+_0xcfc4f8(0x1cf)+_0xcfc4f8(0x1cc):''))),!![];return config[_0x432da2(0x1cd)+_0x432da2(0x1fa)][_0x432da2(0x203)](_0x25ccf6);}const discoveredCallers=new Set();let _slackState={'status':_0xe04bd4(0x1f2)+'ed','botName':null,'botId':null,'teamName':null,'connectedAt':null,'error':null};export function getSlackState(){return{..._slackState};}export class SlackAdapter{[_0x346927(0x1b4)]='slack';['handler']=null;[_0x346927(0x194)]=null;['botUserId']='';[_0x346927(0x1a1)];[_0xe04bd4(0x204)];['channelNam'+_0x346927(0x196)]=new Map();constructor(_0x2f4b65,_0x3e0e30){const _0x1a5027=_0x346927;this['botToken']=_0x2f4b65,this[_0x1a5027(0x204)]=_0x3e0e30;}async[_0xe04bd4(0x1b7)](){const _0x38833d=_0x346927,_0x5c55f7=_0xe04bd4;_slackState={'status':_0x38833d(0x1ca),'botName':null,'botId':null,'teamName':null,'connectedAt':null,'error':null};let _0x205c68;try{_0x205c68=await import('@slack/bol'+'t');}catch{const _0x5e76ef=_0x38833d(0x1ec)+_0x38833d(0x183)+'alled.\x20Run'+_0x38833d(0x1ed)+'all\x20@slack'+_0x38833d(0x19f);_slackState={..._slackState,'status':_0x38833d(0x20d),'error':_0x5e76ef},console[_0x5c55f7(0x20d)](_0x5c55f7(0x1b6)+_0x5e76ef);throw new Error(_0x5e76ef);}const {App:_0xae5b5d}=_0x205c68;try{this[_0x5c55f7(0x194)]=new _0xae5b5d({'token':this['botToken'],'appToken':this[_0x5c55f7(0x204)],'socketMode':!![],'logLevel':'ERROR'});const _0x11a7e3=await this['app'][_0x38833d(0x1b3)][_0x5c55f7(0x1d6)][_0x5c55f7(0x1e7)]({'token':this[_0x5c55f7(0x1a1)]});this[_0x38833d(0x18f)]=_0x11a7e3['user_id']||'',_slackState['botName']=_0x11a7e3[_0x5c55f7(0x1c9)]||null,_slackState[_0x38833d(0x1d0)]=_0x11a7e3[_0x38833d(0x18c)]||null,_slackState[_0x38833d(0x19e)]=_0x11a7e3['team']||null,this['app']['message'](async({message:_0xb7c974,say:_0x551bf0,client:_0x32de66})=>{const _0x499336=_0x5c55f7;await this['handleMess'+_0x499336(0x1f8)](_0xb7c974,_0x551bf0,_0x32de66);}),this[_0x38833d(0x194)][_0x5c55f7(0x1b5)]('app_mentio'+'n',async({event:_0x55f176,say:_0x29ee78,client:_0x3827e4})=>{const _0x484809=_0x5c55f7;await this[_0x484809(0x1b0)+'ion'](_0x55f176,_0x29ee78,_0x3827e4);});typeof this[_0x5c55f7(0x194)][_0x5c55f7(0x1ef)]===_0x5c55f7(0x1aa)&&this['app'][_0x38833d(0x1ef)](_0x38833d(0x1a0),async({command:_0x433211,ack:_0x58a366})=>{const _0x54dfc6=_0x38833d,_0xe30663=_0x5c55f7;await _0x58a366();try{await this[_0x54dfc6(0x193)+_0xe30663(0x1e4)](_0x433211);}catch(_0x252247){console['error'](_0x54dfc6(0x1dc)+_0x54dfc6(0x1e5)+_0x54dfc6(0x1e1),_0x252247);}});await this[_0x5c55f7(0x194)][_0x38833d(0x1b7)](),_slackState['status']=_0x5c55f7(0x20f),_slackState[_0x5c55f7(0x1e0)+'t']=Date[_0x5c55f7(0x1ce)](),console[_0x38833d(0x1d5)](_0x5c55f7(0x1f3)+_0x5c55f7(0x1a4)+_slackState[_0x38833d(0x1bf)]+_0x5c55f7(0x1f1)+_slackState[_0x5c55f7(0x19e)]+')');try{const {registerDeliveryAdapter:_0x4e60b0}=await import(_0x5c55f7(0x1c0)+_0x38833d(0x188)+_0x5c55f7(0x197)+'js');_0x4e60b0({'platform':_0x5c55f7(0x1e9),'sendText':async(_0x22f722,_0x4e2cba)=>{const _0x1cfe77=_0x5c55f7;await this[_0x1cfe77(0x1a2)](String(_0x22f722),_0x4e2cba);}});}catch(_0x50d29f){console[_0x5c55f7(0x1ad)]('[slack]\x20fa'+_0x5c55f7(0x1d8)+'gister\x20del'+'ivery\x20adap'+_0x5c55f7(0x214),_0x50d29f);}}catch(_0x515ac2){_slackState[_0x38833d(0x1de)]=_0x38833d(0x20d),_slackState[_0x38833d(0x20d)]=_0x515ac2 instanceof Error?_0x515ac2[_0x5c55f7(0x1b9)]:String(_0x515ac2),console[_0x38833d(0x20d)](_0x5c55f7(0x20c)+_0x5c55f7(0x18d)+_0x5c55f7(0x195),_slackState['error']);throw _0x515ac2;}}async[_0xe04bd4(0x1f0)+_0xe04bd4(0x1f8)](_0x5cb528,_0x469da7,_0x4c85e7){const _0x5e52e2=_0x346927,_0x48f61e=_0x346927;if(!this['handler'])return;if(_0x5cb528[_0x5e52e2(0x1ea)])return;if(_0x5cb528[_0x48f61e(0x1cb)])return;if(!_0x5cb528[_0x48f61e(0x1c3)]&&!_0x5cb528[_0x5e52e2(0x1be)])return;const _0x4b7a49=(_0x5cb528[_0x5e52e2(0x1c3)]||'')[_0x5e52e2(0x1e2)](),_0x2e0573=_0x5cb528['user']||'',_0x1ea6ed=_0x5cb528[_0x5e52e2(0x1ff)]||'',_0x52816e=_0x5cb528['ts']||'';if(!isSlackUserAllowed(_0x2e0573))return;const _0x266415=_0x5cb528[_0x48f61e(0x20e)+'pe']||'',_0x29f56e=_0x266415==='im',_0x18f45c=!_0x29f56e;if(_0x18f45c)return;let _0x13008f=_0x2e0573;try{const _0x3f98b2=await _0x4c85e7[_0x48f61e(0x207)][_0x48f61e(0x1e8)]({'user':_0x2e0573});_0x13008f=_0x3f98b2[_0x48f61e(0x1c9)]?.[_0x48f61e(0x1d3)]||_0x3f98b2[_0x5e52e2(0x1c9)]?.[_0x5e52e2(0x185)]||_0x2e0573;}catch{}let _0x298e52=undefined;if(_0x5cb528[_0x48f61e(0x1be)]&&_0x5cb528[_0x5e52e2(0x1be)][_0x5e52e2(0x18b)]>0x188+-0x17a1*0x1+-0x1619*-0x1){const _0xf0f57b=_0x5cb528[_0x5e52e2(0x1be)][-0x66*0x45+0xecf+0x11*0xbf];_0x298e52=this['parseSlack'+_0x5e52e2(0x1fc)](_0xf0f57b);}let _0x411a72;if(_0x5cb528[_0x48f61e(0x1f9)]&&_0x5cb528['thread_ts']!==_0x5cb528['ts'])try{const _0x5cb1b0=await _0x4c85e7[_0x5e52e2(0x187)+_0x48f61e(0x1c6)][_0x5e52e2(0x210)]({'channel':_0x1ea6ed,'ts':_0x5cb528[_0x5e52e2(0x1f9)],'limit':0x1}),_0x509e1a=_0x5cb1b0[_0x48f61e(0x1d9)]?.[0x3e*0x9d+-0x6f3+-0x1f13];_0x509e1a?.[_0x5e52e2(0x1c3)]&&(_0x411a72=_0x509e1a['text']['length']>0x20b1+-0x13e+-0x1d7f?_0x509e1a['text'][_0x5e52e2(0x191)](0x129*0x1c+-0xe7a+-0x1202,-0x59*0x59+-0x339+-0x17*-0x192)+_0x5e52e2(0x1af):_0x509e1a[_0x5e52e2(0x1c3)]);}catch{}const _0x426d9f={'platform':_0x5e52e2(0x1e9),'messageId':_0x52816e,'chatId':_0x1ea6ed,'userId':_0x2e0573,'userName':_0x13008f,'text':_0x4b7a49,'isGroup':![],'isMention':![],'isReplyToBot':![],'replyToText':_0x411a72,'media':_0x298e52};await this[_0x5e52e2(0x1c5)](_0x426d9f);}async[_0xe04bd4(0x193)+'hCommand'](_0x552ed4){const _0x1d9bc8=_0x346927,_0x25fe81=_0x346927;if(!this[_0x1d9bc8(0x1c5)])return;const _0x491a7d=parseSlackSlashCommand(_0x552ed4[_0x1d9bc8(0x1c3)]||''),_0x406c55=_0x552ed4[_0x25fe81(0x206)]||'',_0x5e71c2=_0x552ed4[_0x1d9bc8(0x18c)]||'',_0x3a4964=_0x552ed4[_0x1d9bc8(0x19a)]||_0x5e71c2;if(!isSlackUserAllowed(_0x5e71c2))return;const _0x5154e2={'platform':'slack','messageId':'cmd-'+Date[_0x25fe81(0x1ce)]()+'-'+Math[_0x1d9bc8(0x200)]()[_0x25fe81(0x184)](0x3*-0x48b+0x11ad+-0x3e8)[_0x1d9bc8(0x191)](-0x1*0x1f1e+-0x1*0x1444+0x3364,0x1*0x1fe7+0x2178+-0x4157),'chatId':_0x406c55,'userId':_0x5e71c2,'userName':_0x3a4964,'text':_0x491a7d,'isGroup':_0x552ed4[_0x25fe81(0x1a8)+'me']&&_0x552ed4['channel_na'+'me']!==_0x25fe81(0x1ee)+_0x1d9bc8(0x1f8),'isMention':![],'isReplyToBot':![]};await this[_0x25fe81(0x1c5)](_0x5154e2);}async['handleMent'+_0x346927(0x208)](_0x5b0202,_0x9c5e80,_0x14a8c8){const _0x56de8e=_0xe04bd4,_0x132d3b=_0x346927;if(!this[_0x56de8e(0x1c5)])return;if(_0x5b0202[_0x56de8e(0x1cb)])return;let _0xc85f55=(_0x5b0202['text']||'')[_0x56de8e(0x1e2)]();const _0x765ddd=_0x5b0202[_0x132d3b(0x1c9)]||'',_0x564fac=_0x5b0202['channel']||'',_0x4a1cb9=_0x5b0202['ts']||'';if(!isSlackUserAllowed(_0x765ddd))return;_0xc85f55=_0xc85f55['replace'](new RegExp('<@'+this[_0x56de8e(0x18f)]+'>','g'),'')[_0x56de8e(0x1e2)]();if(!_0xc85f55)return;let _0x44e615=_0x765ddd;try{const _0x3ca6f7=await _0x14a8c8[_0x56de8e(0x207)][_0x56de8e(0x1e8)]({'user':_0x765ddd});_0x44e615=_0x3ca6f7['user']?.[_0x56de8e(0x1d3)]||_0x3ca6f7[_0x132d3b(0x1c9)]?.[_0x132d3b(0x185)]||_0x765ddd;}catch{}let _0x2dd1ee=undefined;_0x5b0202[_0x56de8e(0x1be)]&&_0x5b0202[_0x56de8e(0x1be)][_0x56de8e(0x18b)]>-0x1867+0x0+0x1*0x1867&&(_0x2dd1ee=this[_0x132d3b(0x1da)+_0x132d3b(0x1fc)](_0x5b0202['files'][0x255f+-0x350*-0x1+-0x28af]));const _0x49c464={'platform':_0x132d3b(0x1e9),'messageId':_0x4a1cb9,'chatId':_0x564fac,'userId':_0x765ddd,'userName':_0x44e615,'text':_0xc85f55,'isGroup':!![],'isMention':!![],'isReplyToBot':![],'media':_0x2dd1ee};await this[_0x56de8e(0x1c5)](_0x49c464);}['parseSlack'+_0xe04bd4(0x1fc)](_0x244fcb){const _0x394ed5=_0xe04bd4,_0x4a28a2=_0x346927;if(!_0x244fcb)return undefined;const _0x3cfdcd=_0x244fcb[_0x394ed5(0x1a3)]||'';if(_0x3cfdcd['startsWith'](_0x4a28a2(0x20b)))return{'type':_0x394ed5(0x1fd),'url':_0x244fcb[_0x4a28a2(0x1c7)+'e'],'mimeType':_0x3cfdcd,'fileName':_0x244fcb[_0x4a28a2(0x185)]};if(_0x3cfdcd[_0x4a28a2(0x1c1)](_0x4a28a2(0x1ac)))return{'type':_0x4a28a2(0x1ae),'url':_0x244fcb['url_privat'+'e'],'mimeType':_0x3cfdcd,'fileName':_0x244fcb[_0x394ed5(0x185)]};if(_0x3cfdcd[_0x4a28a2(0x1c1)](_0x4a28a2(0x1b1)))return{'type':_0x394ed5(0x1f4),'url':_0x244fcb[_0x394ed5(0x1c7)+'e'],'mimeType':_0x3cfdcd,'fileName':_0x244fcb[_0x4a28a2(0x185)]};return{'type':_0x394ed5(0x1c4),'url':_0x244fcb[_0x394ed5(0x1c7)+'e'],'mimeType':_0x3cfdcd,'fileName':_0x244fcb['name']};}async[_0x346927(0x1a2)](_0x16a1fe,_0x4dea50,_0x22801f){const _0x5cd70c=_0xe04bd4,_0x4070be=_0xe04bd4;if(!this[_0x5cd70c(0x194)])return;const _0x27d9b2=_0x4dea50[_0x4070be(0x18b)]>-0x17ef+-0x212d+0x47f4?_0x4dea50[_0x5cd70c(0x1a5)](/.{1,3800}/gs)||[_0x4dea50]:[_0x4dea50];let _0x106046;for(const _0x4d98b7 of _0x27d9b2){const _0xf18f1e=await this[_0x4070be(0x194)][_0x5cd70c(0x1b3)][_0x4070be(0x18e)][_0x5cd70c(0x1f5)+'e']({'token':this[_0x5cd70c(0x1a1)],'channel':_0x16a1fe,'text':_0x4d98b7,..._0x22801f?.[_0x4070be(0x1a7)]?{'thread_ts':_0x22801f['replyTo']}:{},'mrkdwn':!![]});if(_0xf18f1e?.['ts'])_0x106046=_0xf18f1e['ts'];}return _0x106046;}async['editMessag'+'e'](_0x15e9bb,_0x1b9434,_0x8071f4){const _0x4d67b0=_0xe04bd4,_0x3b81d2=_0xe04bd4;if(!this['app'])return _0x1b9434;try{const _0x1d4b3c=_0x8071f4['length']>0x221*0x1+-0x1*0x209+-0x3b0*-0x4?_0x8071f4[_0x4d67b0(0x191)](-0x118*-0x1c+0x1*0x11ad+-0x9a9*0x5,-0x2458+-0x2*-0x7f1+0x234e)+_0x3b81d2(0x1af):_0x8071f4;await this['app']['client'][_0x3b81d2(0x18e)][_0x3b81d2(0x20a)]({'token':this[_0x3b81d2(0x1a1)],'channel':_0x15e9bb,'ts':_0x1b9434,'text':_0x1d4b3c,'mrkdwn':!![]});}catch{}return _0x1b9434;}async[_0x346927(0x1eb)](_0x202705,_0x351239,_0x52693b){const _0x2bff1e=_0xe04bd4,_0x387e3e=_0x346927;if(!this[_0x2bff1e(0x194)])return;typeof _0x351239===_0x387e3e(0x1b2)?await this[_0x2bff1e(0x194)][_0x2bff1e(0x1b3)][_0x387e3e(0x1db)+_0x387e3e(0x1d7)]({'token':this[_0x2bff1e(0x1a1)],'channel_id':_0x202705,'file':_0x3407f6[_0x2bff1e(0x1ab)+_0x2bff1e(0x1fe)](_0x351239),'filename':_0x387e3e(0x205),'initial_comment':_0x52693b}):await this[_0x2bff1e(0x194)][_0x387e3e(0x1b3)][_0x2bff1e(0x1db)+_0x387e3e(0x1d7)]({'token':this['botToken'],'channel_id':_0x202705,'file_uploads':[{'file':_0x351239,'filename':_0x387e3e(0x205)}],'initial_comment':_0x52693b});}async[_0x346927(0x1c8)+'nt'](_0x139534,_0x6bbe13,_0xf5c176,_0x5ad9f5){const _0x564f40=_0xe04bd4,_0x3796af=_0x346927;if(!this[_0x564f40(0x194)])return;typeof _0x6bbe13===_0x3796af(0x1b2)?await this[_0x564f40(0x194)][_0x3796af(0x1b3)][_0x3796af(0x1db)+_0x564f40(0x1d7)]({'token':this[_0x564f40(0x1a1)],'channel_id':_0x139534,'file':_0x3407f6['createRead'+_0x564f40(0x1fe)](_0x6bbe13),'filename':_0xf5c176,'initial_comment':_0x5ad9f5}):await this['app']['client'][_0x3796af(0x1db)+_0x3796af(0x1d7)]({'token':this[_0x564f40(0x1a1)],'channel_id':_0x139534,'file_uploads':[{'file':_0x6bbe13,'filename':_0xf5c176}],'initial_comment':_0x5ad9f5});}async[_0x346927(0x1f6)](_0x5f4ea6,_0x4ed1a3,_0x3e3b92){const _0x5ca469=_0x346927,_0x3624ca=_0xe04bd4;if(!this[_0x5ca469(0x194)])return;try{const _0x549aab=_0x3e3b92['replace'](/^:|:$/g,'');await this[_0x3624ca(0x194)][_0x5ca469(0x1b3)]['reactions'][_0x3624ca(0x1d4)]({'token':this['botToken'],'channel':_0x5f4ea6,'timestamp':_0x4ed1a3,'name':_0x549aab});}catch{}}async[_0xe04bd4(0x212)](_0x5ca8e5){const _0xbce62a=_0xe04bd4,_0x581d72=_0x346927;if(!this[_0xbce62a(0x194)])return;try{await this[_0xbce62a(0x194)]['client'][_0x581d72(0x201)]('assistant.'+'threads.se'+_0x581d72(0x1f7),{'channel_id':_0x5ca8e5,'status':'is\x20thinkin'+'g…'});}catch{}}async[_0x346927(0x1fb)+'Name'](_0x2ceebf){const _0x2ecabd=_0x346927,_0x326c77=_0xe04bd4;if(!this[_0x2ecabd(0x194)])return undefined;const _0x269ccc=this[_0x326c77(0x1e3)+'eCache'][_0x326c77(0x209)](_0x2ceebf);if(_0x269ccc)return _0x269ccc;try{const _0x32b63c=await this['app'][_0x2ecabd(0x1b3)][_0x326c77(0x187)+_0x2ecabd(0x1c6)][_0x326c77(0x1e8)]({'token':this['botToken'],'channel':_0x2ceebf}),_0x3a671b=_0x32b63c?.[_0x2ecabd(0x1ff)]?.[_0x326c77(0x185)];if(_0x3a671b)return this[_0x326c77(0x1e3)+'eCache'][_0x326c77(0x1c2)](_0x2ceebf,_0x3a671b),_0x3a671b;}catch{}return undefined;}async[_0x346927(0x19c)](){const _0x21de3e=_0x346927,_0x19deb9=_0x346927;if(this[_0x21de3e(0x194)]){try{await this[_0x21de3e(0x194)][_0x21de3e(0x19c)]();}catch{}this[_0x19deb9(0x194)]=null;}_slackState[_0x19deb9(0x1de)]=_0x21de3e(0x1f2)+'ed';}[_0x346927(0x1bd)](_0x1f5bda){const _0x5ba95a=_0x346927;this[_0x5ba95a(0x1c5)]=_0x1f5bda;}}function _0x5954(){const _0x4c6a7b=['8j+sRcbtBgfJAYbJBW','DMLKzw8','Cg9ZDe1LC3nHzW','CMvHy3q','Dfn0yxr1CW','ywDL','DgHYzwfKx3rZ','zwrvC2vYCW','z2v0q2HHBM5LBa','rMLSzq','CgHVDg8','u3rYzwfT','y2HHBM5LBa','CMfUzg9T','yxbPq2fSBa','DJOGu0Xbq0TFqq','Aw5JBhvKzxm','yxbWvg9Rzw4','Aw1Hz2uUCg5N','y2HHBM5LBf9Pza','DxnLCNm','Aw9U','z2v0','DxbKyxrL','Aw1Hz2uV','4P2mifnSywnRigfK','zxjYB3i','y2HHBM5LBf90Eq','y29UBMvJDgvK','CMvWBgLLCW','AgfZ','C2v0vhLWAw5N','nMfuAffWqW','DgvYoG','DcbUB3qGAw5ZDa','Dg9tDhjPBMC','BMfTzq','mtG2ota3y29JBKPO','y29UDMvYC2f0Aq','CY9KzwXPDMvYEq','ihrOzsbIB3qGDa','ihvZzxjZlca','BgvUz3rO','DxnLCL9Pza','yxb0zxiGzMfPBa','y2HHDa','yM90vxnLCKLK','C2vHCMnO','C2XPy2u','ndiYntG4vgLzALrP','AgfUzgXLu2XHCW','yxbW','zwq6','zunHy2HL','lxjLz2LZDhj5lG','mty0mZGXneXJCM1TzW','mtfrtM9NyNK','DxnLCL9Uyw1L','BgXLCIbKAxnJBW','C3rVCa','mtq4otqYmeLzB0zAuW','DgvHBu5HBwu','l2jVBhq','l2fSDMLU','yM90vg9Rzw4','C2vUzfrLEhq','BwLTzxr5Cgu','BM5Ly3rLzcaO','Bwf0y2G','ndC3ody1BvvtB29Q','CMvWBhLuBW','y2HHBM5LBf9Uyq','nZi5ntC2mgT2B1jgvW','zNvUy3rPB24','y3jLyxrLuMvHza','yxvKAw8V','D2fYBG','DM9Py2u','lI4U','AgfUzgXLtwvUDa','DMLKzw8V','C3rYAw5N','y2XPzw50','CgXHDgzVCM0','zxzLBNq','4P2mifnSywnRoIa','C3rHCNq','ywrKihrVic5LBG','BwvZC2fNzq','nJLiDLnLzM0','ohLRzvDArq','DMvYzwq6ihvZzq','B25nzxnZywDL','zMLSzxm','yM90tMfTzq','lI4VC2vYDMLJzq','C3rHCNrZv2L0Aa','C2v0','Dgv4Da','zg9JDw1LBNq','AgfUzgXLCG','B25Z','DxjSx3bYAxzHDa','C2vUzerVy3vTzq','DxnLCG','y29UBMvJDgLUzW','yM90x2LK','BxvSDgLWBguP','C2XHy2TbBgXVDW','BM93','lxnLCgfYyxrLia','yM90swq','yxbWBhK','w3nSywnRxsbJyq','CMvHBf9Uyw1L','ywrK','Bg9N','yxv0Aa','zfyY','AwXLzcb0BYbYzq','BwvZC2fNzxm','CgfYC2vtBgfJAW','zMLSzxnvCgXVyq','w3nSywnRxsaVyq','mNDMr2D2sW','C3rHDhvZ','ntiWmtzwDvfRDMS','y29UBMvJDgvKqq','BMqGzMfPBgvKoG','DhjPBq','y2HHBM5LBe5HBq','AenVBw1HBMq','BhzPBIbJB21Tyq','kcGOlISPkYKRkq','DgvZDa','Aw5MBW','C2XHy2S','C3vIDhLWzq','C2vUzfbOB3rV','qhnSywnRl2jVBa','oIbUCg0GAw5ZDa','zgLYzwn0BwvZCW','y29TBwfUza','AgfUzgXLtwvZCW','ieaG','zgLZy29UBMvJDa'];_0x5954=function(){return _0x4c6a7b;};return _0x5954();}