alvin-bot 5.6.2 → 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 (137) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +1 -1
  3. package/dist/claude.js +1 -102
  4. package/dist/config.js +1 -96
  5. package/dist/engine.js +1 -90
  6. package/dist/find-claude-binary.js +1 -98
  7. package/dist/handlers/async-agent-chunk-handler.js +1 -50
  8. package/dist/handlers/background-bypass.js +1 -75
  9. package/dist/handlers/commands.js +1 -2336
  10. package/dist/handlers/cron-progress.js +1 -52
  11. package/dist/handlers/document.js +1 -194
  12. package/dist/handlers/message.js +1 -959
  13. package/dist/handlers/photo.js +1 -154
  14. package/dist/handlers/platform-message.js +1 -360
  15. package/dist/handlers/stuck-timer.js +1 -54
  16. package/dist/handlers/video.js +1 -237
  17. package/dist/handlers/voice.js +1 -148
  18. package/dist/i18n.js +1 -805
  19. package/dist/index.js +1 -697
  20. package/dist/init-data-dir.js +1 -98
  21. package/dist/middleware/auth.js +1 -233
  22. package/dist/migrate.js +1 -162
  23. package/dist/paths.js +1 -146
  24. package/dist/platforms/discord.js +1 -175
  25. package/dist/platforms/index.js +1 -130
  26. package/dist/platforms/signal.js +1 -205
  27. package/dist/platforms/slack-slash-parser.js +1 -32
  28. package/dist/platforms/slack.js +1 -501
  29. package/dist/platforms/telegram.js +1 -111
  30. package/dist/platforms/types.js +1 -8
  31. package/dist/platforms/whatsapp-auth-helpers.js +1 -53
  32. package/dist/platforms/whatsapp.js +1 -707
  33. package/dist/providers/claude-sdk-provider.js +1 -565
  34. package/dist/providers/codex-cli-provider.js +1 -134
  35. package/dist/providers/index.js +1 -7
  36. package/dist/providers/ollama-provider.js +1 -32
  37. package/dist/providers/openai-compatible.js +1 -406
  38. package/dist/providers/registry.js +1 -352
  39. package/dist/providers/runtime-header.js +1 -45
  40. package/dist/providers/tool-executor.js +1 -475
  41. package/dist/providers/types.js +1 -227
  42. package/dist/services/access.js +1 -144
  43. package/dist/services/allowed-users-gate.js +1 -56
  44. package/dist/services/alvin-dispatch.js +1 -130
  45. package/dist/services/alvin-mcp-tools.js +1 -104
  46. package/dist/services/asset-index.js +1 -224
  47. package/dist/services/async-agent-parser.js +1 -418
  48. package/dist/services/async-agent-watcher.js +1 -443
  49. package/dist/services/auto-diagnostic.js +1 -228
  50. package/dist/services/broadcast.js +1 -52
  51. package/dist/services/browser-manager.js +1 -562
  52. package/dist/services/browser-webfetch.js +1 -127
  53. package/dist/services/browser.js +1 -121
  54. package/dist/services/cdp-bootstrap.js +1 -357
  55. package/dist/services/compaction.js +1 -144
  56. package/dist/services/critical-notify.js +1 -203
  57. package/dist/services/cron-resolver.js +1 -58
  58. package/dist/services/cron-scheduling.js +1 -310
  59. package/dist/services/cron.js +1 -861
  60. package/dist/services/custom-tools.js +1 -317
  61. package/dist/services/delivery-queue.js +1 -173
  62. package/dist/services/delivery-registry.js +1 -21
  63. package/dist/services/disk-cleanup.js +1 -203
  64. package/dist/services/elevenlabs.js +1 -58
  65. package/dist/services/embeddings/auto-detect.js +1 -74
  66. package/dist/services/embeddings/fts5.js +1 -108
  67. package/dist/services/embeddings/gemini.js +1 -65
  68. package/dist/services/embeddings/index.js +1 -496
  69. package/dist/services/embeddings/ollama.js +1 -78
  70. package/dist/services/embeddings/openai.js +1 -49
  71. package/dist/services/embeddings/provider.js +1 -22
  72. package/dist/services/embeddings/vector-base.js +1 -113
  73. package/dist/services/embeddings-migration.js +1 -193
  74. package/dist/services/embeddings.js +1 -9
  75. package/dist/services/env-file.js +1 -50
  76. package/dist/services/exec-guard.js +1 -71
  77. package/dist/services/fallback-order.js +1 -154
  78. package/dist/services/file-permissions.js +1 -93
  79. package/dist/services/heartbeat-file.js +1 -65
  80. package/dist/services/heartbeat.js +1 -313
  81. package/dist/services/hooks.js +1 -44
  82. package/dist/services/imagegen.js +1 -72
  83. package/dist/services/language-detect.js +1 -154
  84. package/dist/services/markdown.js +1 -63
  85. package/dist/services/mcp.js +1 -263
  86. package/dist/services/memory-extractor.js +1 -178
  87. package/dist/services/memory-inject-mode.js +1 -43
  88. package/dist/services/memory-layers.js +1 -156
  89. package/dist/services/memory.js +1 -146
  90. package/dist/services/ollama-manager.js +1 -339
  91. package/dist/services/permissions-wizard.js +1 -291
  92. package/dist/services/personality.js +1 -376
  93. package/dist/services/plugins.js +1 -171
  94. package/dist/services/preflight.js +1 -292
  95. package/dist/services/process-manager.js +1 -291
  96. package/dist/services/release-highlights.js +1 -79
  97. package/dist/services/reminders.js +1 -97
  98. package/dist/services/restart.js +1 -48
  99. package/dist/services/security-audit.js +1 -74
  100. package/dist/services/self-diagnosis.js +1 -272
  101. package/dist/services/self-search.js +1 -129
  102. package/dist/services/session-persistence.js +1 -237
  103. package/dist/services/session.js +1 -282
  104. package/dist/services/skills.js +1 -290
  105. package/dist/services/ssrf-guard.js +1 -162
  106. package/dist/services/standing-orders.js +1 -29
  107. package/dist/services/steer-channel.js +1 -46
  108. package/dist/services/stop-controller.js +1 -52
  109. package/dist/services/subagent-dedup.js +1 -0
  110. package/dist/services/subagent-delivery.js +1 -452
  111. package/dist/services/subagent-stats.js +1 -123
  112. package/dist/services/subagents.js +1 -814
  113. package/dist/services/sudo.js +1 -329
  114. package/dist/services/telegram.js +1 -158
  115. package/dist/services/timing-safe-bearer.js +1 -51
  116. package/dist/services/tool-discovery.js +1 -214
  117. package/dist/services/trends.js +1 -580
  118. package/dist/services/updater.js +1 -291
  119. package/dist/services/usage-tracker.js +1 -144
  120. package/dist/services/users.js +1 -271
  121. package/dist/services/voice.js +1 -104
  122. package/dist/services/watchdog-brake.js +1 -154
  123. package/dist/services/watchdog.js +1 -311
  124. package/dist/services/workspaces.js +1 -276
  125. package/dist/tui/index.js +1 -667
  126. package/dist/util/console-formatter.js +1 -109
  127. package/dist/util/debounce.js +1 -24
  128. package/dist/util/telegram-error-filter.js +1 -62
  129. package/dist/version.js +1 -24
  130. package/dist/web/bind-strategy.js +1 -42
  131. package/dist/web/canvas.js +1 -30
  132. package/dist/web/doctor-api.js +1 -604
  133. package/dist/web/openai-compat.js +1 -252
  134. package/dist/web/server.js +1 -1831
  135. package/dist/web/setup-api.js +1 -1101
  136. package/package.json +5 -2
  137. 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();}