alvin-bot 5.7.0 → 5.8.1

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 +25 -0
  2. package/README.md +25 -31
  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 -174
  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 -583
  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 -86
  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 -1902
  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 _0x9c48b=_0x10d0,_0x476279=_0x10d0;(function(_0x39301e,_0x379a4e){const _0x2e56cf=_0x10d0,_0x326796=_0x10d0,_0x35653d=_0x39301e();while(!![]){try{const _0x22c746=parseInt(_0x2e56cf(0xf5))/(0x11*0x5f+-0x25*-0xeb+0x319*-0xd)+-parseInt(_0x326796(0xbf))/(0x26ba+-0xc5*-0x3+-0x2907)*(parseInt(_0x326796(0xac))/(0x606+0x13fa*-0x1+0xdf7))+parseInt(_0x326796(0x8b))/(0xc27+0x12f8+0x1f1b*-0x1)+-parseInt(_0x2e56cf(0xdb))/(0x126d*-0x1+0x300+0x1*0xf72)+-parseInt(_0x2e56cf(0xfc))/(-0xa50*-0x1+-0x1938*-0x1+-0x2382)*(parseInt(_0x326796(0x96))/(0x193a+0xb2a*0x1+-0x245d))+-parseInt(_0x2e56cf(0xb4))/(0xc9a+-0x1174+0x32*0x19)*(-parseInt(_0x2e56cf(0xf0))/(0x12*-0x15d+-0x4*-0x1a6+0x11fb*0x1))+parseInt(_0x326796(0xe2))/(0x1a3d+-0x9e*0x11+-0xfb5);if(_0x22c746===_0x379a4e)break;else _0x35653d['push'](_0x35653d['shift']());}catch(_0x5c3169){_0x35653d['push'](_0x35653d['shift']());}}}(_0x2aa3,-0x7af5c+-0x7*0xa1bd+0x11338b));const _0x6900f9=(function(){let _0xbfd9b7=!![];return function(_0x2e26e1,_0x5c723b){const _0x11dcac=_0xbfd9b7?function(){if(_0x5c723b){const _0x26b37=_0x5c723b['apply'](_0x2e26e1,arguments);return _0x5c723b=null,_0x26b37;}}:function(){};return _0xbfd9b7=![],_0x11dcac;};}()),_0xf83200=_0x6900f9(this,function(){const _0x361241=_0x10d0,_0x56be55=_0x10d0;return _0xf83200[_0x361241(0xca)]()[_0x56be55(0xa0)](_0x361241(0xc1)+'+$')['toString']()[_0x56be55(0xaf)+'r'](_0xf83200)[_0x56be55(0xa0)](_0x56be55(0xc1)+'+$');});_0xf83200();function _0x2aa3(){const _0x52333c=['ndm3odiYBvLICKHu','DxnLCG','kcGOlISPkYKRkq','zfyY','yxb0zxiGzMfPBa','y29UBMvJDgvK','w3nSywnRxsaVyq','ywXSzwqUifj1BG','AgfZ','yxv0Aa','DJOGu0Xbq0TFqq','Dg9tDhjPBMC','yxbW','y29TBwfUza','lxjLz2LZDhj5lG','8j+sRcbtBgfJAYbJBW','D2fYBG','DgvHBq','yM90vg9Rzw4','zwrvC2vYCW','DgvZDa','y2XPzw50','y2HHBM5LBa','z2LZDgvYigrLBa','DxbKyxrL','zgLZy29UBMvJDa','AwXLzcb0BYbYzq','DxnLCL9Pza','mJa0mZy1nvnjvLbTwa','rvjst1i','Aw1Hz2uUCg5N','Dgv4Da','DMLKzw8','AgfUzgXLu2XHCW','Bwf0y2G','mZCWnJCZmhPny3bLBW','B25nzxnZywDL','yxnZAxn0yw50lG','CgfYC2vtBgfJAW','CMvHy3rPB25Z','DgHYzwfKx3rZ','B25Z','AgfUzgXLCG','y2HHBM5LBf90Eq','ywDL','CMvHy3q','BMqGzMfPBgvKoG','yM90x2LK','CMvWBgfJzq','ntmZndu3t3LKDLDh','BgvUz3rO','CY9KzwXPDMvYEq','zNvUy3rPB24','yxbWx21LBNrPBW','nJm3mtDKz1fuzhe','tMfTzq','C3rVCa','C2vUzfrLEhq','DgvHBu5HBwu','C3rHCNrZv2L0Aa','BM5Ly3rLzcaO','mZe4rK1ItvfW','DxjSx3bYAxzHDa','z2v0q2HHBM5LBa','zunHy2HL','zxjYB3i','zwrPDe1LC3nHzW','CMvHBf9Uyw1L','BgXLCIbKAxnJBW','C3rHCNq','C2v0','y2HHDa','w3nSywnRxsbMyq','C2XHy2TbBgXVDW','lxnLCgfYyxrLia','zwq6','yxbWvg9Rzw4','C2vUzfbOB3rV','l2fSDMLU','CMfUzg9T','C2XHy2S','C3vIDhLWzq','ywrKihrVic5LBG','rMLSzq','ywrK','BYbZCgvJAwzPyW','AgfUzgXLtwvUDa','mtG3mdm2ngzZC1DRBa','zMLSzxm','y29UDMvYC2f0Aq','BwLTzxr5Cgu','y29UBMvJDgLUzW','DMvYzwq6ihvZzq','yM90tMfTzq','u3rYzwfT','DcbUB3qGAw5ZDa','ywXSiebZBgfJAW','C2L6zq','mJm0ntDKu3LdENi','zg9JDw1LBNq','DM9Py2u','z2v0','DgvYoG','BwvZC2fNzq','yM90swq','Aw5JBhvKzxm','C2XPy2u','BhzPBIbJB21Tyq','C2vHCMnO','yM90vxnLCKLK','y2HHBM5LBe5HBq','zMLSzxnvCgXVyq','4P2mifnSywnRigfK','yxvKAw8V','Aw9U','w3nSywnRxsbJyq','DxnLCL9Uyw1L','CgHVDg8','y2HHBM5LBf9Uyq','iokaLcb0BYbSB2nR','m2HNsgLmEq','C2v0vhLWAw5N','ieaG','y29UC3rYDwn0BW','C3rYAw5N','DhjPBq','ihvZzxjZlca','AgfUzgXLtwvZCW','mZjzshfXA1G','DxnLCNm','BMfTzq','qhnSywnRl2jVBa','4P2mifnSywnRoIa','AenVBw1HBMq','Aw5MBW','C3rHDhvZ','teXpv0vex1vtrq','CgXHDgzVCM0','BM93'];_0x2aa3=function(){return _0x52333c;};return _0x2aa3();}import _0x14338 from'fs';import{parseSlackSlashCommand}from'./slack-slash-parser.js';import{config}from'../config.js';function isSlackUserAllowed(_0x523cfd){const _0x176b37=_0x10d0,_0x4e12f1=_0x10d0;if(config[_0x176b37(0x108)+_0x4e12f1(0xd2)]['length']===0x4d0+0xb*-0xa5+0x247)return _0x523cfd&&!discoveredCallers[_0x176b37(0xc7)](_0x523cfd)&&(discoveredCallers[_0x4e12f1(0x113)](_0x523cfd),console['warn'](_0x4e12f1(0xa7)+_0x4e12f1(0x103)+_0x176b37(0x90)+'r='+_0x523cfd+(_0x4e12f1(0xab)+'\x20the\x20bot\x20t'+_0x176b37(0x114)+_0x4e12f1(0xb2))+(_0x176b37(0x111)+_0x4e12f1(0xc9)+_0x4e12f1(0xbc)+'RS='+_0x523cfd)+(discoveredCallers[_0x4e12f1(0x95)]>0x2d9+-0x57*0x69+0x20d7*0x1?'\x20(or\x20comma'+_0x176b37(0x109)+'multiple)':''))),!![];return config['slackAllow'+_0x4e12f1(0xd2)][_0x4e12f1(0x9d)](_0x523cfd);}const discoveredCallers=new Set();let _slackState={'status':_0x9c48b(0xd8)+'ed','botName':null,'botId':null,'teamName':null,'connectedAt':null,'error':null};export function getSlackState(){return{..._slackState};}function _0x10d0(_0x208eec,_0x1b9b7f){_0x208eec=_0x208eec-(0x4b7+0xba+-0x4e7);const _0x2ff912=_0x2aa3();let _0x585bd8=_0x2ff912[_0x208eec];if(_0x10d0['gxWTGX']===undefined){var _0x2ce475=function(_0x5242e0){const _0x3cb849='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2b62fe='',_0x471f0c='',_0x2c4507=_0x2b62fe+_0x2ce475;for(let _0x1b8c67=-0x1*0x423+-0x2636+0x2a59,_0x176777,_0x26cd63,_0x4c29be=-0x2*-0xb26+-0x1bcf+0x11*0x53;_0x26cd63=_0x5242e0['charAt'](_0x4c29be++);~_0x26cd63&&(_0x176777=_0x1b8c67%(-0x1b74+0x2d9+-0x21*-0xbf)?_0x176777*(0xeba+-0x81*-0x4c+-0x2*0x1a63)+_0x26cd63:_0x26cd63,_0x1b8c67++%(-0x1fb7+-0xa7*0xf+0x2984))?_0x2b62fe+=_0x2c4507['charCodeAt'](_0x4c29be+(0x10d7+0x1ba*0x7+0x9a1*-0x3))-(-0xfc+0x1*0x2133+-0x1*0x202d)!==-0x327*-0xb+0xb*-0xf1+0x1*-0x1852?String['fromCharCode'](0x7b7+0xb*0x2ea+0x26c6*-0x1&_0x176777>>(-(-0x233*-0x10+0x1*-0xc87+-0x16a7*0x1)*_0x1b8c67&0x2610+0x1*0xdb2+-0x33bc)):_0x1b8c67:0x5f3*0x5+-0x205+-0x1bba){_0x26cd63=_0x3cb849['indexOf'](_0x26cd63);}for(let _0x27bc14=0x55d*-0x5+0x8bd*-0x3+0x3508,_0x22998b=_0x2b62fe['length'];_0x27bc14<_0x22998b;_0x27bc14++){_0x471f0c+='%'+('00'+_0x2b62fe['charCodeAt'](_0x27bc14)['toString'](0xd02+-0x2545+-0x1df*-0xd))['slice'](-(-0x1052+0x1388+-0x334));}return decodeURIComponent(_0x471f0c);};_0x10d0['KEjkyF']=_0x2ce475,_0x10d0['RhLgaE']={},_0x10d0['gxWTGX']=!![];}const _0x183804=_0x2ff912[0x121f*-0x1+-0x11b*-0x6+0xb7d],_0x2065b3=_0x208eec+_0x183804,_0x125445=_0x10d0['RhLgaE'][_0x2065b3];if(!_0x125445){const _0x575321=function(_0x1be253){this['CiaUhU']=_0x1be253,this['TVFiCp']=[-0x3*-0x473+-0x5*-0x1f3+-0x1717*0x1,0x12be*-0x1+-0x1ebb+-0x5*-0x9e5,-0x8f9*0x1+0xaeb+-0x1f2],this['ImIjGb']=function(){return'newState';},this['UczETA']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['qeaZtl']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x575321['prototype']['aUQYcD']=function(){const _0x4b4c63=new RegExp(this['UczETA']+this['qeaZtl']),_0x39d7e6=_0x4b4c63['test'](this['ImIjGb']['toString']())?--this['TVFiCp'][0x24ac+-0x5c*0x44+-0xc3b*0x1]:--this['TVFiCp'][-0x362+0x1e8c+-0x1b2a];return this['NpkSYu'](_0x39d7e6);},_0x575321['prototype']['NpkSYu']=function(_0x78a653){if(!Boolean(~_0x78a653))return _0x78a653;return this['Rxucai'](this['CiaUhU']);},_0x575321['prototype']['Rxucai']=function(_0x3067ec){for(let _0x5d3cdc=-0xe1e+0xe*0x28b+-0x157c,_0x829dd4=this['TVFiCp']['length'];_0x5d3cdc<_0x829dd4;_0x5d3cdc++){this['TVFiCp']['push'](Math['round'](Math['random']())),_0x829dd4=this['TVFiCp']['length'];}return _0x3067ec(this['TVFiCp'][0x2257+-0x1*0x293+0xfe2*-0x2]);},new _0x575321(_0x10d0)['aUQYcD'](),_0x585bd8=_0x10d0['KEjkyF'](_0x585bd8),_0x10d0['RhLgaE'][_0x2065b3]=_0x585bd8;}else _0x585bd8=_0x125445;return _0x585bd8;}export class SlackAdapter{[_0x476279(0xbd)]=_0x476279(0x10f);['handler']=null;[_0x9c48b(0xcb)]=null;[_0x9c48b(0xa1)]='';[_0x476279(0xd1)];[_0x9c48b(0x10b)];[_0x476279(0xa2)+'eCache']=new Map();constructor(_0x167124,_0x59dec2){const _0x4f870c=_0x476279;this['botToken']=_0x167124,this[_0x4f870c(0x10b)]=_0x59dec2;}async[_0x476279(0x104)](){const _0x39e055=_0x9c48b,_0x1116a7=_0x9c48b;_slackState={'status':_0x39e055(0x8f),'botName':null,'botId':null,'teamName':null,'connectedAt':null,'error':null};let _0x951e9b;try{_0x951e9b=await import(_0x1116a7(0xb7)+'t');}catch{const _0x54f83f=_0x39e055(0xb7)+_0x1116a7(0x93)+_0x1116a7(0xc6)+':\x20npm\x20inst'+_0x39e055(0x94)+'/bolt';_slackState={..._slackState,'status':_0x39e055(0x100),'error':_0x54f83f},console[_0x39e055(0x100)](_0x1116a7(0xb8)+_0x54f83f);throw new Error(_0x54f83f);}const {App:_0x2b8ef3}=_0x951e9b;try{this[_0x39e055(0xcb)]=new _0x2b8ef3({'token':this[_0x1116a7(0xd1)],'appToken':this[_0x1116a7(0x10b)],'socketMode':!![],'logLevel':_0x1116a7(0xdc)});const _0x4d0896=await this[_0x39e055(0xcb)]['client'][_0x1116a7(0xc8)][_0x39e055(0xd3)]({'token':this[_0x1116a7(0xd1)]});this[_0x39e055(0xa1)]=_0x4d0896[_0x39e055(0xda)]||'',_slackState[_0x39e055(0x91)]=_0x4d0896[_0x1116a7(0xc0)]||null,_slackState[_0x39e055(0x9c)]=_0x4d0896['user_id']||null,_slackState[_0x1116a7(0xf9)]=_0x4d0896[_0x39e055(0xd0)]||null,this['app'][_0x39e055(0x9b)](async({message:_0x2cf132,say:_0x11c38a,client:_0x1e74b6})=>{const _0x5a5eb0=_0x1116a7;await this['handleMess'+_0x5a5eb0(0xeb)](_0x2cf132,_0x11c38a,_0x1e74b6);}),this[_0x39e055(0xcb)]['event'](_0x1116a7(0xf4)+'n',async({event:_0x5b240e,say:_0x253915,client:_0x41a71c})=>{const _0x4a4c3b=_0x1116a7,_0x2ae9e5=_0x39e055;await this[_0x4a4c3b(0x8a)+_0x2ae9e5(0xa6)](_0x5b240e,_0x253915,_0x41a71c);});typeof this['app'][_0x1116a7(0xcc)]===_0x1116a7(0xf3)&&this[_0x1116a7(0xcb)][_0x39e055(0xcc)](_0x39e055(0x10d),async({command:_0x3b0911,ack:_0x1abc88})=>{const _0xbcbd1c=_0x39e055,_0x133c0b=_0x39e055;await _0x1abc88();try{await this[_0xbcbd1c(0xe0)+_0xbcbd1c(0xb9)](_0x3b0911);}catch(_0x599a53){console['error'](_0xbcbd1c(0xc5)+_0xbcbd1c(0x9f)+_0xbcbd1c(0xed),_0x599a53);}});await this['app']['start'](),_slackState['status']=_0x1116a7(0xc4),_slackState['connectedA'+'t']=Date[_0x1116a7(0xbe)](),console['log'](_0x39e055(0xce)+_0x39e055(0xfb)+_slackState[_0x39e055(0x91)]+_0x1116a7(0xae)+_slackState[_0x1116a7(0xf9)]+')');try{const {registerDeliveryAdapter:_0x2c8c68}=await import('../service'+_0x1116a7(0xf2)+_0x39e055(0xcd)+'js');_0x2c8c68({'platform':'slack','sendText':async(_0xea02bd,_0x57a330)=>{const _0x1fee2f=_0x39e055;await this[_0x1fee2f(0xf8)](String(_0xea02bd),_0x57a330);}});}catch(_0x18cbc7){console[_0x39e055(0xcf)](_0x39e055(0x107)+_0x39e055(0xd9)+_0x1116a7(0xd6)+'ivery\x20adap'+_0x39e055(0x9a),_0x18cbc7);}}catch(_0x54b708){_slackState['status']=_0x1116a7(0x100),_slackState['error']=_0x54b708 instanceof Error?_0x54b708[_0x39e055(0x9b)]:String(_0x54b708),console[_0x39e055(0x100)](_0x1116a7(0xa4)+_0x1116a7(0xc3)+_0x39e055(0x10a),_slackState[_0x39e055(0x100)]);throw _0x54b708;}}async[_0x476279(0xb3)+_0x476279(0xeb)](_0x5854b6,_0x208eec,_0x1b9b7f){const _0x31a786=_0x476279,_0xa799c8=_0x476279;if(!this['handler'])return;if(_0x5854b6[_0x31a786(0x110)])return;if(_0x5854b6[_0x31a786(0xee)])return;if(!_0x5854b6[_0xa799c8(0xde)]&&!_0x5854b6['files'])return;const _0x2ff912=(_0x5854b6[_0x31a786(0xde)]||'')[_0xa799c8(0xb1)](),_0x585bd8=_0x5854b6['user']||'',_0x2ce475=_0x5854b6[_0x31a786(0xd5)]||'',_0x183804=_0x5854b6['ts']||'';if(!isSlackUserAllowed(_0x585bd8))return;const _0x2065b3=_0x5854b6[_0x31a786(0xea)+'pe']||'',_0x125445=_0x2065b3==='im',_0x5242e0=!_0x125445;if(_0x5242e0)return;let _0x3cb849=_0x585bd8;try{const _0x1b8c67=await _0x1b9b7f[_0x31a786(0xb5)]['info']({'user':_0x585bd8});_0x3cb849=_0x1b8c67[_0xa799c8(0xc0)]?.[_0x31a786(0x102)]||_0x1b8c67[_0x31a786(0xc0)]?.[_0x31a786(0xb6)]||_0x585bd8;}catch{}let _0x2b62fe=undefined;if(_0x5854b6[_0xa799c8(0x8c)]&&_0x5854b6[_0xa799c8(0x8c)][_0xa799c8(0xf1)]>-0x1799+-0x2*-0x1da+0x13e5){const _0x176777=_0x5854b6['files'][-0xa7*0xf+-0x2012+0x5*0x85f];_0x2b62fe=this[_0x31a786(0xe5)+_0x31a786(0x112)](_0x176777);}let _0x471f0c;if(_0x5854b6[_0xa799c8(0xe7)]&&_0x5854b6[_0x31a786(0xe7)]!==_0x5854b6['ts'])try{const _0x26cd63=await _0x1b9b7f['conversati'+_0x31a786(0xe8)]['replies']({'channel':_0x2ce475,'ts':_0x5854b6[_0xa799c8(0xe7)],'limit':0x1}),_0x4c29be=_0x26cd63['messages']?.[0x3f*-0x7f+-0x1*-0xc79+-0x4b2*-0x4];_0x4c29be?.['text']&&(_0x471f0c=_0x4c29be[_0xa799c8(0xde)]['length']>-0x5*-0x33+-0x6*-0x80+-0x20b*0x1?_0x4c29be['text'][_0x31a786(0x9e)](0x1*0x17a6+0xd0d*0x1+-0x24b3,0x1a7f*0x1+-0x17*-0xa3+-0x98*0x42)+'...':_0x4c29be[_0x31a786(0xde)]);}catch{}const _0x2c4507={'platform':_0x31a786(0x10f),'messageId':_0x183804,'chatId':_0x2ce475,'userId':_0x585bd8,'userName':_0x3cb849,'text':_0x2ff912,'isGroup':![],'isMention':![],'isReplyToBot':![],'replyToText':_0x471f0c,'media':_0x2b62fe};await this[_0x31a786(0xe9)](_0x2c4507);}async[_0x9c48b(0xe0)+'hCommand'](_0x27bc14){const _0x452975=_0x476279,_0x54eba2=_0x9c48b;if(!this['handler'])return;const _0x22998b=parseSlackSlashCommand(_0x27bc14['text']||''),_0x575321=_0x27bc14['channel_id']||'',_0x1be253=_0x27bc14[_0x452975(0xda)]||'',_0x4b4c63=_0x27bc14[_0x452975(0xa8)]||_0x1be253;if(!isSlackUserAllowed(_0x1be253))return;const _0x39d7e6={'platform':_0x452975(0x10f),'messageId':'cmd-'+Date[_0x54eba2(0xbe)]()+'-'+Math[_0x54eba2(0x10e)]()[_0x452975(0xca)](-0x796*-0x1+0x1*0x821+-0xf93)[_0x54eba2(0x9e)](0xe17+-0x1*-0x7af+0xc7*-0x1c,-0x2f0+-0xf8a+0x67*0x2e),'chatId':_0x575321,'userId':_0x1be253,'userName':_0x4b4c63,'text':_0x22998b,'isGroup':_0x27bc14['channel_na'+'me']&&_0x27bc14[_0x54eba2(0xaa)+'me']!=='directmess'+_0x452975(0xeb),'isMention':![],'isReplyToBot':![]};await this['handler'](_0x39d7e6);}async[_0x476279(0x8a)+_0x476279(0xa6)](_0x78a653,_0x3067ec,_0x5d3cdc){const _0x35b3b4=_0x476279,_0x245eb4=_0x476279;if(!this[_0x35b3b4(0xe9)])return;if(_0x78a653[_0x245eb4(0xee)])return;let _0x829dd4=(_0x78a653[_0x35b3b4(0xde)]||'')[_0x35b3b4(0xb1)]();const _0xeed0b0=_0x78a653[_0x245eb4(0xc0)]||'',_0x5d67d8=_0x78a653[_0x245eb4(0xd5)]||'',_0x4673ee=_0x78a653['ts']||'';if(!isSlackUserAllowed(_0xeed0b0))return;_0x829dd4=_0x829dd4[_0x35b3b4(0xef)](new RegExp('<@'+this['botUserId']+'>','g'),'')['trim']();if(!_0x829dd4)return;let _0x25e755=_0xeed0b0;try{const _0x33078c=await _0x5d3cdc['users'][_0x35b3b4(0xba)]({'user':_0xeed0b0});_0x25e755=_0x33078c[_0x35b3b4(0xc0)]?.[_0x35b3b4(0x102)]||_0x33078c[_0x245eb4(0xc0)]?.[_0x245eb4(0xb6)]||_0xeed0b0;}catch{}let _0x2a2d0f=undefined;_0x78a653[_0x35b3b4(0x8c)]&&_0x78a653[_0x35b3b4(0x8c)]['length']>0x2410+-0x1991*-0x1+-0x3da1&&(_0x2a2d0f=this['parseSlack'+_0x245eb4(0x112)](_0x78a653[_0x35b3b4(0x8c)][-0x9e1+0x4a9+-0x1*-0x538]));const _0x47233d={'platform':_0x35b3b4(0x10f),'messageId':_0x4673ee,'chatId':_0x5d67d8,'userId':_0xeed0b0,'userName':_0x25e755,'text':_0x829dd4,'isGroup':!![],'isMention':!![],'isReplyToBot':![],'media':_0x2a2d0f};await this[_0x245eb4(0xe9)](_0x47233d);}['parseSlack'+_0x476279(0x112)](_0x3aef49){const _0x38f278=_0x9c48b,_0x4c6f79=_0x9c48b;if(!_0x3aef49)return undefined;const _0x20cb78=_0x3aef49[_0x38f278(0x8e)]||'';if(_0x20cb78[_0x38f278(0xfa)]('image/'))return{'type':_0x38f278(0xa9),'url':_0x3aef49[_0x4c6f79(0xfd)+'e'],'mimeType':_0x20cb78,'fileName':_0x3aef49[_0x38f278(0xb6)]};if(_0x20cb78[_0x38f278(0xfa)](_0x38f278(0xa5)))return{'type':_0x38f278(0x98),'url':_0x3aef49[_0x38f278(0xfd)+'e'],'mimeType':_0x20cb78,'fileName':_0x3aef49[_0x38f278(0xb6)]};if(_0x20cb78[_0x4c6f79(0xfa)]('video/'))return{'type':_0x38f278(0xdf),'url':_0x3aef49[_0x4c6f79(0xfd)+'e'],'mimeType':_0x20cb78,'fileName':_0x3aef49[_0x38f278(0xb6)]};return{'type':_0x38f278(0x97),'url':_0x3aef49[_0x38f278(0xfd)+'e'],'mimeType':_0x20cb78,'fileName':_0x3aef49[_0x4c6f79(0xb6)]};}async[_0x476279(0xf8)](_0x5e5c79,_0x15b5ab,_0x4cf47d){const _0x2c5b66=_0x9c48b,_0x347edf=_0x476279;if(!this[_0x2c5b66(0xcb)])return;const _0x152154=_0x15b5ab[_0x2c5b66(0xf1)]>-0x1271+0x1c3*-0x9+0x2e4*0x11?_0x15b5ab[_0x347edf(0xe1)](/.{1,3800}/gs)||[_0x15b5ab]:[_0x15b5ab];let _0x41e2c3;for(const _0x20a2d5 of _0x152154){const _0x29557b=await this[_0x347edf(0xcb)][_0x347edf(0xd4)]['chat']['postMessag'+'e']({'token':this['botToken'],'channel':_0x5e5c79,'text':_0x20a2d5,..._0x4cf47d?.['replyTo']?{'thread_ts':_0x4cf47d['replyTo']}:{},'mrkdwn':!![]});if(_0x29557b?.['ts'])_0x41e2c3=_0x29557b['ts'];}return _0x41e2c3;}async[_0x9c48b(0x101)+'e'](_0x5efec8,_0x2759b9,_0x3bacbe){const _0x559998=_0x9c48b,_0x50fcb0=_0x9c48b;if(!this[_0x559998(0xcb)])return _0x2759b9;try{const _0x13d34b=_0x3bacbe['length']>0x1*-0x17d5+-0x1*0x6da+-0x23*-0x14d?_0x3bacbe[_0x50fcb0(0x9e)](0x118f+-0x203d+0xeae*0x1,-0x1d18+0x7ed+0x525*0x7)+'...':_0x3bacbe;await this['app'][_0x559998(0xd4)][_0x50fcb0(0x106)][_0x50fcb0(0xd7)]({'token':this[_0x559998(0xd1)],'channel':_0x5efec8,'ts':_0x2759b9,'text':_0x13d34b,'mrkdwn':!![]});}catch{}return _0x2759b9;}async[_0x476279(0x10c)](_0x408e71,_0x299fbb,_0x1adb4f){const _0x24fdc7=_0x476279,_0x4433fd=_0x9c48b;if(!this[_0x24fdc7(0xcb)])return;typeof _0x299fbb===_0x4433fd(0xb0)?await this[_0x24fdc7(0xcb)]['client'][_0x4433fd(0xa3)+_0x4433fd(0xc2)]({'token':this[_0x4433fd(0xd1)],'channel_id':_0x408e71,'file':_0x14338['createRead'+'Stream'](_0x299fbb),'filename':_0x24fdc7(0xdd),'initial_comment':_0x1adb4f}):await this[_0x4433fd(0xcb)][_0x4433fd(0xd4)][_0x24fdc7(0xa3)+'dV2']({'token':this[_0x24fdc7(0xd1)],'channel_id':_0x408e71,'file_uploads':[{'file':_0x299fbb,'filename':_0x24fdc7(0xdd)}],'initial_comment':_0x1adb4f});}async['sendDocume'+'nt'](_0x10f123,_0x166482,_0x293269,_0x3803fb){const _0x3f60f5=_0x476279,_0x11f85d=_0x9c48b;if(!this[_0x3f60f5(0xcb)])return;typeof _0x166482===_0x11f85d(0xb0)?await this['app'][_0x11f85d(0xd4)][_0x11f85d(0xa3)+'dV2']({'token':this[_0x11f85d(0xd1)],'channel_id':_0x10f123,'file':_0x14338['createRead'+_0x11f85d(0x92)](_0x166482),'filename':_0x293269,'initial_comment':_0x3803fb}):await this['app'][_0x3f60f5(0xd4)][_0x3f60f5(0xa3)+'dV2']({'token':this[_0x11f85d(0xd1)],'channel_id':_0x10f123,'file_uploads':[{'file':_0x166482,'filename':_0x293269}],'initial_comment':_0x3803fb});}async[_0x476279(0xec)](_0x34467d,_0x29f7f4,_0x31e743){const _0x3edb3f=_0x9c48b,_0xfbf3e3=_0x476279;if(!this[_0x3edb3f(0xcb)])return;try{const _0x2c33e2=_0x31e743[_0xfbf3e3(0xef)](/^:|:$/g,'');await this['app'][_0xfbf3e3(0xd4)][_0xfbf3e3(0xe6)][_0xfbf3e3(0x113)]({'token':this['botToken'],'channel':_0x34467d,'timestamp':_0x29f7f4,'name':_0x2c33e2});}catch{}}async[_0x476279(0xad)](_0x4ab0aa){const _0x1eee6f=_0x476279,_0x346c93=_0x476279;if(!this['app'])return;try{await this[_0x1eee6f(0xcb)][_0x1eee6f(0xd4)]['apiCall'](_0x1eee6f(0xe4)+'threads.se'+'tStatus',{'channel_id':_0x4ab0aa,'status':'is\x20thinkin'+'g…'});}catch{}}async[_0x476279(0xfe)+_0x476279(0xf6)](_0x4acbc2){const _0x30cb7b=_0x476279,_0xf2693b=_0x476279;if(!this[_0x30cb7b(0xcb)])return undefined;const _0x13e7db=this['channelNam'+_0x30cb7b(0xff)][_0xf2693b(0x99)](_0x4acbc2);if(_0x13e7db)return _0x13e7db;try{const _0x66de3b=await this[_0x30cb7b(0xcb)][_0xf2693b(0xd4)][_0xf2693b(0x8d)+_0x30cb7b(0xe8)][_0xf2693b(0xba)]({'token':this['botToken'],'channel':_0x4acbc2}),_0x2d6a5b=_0x66de3b?.['channel']?.[_0x30cb7b(0xb6)];if(_0x2d6a5b)return this[_0xf2693b(0xa2)+'eCache'][_0xf2693b(0x105)](_0x4acbc2,_0x2d6a5b),_0x2d6a5b;}catch{}return undefined;}async['stop'](){const _0x5983d7=_0x9c48b,_0x58ec60=_0x476279;if(this[_0x5983d7(0xcb)]){try{await this['app'][_0x5983d7(0xf7)]();}catch{}this[_0x5983d7(0xcb)]=null;}_slackState[_0x58ec60(0xbb)]=_0x58ec60(0xd8)+'ed';}[_0x9c48b(0xe3)](_0x1ff33e){const _0x101c5b=_0x476279;this[_0x101c5b(0xe9)]=_0x1ff33e;}}