@elizaos/plugin-slack 2.0.0-alpha.7 → 2.0.0-beta.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.
- package/LICENSE +1 -0
- package/README.md +209 -0
- package/auto-enable.ts +21 -0
- package/dist/index.js +2503 -2985
- package/dist/index.js.map +10 -21
- package/package.json +25 -24
package/dist/index.js.map
CHANGED
|
@@ -1,28 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/
|
|
3
|
+
"sources": ["../src/index.ts", "../src/connector-account-provider.ts", "../src/accounts.ts", "../src/connector-credential-refs.ts", "../src/types.ts", "../src/service.ts", "../src/formatting.ts", "../src/workflow-credential-provider.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {
|
|
6
|
-
"import {\n type Action,\n type ActionExample,\n type ActionResult,\n type Content,\n composePromptFromState,\n type HandlerCallback,\n type HandlerOptions,\n type IAgentRuntime,\n type Memory,\n ModelType,\n parseJSONObjectFromText,\n type State,\n} from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { isValidMessageTs, SLACK_SERVICE_NAME } from \"../types\";\n\nconst deleteMessageTemplate = `You are helping to extract delete message parameters for Slack.\n\nThe user wants to delete a Slack message.\n\nRecent conversation:\n{{recentMessages}}\n\nExtract the following:\n1. messageTs: The message timestamp to delete (format: 1234567890.123456)\n2. channelId: The channel ID (optional, defaults to current channel)\n\nRespond with a JSON object like:\n{\n \"messageTs\": \"1234567890.123456\",\n \"channelId\": null\n}\n\nOnly respond with the JSON object, no other text.`;\n\nexport const deleteMessage: Action = {\n name: \"SLACK_DELETE_MESSAGE\",\n similes: [\"REMOVE_SLACK_MESSAGE\", \"DELETE_MESSAGE\", \"SLACK_REMOVE\"],\n description: \"Delete a Slack message\",\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['slack', 'delete', 'message'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:slack|delete|message)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'slack';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n return message.content.source === \"slack\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult | undefined> => {\n const slackService = runtime.getService(SLACK_SERVICE_NAME) as SlackService;\n\n if (!slackService || !slackService.client) {\n await callback?.({\n text: \"Slack service is not available.\",\n source: \"slack\",\n });\n return { success: false, error: \"Slack service not available\" };\n }\n\n const prompt = composePromptFromState({\n state,\n template: deleteMessageTemplate,\n });\n\n let deleteInfo: {\n messageTs: string;\n channelId?: string | null;\n } | null = null;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsedResponse = parseJSONObjectFromText(response);\n if (parsedResponse?.messageTs) {\n deleteInfo = {\n messageTs: String(parsedResponse.messageTs),\n channelId: parsedResponse.channelId\n ? String(parsedResponse.channelId)\n : null,\n };\n break;\n }\n }\n\n if (!deleteInfo || !deleteInfo.messageTs) {\n runtime.logger.debug(\n { src: \"plugin:slack:action:delete-message\" },\n \"[SLACK_DELETE_MESSAGE] Could not extract delete info\",\n );\n await callback?.({\n text: \"I couldn't understand which message to delete. Please specify the message timestamp.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not extract delete parameters\" };\n }\n\n if (!isValidMessageTs(deleteInfo.messageTs)) {\n await callback?.({\n text: \"The message timestamp format is invalid. Please provide a valid Slack message timestamp.\",\n source: \"slack\",\n });\n return { success: false, error: \"Invalid message timestamp\" };\n }\n\n const stateData = state?.data;\n const room = stateData?.room || (await runtime.getRoom(message.roomId));\n const channelId = deleteInfo.channelId || room?.channelId;\n\n if (!channelId) {\n await callback?.({\n text: \"I couldn't determine the channel for the message deletion.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not determine channel\" };\n }\n\n await slackService.deleteMessage(channelId, deleteInfo.messageTs);\n\n const response: Content = {\n text: \"Message deleted successfully.\",\n source: message.content.source,\n };\n\n runtime.logger.debug(\n {\n src: \"plugin:slack:action:delete-message\",\n messageTs: deleteInfo.messageTs,\n channelId,\n },\n \"[SLACK_DELETE_MESSAGE] Message deleted\",\n );\n\n await callback?.(response);\n\n return {\n success: true,\n data: {\n messageTs: deleteInfo.messageTs,\n channelId,\n },\n };\n },\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Delete that last message I sent\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I'll delete that message for you.\",\n actions: [\"SLACK_DELETE_MESSAGE\"],\n },\n },\n ],\n ] as ActionExample[][],\n};\n\nexport default deleteMessage;\n",
|
|
7
|
-
"import type {\n Character,\n EntityPayload,\n EventPayload,\n MessagePayload,\n WorldPayload,\n} from \"@elizaos/core\";\nimport type { App as BoltApp } from \"@slack/bolt\";\nimport type { WebClient } from \"@slack/web-api\";\n\n/**\n * Slack-specific event types\n */\nexport enum SlackEventTypes {\n MESSAGE_RECEIVED = \"SLACK_MESSAGE_RECEIVED\",\n MESSAGE_SENT = \"SLACK_MESSAGE_SENT\",\n REACTION_ADDED = \"SLACK_REACTION_ADDED\",\n REACTION_REMOVED = \"SLACK_REACTION_REMOVED\",\n CHANNEL_JOINED = \"SLACK_CHANNEL_JOINED\",\n CHANNEL_LEFT = \"SLACK_CHANNEL_LEFT\",\n MEMBER_JOINED_CHANNEL = \"SLACK_MEMBER_JOINED_CHANNEL\",\n MEMBER_LEFT_CHANNEL = \"SLACK_MEMBER_LEFT_CHANNEL\",\n APP_MENTION = \"SLACK_APP_MENTION\",\n SLASH_COMMAND = \"SLACK_SLASH_COMMAND\",\n FILE_SHARED = \"SLACK_FILE_SHARED\",\n THREAD_REPLY = \"SLACK_THREAD_REPLY\",\n}\n\nexport interface SlackMessageReceivedPayload extends MessagePayload {\n channelId: string;\n threadTs: string | undefined;\n userId: string;\n teamId: string | undefined;\n isThreadReply: boolean;\n files: SlackFile[];\n}\n\nexport interface SlackMessageSentPayload extends MessagePayload {\n channelId: string;\n threadTs: string | undefined;\n messageTs: string;\n}\n\nexport interface SlackReactionPayload extends EventPayload {\n reaction: string;\n userId: string;\n channelId: string;\n messageTs: string;\n itemUser: string | undefined;\n}\n\nexport interface SlackChannelPayload extends WorldPayload {\n channelId: string;\n channelName: string;\n channelType: SlackChannelType;\n}\n\nexport interface SlackMemberPayload extends EntityPayload {\n userId: string;\n channelId: string;\n}\n\nexport interface SlackAppMentionPayload extends MessagePayload {\n channelId: string;\n userId: string;\n threadTs: string | undefined;\n}\n\nexport interface SlackSlashCommandPayload extends EventPayload {\n command: string;\n text: string;\n userId: string;\n channelId: string;\n teamId: string;\n responseUrl: string;\n triggerId: string;\n}\n\nexport interface SlackFile {\n id: string;\n name: string;\n title: string;\n mimetype: string;\n filetype: string;\n size: number;\n urlPrivate: string;\n urlPrivateDownload: string | undefined;\n permalink: string;\n thumb64: string | undefined;\n thumb80: string | undefined;\n thumb360: string | undefined;\n}\n\nexport type SlackChannelType = \"channel\" | \"group\" | \"im\" | \"mpim\";\n\nexport interface SlackEventPayloadMap {\n [SlackEventTypes.MESSAGE_RECEIVED]: SlackMessageReceivedPayload;\n [SlackEventTypes.MESSAGE_SENT]: SlackMessageSentPayload;\n [SlackEventTypes.REACTION_ADDED]: SlackReactionPayload;\n [SlackEventTypes.REACTION_REMOVED]: SlackReactionPayload;\n [SlackEventTypes.CHANNEL_JOINED]: SlackChannelPayload;\n [SlackEventTypes.CHANNEL_LEFT]: SlackChannelPayload;\n [SlackEventTypes.MEMBER_JOINED_CHANNEL]: SlackMemberPayload;\n [SlackEventTypes.MEMBER_LEFT_CHANNEL]: SlackMemberPayload;\n [SlackEventTypes.APP_MENTION]: SlackAppMentionPayload;\n [SlackEventTypes.SLASH_COMMAND]: SlackSlashCommandPayload;\n [SlackEventTypes.FILE_SHARED]: SlackMessageReceivedPayload;\n [SlackEventTypes.THREAD_REPLY]: SlackMessageReceivedPayload;\n}\n\nexport interface SlackUser {\n id: string;\n teamId: string | undefined;\n name: string;\n deleted: boolean;\n realName: string | undefined;\n tz: string | undefined;\n tzLabel: string | undefined;\n tzOffset: number | undefined;\n profile: SlackUserProfile;\n isAdmin: boolean;\n isOwner: boolean;\n isPrimaryOwner: boolean;\n isRestricted: boolean;\n isUltraRestricted: boolean;\n isBot: boolean;\n isAppUser: boolean;\n updated: number;\n}\n\nexport interface SlackUserProfile {\n title: string | undefined;\n phone: string | undefined;\n skype: string | undefined;\n realName: string | undefined;\n realNameNormalized: string | undefined;\n displayName: string | undefined;\n displayNameNormalized: string | undefined;\n statusText: string | undefined;\n statusEmoji: string | undefined;\n statusExpiration: number | undefined;\n avatarHash: string | undefined;\n email: string | undefined;\n image24: string | undefined;\n image32: string | undefined;\n image48: string | undefined;\n image72: string | undefined;\n image192: string | undefined;\n image512: string | undefined;\n image1024: string | undefined;\n imageOriginal: string | undefined;\n team: string | undefined;\n}\n\nexport interface SlackChannel {\n id: string;\n name: string;\n isChannel: boolean;\n isGroup: boolean;\n isIm: boolean;\n isMpim: boolean;\n isPrivate: boolean;\n isArchived: boolean;\n isGeneral: boolean;\n isShared: boolean;\n isOrgShared: boolean;\n isMember: boolean;\n topic: SlackChannelTopic | undefined;\n purpose: SlackChannelPurpose | undefined;\n numMembers: number | undefined;\n created: number;\n creator: string;\n}\n\nexport interface SlackChannelTopic {\n value: string;\n creator: string;\n lastSet: number;\n}\n\nexport interface SlackChannelPurpose {\n value: string;\n creator: string;\n lastSet: number;\n}\n\nexport interface SlackMessage {\n type: string;\n subtype: string | undefined;\n ts: string;\n user: string | undefined;\n text: string;\n threadTs: string | undefined;\n replyCount: number | undefined;\n replyUsersCount: number | undefined;\n latestReply: string | undefined;\n reactions: SlackReaction[] | undefined;\n files: SlackFile[] | undefined;\n attachments: SlackAttachment[] | undefined;\n blocks: SlackBlock[] | undefined;\n}\n\nexport interface SlackReaction {\n name: string;\n count: number;\n users: string[];\n}\n\nexport interface SlackAttachment {\n id: number;\n fallback: string | undefined;\n color: string | undefined;\n pretext: string | undefined;\n authorName: string | undefined;\n authorLink: string | undefined;\n authorIcon: string | undefined;\n title: string | undefined;\n titleLink: string | undefined;\n text: string | undefined;\n fields: SlackAttachmentField[] | undefined;\n imageUrl: string | undefined;\n thumbUrl: string | undefined;\n footer: string | undefined;\n footerIcon: string | undefined;\n ts: string | undefined;\n}\n\nexport interface SlackAttachmentField {\n title: string;\n value: string;\n short: boolean;\n}\n\nexport interface SlackBlock {\n type: string;\n blockId: string | undefined;\n elements: SlackBlockElement[] | undefined;\n text: SlackBlockText | undefined;\n}\n\nexport interface SlackBlockElement {\n type: string;\n text: SlackBlockText | undefined;\n actionId: string | undefined;\n url: string | undefined;\n value: string | undefined;\n style: string | undefined;\n}\n\nexport interface SlackBlockText {\n type: string;\n text: string;\n emoji: boolean | undefined;\n verbatim: boolean | undefined;\n}\n\nexport interface SlackTeam {\n id: string;\n name: string;\n domain: string;\n emailDomain: string | undefined;\n icon: SlackTeamIcon;\n}\n\nexport interface SlackTeamIcon {\n image34: string | undefined;\n image44: string | undefined;\n image68: string | undefined;\n image88: string | undefined;\n image102: string | undefined;\n image132: string | undefined;\n image230: string | undefined;\n imageDefault: boolean;\n}\n\nexport interface ISlackService {\n app: BoltApp | null;\n client: WebClient | null;\n character: Character;\n botUserId: string | null;\n teamId: string | null;\n}\n\nexport const SLACK_SERVICE_NAME = \"slack\";\n\nexport const ServiceType = {\n SLACK: \"slack\",\n} as const;\n\nexport interface SlackSettings {\n allowedChannelIds: string[] | undefined;\n shouldIgnoreBotMessages: boolean;\n shouldRespondOnlyToMentions: boolean;\n}\n\nexport interface SlackMessageSendOptions {\n threadTs: string | undefined;\n replyBroadcast: boolean | undefined;\n unfurlLinks: boolean | undefined;\n unfurlMedia: boolean | undefined;\n mrkdwn: boolean | undefined;\n attachments: SlackAttachment[] | undefined;\n blocks: SlackBlock[] | undefined;\n}\n\nexport class SlackPluginError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n ) {\n super(message);\n this.name = \"SlackPluginError\";\n }\n}\n\nexport class SlackServiceNotInitializedError extends SlackPluginError {\n constructor() {\n super(\"Slack service is not initialized\", \"SERVICE_NOT_INITIALIZED\");\n this.name = \"SlackServiceNotInitializedError\";\n }\n}\n\nexport class SlackClientNotAvailableError extends SlackPluginError {\n constructor() {\n super(\"Slack client is not available\", \"CLIENT_NOT_AVAILABLE\");\n this.name = \"SlackClientNotAvailableError\";\n }\n}\n\nexport class SlackConfigurationError extends SlackPluginError {\n constructor(missingConfig: string) {\n super(`Missing required configuration: ${missingConfig}`, \"MISSING_CONFIG\");\n this.name = \"SlackConfigurationError\";\n }\n}\n\nexport class SlackApiError extends SlackPluginError {\n constructor(\n message: string,\n public readonly apiErrorCode: string | undefined,\n ) {\n super(message, \"API_ERROR\");\n this.name = \"SlackApiError\";\n }\n}\n\n/**\n * Validates a Slack channel ID format\n */\nexport function isValidChannelId(id: string): boolean {\n // Slack channel IDs start with C (public), G (private/group), or D (DM)\n return /^[CGD][A-Z0-9]{8,}$/i.test(id);\n}\n\n/**\n * Validates a Slack user ID format\n */\nexport function isValidUserId(id: string): boolean {\n // Slack user IDs start with U or W (enterprise grid)\n return /^[UW][A-Z0-9]{8,}$/i.test(id);\n}\n\n/**\n * Validates a Slack team ID format\n */\nexport function isValidTeamId(id: string): boolean {\n // Slack team IDs start with T\n return /^T[A-Z0-9]{8,}$/i.test(id);\n}\n\n/**\n * Validates a Slack message timestamp format\n */\nexport function isValidMessageTs(ts: string): boolean {\n // Slack timestamps are in the format: 1234567890.123456\n return /^\\d+\\.\\d{6}$/.test(ts);\n}\n\n/**\n * Parses a Slack message link to extract channel and message IDs\n */\nexport function parseSlackMessageLink(\n link: string,\n): { channelId: string; messageTs: string } | null {\n // Format: https://workspace.slack.com/archives/C12345678/p1234567890123456\n const match = link.match(/\\/archives\\/([CGD][A-Z0-9]+)\\/p(\\d+)/i);\n if (!match) return null;\n\n const channelId = match[1];\n const ts = match[2];\n // Convert the timestamp: p1234567890123456 -> 1234567890.123456\n const messageTs = `${ts.slice(0, 10)}.${ts.slice(10)}`;\n\n return { channelId, messageTs };\n}\n\n/**\n * Formats a message timestamp for use in Slack links\n */\nexport function formatMessageTsForLink(ts: string): string {\n // Convert: 1234567890.123456 -> p1234567890123456\n return `p${ts.replace(\".\", \"\")}`;\n}\n\n/**\n * Gets the display name for a Slack user\n */\nexport function getSlackUserDisplayName(user: SlackUser): string {\n return user.profile.displayName || user.profile.realName || user.name;\n}\n\n/**\n * Determines the channel type from a Slack channel object\n */\nexport function getSlackChannelType(channel: SlackChannel): SlackChannelType {\n if (channel.isIm) return \"im\";\n if (channel.isMpim) return \"mpim\";\n if (channel.isGroup || channel.isPrivate) return \"group\";\n return \"channel\";\n}\n\n/**\n * Maximum message length for Slack messages\n */\nexport const MAX_SLACK_MESSAGE_LENGTH = 4000;\n\n/**\n * Maximum number of blocks per message\n */\nexport const MAX_SLACK_BLOCKS = 50;\n\n/**\n * Maximum file size for uploads (in bytes) - 1GB for paid, varies for free\n */\nexport const MAX_SLACK_FILE_SIZE = 1024 * 1024 * 1024;\n",
|
|
8
|
-
"import {\n type Action,\n type ActionExample,\n type ActionResult,\n type Content,\n composePromptFromState,\n type HandlerCallback,\n type HandlerOptions,\n type IAgentRuntime,\n type Memory,\n ModelType,\n parseJSONObjectFromText,\n type State,\n} from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { isValidMessageTs, SLACK_SERVICE_NAME } from \"../types\";\n\nconst editMessageTemplate = `You are helping to extract edit message parameters for Slack.\n\nThe user wants to edit an existing Slack message.\n\nRecent conversation:\n{{recentMessages}}\n\nExtract the following:\n1. messageTs: The message timestamp to edit (format: 1234567890.123456)\n2. newText: The new text content for the message\n3. channelId: The channel ID (optional, defaults to current channel)\n\nRespond with a JSON object like:\n{\n \"messageTs\": \"1234567890.123456\",\n \"newText\": \"The updated message content\",\n \"channelId\": null\n}\n\nOnly respond with the JSON object, no other text.`;\n\nexport const editMessage: Action = {\n name: \"SLACK_EDIT_MESSAGE\",\n similes: [\n \"UPDATE_SLACK_MESSAGE\",\n \"MODIFY_MESSAGE\",\n \"CHANGE_MESSAGE\",\n \"SLACK_UPDATE\",\n ],\n description: \"Edit an existing Slack message\",\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['slack', 'edit', 'message'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:slack|edit|message)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'slack';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n return message.content.source === \"slack\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult | undefined> => {\n const slackService = runtime.getService(SLACK_SERVICE_NAME) as SlackService;\n\n if (!slackService || !slackService.client) {\n await callback?.({\n text: \"Slack service is not available.\",\n source: \"slack\",\n });\n return { success: false, error: \"Slack service not available\" };\n }\n\n const prompt = composePromptFromState({\n state,\n template: editMessageTemplate,\n });\n\n let editInfo: {\n messageTs: string;\n newText: string;\n channelId?: string | null;\n } | null = null;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsedResponse = parseJSONObjectFromText(response);\n if (parsedResponse?.messageTs && parsedResponse?.newText) {\n editInfo = {\n messageTs: String(parsedResponse.messageTs),\n newText: String(parsedResponse.newText),\n channelId: parsedResponse.channelId\n ? String(parsedResponse.channelId)\n : null,\n };\n break;\n }\n }\n\n if (!editInfo || !editInfo.messageTs || !editInfo.newText) {\n runtime.logger.debug(\n { src: \"plugin:slack:action:edit-message\" },\n \"[SLACK_EDIT_MESSAGE] Could not extract edit info\",\n );\n await callback?.({\n text: \"I couldn't understand the edit request. Please specify the message timestamp and new content.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not extract edit parameters\" };\n }\n\n if (!isValidMessageTs(editInfo.messageTs)) {\n await callback?.({\n text: \"The message timestamp format is invalid. Please provide a valid Slack message timestamp.\",\n source: \"slack\",\n });\n return { success: false, error: \"Invalid message timestamp\" };\n }\n\n const stateData = state?.data;\n const room = stateData?.room || (await runtime.getRoom(message.roomId));\n const channelId = editInfo.channelId || room?.channelId;\n\n if (!channelId) {\n await callback?.({\n text: \"I couldn't determine the channel for the message edit.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not determine channel\" };\n }\n\n await slackService.editMessage(\n channelId,\n editInfo.messageTs,\n editInfo.newText,\n );\n\n const response: Content = {\n text: \"Message edited successfully.\",\n source: message.content.source,\n };\n\n runtime.logger.debug(\n {\n src: \"plugin:slack:action:edit-message\",\n messageTs: editInfo.messageTs,\n channelId,\n },\n \"[SLACK_EDIT_MESSAGE] Message edited\",\n );\n\n await callback?.(response);\n\n return {\n success: true,\n data: {\n messageTs: editInfo.messageTs,\n channelId,\n newText: editInfo.newText,\n },\n };\n },\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Edit that message to say 'Meeting at 3pm' instead\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I'll update that message for you.\",\n actions: [\"SLACK_EDIT_MESSAGE\"],\n },\n },\n ],\n ] as ActionExample[][],\n};\n\nexport default editMessage;\n",
|
|
9
|
-
"import type {\n Action,\n ActionExample,\n ActionResult,\n Content,\n HandlerCallback,\n HandlerOptions,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { SLACK_SERVICE_NAME } from \"../types\";\n\nexport const emojiList: Action = {\n name: \"SLACK_EMOJI_LIST\",\n similes: [\n \"LIST_SLACK_EMOJI\",\n \"SHOW_EMOJI\",\n \"GET_CUSTOM_EMOJI\",\n \"CUSTOM_EMOJI\",\n \"WORKSPACE_EMOJI\",\n ],\n description: \"List custom emoji available in the Slack workspace\",\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['slack', 'emoji', 'list'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:slack|emoji|list)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'slack';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n return message.content.source === \"slack\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult | undefined> => {\n const slackService = runtime.getService(SLACK_SERVICE_NAME) as SlackService;\n\n if (!slackService || !slackService.client) {\n await callback?.({\n text: \"Slack service is not available.\",\n source: \"slack\",\n });\n return { success: false, error: \"Slack service not available\" };\n }\n\n const emoji = await slackService.getEmojiList();\n const emojiNames = Object.keys(emoji).sort();\n\n if (emojiNames.length === 0) {\n const response: Content = {\n text: \"There are no custom emoji in this workspace.\",\n source: message.content.source,\n };\n await callback?.(response);\n\n return {\n success: true,\n data: {\n emojiCount: 0,\n emoji: {},\n },\n };\n }\n\n // Group emoji into chunks for display\n const _chunkSize = 20;\n const displayCount = Math.min(emojiNames.length, 100);\n const displayEmoji = emojiNames.slice(0, displayCount);\n\n // Detect aliases (emoji that reference other emoji with \"alias:\")\n const aliases: string[] = [];\n const custom: string[] = [];\n\n for (const name of displayEmoji) {\n const value = emoji[name];\n if (value.startsWith(\"alias:\")) {\n aliases.push(name);\n } else {\n custom.push(name);\n }\n }\n\n const emojiDisplay = custom.map((name) => `:${name}:`).join(\" \");\n const aliasDisplay =\n aliases.length > 0\n ? `\\n\\nAliases: ${aliases.map((name) => `:${name}:`).join(\" \")}`\n : \"\";\n\n const truncationNote =\n emojiNames.length > displayCount\n ? `\\n\\n(Showing ${displayCount} of ${emojiNames.length} total custom emoji)`\n : \"\";\n\n const response: Content = {\n text: `Custom emoji in this workspace (${emojiNames.length} total):\\n\\n${emojiDisplay}${aliasDisplay}${truncationNote}`,\n source: message.content.source,\n };\n\n runtime.logger.debug(\n {\n src: \"plugin:slack:action:emoji-list\",\n emojiCount: emojiNames.length,\n },\n \"[SLACK_EMOJI_LIST] Emoji listed\",\n );\n\n await callback?.(response);\n\n return {\n success: true,\n data: {\n emojiCount: emojiNames.length,\n emoji: Object.fromEntries(\n displayEmoji.map((name) => [name, emoji[name]]),\n ),\n },\n };\n },\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Show me the custom emoji in this workspace\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I'll list the custom emoji available.\",\n actions: [\"SLACK_EMOJI_LIST\"],\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"What emoji can I use here?\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"Let me show you the custom emoji in this workspace.\",\n actions: [\"SLACK_EMOJI_LIST\"],\n },\n },\n ],\n ] as ActionExample[][],\n};\n\nexport default emojiList;\n",
|
|
10
|
-
"import {\n type Action,\n type ActionExample,\n type ActionResult,\n type Content,\n composePromptFromState,\n type HandlerCallback,\n type HandlerOptions,\n type IAgentRuntime,\n type Memory,\n ModelType,\n parseJSONObjectFromText,\n type State,\n} from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport {\n getSlackUserDisplayName,\n isValidUserId,\n SLACK_SERVICE_NAME,\n} from \"../types\";\n\nconst getUserInfoTemplate = `You are helping to extract user info parameters for Slack.\n\nThe user wants to get information about a Slack user.\n\nRecent conversation:\n{{recentMessages}}\n\nExtract the following:\n1. userId: The Slack user ID to look up (format: U followed by alphanumeric characters, e.g., U0123456789)\n\nRespond with a JSON object like:\n{\n \"userId\": \"U0123456789\"\n}\n\nOnly respond with the JSON object, no other text.`;\n\nexport const getUserInfo: Action = {\n name: \"SLACK_GET_USER_INFO\",\n similes: [\n \"GET_SLACK_USER\",\n \"USER_INFO\",\n \"SLACK_USER\",\n \"MEMBER_INFO\",\n \"WHO_IS\",\n ],\n description: \"Get information about a Slack user\",\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['slack', 'get', 'user', 'info'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:slack|get|user|info)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'slack';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n return message.content.source === \"slack\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult | undefined> => {\n const slackService = runtime.getService(SLACK_SERVICE_NAME) as SlackService;\n\n if (!slackService || !slackService.client) {\n await callback?.({\n text: \"Slack service is not available.\",\n source: \"slack\",\n });\n return { success: false, error: \"Slack service not available\" };\n }\n\n const prompt = composePromptFromState({\n state,\n template: getUserInfoTemplate,\n });\n\n let userInfo: { userId: string } | null = null;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsedResponse = parseJSONObjectFromText(response);\n if (parsedResponse?.userId) {\n userInfo = {\n userId: String(parsedResponse.userId),\n };\n break;\n }\n }\n\n if (!userInfo || !userInfo.userId) {\n runtime.logger.debug(\n { src: \"plugin:slack:action:get-user-info\" },\n \"[SLACK_GET_USER_INFO] Could not extract user info\",\n );\n await callback?.({\n text: \"I couldn't determine which user to look up. Please specify a user ID.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not extract user ID\" };\n }\n\n if (!isValidUserId(userInfo.userId)) {\n await callback?.({\n text: \"The user ID format is invalid. Slack user IDs start with U followed by alphanumeric characters.\",\n source: \"slack\",\n });\n return { success: false, error: \"Invalid user ID format\" };\n }\n\n const user = await slackService.getUser(userInfo.userId);\n\n if (!user) {\n await callback?.({\n text: `I couldn't find a user with ID ${userInfo.userId}.`,\n source: \"slack\",\n });\n return { success: false, error: \"User not found\" };\n }\n\n const displayName = getSlackUserDisplayName(user);\n const roles: string[] = [];\n if (user.isAdmin) roles.push(\"Admin\");\n if (user.isOwner) roles.push(\"Owner\");\n if (user.isPrimaryOwner) roles.push(\"Primary Owner\");\n if (user.isBot) roles.push(\"Bot\");\n if (user.isRestricted) roles.push(\"Guest\");\n\n const userDetails = [\n `**Name:** ${displayName}`,\n user.profile.realName && user.profile.realName !== displayName\n ? `**Real Name:** ${user.profile.realName}`\n : null,\n `**Username:** @${user.name}`,\n user.profile.title ? `**Title:** ${user.profile.title}` : null,\n user.profile.email ? `**Email:** ${user.profile.email}` : null,\n user.tz ? `**Timezone:** ${user.tzLabel || user.tz}` : null,\n user.profile.statusText\n ? `**Status:** ${user.profile.statusEmoji || \"\"} ${user.profile.statusText}`\n : null,\n roles.length > 0 ? `**Roles:** ${roles.join(\", \")}` : null,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n const response: Content = {\n text: `User information for ${displayName}:\\n\\n${userDetails}`,\n source: message.content.source,\n };\n\n runtime.logger.debug(\n {\n src: \"plugin:slack:action:get-user-info\",\n userId: userInfo.userId,\n displayName,\n },\n \"[SLACK_GET_USER_INFO] User info retrieved\",\n );\n\n await callback?.(response);\n\n return {\n success: true,\n data: {\n userId: user.id,\n name: user.name,\n displayName,\n realName: user.profile.realName,\n title: user.profile.title,\n email: user.profile.email,\n timezone: user.tz,\n isAdmin: user.isAdmin,\n isOwner: user.isOwner,\n isBot: user.isBot,\n statusText: user.profile.statusText,\n statusEmoji: user.profile.statusEmoji,\n avatar: user.profile.image192 || user.profile.image72,\n },\n };\n },\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Who is U0123456789?\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"Let me look up that user for you.\",\n actions: [\"SLACK_GET_USER_INFO\"],\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Get information about the user who sent the last message\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I'll fetch their profile information.\",\n actions: [\"SLACK_GET_USER_INFO\"],\n },\n },\n ],\n ] as ActionExample[][],\n};\n\nexport default getUserInfo;\n",
|
|
11
|
-
"import type {\n Action,\n ActionExample,\n ActionResult,\n Content,\n HandlerCallback,\n HandlerOptions,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { SLACK_SERVICE_NAME } from \"../types\";\n\nexport const listChannels: Action = {\n name: \"SLACK_LIST_CHANNELS\",\n similes: [\n \"LIST_SLACK_CHANNELS\",\n \"SHOW_CHANNELS\",\n \"GET_CHANNELS\",\n \"CHANNELS_LIST\",\n ],\n description: \"List available Slack channels in the workspace\",\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['slack', 'list', 'channels'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:slack|list|channels)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'slack';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n return message.content.source === \"slack\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult | undefined> => {\n const slackService = runtime.getService(SLACK_SERVICE_NAME) as SlackService;\n\n if (!slackService || !slackService.client) {\n await callback?.({\n text: \"Slack service is not available.\",\n source: \"slack\",\n });\n return { success: false, error: \"Slack service not available\" };\n }\n\n const channels = await slackService.listChannels({\n types: \"public_channel,private_channel\",\n limit: 100,\n });\n\n // Sort channels by name\n const sortedChannels = channels\n .filter((ch) => !ch.isArchived)\n .sort((a, b) => a.name.localeCompare(b.name));\n\n // Format channel list\n const channelList = sortedChannels.map((ch) => {\n const memberCount =\n ch.numMembers !== undefined ? ` (${ch.numMembers} members)` : \"\";\n const privateIndicator = ch.isPrivate ? \" 🔒\" : \"\";\n const topic = ch.topic?.value\n ? ` - ${ch.topic.value.slice(0, 50)}${ch.topic.value.length > 50 ? \"...\" : \"\"}`\n : \"\";\n return `• #${ch.name}${privateIndicator}${memberCount}${topic}`;\n });\n\n const response: Content = {\n text: `Found ${sortedChannels.length} channels:\\n\\n${channelList.join(\"\\n\")}`,\n source: message.content.source,\n };\n\n runtime.logger.debug(\n {\n src: \"plugin:slack:action:list-channels\",\n channelCount: sortedChannels.length,\n },\n \"[SLACK_LIST_CHANNELS] Channels listed\",\n );\n\n await callback?.(response);\n\n return {\n success: true,\n data: {\n channelCount: sortedChannels.length,\n channels: sortedChannels.map((ch) => ({\n id: ch.id,\n name: ch.name,\n isPrivate: ch.isPrivate,\n numMembers: ch.numMembers,\n topic: ch.topic?.value,\n purpose: ch.purpose?.value,\n })),\n },\n };\n },\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Show me all the channels in this workspace\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I'll list all the available channels.\",\n actions: [\"SLACK_LIST_CHANNELS\"],\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"What channels can I join?\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"Let me show you the available channels.\",\n actions: [\"SLACK_LIST_CHANNELS\"],\n },\n },\n ],\n ] as ActionExample[][],\n};\n\nexport default listChannels;\n",
|
|
12
|
-
"import {\n type Action,\n type ActionExample,\n type ActionResult,\n type Content,\n composePromptFromState,\n type HandlerCallback,\n type HandlerOptions,\n type IAgentRuntime,\n type Memory,\n ModelType,\n parseJSONObjectFromText,\n type State,\n} from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { SLACK_SERVICE_NAME } from \"../types\";\n\nconst listPinsTemplate = `You are helping to extract list pins parameters for Slack.\n\nThe user wants to see pinned messages in a Slack channel.\n\nRecent conversation:\n{{recentMessages}}\n\nExtract the following:\n1. channelRef: The channel to list pins from (default: \"current\" for the current channel, or a channel name/ID)\n\nRespond with a JSON object like:\n{\n \"channelRef\": \"current\"\n}\n\nOnly respond with the JSON object, no other text.`;\n\nexport const listPins: Action = {\n name: \"SLACK_LIST_PINS\",\n similes: [\n \"LIST_SLACK_PINS\",\n \"SHOW_PINS\",\n \"GET_PINNED_MESSAGES\",\n \"PINNED_MESSAGES\",\n ],\n description: \"List pinned messages in a Slack channel\",\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['slack', 'list', 'pins'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:slack|list|pins)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'slack';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n return message.content.source === \"slack\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult | undefined> => {\n const slackService = runtime.getService(SLACK_SERVICE_NAME) as SlackService;\n\n if (!slackService || !slackService.client) {\n await callback?.({\n text: \"Slack service is not available.\",\n source: \"slack\",\n });\n return { success: false, error: \"Slack service not available\" };\n }\n\n const prompt = composePromptFromState({\n state,\n template: listPinsTemplate,\n });\n\n let listInfo: { channelRef?: string } | null = null;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsedResponse = parseJSONObjectFromText(response);\n if (parsedResponse) {\n listInfo = {\n channelRef: parsedResponse.channelRef\n ? String(parsedResponse.channelRef)\n : \"current\",\n };\n break;\n }\n }\n\n if (!listInfo) {\n listInfo = { channelRef: \"current\" };\n }\n\n const stateData = state?.data;\n const room = stateData?.room || (await runtime.getRoom(message.roomId));\n\n if (!room || !room.channelId) {\n await callback?.({\n text: \"I couldn't determine the current channel.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not determine channel\" };\n }\n\n let targetChannelId = room.channelId;\n\n // If a specific channel was referenced (not \"current\"), try to find it\n if (listInfo.channelRef && listInfo.channelRef !== \"current\") {\n const channels = await slackService.listChannels();\n const targetChannel = channels.find((ch) => {\n const channelName = ch.name?.toLowerCase() || \"\";\n const searchTerm = listInfo?.channelRef?.toLowerCase() || \"\";\n return (\n channelName === searchTerm ||\n channelName === searchTerm.replace(/^#/, \"\") ||\n ch.id === listInfo?.channelRef\n );\n });\n if (targetChannel) {\n targetChannelId = targetChannel.id;\n }\n }\n\n const pins = await slackService.listPins(targetChannelId);\n\n if (pins.length === 0) {\n const channelInfo = await slackService.getChannel(targetChannelId);\n const channelName = channelInfo?.name || targetChannelId;\n\n const response: Content = {\n text: `There are no pinned messages in #${channelName}.`,\n source: message.content.source,\n };\n await callback?.(response);\n\n return {\n success: true,\n data: {\n channelId: targetChannelId,\n pinCount: 0,\n pins: [],\n },\n };\n }\n\n // Format pinned messages\n const formattedPins = pins.map((pin, index) => {\n const timestamp = new Date(parseFloat(pin.ts) * 1000).toISOString();\n const user = pin.user || \"unknown\";\n const text = pin.text?.slice(0, 100) || \"[no text]\";\n const truncated = pin.text && pin.text.length > 100 ? \"...\" : \"\";\n return `${index + 1}. [${timestamp}] ${user}: ${text}${truncated}`;\n });\n\n const channelInfo = await slackService.getChannel(targetChannelId);\n const channelName = channelInfo?.name || targetChannelId;\n\n const response: Content = {\n text: `Pinned messages in #${channelName} (${pins.length}):\\n\\n${formattedPins.join(\"\\n\\n\")}`,\n source: message.content.source,\n };\n\n runtime.logger.debug(\n {\n src: \"plugin:slack:action:list-pins\",\n channelId: targetChannelId,\n pinCount: pins.length,\n },\n \"[SLACK_LIST_PINS] Pins listed\",\n );\n\n await callback?.(response);\n\n return {\n success: true,\n data: {\n channelId: targetChannelId,\n channelName,\n pinCount: pins.length,\n pins: pins.map((p) => ({\n ts: p.ts,\n user: p.user,\n text: p.text,\n })),\n },\n };\n },\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Show me the pinned messages in this channel\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I'll list the pinned messages.\",\n actions: [\"SLACK_LIST_PINS\"],\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"What's pinned in #announcements?\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"Let me check the pins in #announcements.\",\n actions: [\"SLACK_LIST_PINS\"],\n },\n },\n ],\n ] as ActionExample[][],\n};\n\nexport default listPins;\n",
|
|
13
|
-
"import {\n type Action,\n type ActionExample,\n type ActionResult,\n type Content,\n composePromptFromState,\n type HandlerCallback,\n type HandlerOptions,\n type IAgentRuntime,\n type Memory,\n ModelType,\n parseJSONObjectFromText,\n type State,\n} from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { isValidMessageTs, SLACK_SERVICE_NAME } from \"../types\";\n\nconst pinMessageTemplate = `You are helping to extract pin message parameters for Slack.\n\nThe user wants to pin a message in a Slack channel.\n\nRecent conversation:\n{{recentMessages}}\n\nExtract the following:\n1. messageTs: The message timestamp to pin (format: 1234567890.123456)\n2. channelId: The channel ID (optional, defaults to current channel)\n\nRespond with a JSON object like:\n{\n \"messageTs\": \"1234567890.123456\",\n \"channelId\": null\n}\n\nOnly respond with the JSON object, no other text.`;\n\nexport const pinMessage: Action = {\n name: \"SLACK_PIN_MESSAGE\",\n similes: [\"PIN_SLACK_MESSAGE\", \"PIN_MESSAGE\", \"SLACK_PIN\", \"SAVE_MESSAGE\"],\n description: \"Pin a message in a Slack channel\",\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['slack', 'pin', 'message'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:slack|pin|message)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'slack';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n return message.content.source === \"slack\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult | undefined> => {\n const slackService = runtime.getService(SLACK_SERVICE_NAME) as SlackService;\n\n if (!slackService || !slackService.client) {\n await callback?.({\n text: \"Slack service is not available.\",\n source: \"slack\",\n });\n return { success: false, error: \"Slack service not available\" };\n }\n\n const prompt = composePromptFromState({\n state,\n template: pinMessageTemplate,\n });\n\n let pinInfo: {\n messageTs: string;\n channelId?: string | null;\n } | null = null;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsedResponse = parseJSONObjectFromText(response);\n if (parsedResponse?.messageTs) {\n pinInfo = {\n messageTs: String(parsedResponse.messageTs),\n channelId: parsedResponse.channelId\n ? String(parsedResponse.channelId)\n : null,\n };\n break;\n }\n }\n\n if (!pinInfo || !pinInfo.messageTs) {\n runtime.logger.debug(\n { src: \"plugin:slack:action:pin-message\" },\n \"[SLACK_PIN_MESSAGE] Could not extract pin info\",\n );\n await callback?.({\n text: \"I couldn't understand which message to pin. Please specify the message timestamp.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not extract pin parameters\" };\n }\n\n if (!isValidMessageTs(pinInfo.messageTs)) {\n await callback?.({\n text: \"The message timestamp format is invalid. Please provide a valid Slack message timestamp.\",\n source: \"slack\",\n });\n return { success: false, error: \"Invalid message timestamp\" };\n }\n\n const stateData = state?.data;\n const room = stateData?.room || (await runtime.getRoom(message.roomId));\n const channelId = pinInfo.channelId || room?.channelId;\n\n if (!channelId) {\n await callback?.({\n text: \"I couldn't determine the channel for pinning the message.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not determine channel\" };\n }\n\n await slackService.pinMessage(channelId, pinInfo.messageTs);\n\n const response: Content = {\n text: \"Message pinned successfully.\",\n source: message.content.source,\n };\n\n runtime.logger.debug(\n {\n src: \"plugin:slack:action:pin-message\",\n messageTs: pinInfo.messageTs,\n channelId,\n },\n \"[SLACK_PIN_MESSAGE] Message pinned\",\n );\n\n await callback?.(response);\n\n return {\n success: true,\n data: {\n messageTs: pinInfo.messageTs,\n channelId,\n },\n };\n },\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Pin that important announcement\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I'll pin that message to the channel.\",\n actions: [\"SLACK_PIN_MESSAGE\"],\n },\n },\n ],\n ] as ActionExample[][],\n};\n\nexport default pinMessage;\n",
|
|
14
|
-
"import {\n type Action,\n type ActionExample,\n type ActionResult,\n type Content,\n composePromptFromState,\n type HandlerCallback,\n type HandlerOptions,\n type IAgentRuntime,\n type Memory,\n ModelType,\n parseJSONObjectFromText,\n type State,\n} from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { isValidMessageTs, SLACK_SERVICE_NAME } from \"../types\";\n\nconst reactToMessageTemplate = `You are helping to extract reaction parameters for Slack.\n\nThe user wants to add a reaction (emoji) to a Slack message.\n\nRecent conversation:\n{{recentMessages}}\n\nExtract the following:\n1. emoji: The emoji name to react with (without colons, e.g., \"thumbsup\" not \":thumbsup:\")\n2. messageTs: The message timestamp to react to (format: 1234567890.123456)\n3. channelId: The channel ID (optional, defaults to current channel)\n4. remove: Whether to remove the reaction instead of adding it (default: false)\n\nRespond with a JSON object like:\n{\n \"emoji\": \"thumbsup\",\n \"messageTs\": \"1234567890.123456\",\n \"channelId\": null,\n \"remove\": false\n}\n\nOnly respond with the JSON object, no other text.`;\n\nexport const reactToMessage: Action = {\n name: \"SLACK_REACT_TO_MESSAGE\",\n similes: [\n \"ADD_SLACK_REACTION\",\n \"REACT_SLACK\",\n \"SLACK_EMOJI\",\n \"ADD_EMOJI\",\n \"REMOVE_REACTION\",\n ],\n description: \"Add or remove an emoji reaction to a Slack message\",\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['slack', 'react', 'message'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:slack|react|message)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'slack';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n return message.content.source === \"slack\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult | undefined> => {\n const slackService = runtime.getService(SLACK_SERVICE_NAME) as SlackService;\n\n if (!slackService || !slackService.client) {\n await callback?.({\n text: \"Slack service is not available.\",\n source: \"slack\",\n });\n return { success: false, error: \"Slack service not available\" };\n }\n\n const prompt = composePromptFromState({\n state,\n template: reactToMessageTemplate,\n });\n\n let reactionInfo: {\n emoji: string;\n messageTs: string;\n channelId?: string | null;\n remove?: boolean;\n } | null = null;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsedResponse = parseJSONObjectFromText(response);\n if (parsedResponse?.emoji && parsedResponse?.messageTs) {\n reactionInfo = {\n emoji: String(parsedResponse.emoji),\n messageTs: String(parsedResponse.messageTs),\n channelId: parsedResponse.channelId\n ? String(parsedResponse.channelId)\n : null,\n remove: Boolean(parsedResponse.remove),\n };\n break;\n }\n }\n\n if (!reactionInfo || !reactionInfo.emoji || !reactionInfo.messageTs) {\n runtime.logger.debug(\n { src: \"plugin:slack:action:react-to-message\" },\n \"[SLACK_REACT_TO_MESSAGE] Could not extract reaction info\",\n );\n await callback?.({\n text: \"I couldn't understand the reaction request. Please specify the emoji and message to react to.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not extract reaction parameters\" };\n }\n\n if (!isValidMessageTs(reactionInfo.messageTs)) {\n await callback?.({\n text: \"The message timestamp format is invalid. Please provide a valid Slack message timestamp.\",\n source: \"slack\",\n });\n return { success: false, error: \"Invalid message timestamp\" };\n }\n\n const stateData = state?.data;\n const room = stateData?.room || (await runtime.getRoom(message.roomId));\n const channelId = reactionInfo.channelId || room?.channelId;\n\n if (!channelId) {\n await callback?.({\n text: \"I couldn't determine the channel for the reaction.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not determine channel\" };\n }\n\n if (reactionInfo.remove) {\n await slackService.removeReaction(\n channelId,\n reactionInfo.messageTs,\n reactionInfo.emoji,\n );\n } else {\n await slackService.sendReaction(\n channelId,\n reactionInfo.messageTs,\n reactionInfo.emoji,\n );\n }\n\n const actionWord = reactionInfo.remove ? \"removed\" : \"added\";\n const response: Content = {\n text: `Reaction :${reactionInfo.emoji}: ${actionWord} successfully.`,\n source: message.content.source,\n };\n\n runtime.logger.debug(\n {\n src: \"plugin:slack:action:react-to-message\",\n emoji: reactionInfo.emoji,\n messageTs: reactionInfo.messageTs,\n channelId,\n remove: reactionInfo.remove,\n },\n `[SLACK_REACT_TO_MESSAGE] Reaction ${actionWord}`,\n );\n\n await callback?.(response);\n\n return {\n success: true,\n data: {\n emoji: reactionInfo.emoji,\n messageTs: reactionInfo.messageTs,\n channelId,\n action: reactionInfo.remove ? \"removed\" : \"added\",\n },\n };\n },\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"React to the last message with a thumbs up\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I'll add a thumbs up reaction to that message.\",\n actions: [\"SLACK_REACT_TO_MESSAGE\"],\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Add a :tada: emoji to that announcement\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"Adding the tada emoji reaction now.\",\n actions: [\"SLACK_REACT_TO_MESSAGE\"],\n },\n },\n ],\n ] as ActionExample[][],\n};\n\nexport default reactToMessage;\n",
|
|
15
|
-
"import {\n type Action,\n type ActionExample,\n type ActionResult,\n type Content,\n composePromptFromState,\n type HandlerCallback,\n type HandlerOptions,\n type IAgentRuntime,\n type Memory,\n ModelType,\n parseJSONObjectFromText,\n type State,\n} from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { SLACK_SERVICE_NAME } from \"../types\";\n\nconst readChannelTemplate = `You are helping to extract read channel parameters for Slack.\n\nThe user wants to read message history from a Slack channel.\n\nRecent conversation:\n{{recentMessages}}\n\nExtract the following:\n1. channelRef: The channel to read from (default: \"current\" for the current channel, or a channel name/ID)\n2. limit: Number of messages to retrieve (default: 10, max: 100)\n3. before: Optional message timestamp to fetch messages before\n4. after: Optional message timestamp to fetch messages after\n\nRespond with a JSON object like:\n{\n \"channelRef\": \"current\",\n \"limit\": 10,\n \"before\": null,\n \"after\": null\n}\n\nOnly respond with the JSON object, no other text.`;\n\nexport const readChannel: Action = {\n name: \"SLACK_READ_CHANNEL\",\n similes: [\n \"READ_SLACK_MESSAGES\",\n \"GET_CHANNEL_HISTORY\",\n \"SLACK_HISTORY\",\n \"FETCH_MESSAGES\",\n \"LIST_MESSAGES\",\n ],\n description: \"Read message history from a Slack channel\",\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['slack', 'read', 'channel'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:slack|read|channel)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'slack';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n return message.content.source === \"slack\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult | undefined> => {\n const slackService = runtime.getService(SLACK_SERVICE_NAME) as SlackService;\n\n if (!slackService || !slackService.client) {\n await callback?.({\n text: \"Slack service is not available.\",\n source: \"slack\",\n });\n return { success: false, error: \"Slack service not available\" };\n }\n\n const prompt = composePromptFromState({\n state,\n template: readChannelTemplate,\n });\n\n let readInfo: {\n channelRef?: string;\n limit?: number;\n before?: string | null;\n after?: string | null;\n } | null = null;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsedResponse = parseJSONObjectFromText(response);\n if (parsedResponse) {\n readInfo = {\n channelRef: parsedResponse.channelRef\n ? String(parsedResponse.channelRef)\n : \"current\",\n limit: parsedResponse.limit\n ? Math.min(Number(parsedResponse.limit), 100)\n : 10,\n before: parsedResponse.before\n ? String(parsedResponse.before)\n : undefined,\n after: parsedResponse.after\n ? String(parsedResponse.after)\n : undefined,\n };\n break;\n }\n }\n\n if (!readInfo) {\n readInfo = { channelRef: \"current\", limit: 10 };\n }\n\n const stateData = state?.data;\n const room = stateData?.room || (await runtime.getRoom(message.roomId));\n\n if (!room || !room.channelId) {\n await callback?.({\n text: \"I couldn't determine the current channel.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not determine channel\" };\n }\n\n let targetChannelId = room.channelId;\n\n // If a specific channel was referenced (not \"current\"), try to find it\n if (readInfo.channelRef && readInfo.channelRef !== \"current\") {\n const channels = await slackService.listChannels();\n const targetChannel = channels.find((ch) => {\n const channelName = ch.name?.toLowerCase() || \"\";\n const searchTerm = readInfo?.channelRef?.toLowerCase() || \"\";\n return (\n channelName === searchTerm ||\n channelName === searchTerm.replace(/^#/, \"\") ||\n ch.id === readInfo?.channelRef\n );\n });\n if (targetChannel) {\n targetChannelId = targetChannel.id;\n }\n }\n\n const messages = await slackService.readHistory(targetChannelId, {\n limit: readInfo.limit,\n before: readInfo.before || undefined,\n after: readInfo.after || undefined,\n });\n\n // Format messages for display\n const formattedMessages = messages.map((msg) => {\n const timestamp = new Date(parseFloat(msg.ts) * 1000).toISOString();\n const user = msg.user || \"unknown\";\n const text = msg.text || \"[no text]\";\n return `[${timestamp}] ${user}: ${text}`;\n });\n\n const channelInfo = await slackService.getChannel(targetChannelId);\n const channelName = channelInfo?.name || targetChannelId;\n\n const response: Content = {\n text: `Here are the last ${messages.length} messages from #${channelName}:\\n\\n${formattedMessages.join(\"\\n\")}`,\n source: message.content.source,\n };\n\n runtime.logger.debug(\n {\n src: \"plugin:slack:action:read-channel\",\n channelId: targetChannelId,\n messageCount: messages.length,\n },\n \"[SLACK_READ_CHANNEL] Channel history retrieved\",\n );\n\n await callback?.(response);\n\n return {\n success: true,\n data: {\n channelId: targetChannelId,\n channelName,\n messageCount: messages.length,\n messages: messages.map((m) => ({\n ts: m.ts,\n user: m.user,\n text: m.text,\n threadTs: m.threadTs,\n })),\n },\n };\n },\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Show me the last 5 messages in this channel\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I'll fetch the recent messages for you.\",\n actions: [\"SLACK_READ_CHANNEL\"],\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"What's been happening in #announcements?\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"Let me check the recent messages in #announcements.\",\n actions: [\"SLACK_READ_CHANNEL\"],\n },\n },\n ],\n ] as ActionExample[][],\n};\n\nexport default readChannel;\n",
|
|
16
|
-
"import {\n type Action,\n type ActionExample,\n type ActionResult,\n type Content,\n composePromptFromState,\n type HandlerCallback,\n type HandlerOptions,\n type IAgentRuntime,\n type Memory,\n ModelType,\n parseJSONObjectFromText,\n type State,\n} from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { SLACK_SERVICE_NAME } from \"../types\";\n\nconst sendMessageTemplate = `You are helping to extract send message parameters for Slack.\n\nThe user wants to send a message to a Slack channel.\n\nRecent conversation:\n{{recentMessages}}\n\nExtract the following:\n1. text: The message text to send\n2. channelRef: The channel to send to (default: \"current\" for the current channel, or a channel name/ID)\n3. threadTs: Optional thread timestamp to reply in a thread (default: null)\n\nRespond with a JSON object like:\n{\n \"text\": \"The message to send\",\n \"channelRef\": \"current\",\n \"threadTs\": null\n}\n\nOnly respond with the JSON object, no other text.`;\n\nexport const sendMessage: Action = {\n name: \"SLACK_SEND_MESSAGE\",\n similes: [\n \"SEND_SLACK_MESSAGE\",\n \"POST_TO_SLACK\",\n \"MESSAGE_SLACK\",\n \"SLACK_POST\",\n \"SEND_TO_CHANNEL\",\n ],\n description: \"Send a message to a Slack channel or thread\",\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['slack', 'send', 'message'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:slack|send|message)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'slack';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n return message.content.source === \"slack\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult | undefined> => {\n const slackService = runtime.getService(SLACK_SERVICE_NAME) as SlackService;\n\n if (!slackService || !slackService.client) {\n await callback?.({\n text: \"Slack service is not available.\",\n source: \"slack\",\n });\n return { success: false, error: \"Slack service not available\" };\n }\n\n const prompt = composePromptFromState({\n state,\n template: sendMessageTemplate,\n });\n\n let messageInfo: {\n text: string;\n channelRef?: string;\n threadTs?: string | null;\n } | null = null;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsedResponse = parseJSONObjectFromText(response);\n if (parsedResponse?.text) {\n messageInfo = {\n text: String(parsedResponse.text),\n channelRef: parsedResponse.channelRef\n ? String(parsedResponse.channelRef)\n : \"current\",\n threadTs: parsedResponse.threadTs\n ? String(parsedResponse.threadTs)\n : undefined,\n };\n break;\n }\n }\n\n if (!messageInfo || !messageInfo.text) {\n runtime.logger.debug(\n { src: \"plugin:slack:action:send-message\" },\n \"[SLACK_SEND_MESSAGE] Could not extract message info\",\n );\n await callback?.({\n text: \"I couldn't understand what message you want me to send. Please try again with a clearer request.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not extract message parameters\" };\n }\n\n const stateData = state?.data;\n const room = stateData?.room || (await runtime.getRoom(message.roomId));\n\n if (!room || !room.channelId) {\n await callback?.({\n text: \"I couldn't determine the current channel.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not determine channel\" };\n }\n\n let targetChannelId = room.channelId;\n\n // If a specific channel was referenced (not \"current\"), try to find it\n if (messageInfo.channelRef && messageInfo.channelRef !== \"current\") {\n const channels = await slackService.listChannels();\n const targetChannel = channels.find((ch) => {\n const channelName = ch.name?.toLowerCase() || \"\";\n const searchTerm = messageInfo?.channelRef?.toLowerCase() || \"\";\n return (\n channelName === searchTerm ||\n channelName === searchTerm.replace(/^#/, \"\") ||\n ch.id === messageInfo?.channelRef\n );\n });\n if (targetChannel) {\n targetChannelId = targetChannel.id;\n }\n }\n\n const result = await slackService.sendMessage(\n targetChannelId,\n messageInfo.text,\n {\n threadTs: messageInfo.threadTs || undefined,\n replyBroadcast: undefined,\n unfurlLinks: undefined,\n unfurlMedia: undefined,\n mrkdwn: undefined,\n attachments: undefined,\n blocks: undefined,\n },\n );\n\n const response: Content = {\n text: \"Message sent successfully.\",\n source: message.content.source,\n };\n\n runtime.logger.debug(\n {\n src: \"plugin:slack:action:send-message\",\n messageTs: result.ts,\n channelId: targetChannelId,\n },\n \"[SLACK_SEND_MESSAGE] Message sent successfully\",\n );\n\n await callback?.(response);\n\n return {\n success: true,\n data: {\n messageTs: result.ts,\n channelId: targetChannelId,\n },\n };\n },\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Send a message to #general saying 'Hello everyone!'\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I'll send that message to #general for you.\",\n actions: [\"SLACK_SEND_MESSAGE\"],\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Post 'Meeting starts in 5 minutes' to this channel\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I'll post that announcement here.\",\n actions: [\"SLACK_SEND_MESSAGE\"],\n },\n },\n ],\n ] as ActionExample[][],\n};\n\nexport default sendMessage;\n",
|
|
17
|
-
"import {\n type Action,\n type ActionExample,\n type ActionResult,\n type Content,\n composePromptFromState,\n type HandlerCallback,\n type HandlerOptions,\n type IAgentRuntime,\n type Memory,\n ModelType,\n parseJSONObjectFromText,\n type State,\n} from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { isValidMessageTs, SLACK_SERVICE_NAME } from \"../types\";\n\nconst unpinMessageTemplate = `You are helping to extract unpin message parameters for Slack.\n\nThe user wants to unpin a message from a Slack channel.\n\nRecent conversation:\n{{recentMessages}}\n\nExtract the following:\n1. messageTs: The message timestamp to unpin (format: 1234567890.123456)\n2. channelId: The channel ID (optional, defaults to current channel)\n\nRespond with a JSON object like:\n{\n \"messageTs\": \"1234567890.123456\",\n \"channelId\": null\n}\n\nOnly respond with the JSON object, no other text.`;\n\nexport const unpinMessage: Action = {\n name: \"SLACK_UNPIN_MESSAGE\",\n similes: [\n \"UNPIN_SLACK_MESSAGE\",\n \"UNPIN_MESSAGE\",\n \"SLACK_UNPIN\",\n \"REMOVE_PIN\",\n ],\n description: \"Unpin a message from a Slack channel\",\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['slack', 'unpin', 'message'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:slack|unpin|message)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'slack';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n return message.content.source === \"slack\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult | undefined> => {\n const slackService = runtime.getService(SLACK_SERVICE_NAME) as SlackService;\n\n if (!slackService || !slackService.client) {\n await callback?.({\n text: \"Slack service is not available.\",\n source: \"slack\",\n });\n return { success: false, error: \"Slack service not available\" };\n }\n\n const prompt = composePromptFromState({\n state,\n template: unpinMessageTemplate,\n });\n\n let unpinInfo: {\n messageTs: string;\n channelId?: string | null;\n } | null = null;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsedResponse = parseJSONObjectFromText(response);\n if (parsedResponse?.messageTs) {\n unpinInfo = {\n messageTs: String(parsedResponse.messageTs),\n channelId: parsedResponse.channelId\n ? String(parsedResponse.channelId)\n : null,\n };\n break;\n }\n }\n\n if (!unpinInfo || !unpinInfo.messageTs) {\n runtime.logger.debug(\n { src: \"plugin:slack:action:unpin-message\" },\n \"[SLACK_UNPIN_MESSAGE] Could not extract unpin info\",\n );\n await callback?.({\n text: \"I couldn't understand which message to unpin. Please specify the message timestamp.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not extract unpin parameters\" };\n }\n\n if (!isValidMessageTs(unpinInfo.messageTs)) {\n await callback?.({\n text: \"The message timestamp format is invalid. Please provide a valid Slack message timestamp.\",\n source: \"slack\",\n });\n return { success: false, error: \"Invalid message timestamp\" };\n }\n\n const stateData = state?.data;\n const room = stateData?.room || (await runtime.getRoom(message.roomId));\n const channelId = unpinInfo.channelId || room?.channelId;\n\n if (!channelId) {\n await callback?.({\n text: \"I couldn't determine the channel for unpinning the message.\",\n source: \"slack\",\n });\n return { success: false, error: \"Could not determine channel\" };\n }\n\n await slackService.unpinMessage(channelId, unpinInfo.messageTs);\n\n const response: Content = {\n text: \"Message unpinned successfully.\",\n source: message.content.source,\n };\n\n runtime.logger.debug(\n {\n src: \"plugin:slack:action:unpin-message\",\n messageTs: unpinInfo.messageTs,\n channelId,\n },\n \"[SLACK_UNPIN_MESSAGE] Message unpinned\",\n );\n\n await callback?.(response);\n\n return {\n success: true,\n data: {\n messageTs: unpinInfo.messageTs,\n channelId,\n },\n };\n },\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: {\n text: \"Unpin that old announcement\",\n },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I'll remove the pin from that message.\",\n actions: [\"SLACK_UNPIN_MESSAGE\"],\n },\n },\n ],\n ] as ActionExample[][],\n};\n\nexport default unpinMessage;\n",
|
|
18
|
-
"import type { IAgentRuntime, Memory, Provider, State } from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { getSlackChannelType, ServiceType } from \"../types\";\nimport { validateActionKeywords, validateActionRegex } from \"@elizaos/core\";\n\n/**\n * Provider for retrieving Slack channel state information.\n */\nexport const channelStateProvider: Provider = {\n name: \"slackChannelState\",\n description: \"Provides information about the current Slack channel context\",\n dynamic: true,\n relevanceKeywords: [\n \"slackchannelstate\",\n \"channelstateprovider\",\n \"plugin\",\n \"slack\",\n \"status\",\n \"state\",\n \"context\",\n \"info\",\n \"details\",\n \"chat\",\n \"conversation\",\n \"agent\",\n \"room\",\n \"channel\",\n ],\nget: async (runtime: IAgentRuntime, message: Memory, state: State) => { const __providerKeywords = [\"slackchannelstate\", \"channelstateprovider\", \"plugin\", \"slack\", \"status\", \"state\", \"context\", \"info\", \"details\", \"chat\", \"conversation\", \"agent\", \"room\", \"channel\"];\n const __providerRegex = new RegExp(`\\\\b(${__providerKeywords.join(\"|\")})\\\\b`, \"i\");\n const __recentMessages = state?.recentMessagesData || [];\n const __isRelevant =\n validateActionKeywords(message, __recentMessages, __providerKeywords) ||\n validateActionRegex(message, __recentMessages, __providerRegex);\n if (!__isRelevant) {\n return { text: \"\" };\n }\n\n\n const room = state.data?.room ?? (await runtime.getRoom(message.roomId));\n if (!room) {\n return {\n data: {},\n values: {},\n text: \"\",\n };\n }\n\n // If message source is not slack, return empty\n if (message.content.source !== \"slack\") {\n return {\n data: {},\n values: {},\n text: \"\",\n };\n }\n\n const agentName = state?.agentName || \"The agent\";\n const senderName = state?.senderName || \"someone\";\n\n let responseText = \"\";\n let channelType = \"\";\n let workspaceName = \"\";\n let channelName = \"\";\n const channelId = room.channelId ?? \"\";\n const threadTs = room.metadata?.threadTs as string | undefined;\n\n const slackService = runtime.getService(ServiceType.SLACK) as SlackService;\n if (!slackService || !slackService.client) {\n runtime.logger.warn(\n {\n src: \"plugin:slack:provider:channelState\",\n agentId: runtime.agentId,\n channelId,\n },\n \"No Slack client found\",\n );\n return {\n data: {\n room,\n channelType: \"unknown\",\n channelId,\n },\n values: {\n channelType: \"unknown\",\n channelId,\n },\n text: \"\",\n };\n }\n\n // Get channel info\n const channel = channelId ? await slackService.getChannel(channelId) : null;\n if (channel) {\n channelName = channel.name;\n const slackChannelType = getSlackChannelType(channel);\n\n if (slackChannelType === \"im\") {\n channelType = \"DM\";\n responseText = `${agentName} is currently in a direct message conversation with ${senderName} on Slack. ${agentName} should engage in conversation, responding to messages that are addressed to them.`;\n } else if (slackChannelType === \"mpim\") {\n channelType = \"GROUP_DM\";\n responseText = `${agentName} is currently in a group direct message on Slack. ${agentName} should be aware that multiple people can see this conversation.`;\n } else {\n channelType =\n slackChannelType === \"group\" ? \"PRIVATE_CHANNEL\" : \"PUBLIC_CHANNEL\";\n\n if (threadTs) {\n responseText = `${agentName} is currently in a thread within the channel #${channelName} on Slack.`;\n responseText += `\\n${agentName} should keep responses focused on the thread topic and be mindful of thread etiquette.`;\n } else {\n responseText = `${agentName} is currently having a conversation in the Slack channel #${channelName}.`;\n responseText += `\\n${agentName} is in a channel with other users and should only participate when directly addressed or when the conversation is relevant to them.`;\n }\n\n if (channel.topic?.value) {\n responseText += `\\nChannel topic: ${channel.topic.value}`;\n }\n if (channel.purpose?.value) {\n responseText += `\\nChannel purpose: ${channel.purpose.value}`;\n }\n }\n } else {\n channelType = \"unknown\";\n responseText = `${agentName} is in a Slack conversation but couldn't retrieve channel details.`;\n }\n\n // Add workspace context if available\n const teamId = slackService.getTeamId();\n if (teamId && room.worldId) {\n const world = await runtime.getWorld(room.worldId);\n if (world) {\n workspaceName = world.name;\n responseText += `\\nWorkspace: ${workspaceName}`;\n }\n }\n\n // Add thread context if applicable\n if (threadTs) {\n responseText += `\\nThis is a threaded conversation (thread timestamp: ${threadTs}).`;\n }\n\n return {\n data: {\n room,\n channelType,\n workspaceName,\n channelName,\n channelId,\n threadTs,\n isThread: Boolean(threadTs),\n topic: channel?.topic?.value,\n purpose: channel?.purpose?.value,\n isPrivate: channel?.isPrivate,\n numMembers: channel?.numMembers,\n },\n values: {\n channelType,\n workspaceName,\n channelName,\n channelId,\n isThread: Boolean(threadTs),\n },\n text: responseText,\n };\n },\n};\n\nexport default channelStateProvider;\n",
|
|
19
|
-
"import type { IAgentRuntime, Memory, Provider, State } from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { getSlackUserDisplayName, ServiceType } from \"../types\";\nimport { validateActionKeywords, validateActionRegex } from \"@elizaos/core\";\n\n/**\n * Provider for retrieving Slack channel member information.\n */\nexport const memberListProvider: Provider = {\n name: \"slackMemberList\",\n description:\n \"Provides information about members in the current Slack channel\",\n dynamic: true,\n relevanceKeywords: [\n \"slackmemberlist\",\n \"memberlistprovider\",\n \"plugin\",\n \"slack\",\n \"status\",\n \"state\",\n \"context\",\n \"info\",\n \"details\",\n \"chat\",\n \"conversation\",\n \"agent\",\n \"room\",\n \"channel\",\n ],\nget: async (runtime: IAgentRuntime, message: Memory, state: State) => { const __providerKeywords = [\"slackmemberlist\", \"memberlistprovider\", \"plugin\", \"slack\", \"status\", \"state\", \"context\", \"info\", \"details\", \"chat\", \"conversation\", \"agent\", \"room\", \"channel\"];\n const __providerRegex = new RegExp(`\\\\b(${__providerKeywords.join(\"|\")})\\\\b`, \"i\");\n const __recentMessages = state?.recentMessagesData || [];\n const __isRelevant =\n validateActionKeywords(message, __recentMessages, __providerKeywords) ||\n validateActionRegex(message, __recentMessages, __providerRegex);\n if (!__isRelevant) {\n return { text: \"\" };\n }\n\n\n // If message source is not slack, return empty\n if (message.content.source !== \"slack\") {\n return {\n data: {},\n values: {},\n text: \"\",\n };\n }\n\n const room = state.data?.room ?? (await runtime.getRoom(message.roomId));\n if (!room || !room.channelId) {\n return {\n data: {},\n values: {},\n text: \"\",\n };\n }\n\n const slackService = runtime.getService(ServiceType.SLACK) as SlackService;\n if (!slackService || !slackService.client) {\n return {\n data: {},\n values: {},\n text: \"\",\n };\n }\n\n const channelId = room.channelId;\n\n // Get channel members\n const membersResult = await slackService.client.conversations.members({\n channel: channelId,\n limit: 100,\n });\n\n const memberIds = membersResult.members || [];\n\n if (memberIds.length === 0) {\n return {\n data: {\n channelId,\n memberCount: 0,\n members: [],\n },\n values: {\n memberCount: 0,\n },\n text: \"No members found in this channel.\",\n };\n }\n\n // Get user info for each member (limited to first 20 for performance)\n const memberLimit = 20;\n const limitedMemberIds = memberIds.slice(0, memberLimit);\n const members: Array<{\n id: string;\n name: string;\n displayName: string;\n isBot: boolean;\n isAdmin: boolean;\n }> = [];\n\n for (const memberId of limitedMemberIds) {\n const user = await slackService.getUser(memberId);\n if (user) {\n members.push({\n id: user.id,\n name: user.name,\n displayName: getSlackUserDisplayName(user),\n isBot: user.isBot,\n isAdmin: user.isAdmin || user.isOwner,\n });\n }\n }\n\n // Get channel info for name\n const channel = await slackService.getChannel(channelId);\n const channelName = channel?.name || channelId;\n\n // Format member list\n const botUserId = slackService.getBotUserId();\n const memberDescriptions = members.map((m) => {\n const tags: string[] = [];\n if (m.id === botUserId) tags.push(\"this bot\");\n if (m.isBot && m.id !== botUserId) tags.push(\"bot\");\n if (m.isAdmin) tags.push(\"admin\");\n const tagStr = tags.length > 0 ? ` (${tags.join(\", \")})` : \"\";\n return `- ${m.displayName} (@${m.name})${tagStr}`;\n });\n\n const truncationNote =\n memberIds.length > memberLimit\n ? `\\n\\n(Showing ${memberLimit} of ${memberIds.length} total members)`\n : \"\";\n\n const responseText = `Members in #${channelName}:\\n${memberDescriptions.join(\"\\n\")}${truncationNote}`;\n\n return {\n data: {\n channelId,\n channelName,\n memberCount: memberIds.length,\n members,\n hasMoreMembers: memberIds.length > memberLimit,\n },\n values: {\n channelId,\n channelName,\n memberCount: memberIds.length,\n },\n text: responseText,\n };\n },\n};\n\nexport default memberListProvider;\n",
|
|
20
|
-
"import type { IAgentRuntime, Memory, Provider, State } from \"@elizaos/core\";\nimport type { SlackService } from \"../service\";\nimport { ServiceType } from \"../types\";\nimport { validateActionKeywords, validateActionRegex } from \"@elizaos/core\";\n\n/**\n * Provider for retrieving Slack workspace information.\n */\nexport const workspaceInfoProvider: Provider = {\n name: \"slackWorkspaceInfo\",\n description: \"Provides information about the Slack workspace\",\n dynamic: true,\n relevanceKeywords: [\n \"slackworkspaceinfo\",\n \"workspaceinfoprovider\",\n \"plugin\",\n \"slack\",\n \"status\",\n \"state\",\n \"context\",\n \"info\",\n \"details\",\n \"chat\",\n \"conversation\",\n \"agent\",\n \"room\",\n \"channel\",\n ],\nget: async (runtime: IAgentRuntime, message: Memory, state: State) => { const __providerKeywords = [\"slackworkspaceinfo\", \"workspaceinfoprovider\", \"plugin\", \"slack\", \"status\", \"state\", \"context\", \"info\", \"details\", \"chat\", \"conversation\", \"agent\", \"room\", \"channel\"];\n const __providerRegex = new RegExp(`\\\\b(${__providerKeywords.join(\"|\")})\\\\b`, \"i\");\n const __recentMessages = state?.recentMessagesData || [];\n const __isRelevant =\n validateActionKeywords(message, __recentMessages, __providerKeywords) ||\n validateActionRegex(message, __recentMessages, __providerRegex);\n if (!__isRelevant) {\n return { text: \"\" };\n }\n\n\n // If message source is not slack, return empty\n if (message.content.source !== \"slack\") {\n return {\n data: {},\n values: {},\n text: \"\",\n };\n }\n\n const slackService = runtime.getService(ServiceType.SLACK) as SlackService;\n if (!slackService || !slackService.client) {\n return {\n data: {},\n values: {},\n text: \"\",\n };\n }\n\n const teamId = slackService.getTeamId();\n const botUserId = slackService.getBotUserId();\n const isConnected = slackService.isServiceConnected();\n\n let workspaceName = \"\";\n let domain = \"\";\n\n // Get workspace info from world if available\n const room = state.data?.room ?? (await runtime.getRoom(message.roomId));\n if (room?.worldId) {\n const world = await runtime.getWorld(room.worldId);\n if (world) {\n workspaceName = world.name;\n const worldMetadata = world.metadata as\n | Record<string, unknown>\n | undefined;\n domain = (worldMetadata?.domain as string) || \"\";\n }\n }\n\n // Get channel statistics\n const channels = await slackService.listChannels({\n types: \"public_channel,private_channel\",\n });\n const publicChannels = channels.filter(\n (ch) => !ch.isPrivate && !ch.isArchived,\n );\n const privateChannels = channels.filter(\n (ch) => ch.isPrivate && !ch.isArchived,\n );\n const memberChannels = channels.filter(\n (ch) => ch.isMember && !ch.isArchived,\n );\n\n // Get allowed channels\n const allowedChannelIds = slackService.getAllowedChannelIds();\n const hasChannelRestrictions = allowedChannelIds.length > 0;\n\n const agentName = state?.agentName || \"The agent\";\n\n let responseText = `${agentName} is connected to the Slack workspace`;\n if (workspaceName) {\n responseText += ` \"${workspaceName}\"`;\n }\n if (domain) {\n responseText += ` (${domain}.slack.com)`;\n }\n responseText += \".\";\n\n responseText += `\\n\\nWorkspace statistics:`;\n responseText += `\\n- Public channels: ${publicChannels.length}`;\n responseText += `\\n- Private channels: ${privateChannels.length}`;\n responseText += `\\n- Channels the bot is a member of: ${memberChannels.length}`;\n\n if (hasChannelRestrictions) {\n responseText += `\\n\\nNote: The bot is restricted to ${allowedChannelIds.length} specific channel(s).`;\n }\n\n return {\n data: {\n teamId,\n botUserId,\n workspaceName,\n domain,\n isConnected,\n publicChannelCount: publicChannels.length,\n privateChannelCount: privateChannels.length,\n memberChannelCount: memberChannels.length,\n hasChannelRestrictions,\n allowedChannelIds,\n },\n values: {\n teamId: teamId || \"\",\n botUserId: botUserId || \"\",\n workspaceName,\n domain,\n isConnected,\n publicChannelCount: publicChannels.length,\n privateChannelCount: privateChannels.length,\n memberChannelCount: memberChannels.length,\n },\n text: responseText,\n };\n },\n};\n\nexport default workspaceInfoProvider;\n",
|
|
21
|
-
"import {\n ChannelType,\n type Character,\n type Content,\n createUniqueUuid,\n type EventPayload,\n type HandlerCallback,\n type IAgentRuntime,\n type IMessageService,\n type Media,\n type Memory,\n type Room,\n Service,\n stringToUuid,\n type UUID,\n type World,\n} from \"@elizaos/core\";\nimport { App, LogLevel } from \"@slack/bolt\";\nimport type { WebAPICallResult, WebClient } from \"@slack/web-api\";\n\n// Define Slack event types inline to avoid import issues\ninterface SlackMessageEventType {\n type: \"message\";\n channel: string;\n user?: string;\n text?: string;\n ts: string;\n thread_ts?: string;\n team?: string;\n bot_id?: string;\n files?: Array<Record<string, unknown>>;\n}\n\ninterface SlackAppMentionEventType {\n type: \"app_mention\";\n channel: string;\n user?: string;\n text: string;\n ts: string;\n thread_ts?: string;\n event_ts: string;\n}\n\n// Helper to get message service from runtime\nconst getMessageService = (runtime: IAgentRuntime): IMessageService | null => {\n if (\"messageService\" in runtime) {\n const withMessageService = runtime as IAgentRuntime & {\n messageService?: IMessageService | null;\n };\n return withMessageService.messageService ?? null;\n }\n return null;\n};\n\nimport {\n getSlackChannelType,\n getSlackUserDisplayName,\n type ISlackService,\n isValidChannelId,\n MAX_SLACK_MESSAGE_LENGTH,\n SLACK_SERVICE_NAME,\n type SlackAttachment,\n type SlackBlock,\n type SlackChannel,\n SlackEventTypes,\n type SlackFile,\n type SlackMessage,\n type SlackMessageSendOptions,\n type SlackSettings,\n type SlackUser,\n} from \"./types\";\n\n/**\n * SlackService class for interacting with Slack via Socket Mode\n */\nexport class SlackService extends Service implements ISlackService {\n static serviceType: string = SLACK_SERVICE_NAME;\n capabilityDescription =\n \"The agent is able to send and receive messages on Slack\";\n\n app: App | null = null;\n client: WebClient | null = null;\n character: Character;\n botUserId: string | null = null;\n teamId: string | null = null;\n\n private settings: SlackSettings;\n private botToken: string | null = null;\n private appToken: string | null = null;\n private signingSecret: string | null = null;\n private userToken: string | undefined = undefined;\n private allowedChannelIds: Set<string> = new Set();\n private dynamicChannelIds: Set<string> = new Set();\n private userCache: Map<string, SlackUser> = new Map();\n private channelCache: Map<string, SlackChannel> = new Map();\n private isStarting = false;\n private isConnected = false;\n\n constructor(runtime: IAgentRuntime) {\n super(runtime);\n this.character = runtime.character;\n this.settings = this.loadSettings();\n\n // Parse allowed channel IDs\n const channelIdsRaw = runtime.getSetting(\"SLACK_CHANNEL_IDS\") as\n | string\n | undefined;\n if (channelIdsRaw?.trim()) {\n channelIdsRaw\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0 && isValidChannelId(s))\n .forEach((id) => this.allowedChannelIds.add(id));\n\n this.runtime.logger.debug(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n allowedChannelIds: Array.from(this.allowedChannelIds),\n },\n \"Channel restrictions enabled\",\n );\n }\n }\n\n private loadSettings(): SlackSettings {\n const ignoreBotMessages = this.runtime.getSetting(\n \"SLACK_SHOULD_IGNORE_BOT_MESSAGES\",\n );\n const respondOnlyToMentions = this.runtime.getSetting(\n \"SLACK_SHOULD_RESPOND_ONLY_TO_MENTIONS\",\n );\n\n return {\n allowedChannelIds: undefined,\n shouldIgnoreBotMessages:\n ignoreBotMessages === \"true\" || ignoreBotMessages === true,\n shouldRespondOnlyToMentions:\n respondOnlyToMentions === \"true\" || respondOnlyToMentions === true,\n };\n }\n\n static async start(runtime: IAgentRuntime): Promise<SlackService> {\n const service = new SlackService(runtime);\n\n const botToken = runtime.getSetting(\"SLACK_BOT_TOKEN\") as string;\n const appToken = runtime.getSetting(\"SLACK_APP_TOKEN\") as string;\n const signingSecret = runtime.getSetting(\"SLACK_SIGNING_SECRET\") as\n | string\n | undefined;\n const userToken = runtime.getSetting(\"SLACK_USER_TOKEN\") as\n | string\n | undefined;\n\n if (!botToken || !botToken.trim()) {\n runtime.logger.warn(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"SLACK_BOT_TOKEN not provided, Slack service will not start\",\n );\n return service;\n }\n\n if (!appToken || !appToken.trim()) {\n runtime.logger.warn(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"SLACK_APP_TOKEN not provided, Socket Mode will not work\",\n );\n return service;\n }\n\n service.botToken = botToken;\n service.appToken = appToken;\n service.signingSecret = signingSecret || undefined;\n service.userToken = userToken || undefined;\n\n await service.initialize();\n\n return service;\n }\n\n static async stop(runtime: IAgentRuntime): Promise<void> {\n const service = runtime.getService(SLACK_SERVICE_NAME) as\n | SlackService\n | undefined;\n if (service) {\n await service.shutdown();\n }\n }\n\n async stop(): Promise<void> {\n await this.shutdown();\n }\n\n private async initialize(): Promise<void> {\n if (this.isStarting || this.isConnected) {\n return;\n }\n\n this.isStarting = true;\n\n this.runtime.logger.info(\n { src: \"plugin:slack\", agentId: this.runtime.agentId },\n \"Initializing Slack service with Socket Mode\",\n );\n\n this.app = new App({\n token: this.botToken!,\n appToken: this.appToken!,\n socketMode: true,\n logLevel: LogLevel.INFO,\n ...(this.signingSecret ? { signingSecret: this.signingSecret } : {}),\n });\n\n this.client = this.app.client;\n\n // Get bot user info\n const authResult = await this.client.auth.test();\n this.botUserId = authResult.user_id as string;\n this.teamId = authResult.team_id as string;\n\n this.runtime.logger.info(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n botUserId: this.botUserId,\n teamId: this.teamId,\n },\n \"Slack bot authenticated\",\n );\n\n // Register event handlers\n this.registerEventHandlers();\n\n // Start the Socket Mode connection\n await this.app.start();\n\n this.isConnected = true;\n this.isStarting = false;\n\n this.runtime.logger.info(\n { src: \"plugin:slack\", agentId: this.runtime.agentId },\n \"Slack service started successfully\",\n );\n\n // Ensure all workspaces exist\n await this.ensureWorkspaceExists();\n }\n\n private async shutdown(): Promise<void> {\n if (this.app) {\n await this.app.stop();\n this.app = null;\n this.client = null;\n this.isConnected = false;\n\n this.runtime.logger.info(\n { src: \"plugin:slack\", agentId: this.runtime.agentId },\n \"Slack service stopped\",\n );\n }\n }\n\n private registerEventHandlers(): void {\n if (!this.app) return;\n\n // Handle regular messages\n this.app.message(async ({ message, client }) => {\n await this.handleMessage(message as SlackMessageEventType, client);\n });\n\n // Handle app mentions\n this.app.event(\"app_mention\", async ({ event, client }) => {\n await this.handleAppMention(event as SlackAppMentionEventType, client);\n });\n\n // Handle reactions\n this.app.event(\"reaction_added\", async ({ event }) => {\n await this.handleReactionAdded(event);\n });\n\n this.app.event(\"reaction_removed\", async ({ event }) => {\n await this.handleReactionRemoved(event);\n });\n\n // Handle channel joins/leaves\n this.app.event(\"member_joined_channel\", async ({ event }) => {\n await this.handleMemberJoinedChannel(event);\n });\n\n this.app.event(\"member_left_channel\", async ({ event }) => {\n await this.handleMemberLeftChannel(event);\n });\n\n // Handle file shares\n this.app.event(\"file_shared\", async ({ event }) => {\n await this.handleFileShared(event);\n });\n }\n\n private async handleMessage(\n message: SlackMessageEventType,\n _client: WebClient,\n ): Promise<void> {\n // Ignore bot messages if configured\n if (this.settings.shouldIgnoreBotMessages && message.bot_id) {\n return;\n }\n\n // Ignore messages from self\n if (message.user === this.botUserId) {\n return;\n }\n\n // Check channel restrictions\n if (!this.isChannelAllowed(message.channel)) {\n this.runtime.logger.debug(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n channelId: message.channel,\n },\n \"Message received in non-allowed channel, ignoring\",\n );\n return;\n }\n\n // Check if we should only respond to mentions\n const isMentioned = message.text?.includes(`<@${this.botUserId}>`);\n if (this.settings.shouldRespondOnlyToMentions && !isMentioned) {\n return;\n }\n\n const _isThreadReply = Boolean(\n message.thread_ts && message.thread_ts !== message.ts,\n );\n\n // Build memory from message\n const memory = await this.buildMemoryFromMessage(message);\n if (!memory) return;\n\n // Get or create room\n const room = await this.ensureRoomExists(\n message.channel,\n message.thread_ts,\n );\n\n // Store the memory\n await this.runtime.createMemory(memory, \"messages\");\n\n // Emit event\n await this.runtime.emitEvent(\n SlackEventTypes.MESSAGE_RECEIVED as string,\n {\n runtime: this.runtime,\n source: \"slack\",\n } as EventPayload,\n );\n\n // Process the message through the agent\n await this.processAgentMessage(\n memory,\n room,\n message.channel,\n message.thread_ts || message.ts,\n );\n }\n\n private async handleAppMention(\n event: SlackAppMentionEventType,\n _client: WebClient,\n ): Promise<void> {\n // Skip if no user (optional in AppMentionEvent)\n if (!event.user) return;\n\n // Build memory from mention\n const memory = await this.buildMemoryFromMention({\n user: event.user,\n text: event.text,\n channel: event.channel,\n ts: event.ts,\n thread_ts: event.thread_ts,\n });\n if (!memory) return;\n\n // Get or create room\n const room = await this.ensureRoomExists(event.channel, event.thread_ts);\n\n // Store the memory\n await this.runtime.createMemory(memory, \"messages\");\n\n // Emit event\n await this.runtime.emitEvent(\n SlackEventTypes.APP_MENTION as string,\n {\n runtime: this.runtime,\n source: \"slack\",\n } as EventPayload,\n );\n\n // Process the message\n await this.processAgentMessage(\n memory,\n room,\n event.channel,\n event.thread_ts || event.ts,\n );\n }\n\n private async handleReactionAdded(_event: {\n user: string;\n reaction: string;\n item: { type: string; channel: string; ts: string };\n item_user?: string;\n }): Promise<void> {\n await this.runtime.emitEvent(\n SlackEventTypes.REACTION_ADDED as string,\n {\n runtime: this.runtime,\n source: \"slack\",\n } as EventPayload,\n );\n }\n\n private async handleReactionRemoved(_event: {\n user: string;\n reaction: string;\n item: { type: string; channel: string; ts: string };\n item_user?: string;\n }): Promise<void> {\n await this.runtime.emitEvent(\n SlackEventTypes.REACTION_REMOVED as string,\n {\n runtime: this.runtime,\n source: \"slack\",\n } as EventPayload,\n );\n }\n\n private async handleMemberJoinedChannel(event: {\n user: string;\n channel: string;\n team?: string;\n }): Promise<void> {\n // If the bot joined, add to dynamic channels\n if (event.user === this.botUserId) {\n this.dynamicChannelIds.add(event.channel);\n await this.ensureRoomExists(event.channel);\n }\n\n await this.runtime.emitEvent(\n SlackEventTypes.MEMBER_JOINED_CHANNEL as string,\n {\n runtime: this.runtime,\n source: \"slack\",\n } as EventPayload,\n );\n }\n\n private async handleMemberLeftChannel(event: {\n user: string;\n channel: string;\n team?: string;\n }): Promise<void> {\n // If the bot left, remove from dynamic channels\n if (event.user === this.botUserId) {\n this.dynamicChannelIds.delete(event.channel);\n }\n\n await this.runtime.emitEvent(\n SlackEventTypes.MEMBER_LEFT_CHANNEL as string,\n {\n runtime: this.runtime,\n source: \"slack\",\n } as EventPayload,\n );\n }\n\n private async handleFileShared(_event: {\n file_id: string;\n user_id: string;\n channel_id: string;\n }): Promise<void> {\n await this.runtime.emitEvent(\n SlackEventTypes.FILE_SHARED as string,\n {\n runtime: this.runtime,\n source: \"slack\",\n } as EventPayload,\n );\n }\n\n private isChannelAllowed(channelId: string): boolean {\n // If no restrictions, all channels allowed\n if (\n this.allowedChannelIds.size === 0 &&\n this.dynamicChannelIds.size === 0\n ) {\n return true;\n }\n\n // Check static and dynamic allowed lists\n return (\n this.allowedChannelIds.has(channelId) ||\n this.dynamicChannelIds.has(channelId)\n );\n }\n\n private async processAgentMessage(\n memory: Memory,\n room: Room,\n channelId: string,\n threadTs: string,\n ): Promise<void> {\n const callback: HandlerCallback = async (\n response: Content,\n ): Promise<Memory[]> => {\n await this.sendMessage(channelId, response.text || \"\", {\n threadTs,\n replyBroadcast: undefined,\n unfurlLinks: undefined,\n unfurlMedia: undefined,\n mrkdwn: undefined,\n attachments: undefined,\n blocks: undefined,\n });\n\n // Create memory for the response\n const responseMemory: Memory = {\n id: createUniqueUuid(this.runtime, `slack-response-${Date.now()}`),\n agentId: this.runtime.agentId,\n roomId: room.id,\n entityId: this.runtime.agentId,\n content: {\n text: response.text || \"\",\n source: \"slack\",\n inReplyTo: memory.id,\n },\n createdAt: Date.now(),\n };\n\n await this.runtime.createMemory(responseMemory, \"messages\");\n\n await this.runtime.emitEvent(\n SlackEventTypes.MESSAGE_SENT as string,\n {\n runtime: this.runtime,\n source: \"slack\",\n } as EventPayload,\n );\n\n return [responseMemory];\n };\n\n const messageService = getMessageService(this.runtime);\n if (messageService) {\n await messageService.handleMessage(this.runtime, memory, callback);\n }\n }\n\n private async buildMemoryFromMessage(\n message: SlackMessageEventType,\n ): Promise<Memory | null> {\n if (!message.user) return null;\n\n const roomId = await this.getRoomId(message.channel, message.thread_ts);\n const entityId = this.getEntityId(message.user);\n\n // Get user info for display name\n const user = await this.getUser(message.user);\n const displayName = user ? getSlackUserDisplayName(user) : message.user;\n\n // Extract media from files\n const media: Media[] = [];\n if (\"files\" in message && message.files) {\n for (const file of message.files as unknown as SlackFile[]) {\n media.push({\n id: file.id,\n url: file.urlPrivate,\n title: file.title || file.name,\n source: \"slack\",\n description: file.name,\n });\n }\n }\n\n const memory: Memory = {\n id: createUniqueUuid(this.runtime, `slack-${message.ts}`),\n agentId: this.runtime.agentId,\n roomId,\n entityId,\n content: {\n text: message.text || \"\",\n source: \"slack\",\n name: displayName,\n ...(media.length > 0 ? { attachments: media } : {}),\n },\n createdAt: this.parseSlackTimestamp(message.ts),\n };\n\n return memory;\n }\n\n private async buildMemoryFromMention(event: {\n user: string;\n text: string;\n channel: string;\n ts: string;\n thread_ts?: string;\n }): Promise<Memory | null> {\n const roomId = await this.getRoomId(event.channel, event.thread_ts);\n const entityId = this.getEntityId(event.user);\n\n const user = await this.getUser(event.user);\n const displayName = user ? getSlackUserDisplayName(user) : event.user;\n\n // Remove the bot mention from the text\n const cleanText = event.text.replace(`<@${this.botUserId}>`, \"\").trim();\n\n const memory: Memory = {\n id: createUniqueUuid(this.runtime, `slack-mention-${event.ts}`),\n agentId: this.runtime.agentId,\n roomId,\n entityId,\n content: {\n text: cleanText,\n source: \"slack\",\n name: displayName,\n },\n createdAt: this.parseSlackTimestamp(event.ts),\n };\n\n return memory;\n }\n\n private async getRoomId(channelId: string, threadTs?: string): Promise<UUID> {\n // Use thread_ts to create unique rooms for threads\n const roomKey = threadTs ? `${channelId}-${threadTs}` : channelId;\n return createUniqueUuid(this.runtime, `slack-room-${roomKey}`);\n }\n\n private getEntityId(userId: string): UUID {\n return stringToUuid(`slack-user-${userId}`);\n }\n\n private parseSlackTimestamp(ts: string): number {\n // Slack timestamps are in the format: 1234567890.123456\n const [seconds] = ts.split(\".\");\n return parseInt(seconds, 10) * 1000;\n }\n\n private async ensureWorkspaceExists(): Promise<void> {\n if (!this.teamId || !this.client) return;\n\n const worldId = createUniqueUuid(\n this.runtime,\n `slack-workspace-${this.teamId}`,\n );\n\n const existingWorld = await this.runtime.getWorld(worldId);\n if (existingWorld) return;\n\n // Get team info\n const teamInfo = await this.client.team.info();\n const team = teamInfo.team;\n\n const world: World = {\n id: worldId,\n name:\n (team as { name?: string })?.name || `Slack Workspace ${this.teamId}`,\n agentId: this.runtime.agentId,\n metadata: {\n type: \"slack\",\n extra: {\n teamId: this.teamId,\n domain: (team as { domain?: string })?.domain,\n },\n },\n };\n\n await this.runtime.createWorld(world);\n\n this.runtime.logger.info(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n worldId,\n teamId: this.teamId,\n },\n \"Created Slack workspace world\",\n );\n }\n\n private async ensureRoomExists(\n channelId: string,\n threadTs?: string,\n ): Promise<Room> {\n const roomId = await this.getRoomId(channelId, threadTs);\n\n const existingRoom = await this.runtime.getRoom(roomId);\n if (existingRoom) return existingRoom;\n\n // Get channel info\n const channel = await this.getChannel(channelId);\n const channelType = channel ? getSlackChannelType(channel) : \"channel\";\n\n const worldId = this.teamId\n ? createUniqueUuid(this.runtime, `slack-workspace-${this.teamId}`)\n : undefined;\n\n const elizaChannelType =\n channelType === \"im\"\n ? ChannelType.DM\n : channelType === \"mpim\"\n ? ChannelType.GROUP\n : ChannelType.GROUP;\n\n const room: Room = {\n id: roomId,\n name: channel?.name || channelId,\n agentId: this.runtime.agentId,\n source: \"slack\",\n type: elizaChannelType,\n channelId,\n worldId,\n metadata: {\n slackChannelType: channelType,\n threadTs,\n topic: channel?.topic?.value,\n purpose: channel?.purpose?.value,\n serverId: this.teamId,\n },\n };\n\n await this.runtime.createRoom(room);\n\n this.runtime.logger.debug(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n roomId,\n channelId,\n threadTs,\n },\n \"Created Slack room\",\n );\n\n return room;\n }\n\n async getUser(userId: string): Promise<SlackUser | null> {\n // Check cache first\n if (this.userCache.has(userId)) {\n return this.userCache.get(userId)!;\n }\n\n if (!this.client) return null;\n\n const result = await this.client.users.info({ user: userId });\n if (!result.user) return null;\n\n const user: SlackUser = {\n id: result.user.id!,\n teamId: result.user.team_id,\n name: result.user.name!,\n deleted: result.user.deleted || false,\n realName: result.user.real_name,\n tz: result.user.tz,\n tzLabel: result.user.tz_label,\n tzOffset: result.user.tz_offset,\n profile: {\n title: result.user.profile?.title,\n phone: result.user.profile?.phone,\n skype: result.user.profile?.skype,\n realName: result.user.profile?.real_name,\n realNameNormalized: result.user.profile?.real_name_normalized,\n displayName: result.user.profile?.display_name,\n displayNameNormalized: result.user.profile?.display_name_normalized,\n statusText: result.user.profile?.status_text,\n statusEmoji: result.user.profile?.status_emoji,\n statusExpiration: result.user.profile?.status_expiration,\n avatarHash: result.user.profile?.avatar_hash,\n email: result.user.profile?.email,\n image24: result.user.profile?.image_24,\n image32: result.user.profile?.image_32,\n image48: result.user.profile?.image_48,\n image72: result.user.profile?.image_72,\n image192: result.user.profile?.image_192,\n image512: result.user.profile?.image_512,\n image1024: result.user.profile?.image_1024,\n imageOriginal: result.user.profile?.image_original,\n team: result.user.profile?.team,\n },\n isAdmin: result.user.is_admin || false,\n isOwner: result.user.is_owner || false,\n isPrimaryOwner: result.user.is_primary_owner || false,\n isRestricted: result.user.is_restricted || false,\n isUltraRestricted: result.user.is_ultra_restricted || false,\n isBot: result.user.is_bot || false,\n isAppUser: result.user.is_app_user || false,\n updated: result.user.updated || 0,\n };\n\n this.userCache.set(userId, user);\n return user;\n }\n\n async getChannel(channelId: string): Promise<SlackChannel | null> {\n // Check cache first\n if (this.channelCache.has(channelId)) {\n return this.channelCache.get(channelId)!;\n }\n\n if (!this.client) return null;\n\n const result = await this.client.conversations.info({ channel: channelId });\n if (!result.channel) return null;\n\n const channel: SlackChannel = {\n id: (result.channel as { id: string }).id,\n name: (result.channel as { name: string }).name || \"\",\n isChannel:\n (result.channel as { is_channel?: boolean }).is_channel || false,\n isGroup: (result.channel as { is_group?: boolean }).is_group || false,\n isIm: (result.channel as { is_im?: boolean }).is_im || false,\n isMpim: (result.channel as { is_mpim?: boolean }).is_mpim || false,\n isPrivate:\n (result.channel as { is_private?: boolean }).is_private || false,\n isArchived:\n (result.channel as { is_archived?: boolean }).is_archived || false,\n isGeneral:\n (result.channel as { is_general?: boolean }).is_general || false,\n isShared: (result.channel as { is_shared?: boolean }).is_shared || false,\n isOrgShared:\n (result.channel as { is_org_shared?: boolean }).is_org_shared || false,\n isMember: (result.channel as { is_member?: boolean }).is_member || false,\n topic: (\n result.channel as {\n topic?: { value: string; creator: string; last_set: number };\n }\n ).topic\n ? {\n value: (result.channel as { topic: { value: string } }).topic.value,\n creator: (result.channel as { topic: { creator: string } }).topic\n .creator,\n lastSet: (result.channel as { topic: { last_set: number } }).topic\n .last_set,\n }\n : undefined,\n purpose: (\n result.channel as {\n purpose?: { value: string; creator: string; last_set: number };\n }\n ).purpose\n ? {\n value: (result.channel as { purpose: { value: string } }).purpose\n .value,\n creator: (result.channel as { purpose: { creator: string } })\n .purpose.creator,\n lastSet: (result.channel as { purpose: { last_set: number } })\n .purpose.last_set,\n }\n : undefined,\n numMembers: (result.channel as { num_members?: number }).num_members,\n created: (result.channel as { created: number }).created,\n creator: (result.channel as { creator: string }).creator,\n };\n\n this.channelCache.set(channelId, channel);\n return channel;\n }\n\n async sendMessage(\n channelId: string,\n text: string,\n options?: SlackMessageSendOptions,\n ): Promise<{ ts: string; channelId: string }> {\n if (!this.client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n // Split message if too long\n const messages = this.splitMessage(text);\n let lastTs = \"\";\n\n for (const msg of messages) {\n const result = await this.client.chat.postMessage({\n channel: channelId,\n text: msg,\n thread_ts: options?.threadTs,\n reply_broadcast: options?.replyBroadcast,\n unfurl_links: options?.unfurlLinks,\n unfurl_media: options?.unfurlMedia,\n mrkdwn: options?.mrkdwn ?? true,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n attachments: options?.attachments as unknown as any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n blocks: options?.blocks as unknown as any,\n });\n\n lastTs = result.ts as string;\n }\n\n return { ts: lastTs, channelId };\n }\n\n async sendReaction(\n channelId: string,\n messageTs: string,\n emoji: string,\n ): Promise<void> {\n if (!this.client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n // Remove colons if present\n const cleanEmoji = emoji.replace(/^:/, \"\").replace(/:$/, \"\");\n\n await this.client.reactions.add({\n channel: channelId,\n timestamp: messageTs,\n name: cleanEmoji,\n });\n }\n\n async removeReaction(\n channelId: string,\n messageTs: string,\n emoji: string,\n ): Promise<void> {\n if (!this.client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const cleanEmoji = emoji.replace(/^:/, \"\").replace(/:$/, \"\");\n\n await this.client.reactions.remove({\n channel: channelId,\n timestamp: messageTs,\n name: cleanEmoji,\n });\n }\n\n async editMessage(\n channelId: string,\n messageTs: string,\n text: string,\n ): Promise<void> {\n if (!this.client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n await this.client.chat.update({\n channel: channelId,\n ts: messageTs,\n text,\n });\n }\n\n async deleteMessage(channelId: string, messageTs: string): Promise<void> {\n if (!this.client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n await this.client.chat.delete({\n channel: channelId,\n ts: messageTs,\n });\n }\n\n async pinMessage(channelId: string, messageTs: string): Promise<void> {\n if (!this.client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n await this.client.pins.add({\n channel: channelId,\n timestamp: messageTs,\n });\n }\n\n async unpinMessage(channelId: string, messageTs: string): Promise<void> {\n if (!this.client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n await this.client.pins.remove({\n channel: channelId,\n timestamp: messageTs,\n });\n }\n\n async listPins(channelId: string): Promise<SlackMessage[]> {\n if (!this.client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const result = await this.client.pins.list({ channel: channelId });\n\n return (result.items || [])\n .filter(\n (item): item is { type: \"message\"; message: Record<string, unknown> } =>\n item.type === \"message\" && \"message\" in item && !!item.message,\n )\n .map((item) => ({\n type: item.message.type as string,\n subtype: item.message.subtype as string | undefined,\n ts: item.message.ts as string,\n user: item.message.user as string | undefined,\n text: item.message.text as string,\n threadTs: item.message.thread_ts as string | undefined,\n replyCount: item.message.reply_count as number | undefined,\n replyUsersCount: item.message.reply_users_count as number | undefined,\n latestReply: item.message.latest_reply as string | undefined,\n reactions: item.message.reactions as\n | { name: string; count: number; users: string[] }[]\n | undefined,\n files: item.message.files as SlackFile[] | undefined,\n attachments: item.message.attachments as SlackAttachment[] | undefined,\n blocks: item.message.blocks as SlackBlock[] | undefined,\n }));\n }\n\n async readHistory(\n channelId: string,\n options?: { limit?: number; before?: string; after?: string },\n ): Promise<SlackMessage[]> {\n if (!this.client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const result = await this.client.conversations.history({\n channel: channelId,\n limit: options?.limit || 100,\n latest: options?.before,\n oldest: options?.after,\n });\n\n return (result.messages || []).map((msg) => ({\n type: msg.type as string,\n subtype: msg.subtype as string | undefined,\n ts: msg.ts as string,\n user: msg.user as string | undefined,\n text: msg.text as string,\n threadTs: msg.thread_ts as string | undefined,\n replyCount: msg.reply_count as number | undefined,\n replyUsersCount: msg.reply_users_count as number | undefined,\n latestReply: msg.latest_reply as string | undefined,\n reactions: msg.reactions as\n | { name: string; count: number; users: string[] }[]\n | undefined,\n files: msg.files as SlackFile[] | undefined,\n attachments: msg.attachments as SlackAttachment[] | undefined,\n blocks: msg.blocks as SlackBlock[] | undefined,\n }));\n }\n\n async listChannels(options?: {\n types?: string;\n limit?: number;\n }): Promise<SlackChannel[]> {\n if (!this.client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const result = await this.client.conversations.list({\n types: options?.types || \"public_channel,private_channel\",\n limit: options?.limit || 1000,\n });\n\n return (result.channels || []).map((ch) => ({\n id: ch.id!,\n name: ch.name || \"\",\n isChannel: ch.is_channel || false,\n isGroup: ch.is_group || false,\n isIm: ch.is_im || false,\n isMpim: ch.is_mpim || false,\n isPrivate: ch.is_private || false,\n isArchived: ch.is_archived || false,\n isGeneral: ch.is_general || false,\n isShared: ch.is_shared || false,\n isOrgShared: ch.is_org_shared || false,\n isMember: ch.is_member || false,\n topic: ch.topic\n ? {\n value: ch.topic.value!,\n creator: ch.topic.creator!,\n lastSet: ch.topic.last_set!,\n }\n : undefined,\n purpose: ch.purpose\n ? {\n value: ch.purpose.value!,\n creator: ch.purpose.creator!,\n lastSet: ch.purpose.last_set!,\n }\n : undefined,\n numMembers: ch.num_members,\n created: ch.created || 0,\n creator: ch.creator || \"\",\n }));\n }\n\n async getEmojiList(): Promise<Record<string, string>> {\n if (!this.client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const result = await this.client.emoji.list();\n return (result.emoji || {}) as Record<string, string>;\n }\n\n async uploadFile(\n channelId: string,\n content: Buffer | string,\n filename: string,\n options?: { title?: string; initialComment?: string; threadTs?: string },\n ): Promise<{ fileId: string; permalink: string }> {\n if (!this.client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const result = await this.client.files.uploadV2({\n channel_id: channelId,\n content: typeof content === \"string\" ? content : undefined,\n file: typeof content !== \"string\" ? content : undefined,\n filename,\n title: options?.title,\n initial_comment: options?.initialComment,\n thread_ts: options?.threadTs,\n });\n\n const resultWithFile = result as WebAPICallResult & {\n file?: { id: string; permalink: string };\n };\n const file = resultWithFile.file;\n return {\n fileId: file?.id || \"\",\n permalink: file?.permalink || \"\",\n };\n }\n\n private splitMessage(text: string): string[] {\n if (text.length <= MAX_SLACK_MESSAGE_LENGTH) {\n return [text];\n }\n\n const messages: string[] = [];\n let remaining = text;\n\n while (remaining.length > 0) {\n if (remaining.length <= MAX_SLACK_MESSAGE_LENGTH) {\n messages.push(remaining);\n break;\n }\n\n // Find a good split point (prefer newlines, then spaces)\n let splitIndex = MAX_SLACK_MESSAGE_LENGTH;\n\n const lastNewline = remaining.lastIndexOf(\"\\n\", MAX_SLACK_MESSAGE_LENGTH);\n if (lastNewline > MAX_SLACK_MESSAGE_LENGTH / 2) {\n splitIndex = lastNewline + 1;\n } else {\n const lastSpace = remaining.lastIndexOf(\" \", MAX_SLACK_MESSAGE_LENGTH);\n if (lastSpace > MAX_SLACK_MESSAGE_LENGTH / 2) {\n splitIndex = lastSpace + 1;\n }\n }\n\n messages.push(remaining.slice(0, splitIndex));\n remaining = remaining.slice(splitIndex);\n }\n\n return messages;\n }\n\n /**\n * Add a channel to the dynamic allowed list\n */\n addAllowedChannel(channelId: string): void {\n if (isValidChannelId(channelId)) {\n this.dynamicChannelIds.add(channelId);\n }\n }\n\n /**\n * Remove a channel from the dynamic allowed list\n */\n removeAllowedChannel(channelId: string): void {\n this.dynamicChannelIds.delete(channelId);\n }\n\n /**\n * Get all currently allowed channel IDs\n */\n getAllowedChannelIds(): string[] {\n return [...this.allowedChannelIds, ...this.dynamicChannelIds];\n }\n\n /**\n * Check if the service is connected\n */\n isServiceConnected(): boolean {\n return this.isConnected && this.app !== null;\n }\n\n /**\n * Get the bot's user ID\n */\n getBotUserId(): string | null {\n return this.botUserId;\n }\n\n /**\n * Get the team/workspace ID\n */\n getTeamId(): string | null {\n return this.teamId;\n }\n\n /**\n * Clear the user cache\n */\n clearUserCache(): void {\n this.userCache.clear();\n }\n\n /**\n * Clear the channel cache\n */\n clearChannelCache(): void {\n this.channelCache.clear();\n }\n}\n",
|
|
5
|
+
"import {\n getConnectorAccountManager,\n type IAgentRuntime,\n logger,\n type Plugin,\n} from \"@elizaos/core\";\nimport { createSlackConnectorAccountProvider } from \"./connector-account-provider\";\n\nimport { SlackService } from \"./service\";\nimport { SlackWorkflowCredentialProvider } from \"./workflow-credential-provider\";\n\nconst slackPlugin: Plugin = {\n name: \"slack\",\n description: \"Slack integration plugin for ElizaOS with Socket Mode support\",\n services: [SlackService, SlackWorkflowCredentialProvider],\n actions: [],\n providers: [],\n // Self-declared auto-enable: activate when the \"slack\" connector is\n // configured under config.connectors. The hardcoded CONNECTOR_PLUGINS map\n // in plugin-auto-enable-engine.ts still serves as a fallback.\n autoEnable: {\n connectorKeys: [\"slack\"],\n },\n init: async (_config: Record<string, string>, runtime: IAgentRuntime) => {\n // Register with the ConnectorAccountManager so the generic HTTP CRUD +\n // OAuth surface can list, create, patch, delete, and run OAuth v2 install\n // flows for Slack workspaces.\n try {\n const manager = getConnectorAccountManager(runtime);\n manager.registerProvider(createSlackConnectorAccountProvider(runtime));\n } catch (err) {\n logger.warn(\n {\n src: \"plugin:slack\",\n err: err instanceof Error ? err.message : String(err),\n },\n \"Failed to register Slack provider with ConnectorAccountManager\",\n );\n }\n\n const botToken = runtime.getSetting(\"SLACK_BOT_TOKEN\") as string;\n const appToken = runtime.getSetting(\"SLACK_APP_TOKEN\") as string;\n const signingSecret = runtime.getSetting(\"SLACK_SIGNING_SECRET\") as string;\n const userToken = runtime.getSetting(\"SLACK_USER_TOKEN\") as string;\n const channelIds = runtime.getSetting(\"SLACK_CHANNEL_IDS\") as string;\n const ignoreBotMessages = runtime.getSetting(\n \"SLACK_SHOULD_IGNORE_BOT_MESSAGES\",\n ) as string;\n const respondOnlyToMentions = runtime.getSetting(\n \"SLACK_SHOULD_RESPOND_ONLY_TO_MENTIONS\",\n ) as string;\n\n // Log configuration status\n const maskToken = (token: string | undefined): string => {\n if (!token || token.trim() === \"\") return \"[not set]\";\n if (token.length <= 8) return \"***\";\n return `${token.slice(0, 4)}...${token.slice(-4)}`;\n };\n\n logger.info(\n {\n src: \"plugin:slack\",\n agentId: runtime.agentId,\n settings: {\n botToken: maskToken(botToken),\n appToken: maskToken(appToken),\n signingSecret: signingSecret ? \"[set]\" : \"[not set]\",\n userToken: maskToken(userToken),\n channelIds: channelIds || \"[all channels]\",\n ignoreBotMessages: ignoreBotMessages || \"false\",\n respondOnlyToMentions: respondOnlyToMentions || \"false\",\n },\n },\n \"Slack plugin initializing\",\n );\n\n if (!botToken || botToken.trim() === \"\") {\n logger.warn(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"SLACK_BOT_TOKEN not provided - Slack plugin is loaded but will not be functional\",\n );\n logger.warn(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"To enable Slack functionality, please provide SLACK_BOT_TOKEN in your .env file\",\n );\n return;\n }\n\n if (!appToken || appToken.trim() === \"\") {\n logger.warn(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"SLACK_APP_TOKEN not provided - Socket Mode will not work\",\n );\n logger.warn(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"To enable Socket Mode, please provide SLACK_APP_TOKEN in your .env file\",\n );\n return;\n }\n\n // Validate token formats\n if (!botToken.startsWith(\"xoxb-\")) {\n logger.warn(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"SLACK_BOT_TOKEN should start with 'xoxb-'. Please verify your token.\",\n );\n }\n\n if (!appToken.startsWith(\"xapp-\")) {\n logger.warn(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"SLACK_APP_TOKEN should start with 'xapp-'. Please verify your token.\",\n );\n }\n\n if (userToken && !userToken.startsWith(\"xoxp-\")) {\n logger.warn(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"SLACK_USER_TOKEN should start with 'xoxp-'. Please verify your token.\",\n );\n }\n\n logger.info(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"Slack plugin configuration validated successfully\",\n );\n },\n};\n\nexport default slackPlugin;\n\n// Account management exports\nexport {\n DEFAULT_ACCOUNT_ID,\n isMultiAccountEnabled,\n listEnabledSlackAccounts,\n listSlackAccountIds,\n normalizeAccountId,\n type ResolvedSlackAccount,\n resolveDefaultSlackAccountId,\n resolveSlackAccount,\n resolveSlackAppToken,\n resolveSlackBotToken,\n resolveSlackReplyToMode,\n resolveSlackUserToken,\n type SlackAccountConfig,\n type SlackActionConfig,\n type SlackChannelConfig,\n type SlackDmConfig,\n type SlackMultiAccountConfig,\n type SlackReactionNotificationMode,\n type SlackSlashCommandConfig,\n type SlackTokenSource,\n} from \"./accounts\";\n// Channel configuration types\nexport type {\n SlackConfig,\n SlackThreadConfig,\n} from \"./config\";\nexport { createSlackConnectorAccountProvider } from \"./connector-account-provider\";\n// Formatting exports\nexport {\n buildSlackMessagePermalink,\n type ChunkSlackTextOpts,\n chunkSlackText,\n escapeSlackMrkdwn,\n extractChannelIdFromMention,\n extractUrlFromSlackLink,\n extractUserIdFromMention,\n formatSlackChannel,\n formatSlackChannelMention,\n formatSlackDate,\n formatSlackLink,\n formatSlackSpecialMention,\n formatSlackUserDisplayName,\n formatSlackUserGroupMention,\n formatSlackUserMention,\n getChannelTypeString,\n isDirectMessage,\n isGroupDm,\n isPrivateChannel,\n markdownToSlackMrkdwn,\n markdownToSlackMrkdwnChunks,\n parseSlackMessagePermalink,\n resolveSlackSystemLocation,\n stripSlackFormatting,\n truncateText,\n} from \"./formatting\";\n// Export service for direct access\nexport { SlackService } from \"./service\";\n// Export types\nexport type {\n ISlackService,\n SlackChannel,\n SlackChannelType,\n SlackEventPayloadMap,\n SlackFile,\n SlackMessage,\n SlackMessageReceivedPayload,\n SlackMessageSendOptions,\n SlackMessageSentPayload,\n SlackReaction,\n SlackReactionPayload,\n SlackSettings,\n SlackTeam,\n SlackUser,\n SlackUserProfile,\n} from \"./types\";\nexport {\n formatMessageTsForLink,\n getSlackChannelType,\n getSlackUserDisplayName,\n isValidChannelId,\n isValidMessageTs,\n isValidTeamId,\n isValidUserId,\n MAX_SLACK_BLOCKS,\n MAX_SLACK_FILE_SIZE,\n MAX_SLACK_MESSAGE_LENGTH,\n parseSlackMessageLink,\n SLACK_SERVICE_NAME,\n SlackApiError,\n SlackClientNotAvailableError,\n SlackConfigurationError,\n SlackEventTypes,\n SlackPluginError,\n SlackServiceNotInitializedError,\n} from \"./types\";\n",
|
|
6
|
+
"/**\n * Slack ConnectorAccountManager provider.\n *\n * Bridges plugin-slack to the @elizaos/core ConnectorAccountManager so the\n * generic HTTP CRUD + OAuth surface can list, create, patch, delete, and run\n * the OAuth v2 install flow for Slack workspaces.\n *\n * Single-account env-only configurations (SLACK_BOT_TOKEN, SLACK_APP_TOKEN)\n * are surfaced as a synthesized 'default' account with role 'OWNER' so\n * downstream consumers see a uniform list. Multi-account configs declared on\n * character.settings.slack are surfaced verbatim.\n */\nimport {\n type ConnectorAccount,\n type ConnectorAccountManager,\n type ConnectorAccountPatch,\n type ConnectorAccountProvider,\n type ConnectorAccountPurpose,\n type ConnectorOAuthCallbackRequest,\n type ConnectorOAuthCallbackResult,\n type ConnectorOAuthStartRequest,\n type ConnectorOAuthStartResult,\n type IAgentRuntime,\n logger,\n} from \"@elizaos/core\";\nimport {\n DEFAULT_ACCOUNT_ID,\n listEnabledSlackAccounts,\n resolveDefaultSlackAccountId,\n resolveSlackAccount,\n} from \"./accounts\";\nimport { persistConnectorCredentialRefs } from \"./connector-credential-refs\";\nimport { SLACK_SERVICE_NAME } from \"./types\";\n\nconst SLACK_OAUTH_AUTHORIZE_URL = \"https://slack.com/oauth/v2/authorize\";\nconst SLACK_OAUTH_TOKEN_URL = \"https://slack.com/api/oauth.v2.access\";\n\nconst DEFAULT_BOT_SCOPES = [\n \"app_mentions:read\",\n \"channels:history\",\n \"channels:read\",\n \"chat:write\",\n \"groups:history\",\n \"groups:read\",\n \"im:history\",\n \"im:read\",\n \"im:write\",\n \"mpim:history\",\n \"mpim:read\",\n \"reactions:read\",\n \"reactions:write\",\n \"users:read\",\n];\n\nconst DEFAULT_PURPOSES: ConnectorAccountPurpose[] = [\n \"messaging\",\n \"posting\",\n \"reading\",\n];\n\ninterface SlackOAuthV2Response {\n ok: boolean;\n error?: string;\n access_token?: string;\n refresh_token?: string;\n expires_in?: number;\n token_type?: string;\n scope?: string;\n bot_user_id?: string;\n app_id?: string;\n team?: { id: string; name?: string };\n enterprise?: { id: string; name?: string } | null;\n authed_user?: {\n id: string;\n scope?: string;\n access_token?: string;\n refresh_token?: string;\n expires_in?: number;\n token_type?: string;\n };\n incoming_webhook?: {\n channel?: string;\n channel_id?: string;\n configuration_url?: string;\n url?: string;\n };\n}\n\nfunction nowMs(): number {\n return Date.now();\n}\n\nfunction nonEmptyString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction readSetting(runtime: IAgentRuntime, key: string): string | undefined {\n return nonEmptyString(runtime.getSetting?.(key));\n}\n\nfunction readClientConfig(runtime: IAgentRuntime): {\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n} {\n const clientId = readSetting(runtime, \"SLACK_CLIENT_ID\");\n const clientSecret = readSetting(runtime, \"SLACK_CLIENT_SECRET\");\n const redirectUri = readSetting(runtime, \"SLACK_REDIRECT_URI\");\n if (!clientId || !clientSecret || !redirectUri) {\n throw new Error(\n \"Slack OAuth requires SLACK_CLIENT_ID, SLACK_CLIENT_SECRET, and SLACK_REDIRECT_URI to be configured.\",\n );\n }\n return { clientId, clientSecret, redirectUri };\n}\n\nfunction synthesizeAccount(\n accountId: string,\n name: string | undefined,\n isDefault: boolean,\n source: string,\n): ConnectorAccount {\n return {\n id: accountId,\n provider: SLACK_SERVICE_NAME,\n label: name ?? `Slack (${accountId})`,\n role: \"OWNER\",\n purpose: DEFAULT_PURPOSES,\n accessGate: \"open\",\n status: \"connected\",\n createdAt: nowMs(),\n updatedAt: nowMs(),\n metadata: {\n synthesized: true,\n source,\n isDefault,\n },\n };\n}\n\nfunction normalizePurposes(\n purpose: ConnectorAccountPatch[\"purpose\"] | undefined,\n fallback: ConnectorAccountPurpose[],\n): ConnectorAccountPurpose[] {\n if (Array.isArray(purpose)) return purpose;\n if (typeof purpose === \"string\" && purpose.trim()) return [purpose];\n return fallback;\n}\n\nfunction mergeStoredAccountPatch(\n account: ConnectorAccount,\n patch: ConnectorAccountPatch,\n): ConnectorAccount {\n return {\n ...account,\n ...patch,\n provider: SLACK_SERVICE_NAME,\n id: account.id,\n purpose: normalizePurposes(patch.purpose, account.purpose),\n externalId:\n patch.externalId === undefined\n ? account.externalId\n : (patch.externalId ?? undefined),\n displayHandle:\n patch.displayHandle === undefined\n ? account.displayHandle\n : (patch.displayHandle ?? undefined),\n ownerBindingId:\n patch.ownerBindingId === undefined\n ? account.ownerBindingId\n : (patch.ownerBindingId ?? undefined),\n ownerIdentityId:\n patch.ownerIdentityId === undefined\n ? account.ownerIdentityId\n : (patch.ownerIdentityId ?? undefined),\n metadata: patch.metadata ?? account.metadata,\n createdAt: account.createdAt,\n };\n}\n\nexport function createSlackConnectorAccountProvider(\n runtime: IAgentRuntime,\n): ConnectorAccountProvider {\n return {\n provider: SLACK_SERVICE_NAME,\n label: \"Slack\",\n\n listAccounts: async (\n manager: ConnectorAccountManager,\n ): Promise<ConnectorAccount[]> => {\n const persisted = await manager\n .getStorage()\n .listAccounts(SLACK_SERVICE_NAME);\n const persistedById = new Map(persisted.map((a) => [a.id, a]));\n\n const enabled = listEnabledSlackAccounts(runtime);\n const defaultAccountId = resolveDefaultSlackAccountId(runtime);\n const synthesized: ConnectorAccount[] = enabled\n .filter((account) => !persistedById.has(account.accountId))\n .map((account) =>\n synthesizeAccount(\n account.accountId,\n account.name,\n account.accountId === defaultAccountId,\n account.botTokenSource,\n ),\n );\n\n if (synthesized.length === 0 && persisted.length === 0) {\n const fallback = resolveSlackAccount(runtime, DEFAULT_ACCOUNT_ID);\n if (fallback.botToken) {\n synthesized.push(\n synthesizeAccount(\n DEFAULT_ACCOUNT_ID,\n fallback.name,\n true,\n fallback.botTokenSource,\n ),\n );\n }\n }\n\n return [...persisted, ...synthesized];\n },\n\n createAccount: async (input: ConnectorAccountPatch) => {\n return {\n ...input,\n provider: SLACK_SERVICE_NAME,\n role: input.role ?? \"OWNER\",\n purpose: input.purpose ?? DEFAULT_PURPOSES,\n accessGate: input.accessGate ?? \"open\",\n status: input.status ?? \"pending\",\n };\n },\n\n patchAccount: async (\n accountId: string,\n patch: ConnectorAccountPatch,\n manager: ConnectorAccountManager,\n ) => {\n const existing = await manager\n .getStorage()\n .getAccount(SLACK_SERVICE_NAME, accountId);\n if (existing) {\n return mergeStoredAccountPatch(existing, patch);\n }\n return { ...patch, provider: SLACK_SERVICE_NAME };\n },\n\n deleteAccount: async (): Promise<void> => {\n // Token revocation is the runtime/secrets store's responsibility; the\n // manager removes the account row after this resolves.\n },\n\n startOAuth: async (\n request: ConnectorOAuthStartRequest,\n ): Promise<ConnectorOAuthStartResult> => {\n const config = readClientConfig(runtime);\n const redirectUri = request.redirectUri ?? config.redirectUri;\n const requestedScopes =\n request.scopes && request.scopes.length > 0\n ? request.scopes\n : DEFAULT_BOT_SCOPES;\n\n const params = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: redirectUri,\n scope: requestedScopes.join(\",\"),\n state: request.flow.state,\n });\n\n return {\n authUrl: `${SLACK_OAUTH_AUTHORIZE_URL}?${params.toString()}`,\n metadata: {\n ...request.metadata,\n requestedScopes,\n redirectUri,\n },\n };\n },\n\n completeOAuth: async (\n request: ConnectorOAuthCallbackRequest,\n manager: ConnectorAccountManager,\n ): Promise<ConnectorOAuthCallbackResult> => {\n const code = nonEmptyString(request.code);\n if (!code) {\n throw new Error(\n \"Slack OAuth callback is missing an authorization code.\",\n );\n }\n\n const config = readClientConfig(runtime);\n const redirectUri =\n nonEmptyString(request.flow.redirectUri) ??\n nonEmptyString(\n (request.flow.metadata as Record<string, unknown> | undefined)\n ?.redirectUri,\n ) ??\n config.redirectUri;\n\n const tokenParams = new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n code,\n redirect_uri: redirectUri,\n });\n\n const response = await fetch(SLACK_OAUTH_TOKEN_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: tokenParams.toString(),\n });\n if (!response.ok) {\n const body = await response.text();\n throw new Error(\n `Slack token exchange failed with ${response.status}: ${body}`,\n );\n }\n const parsed = (await response.json()) as SlackOAuthV2Response;\n if (!parsed.ok || !parsed.access_token) {\n throw new Error(\n `Slack token exchange returned an error: ${parsed.error ?? \"unknown\"}`,\n );\n }\n\n const teamId = parsed.team?.id;\n if (!teamId) {\n throw new Error(\"Slack token exchange did not include a team id.\");\n }\n const teamName = parsed.team?.name;\n const grantedScopes = parsed.scope ? parsed.scope.split(\",\") : [];\n const expiresAt =\n typeof parsed.expires_in === \"number\"\n ? Date.now() + parsed.expires_in * 1000\n : undefined;\n const authedUserExpiresAt =\n typeof parsed.authed_user?.expires_in === \"number\"\n ? Date.now() + parsed.authed_user.expires_in * 1000\n : undefined;\n const oauthCredentialVersion = String(Date.now());\n const accountMetadata = {\n teamId,\n teamName: teamName ?? null,\n appId: parsed.app_id ?? null,\n botUserId: parsed.bot_user_id ?? null,\n enterpriseId: parsed.enterprise?.id ?? null,\n authedUserId: parsed.authed_user?.id ?? null,\n tokenType: parsed.token_type ?? \"bot\",\n grantedScopes,\n hasRefreshToken: Boolean(\n parsed.refresh_token ?? parsed.authed_user?.refresh_token,\n ),\n expiresAt,\n oauthCredentialVersion,\n };\n const pendingAccount = await manager.upsertAccount(\n SLACK_SERVICE_NAME,\n {\n provider: SLACK_SERVICE_NAME,\n role: \"OWNER\",\n purpose: DEFAULT_PURPOSES,\n accessGate: \"open\",\n status: \"pending\",\n externalId: teamId,\n displayHandle: teamName,\n label: teamName ?? `Slack workspace ${teamId}`,\n metadata: accountMetadata,\n },\n request.flow.accountId,\n );\n const credentialPersist = await persistConnectorCredentialRefs({\n runtime,\n manager,\n provider: SLACK_SERVICE_NAME,\n accountIdForRef: pendingAccount.id,\n storageAccountId: pendingAccount.id,\n caller: \"plugin-slack\",\n credentials: [\n {\n credentialType: \"oauth.tokens\",\n value: JSON.stringify({\n access_token: parsed.access_token,\n ...(parsed.refresh_token\n ? { refresh_token: parsed.refresh_token }\n : {}),\n token_type: parsed.token_type ?? \"bot\",\n scope: parsed.scope ?? grantedScopes.join(\",\"),\n ...(expiresAt !== undefined ? { expires_at: expiresAt } : {}),\n ...(parsed.authed_user?.access_token\n ? {\n authed_user: {\n id: parsed.authed_user.id,\n access_token: parsed.authed_user.access_token,\n ...(parsed.authed_user.refresh_token\n ? { refresh_token: parsed.authed_user.refresh_token }\n : {}),\n ...(parsed.authed_user.token_type\n ? { token_type: parsed.authed_user.token_type }\n : {}),\n ...(parsed.authed_user.scope\n ? { scope: parsed.authed_user.scope }\n : {}),\n ...(authedUserExpiresAt !== undefined\n ? { expires_at: authedUserExpiresAt }\n : {}),\n },\n }\n : {}),\n }),\n ...(expiresAt !== undefined ? { expiresAt } : {}),\n metadata: {\n provider: SLACK_SERVICE_NAME,\n hasRefreshToken: Boolean(\n parsed.refresh_token ?? parsed.authed_user?.refresh_token,\n ),\n hasAuthedUserToken: Boolean(parsed.authed_user?.access_token),\n },\n },\n ],\n });\n\n const accountPatch: ConnectorAccountPatch & {\n provider: string;\n id: string;\n } = {\n ...pendingAccount,\n id: pendingAccount.id,\n provider: SLACK_SERVICE_NAME,\n status: \"connected\",\n metadata: {\n ...accountMetadata,\n credentialRefs: credentialPersist.refs,\n credentialRefStorage: {\n vaultAvailable: credentialPersist.vaultAvailable,\n storageAvailable: credentialPersist.storageAvailable,\n },\n },\n };\n\n logger.info(\n {\n src: \"plugin:slack:connector\",\n teamId,\n teamName,\n },\n \"Slack OAuth completed\",\n );\n\n return {\n account: accountPatch,\n flow: { status: \"completed\" },\n };\n },\n };\n}\n",
|
|
22
7
|
"import type { IAgentRuntime } from \"@elizaos/core\";\n\n/**\n * Default account identifier used when no specific account is configured\n */\nexport const DEFAULT_ACCOUNT_ID = \"default\";\n\n/**\n * Source of the Slack token\n */\nexport type SlackTokenSource = \"env\" | \"config\" | \"character\" | \"none\";\n\n/**\n * DM-specific configuration\n */\nexport interface SlackDmConfig {\n /** If false, ignore all incoming Slack DMs */\n enabled?: boolean;\n /** Direct message access policy */\n policy?: \"open\" | \"disabled\" | \"allowlist\";\n /** Allowlist for DM senders (ids or names) */\n allowFrom?: Array<string | number>;\n /** Reply-to mode for DMs */\n replyToMode?: \"off\" | \"first\" | \"all\";\n}\n\n/**\n * Channel-specific configuration\n */\nexport interface SlackChannelConfig {\n /** If false, ignore this channel */\n enabled?: boolean;\n /** Require bot mention to respond */\n requireMention?: boolean;\n /** User allowlist for this channel */\n users?: Array<string | number>;\n /** Reply-to mode for this channel */\n replyToMode?: \"off\" | \"first\" | \"all\";\n}\n\n/**\n * Reaction notification mode\n */\nexport type SlackReactionNotificationMode = \"off\" | \"own\" | \"all\" | \"allowlist\";\n\n/**\n * Slash command configuration\n */\nexport interface SlackSlashCommandConfig {\n /** Enable slash commands */\n enabled?: boolean;\n /** Slash command name (without leading /) */\n command?: string;\n}\n\n/**\n * Action toggles for Slack features\n */\nexport interface SlackActionConfig {\n /** Enable reactions */\n reactions?: boolean;\n /** Enable pins */\n pins?: boolean;\n /** Enable file uploads */\n files?: boolean;\n /** Enable message editing */\n edit?: boolean;\n /** Enable message deletion */\n delete?: boolean;\n /** Enable emoji list */\n emojiList?: boolean;\n /** Enable member info */\n memberInfo?: boolean;\n}\n\n/**\n * Configuration for a single Slack account\n */\nexport interface SlackAccountConfig {\n /** Optional display name for this account */\n name?: string;\n /** If false, do not start this Slack account */\n enabled?: boolean;\n /** Slack bot token (xoxb-...) */\n botToken?: string;\n /** Slack app-level token (xapp-...) */\n appToken?: string;\n /** Slack signing secret */\n signingSecret?: string;\n /** Slack user token (xoxp-...) for user actions */\n userToken?: string;\n /** Controls how channel messages are handled */\n groupPolicy?: \"open\" | \"disabled\" | \"allowlist\";\n /** Outbound text chunk size (chars) */\n textChunkLimit?: number;\n /** Max media size in MB */\n mediaMaxMb?: number;\n /** Reaction notification mode */\n reactionNotifications?: SlackReactionNotificationMode;\n /** Reaction allowlist when mode is 'allowlist' */\n reactionAllowlist?: Array<string | number>;\n /** Reply-to mode */\n replyToMode?: \"off\" | \"first\" | \"all\";\n /** Reply-to mode by chat type */\n replyToModeByChatType?: Record<string, \"off\" | \"first\" | \"all\">;\n /** Per-action toggles */\n actions?: SlackActionConfig;\n /** Slash command configuration */\n slashCommand?: SlackSlashCommandConfig;\n /** DM configuration */\n dm?: SlackDmConfig;\n /** Per-channel configuration keyed by channel ID */\n channels?: Record<string, SlackChannelConfig>;\n /** Allowed channel IDs */\n allowedChannelIds?: string[];\n /** Whether to ignore bot messages */\n shouldIgnoreBotMessages?: boolean;\n /** Whether to respond only to mentions */\n shouldRespondOnlyToMentions?: boolean;\n}\n\n/**\n * Multi-account Slack configuration structure\n */\nexport interface SlackMultiAccountConfig {\n /** Default/base configuration applied to all accounts */\n enabled?: boolean;\n botToken?: string;\n appToken?: string;\n /** Per-account configuration overrides */\n accounts?: Record<string, SlackAccountConfig>;\n}\n\n/**\n * Resolved Slack account with all configuration merged\n */\nexport interface ResolvedSlackAccount {\n accountId: string;\n enabled: boolean;\n name?: string;\n botToken?: string;\n appToken?: string;\n signingSecret?: string;\n userToken?: string;\n botTokenSource: SlackTokenSource;\n appTokenSource: SlackTokenSource;\n config: SlackAccountConfig;\n}\n\n/**\n * Normalizes an account ID, returning the default if not provided\n */\nexport function normalizeAccountId(accountId?: string | null): string {\n if (!accountId || typeof accountId !== \"string\") {\n return DEFAULT_ACCOUNT_ID;\n }\n const trimmed = accountId.trim().toLowerCase();\n return trimmed || DEFAULT_ACCOUNT_ID;\n}\n\n/**\n * Validates and normalizes a Slack token with the expected prefix\n */\nfunction normalizeSlackToken(\n raw: string | null | undefined,\n prefix: string,\n): string | undefined {\n const trimmed = raw?.trim();\n return trimmed?.startsWith(prefix) ? trimmed : undefined;\n}\n\n/**\n * Validates and normalizes a Slack bot token (xoxb-)\n */\nexport function resolveSlackBotToken(raw?: string | null): string | undefined {\n return normalizeSlackToken(raw, \"xoxb-\");\n}\n\n/**\n * Validates and normalizes a Slack app token (xapp-)\n */\nexport function resolveSlackAppToken(raw?: string | null): string | undefined {\n return normalizeSlackToken(raw, \"xapp-\");\n}\n\n/**\n * Validates and normalizes a Slack user token (xoxp-)\n */\nexport function resolveSlackUserToken(raw?: string | null): string | undefined {\n return normalizeSlackToken(raw, \"xoxp-\");\n}\n\n/**\n * Gets the multi-account configuration from runtime settings\n */\nexport function getMultiAccountConfig(\n runtime: IAgentRuntime,\n): SlackMultiAccountConfig {\n const characterSlack = runtime.character?.settings?.slack as\n | SlackMultiAccountConfig\n | undefined;\n\n return {\n enabled: characterSlack?.enabled,\n botToken: characterSlack?.botToken,\n appToken: characterSlack?.appToken,\n accounts: characterSlack?.accounts,\n };\n}\n\n/**\n * Lists all configured account IDs\n */\nexport function listSlackAccountIds(runtime: IAgentRuntime): string[] {\n const config = getMultiAccountConfig(runtime);\n const accounts = config.accounts;\n\n if (!accounts || typeof accounts !== \"object\") {\n return [DEFAULT_ACCOUNT_ID];\n }\n\n const ids = Object.keys(accounts).filter(Boolean);\n if (ids.length === 0) {\n return [DEFAULT_ACCOUNT_ID];\n }\n\n return ids.slice().sort((a, b) => a.localeCompare(b));\n}\n\n/**\n * Resolves the default account ID to use\n */\nexport function resolveDefaultSlackAccountId(runtime: IAgentRuntime): string {\n const ids = listSlackAccountIds(runtime);\n if (ids.includes(DEFAULT_ACCOUNT_ID)) {\n return DEFAULT_ACCOUNT_ID;\n }\n return ids[0] ?? DEFAULT_ACCOUNT_ID;\n}\n\n/**\n * Gets the account-specific configuration\n */\nfunction getAccountConfig(\n runtime: IAgentRuntime,\n accountId: string,\n): SlackAccountConfig | undefined {\n const config = getMultiAccountConfig(runtime);\n const accounts = config.accounts;\n\n if (!accounts || typeof accounts !== \"object\") {\n return undefined;\n }\n\n return accounts[accountId];\n}\n\n/**\n * Merges base configuration with account-specific overrides\n */\n/**\n * Removes undefined values from an object to prevent them from overwriting during spread\n */\nfunction filterDefined<T extends object>(obj: T): Partial<T> {\n return Object.fromEntries(\n Object.entries(obj).filter(([, v]) => v !== undefined),\n ) as Partial<T>;\n}\n\nfunction mergeSlackAccountConfig(\n runtime: IAgentRuntime,\n accountId: string,\n): SlackAccountConfig {\n const multiConfig = getMultiAccountConfig(runtime);\n const { accounts: _ignored, ...baseConfig } = multiConfig;\n const accountConfig = getAccountConfig(runtime, accountId) ?? {};\n\n // Get environment/runtime settings for the base config\n const envChannelIds = runtime.getSetting(\"SLACK_CHANNEL_IDS\") as\n | string\n | undefined;\n\n const envConfig: SlackAccountConfig = {\n shouldIgnoreBotMessages:\n (\n runtime.getSetting(\"SLACK_SHOULD_IGNORE_BOT_MESSAGES\") as string\n )?.toLowerCase() === \"true\",\n shouldRespondOnlyToMentions:\n (\n runtime.getSetting(\"SLACK_SHOULD_RESPOND_ONLY_TO_MENTIONS\") as string\n )?.toLowerCase() === \"true\",\n allowedChannelIds: envChannelIds\n ? envChannelIds\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean)\n : undefined,\n };\n\n // Merge order: env defaults < base config < account config\n // Filter undefined values to prevent them from overwriting defined values\n return {\n ...filterDefined(envConfig),\n ...filterDefined(baseConfig),\n ...filterDefined(accountConfig),\n };\n}\n\n/**\n * Resolves a complete Slack account configuration\n */\nexport function resolveSlackAccount(\n runtime: IAgentRuntime,\n accountId?: string | null,\n): ResolvedSlackAccount {\n const normalizedAccountId = normalizeAccountId(accountId);\n const multiConfig = getMultiAccountConfig(runtime);\n\n const baseEnabled = multiConfig.enabled !== false;\n const merged = mergeSlackAccountConfig(runtime, normalizedAccountId);\n const accountEnabled = merged.enabled !== false;\n const enabled = baseEnabled && accountEnabled;\n\n const allowEnv = normalizedAccountId === DEFAULT_ACCOUNT_ID;\n\n // Resolve bot token\n const envBotToken = allowEnv\n ? resolveSlackBotToken(runtime.getSetting(\"SLACK_BOT_TOKEN\") as string)\n : undefined;\n const configBotToken = resolveSlackBotToken(merged.botToken);\n const botToken = configBotToken ?? envBotToken;\n const botTokenSource: SlackTokenSource = configBotToken\n ? \"config\"\n : envBotToken\n ? \"env\"\n : \"none\";\n\n // Resolve app token\n const envAppToken = allowEnv\n ? resolveSlackAppToken(runtime.getSetting(\"SLACK_APP_TOKEN\") as string)\n : undefined;\n const configAppToken = resolveSlackAppToken(merged.appToken);\n const appToken = configAppToken ?? envAppToken;\n const appTokenSource: SlackTokenSource = configAppToken\n ? \"config\"\n : envAppToken\n ? \"env\"\n : \"none\";\n\n // Resolve signing secret\n const signingSecret =\n merged.signingSecret ??\n (runtime.getSetting(\"SLACK_SIGNING_SECRET\") as string);\n\n // Resolve user token\n const envUserToken = allowEnv\n ? resolveSlackUserToken(runtime.getSetting(\"SLACK_USER_TOKEN\") as string)\n : undefined;\n const configUserToken = resolveSlackUserToken(merged.userToken);\n const userToken = configUserToken ?? envUserToken;\n\n return {\n accountId: normalizedAccountId,\n enabled,\n name: merged.name?.trim() || undefined,\n botToken,\n appToken,\n signingSecret,\n userToken,\n botTokenSource,\n appTokenSource,\n config: merged,\n };\n}\n\n/**\n * Lists all enabled Slack accounts\n */\nexport function listEnabledSlackAccounts(\n runtime: IAgentRuntime,\n): ResolvedSlackAccount[] {\n return listSlackAccountIds(runtime)\n .map((accountId) => resolveSlackAccount(runtime, accountId))\n .filter((account) => account.enabled && account.botToken);\n}\n\n/**\n * Checks if multi-account mode is enabled\n */\nexport function isMultiAccountEnabled(runtime: IAgentRuntime): boolean {\n const accounts = listEnabledSlackAccounts(runtime);\n return accounts.length > 1;\n}\n\n/**\n * Resolves the reply-to mode for a specific chat type\n */\nexport function resolveSlackReplyToMode(\n account: ResolvedSlackAccount,\n chatType?: string | null,\n): \"off\" | \"first\" | \"all\" {\n const normalized = chatType?.toLowerCase().trim();\n\n // Check chat type specific override\n if (\n normalized &&\n account.config.replyToModeByChatType?.[normalized] !== undefined\n ) {\n return account.config.replyToModeByChatType[normalized] ?? \"off\";\n }\n\n // Check DM-specific setting\n if (normalized === \"direct\" || normalized === \"im\") {\n if (account.config.dm?.replyToMode !== undefined) {\n return account.config.dm.replyToMode;\n }\n }\n\n // Fall back to global setting\n return account.config.replyToMode ?? \"off\";\n}\n",
|
|
23
|
-
"import type { SlackChannel, SlackUser } from \"./types\";\n\n/**\n * Escape special characters for Slack mrkdwn format\n * Preserves Slack's angle-bracket tokens so mentions and links stay intact\n */\nfunction escapeSlackMrkdwnSegment(text: string): string {\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n}\n\nconst SLACK_ANGLE_TOKEN_RE = /<[^>\\n]+>/g;\n\n/**\n * Checks if an angle-bracket token is an allowed Slack format\n */\nfunction isAllowedSlackAngleToken(token: string): boolean {\n if (!token.startsWith(\"<\") || !token.endsWith(\">\")) {\n return false;\n }\n const inner = token.slice(1, -1);\n return (\n inner.startsWith(\"@\") ||\n inner.startsWith(\"#\") ||\n inner.startsWith(\"!\") ||\n inner.startsWith(\"mailto:\") ||\n inner.startsWith(\"tel:\") ||\n inner.startsWith(\"http://\") ||\n inner.startsWith(\"https://\") ||\n inner.startsWith(\"slack://\")\n );\n}\n\n/**\n * Escapes Slack mrkdwn content while preserving valid Slack tokens\n */\nfunction escapeSlackMrkdwnContent(text: string): string {\n if (!text.includes(\"&\") && !text.includes(\"<\") && !text.includes(\">\")) {\n return text;\n }\n\n SLACK_ANGLE_TOKEN_RE.lastIndex = 0;\n const out: string[] = [];\n let lastIndex = 0;\n\n for (\n let match = SLACK_ANGLE_TOKEN_RE.exec(text);\n match;\n match = SLACK_ANGLE_TOKEN_RE.exec(text)\n ) {\n const matchIndex = match.index ?? 0;\n out.push(escapeSlackMrkdwnSegment(text.slice(lastIndex, matchIndex)));\n const token = match[0] ?? \"\";\n out.push(\n isAllowedSlackAngleToken(token) ? token : escapeSlackMrkdwnSegment(token),\n );\n lastIndex = matchIndex + token.length;\n }\n\n out.push(escapeSlackMrkdwnSegment(text.slice(lastIndex)));\n return out.join(\"\");\n}\n\n/**\n * Escapes Slack mrkdwn text, handling blockquotes specially\n */\nexport function escapeSlackMrkdwn(text: string): string {\n if (!text.includes(\"&\") && !text.includes(\"<\") && !text.includes(\">\")) {\n return text;\n }\n\n return text\n .split(\"\\n\")\n .map((line) => {\n if (line.startsWith(\"> \")) {\n return `> ${escapeSlackMrkdwnContent(line.slice(2))}`;\n }\n return escapeSlackMrkdwnContent(line);\n })\n .join(\"\\n\");\n}\n\n// Placeholder used during conversion to prevent bold from being matched as italic\nconst BOLD_PLACEHOLDER = \"\\u0000BOLD\\u0000\";\n\n/**\n * Converts markdown bold to Slack mrkdwn\n * Uses placeholder to prevent bold from being matched by italic converter\n */\nfunction convertBold(text: string): string {\n return text.replace(\n /\\*\\*(.+?)\\*\\*/g,\n `${BOLD_PLACEHOLDER}$1${BOLD_PLACEHOLDER}`,\n );\n}\n\n/**\n * Converts markdown italic to Slack mrkdwn\n */\nfunction convertItalic(text: string): string {\n // Markdown uses single * for italic, Slack uses _\n // Then restore bold placeholders to actual asterisks\n const converted = text.replace(\n /(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g,\n \"_$1_\",\n );\n return converted.replace(new RegExp(BOLD_PLACEHOLDER, \"g\"), \"*\");\n}\n\n/**\n * Converts markdown strikethrough to Slack mrkdwn\n */\nfunction convertStrikethrough(text: string): string {\n return text.replace(/~~(.+?)~~/g, \"~$1~\");\n}\n\n/**\n * Converts markdown code blocks to Slack mrkdwn\n */\nfunction convertCodeBlocks(text: string): string {\n // Slack code blocks don't support language hints in the same way\n return text.replace(/```(\\w*)\\n?([\\s\\S]*?)```/g, \"```\\n$2```\");\n}\n\n/**\n * Converts markdown links to Slack mrkdwn links\n */\nfunction convertLinks(text: string): string {\n return text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (_, linkText, url) => {\n const trimmedUrl = url.trim();\n const trimmedText = linkText.trim();\n // If link text matches URL, just use URL\n if (\n trimmedText === trimmedUrl ||\n trimmedText === trimmedUrl.replace(/^mailto:/, \"\")\n ) {\n return `<${escapeSlackMrkdwnSegment(trimmedUrl)}>`;\n }\n return `<${escapeSlackMrkdwnSegment(trimmedUrl)}|${escapeSlackMrkdwnSegment(trimmedText)}>`;\n });\n}\n\n/**\n * Converts markdown headings to Slack mrkdwn (bold text)\n * Uses placeholder to prevent headings from being matched by italic converter\n */\nfunction convertHeadings(text: string): string {\n return text.replace(\n /^#{1,6}\\s+(.+)$/gm,\n `${BOLD_PLACEHOLDER}$1${BOLD_PLACEHOLDER}`,\n );\n}\n\n/**\n * Converts markdown to Slack mrkdwn format\n */\nexport function markdownToSlackMrkdwn(markdown: string): string {\n if (!markdown) {\n return \"\";\n }\n\n // Process in order: code blocks -> links -> headings -> text styles -> escape\n let result = convertCodeBlocks(markdown);\n result = convertLinks(result);\n result = convertHeadings(result);\n result = convertBold(result);\n result = convertItalic(result);\n result = convertStrikethrough(result);\n result = escapeSlackMrkdwn(result);\n\n return result;\n}\n\n/**\n * Options for chunking Slack text\n */\nexport interface ChunkSlackTextOpts {\n /** Max characters per message. Default: 4000 */\n maxChars?: number;\n}\n\nconst DEFAULT_MAX_CHARS = 4000;\n\n/**\n * Chunks Slack text while preserving code blocks\n */\nexport function chunkSlackText(\n text: string,\n maxChars: number = DEFAULT_MAX_CHARS,\n): string[] {\n if (!text) {\n return [];\n }\n\n if (text.length <= maxChars) {\n return [text];\n }\n\n const chunks: string[] = [];\n let remaining = text;\n let inCodeBlock = false;\n\n while (remaining.length > 0) {\n if (remaining.length <= maxChars) {\n chunks.push(remaining);\n break;\n }\n\n // Find a good break point\n let breakPoint = maxChars;\n\n // Check if we're in a code block\n const codeBlockCount = (remaining.slice(0, maxChars).match(/```/g) || [])\n .length;\n inCodeBlock = codeBlockCount % 2 !== 0;\n\n // Try to break at a newline\n const newlineIndex = remaining.lastIndexOf(\"\\n\", maxChars);\n if (newlineIndex > maxChars * 0.5) {\n breakPoint = newlineIndex + 1;\n } else {\n // Try to break at a space\n const spaceIndex = remaining.lastIndexOf(\" \", maxChars);\n if (spaceIndex > maxChars * 0.5) {\n breakPoint = spaceIndex + 1;\n }\n }\n\n let chunk = remaining.slice(0, breakPoint);\n\n // If we're breaking inside a code block, close it\n if (inCodeBlock) {\n chunk += \"\\n```\";\n }\n\n chunks.push(chunk);\n\n remaining = remaining.slice(breakPoint);\n\n // If we were in a code block, reopen it\n if (inCodeBlock) {\n remaining = `\\`\\`\\`\\n${remaining}`;\n }\n }\n\n return chunks;\n}\n\n/**\n * Converts markdown to Slack mrkdwn and splits into chunks\n */\nexport function markdownToSlackMrkdwnChunks(\n markdown: string,\n limit: number,\n): string[] {\n return chunkSlackText(markdownToSlackMrkdwn(markdown), limit);\n}\n\n/**\n * Formats a Slack user mention\n */\nexport function formatSlackUserMention(userId: string): string {\n return `<@${userId}>`;\n}\n\n/**\n * Formats a Slack channel mention\n */\nexport function formatSlackChannelMention(channelId: string): string {\n return `<#${channelId}>`;\n}\n\n/**\n * Formats a Slack user group mention\n */\nexport function formatSlackUserGroupMention(groupId: string): string {\n return `<!subteam^${groupId}>`;\n}\n\n/**\n * Formats a Slack special mention (@here, @channel, @everyone)\n */\nexport function formatSlackSpecialMention(\n type: \"here\" | \"channel\" | \"everyone\",\n): string {\n return `<!${type}>`;\n}\n\n/**\n * Formats a Slack link\n */\nexport function formatSlackLink(url: string, text?: string): string {\n const safeUrl = escapeSlackMrkdwnSegment(url);\n if (text && text !== url) {\n return `<${safeUrl}|${escapeSlackMrkdwnSegment(text)}>`;\n }\n return `<${safeUrl}>`;\n}\n\n/**\n * Formats a Slack date\n */\nexport function formatSlackDate(\n timestamp: number | Date,\n format: string = \"{date_short_pretty} at {time}\",\n fallbackText?: string,\n): string {\n const unix = Math.floor(\n (typeof timestamp === \"number\" ? timestamp : timestamp.getTime()) / 1000,\n );\n const fallback = fallbackText || new Date(unix * 1000).toISOString();\n return `<!date^${unix}^${format}|${fallback}>`;\n}\n\n/**\n * Extracts user ID from a Slack mention\n */\nexport function extractUserIdFromMention(mention: string): string | null {\n const match = mention.match(/^<@([UW][A-Z0-9]+)(?:\\|[^>]*)?>$/i);\n return match ? match[1] : null;\n}\n\n/**\n * Extracts channel ID from a Slack mention\n */\nexport function extractChannelIdFromMention(mention: string): string | null {\n const match = mention.match(/^<#([CGD][A-Z0-9]+)(?:\\|[^>]*)?>$/i);\n return match ? match[1] : null;\n}\n\n/**\n * Extracts URL from a Slack link\n */\nexport function extractUrlFromSlackLink(link: string): string | null {\n const match = link.match(/^<(https?:\\/\\/[^|>]+)(?:\\|[^>]*)?>$/);\n return match ? match[1] : null;\n}\n\n/**\n * Formats a user's display name\n */\nexport function formatSlackUserDisplayName(user: SlackUser): string {\n return user.profile.displayName || user.profile.realName || user.name;\n}\n\n/**\n * Formats a channel for display\n */\nexport function formatSlackChannel(channel: SlackChannel): string {\n if (channel.isIm) {\n return \"Direct Message\";\n }\n if (channel.isMpim) {\n return `Group DM: ${channel.name}`;\n }\n return `#${channel.name}`;\n}\n\n/**\n * Gets the channel type as a human-readable string\n */\nexport function getChannelTypeString(channel: SlackChannel): string {\n if (channel.isIm) {\n return \"DM\";\n }\n if (channel.isMpim) {\n return \"Group DM\";\n }\n if (channel.isPrivate || channel.isGroup) {\n return \"Private Channel\";\n }\n return \"Channel\";\n}\n\n/**\n * Resolves the system location string for logging/display\n */\nexport function resolveSlackSystemLocation(\n channel: SlackChannel,\n teamName?: string,\n): string {\n const channelType = getChannelTypeString(channel);\n const channelName = formatSlackChannel(channel);\n if (teamName) {\n return `${teamName} - ${channelType}: ${channelName}`;\n }\n return `${channelType}: ${channelName}`;\n}\n\n/**\n * Checks if a channel is a direct message\n */\nexport function isDirectMessage(channel: SlackChannel): boolean {\n return channel.isIm;\n}\n\n/**\n * Checks if a channel is a group DM (multi-party IM)\n */\nexport function isGroupDm(channel: SlackChannel): boolean {\n return channel.isMpim;\n}\n\n/**\n * Checks if a channel is a private channel\n */\nexport function isPrivateChannel(channel: SlackChannel): boolean {\n return channel.isPrivate || channel.isGroup;\n}\n\n/**\n * Truncates text to a maximum length with an ellipsis\n */\nexport function truncateText(\n text: string,\n maxLength: number,\n ellipsis = \"…\",\n): string {\n if (text.length <= maxLength) {\n return text;\n }\n return text.slice(0, maxLength - ellipsis.length) + ellipsis;\n}\n\n/**\n * Strips Slack mrkdwn formatting from text\n */\nexport function stripSlackFormatting(text: string): string {\n return text\n .replace(/```[\\s\\S]*?```/g, \"\") // Code blocks (must be before inline code)\n .replace(/\\*([^*]+)\\*/g, \"$1\") // Bold\n .replace(/_([^_]+)_/g, \"$1\") // Italic\n .replace(/~([^~]+)~/g, \"$1\") // Strikethrough\n .replace(/`([^`]+)`/g, \"$1\") // Inline code\n .replace(/<@[UW][A-Z0-9]+(?:\\|[^>]*)?>/gi, \"\") // User mentions\n .replace(/<#[CGD][A-Z0-9]+(?:\\|[^>]*)?>/gi, \"\") // Channel mentions\n .replace(/<!subteam\\^[A-Z0-9]+(?:\\|[^>]*)?>/gi, \"\") // User group mentions\n .replace(/<!(?:here|channel|everyone)(?:\\|[^>]*)?>/gi, \"\") // Special mentions\n .replace(/<(https?:\\/\\/[^|>]+)(?:\\|([^>]*))?>/, \"$2\") // Links with text\n .replace(/<(https?:\\/\\/[^>]+)>/, \"$1\") // Plain links\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .trim();\n}\n\n/**\n * Builds a Slack message permalink\n */\nexport function buildSlackMessagePermalink(\n workspaceDomain: string,\n channelId: string,\n messageTs: string,\n): string {\n const formattedTs = `p${messageTs.replace(\".\", \"\")}`;\n return `https://${workspaceDomain}.slack.com/archives/${channelId}/${formattedTs}`;\n}\n\n/**\n * Parses a Slack message permalink\n */\nexport function parseSlackMessagePermalink(\n link: string,\n): { workspaceDomain: string; channelId: string; messageTs: string } | null {\n const match = link.match(\n /^https?:\\/\\/([^.]+)\\.slack\\.com\\/archives\\/([CGD][A-Z0-9]+)\\/p(\\d+)/i,\n );\n if (!match) {\n return null;\n }\n\n const ts = match[3];\n // Convert p1234567890123456 to 1234567890.123456\n const messageTs = `${ts.slice(0, 10)}.${ts.slice(10)}`;\n\n return {\n workspaceDomain: match[1],\n channelId: match[2],\n messageTs,\n };\n}\n"
|
|
8
|
+
"import {\n CONNECTOR_ACCOUNT_STORAGE_SERVICE_TYPE,\n type ConnectorAccountManager,\n type IAgentRuntime,\n} from \"@elizaos/core\";\n\ntype JsonValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | JsonValue[]\n | { readonly [key: string]: JsonValue };\ntype JsonRecord = Record<string, JsonValue>;\n\nexport interface ConnectorCredentialRefMetadata extends JsonRecord {\n credentialType: string;\n vaultRef: string;\n expiresAt?: number;\n metadata?: JsonRecord;\n}\n\ninterface ConnectorCredentialInput {\n credentialType: string;\n value: string;\n expiresAt?: number;\n metadata?: JsonRecord;\n}\n\ninterface PersistConnectorCredentialRefsParams {\n runtime: IAgentRuntime;\n manager?: ConnectorAccountManager;\n provider: string;\n accountIdForRef: string;\n storageAccountId?: string;\n credentials: ConnectorCredentialInput[];\n caller: string;\n}\n\ntype VaultWriter = {\n name: string;\n write: (\n vaultRef: string,\n credential: ConnectorCredentialInput,\n ) => Promise<string>;\n};\n\ntype CredentialRefWriter = {\n name: string;\n write: (ref: ConnectorCredentialRefMetadata) => Promise<void>;\n};\n\nexport async function persistConnectorCredentialRefs(\n params: PersistConnectorCredentialRefsParams,\n): Promise<{\n refs: ConnectorCredentialRefMetadata[];\n vaultAvailable: boolean;\n storageAvailable: boolean;\n}> {\n const refs: ConnectorCredentialRefMetadata[] = [];\n const vaultWriters = resolveVaultWriters(params.runtime, {\n provider: params.provider,\n accountId: params.accountIdForRef,\n caller: params.caller,\n });\n if (vaultWriters.length === 0) {\n throw new Error(\n `No durable connector credential store or vault writer is available for ${params.provider} account ${params.accountIdForRef}. Refusing to mark OAuth account connected without persisted credentials.`,\n );\n }\n if (!params.storageAccountId) {\n throw new Error(\n `No durable connector account id is available for ${params.provider} account ${params.accountIdForRef}. Refusing to mark OAuth account connected without persisted credential refs.`,\n );\n }\n const storageWriters = resolveCredentialRefWriters(\n params.runtime,\n params.manager,\n params.storageAccountId,\n );\n if (storageWriters.length === 0) {\n throw new Error(\n `No durable connector credential ref writer is available for ${params.provider} account ${params.storageAccountId}. Refusing to mark OAuth account connected without persisted credential refs.`,\n );\n }\n\n for (const credential of params.credentials) {\n const plannedRef = buildConnectorCredentialVaultRef({\n agentId: nonEmptyString(params.runtime.agentId) ?? \"agent\",\n provider: params.provider,\n accountId: params.accountIdForRef,\n credentialType: credential.credentialType,\n });\n const vaultRef = await writeWithFirstAvailableVault(\n vaultWriters,\n plannedRef,\n credential,\n );\n refs.push({\n credentialType: credential.credentialType,\n vaultRef,\n ...(credential.expiresAt !== undefined\n ? { expiresAt: credential.expiresAt }\n : {}),\n ...(credential.metadata ? { metadata: credential.metadata } : {}),\n });\n }\n\n if (refs.length > 0) {\n await writeRefsToStorage(storageWriters, refs);\n }\n\n return {\n refs,\n vaultAvailable: vaultWriters.length > 0,\n storageAvailable: storageWriters.length > 0,\n };\n}\n\nfunction resolveVaultWriters(\n runtime: IAgentRuntime,\n context: { provider: string; accountId: string; caller: string },\n): VaultWriter[] {\n const writers: VaultWriter[] = [];\n const credentialStore = getFirstService(runtime, [\n \"connector_credential_store\",\n \"CONNECTOR_CREDENTIAL_STORE\",\n \"connectorCredentialStore\",\n \"credential_store\",\n ]) as {\n putSecret?: (params: {\n vaultRef?: string;\n agentId: string;\n provider: string;\n accountId: string;\n credentialType: string;\n value: string;\n caller?: string;\n }) => Promise<string> | string;\n } | null;\n if (typeof credentialStore?.putSecret === \"function\") {\n writers.push({\n name: \"connector_credential_store\",\n write: async (vaultRef, credential) =>\n credentialStore.putSecret?.({\n vaultRef,\n agentId: nonEmptyString(runtime.agentId) ?? \"agent\",\n provider: context.provider,\n accountId: context.accountId,\n credentialType: credential.credentialType,\n value: credential.value,\n caller: context.caller,\n }) ?? vaultRef,\n });\n }\n\n const vault = getFirstService(runtime, [\"vault\", \"VAULT\"]) as {\n set?: (\n key: string,\n value: string,\n options?: { sensitive?: boolean; caller?: string },\n ) => Promise<void> | void;\n } | null;\n if (typeof vault?.set === \"function\") {\n writers.push({\n name: \"vault\",\n write: async (vaultRef, credential) => {\n await vault.set?.(vaultRef, credential.value, {\n sensitive: true,\n caller: context.caller,\n });\n return vaultRef;\n },\n });\n }\n\n const secrets = getService(runtime, \"SECRETS\") as {\n setGlobal?: (\n key: string,\n value: string,\n config?: { sensitive?: boolean },\n ) => Promise<boolean> | boolean;\n set?: (\n key: string,\n value: string,\n context: JsonRecord,\n config?: { sensitive?: boolean },\n ) => Promise<boolean> | boolean;\n } | null;\n if (\n typeof secrets?.setGlobal === \"function\" ||\n typeof secrets?.set === \"function\"\n ) {\n writers.push({\n name: \"SECRETS\",\n write: async (vaultRef, credential) => {\n if (typeof secrets.setGlobal === \"function\") {\n await secrets.setGlobal(vaultRef, credential.value, {\n sensitive: true,\n });\n return vaultRef;\n }\n await secrets.set?.(\n vaultRef,\n credential.value,\n { level: \"global\", agentId: runtime.agentId },\n { sensitive: true },\n );\n return vaultRef;\n },\n });\n }\n\n return writers;\n}\n\nfunction resolveCredentialRefWriters(\n runtime: IAgentRuntime,\n manager: ConnectorAccountManager | undefined,\n accountId: string,\n): CredentialRefWriter[] {\n const candidates = [\n manager?.getStorage?.(),\n getService(runtime, CONNECTOR_ACCOUNT_STORAGE_SERVICE_TYPE),\n (runtime as IAgentRuntime & { adapter?: unknown }).adapter,\n ].filter(Boolean);\n\n const writers: CredentialRefWriter[] = [];\n for (const candidate of candidates) {\n const writer = candidate as {\n setConnectorAccountCredentialRef?: (params: {\n accountId: string;\n credentialType: string;\n vaultRef: string;\n metadata?: JsonRecord;\n expiresAt?: number;\n }) => Promise<unknown> | unknown;\n setCredentialRef?: (params: {\n accountId: string;\n credentialType: string;\n vaultRef: string;\n metadata?: JsonRecord;\n expiresAt?: number;\n }) => Promise<unknown> | unknown;\n };\n if (typeof writer.setConnectorAccountCredentialRef === \"function\") {\n writers.push({\n name: \"setConnectorAccountCredentialRef\",\n write: async (ref) => {\n await writer.setConnectorAccountCredentialRef?.({\n accountId,\n credentialType: ref.credentialType,\n vaultRef: ref.vaultRef,\n ...(ref.metadata ? { metadata: ref.metadata } : {}),\n ...(ref.expiresAt !== undefined\n ? { expiresAt: ref.expiresAt }\n : {}),\n });\n },\n });\n } else if (typeof writer.setCredentialRef === \"function\") {\n writers.push({\n name: \"setCredentialRef\",\n write: async (ref) => {\n await writer.setCredentialRef?.({\n accountId,\n credentialType: ref.credentialType,\n vaultRef: ref.vaultRef,\n ...(ref.metadata ? { metadata: ref.metadata } : {}),\n ...(ref.expiresAt !== undefined\n ? { expiresAt: ref.expiresAt }\n : {}),\n });\n },\n });\n }\n }\n return writers;\n}\n\nasync function writeWithFirstAvailableVault(\n writers: VaultWriter[],\n plannedRef: string,\n credential: ConnectorCredentialInput,\n): Promise<string> {\n const errors: string[] = [];\n for (const writer of writers) {\n try {\n return await writer.write(plannedRef, credential);\n } catch (error) {\n errors.push(\n `${writer.name}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n throw new Error(\n `Failed to persist connector credential ref ${plannedRef}: ${errors.join(\"; \")}`,\n );\n}\n\nasync function writeRefsToStorage(\n writers: CredentialRefWriter[],\n refs: ConnectorCredentialRefMetadata[],\n): Promise<void> {\n const errors: string[] = [];\n for (const writer of writers) {\n try {\n for (const ref of refs) {\n await writer.write(ref);\n }\n return;\n } catch (error) {\n errors.push(\n `${writer.name}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n throw new Error(\n `Failed to persist connector credential refs: ${errors.join(\"; \")}`,\n );\n}\n\nfunction buildConnectorCredentialVaultRef(params: {\n agentId: string;\n provider: string;\n accountId: string;\n credentialType: string;\n}): string {\n return [\n \"connector\",\n normalizeVaultSegment(params.agentId),\n normalizeVaultSegment(params.provider),\n normalizeVaultSegment(params.accountId),\n normalizeVaultSegment(params.credentialType),\n ].join(\".\");\n}\n\nfunction normalizeVaultSegment(value: string): string {\n const normalized = value\n .trim()\n .replace(/[^a-zA-Z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n return (normalized || \"unknown\").slice(0, 64);\n}\n\nfunction getFirstService(\n runtime: IAgentRuntime,\n serviceTypes: readonly string[],\n): unknown {\n for (const serviceType of serviceTypes) {\n const service = getService(runtime, serviceType);\n if (service) return service;\n }\n return null;\n}\n\nfunction getService(runtime: IAgentRuntime, serviceType: string): unknown {\n try {\n return runtime.getService?.(serviceType) ?? null;\n } catch {\n return null;\n }\n}\n\nfunction nonEmptyString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n",
|
|
9
|
+
"import type {\n Character,\n EntityPayload,\n EventPayload,\n MessagePayload,\n WorldPayload,\n} from \"@elizaos/core\";\nimport type { App as BoltApp } from \"@slack/bolt\";\n\ntype WebClient = BoltApp[\"client\"];\n\n/**\n * Slack-specific event types\n */\nexport enum SlackEventTypes {\n MESSAGE_RECEIVED = \"SLACK_MESSAGE_RECEIVED\",\n MESSAGE_SENT = \"SLACK_MESSAGE_SENT\",\n REACTION_ADDED = \"SLACK_REACTION_ADDED\",\n REACTION_REMOVED = \"SLACK_REACTION_REMOVED\",\n CHANNEL_JOINED = \"SLACK_CHANNEL_JOINED\",\n CHANNEL_LEFT = \"SLACK_CHANNEL_LEFT\",\n MEMBER_JOINED_CHANNEL = \"SLACK_MEMBER_JOINED_CHANNEL\",\n MEMBER_LEFT_CHANNEL = \"SLACK_MEMBER_LEFT_CHANNEL\",\n APP_MENTION = \"SLACK_APP_MENTION\",\n SLASH_COMMAND = \"SLACK_SLASH_COMMAND\",\n FILE_SHARED = \"SLACK_FILE_SHARED\",\n THREAD_REPLY = \"SLACK_THREAD_REPLY\",\n}\n\nexport interface SlackMessageReceivedPayload extends MessagePayload {\n channelId: string;\n threadTs: string | undefined;\n userId: string;\n teamId: string | undefined;\n isThreadReply: boolean;\n files: SlackFile[];\n}\n\nexport interface SlackMessageSentPayload extends MessagePayload {\n channelId: string;\n threadTs: string | undefined;\n messageTs: string;\n}\n\nexport interface SlackReactionPayload extends EventPayload {\n reaction: string;\n userId: string;\n channelId: string;\n messageTs: string;\n itemUser: string | undefined;\n}\n\nexport interface SlackChannelPayload extends WorldPayload {\n channelId: string;\n channelName: string;\n channelType: SlackChannelType;\n}\n\nexport interface SlackMemberPayload extends EntityPayload {\n userId: string;\n channelId: string;\n}\n\nexport interface SlackAppMentionPayload extends MessagePayload {\n channelId: string;\n userId: string;\n threadTs: string | undefined;\n}\n\nexport interface SlackSlashCommandPayload extends EventPayload {\n command: string;\n text: string;\n userId: string;\n channelId: string;\n teamId: string;\n responseUrl: string;\n triggerId: string;\n}\n\nexport interface SlackFile {\n id: string;\n name: string;\n title: string;\n mimetype: string;\n filetype: string;\n size: number;\n urlPrivate: string;\n urlPrivateDownload: string | undefined;\n permalink: string;\n thumb64: string | undefined;\n thumb80: string | undefined;\n thumb360: string | undefined;\n}\n\nexport type SlackChannelType = \"channel\" | \"group\" | \"im\" | \"mpim\";\n\nexport interface SlackEventPayloadMap {\n [SlackEventTypes.MESSAGE_RECEIVED]: SlackMessageReceivedPayload;\n [SlackEventTypes.MESSAGE_SENT]: SlackMessageSentPayload;\n [SlackEventTypes.REACTION_ADDED]: SlackReactionPayload;\n [SlackEventTypes.REACTION_REMOVED]: SlackReactionPayload;\n [SlackEventTypes.CHANNEL_JOINED]: SlackChannelPayload;\n [SlackEventTypes.CHANNEL_LEFT]: SlackChannelPayload;\n [SlackEventTypes.MEMBER_JOINED_CHANNEL]: SlackMemberPayload;\n [SlackEventTypes.MEMBER_LEFT_CHANNEL]: SlackMemberPayload;\n [SlackEventTypes.APP_MENTION]: SlackAppMentionPayload;\n [SlackEventTypes.SLASH_COMMAND]: SlackSlashCommandPayload;\n [SlackEventTypes.FILE_SHARED]: SlackMessageReceivedPayload;\n [SlackEventTypes.THREAD_REPLY]: SlackMessageReceivedPayload;\n}\n\nexport interface SlackUser {\n id: string;\n teamId: string | undefined;\n name: string;\n deleted: boolean;\n realName: string | undefined;\n tz: string | undefined;\n tzLabel: string | undefined;\n tzOffset: number | undefined;\n profile: SlackUserProfile;\n isAdmin: boolean;\n isOwner: boolean;\n isPrimaryOwner: boolean;\n isRestricted: boolean;\n isUltraRestricted: boolean;\n isBot: boolean;\n isAppUser: boolean;\n updated: number;\n}\n\nexport interface SlackUserProfile {\n title: string | undefined;\n phone: string | undefined;\n skype: string | undefined;\n realName: string | undefined;\n realNameNormalized: string | undefined;\n displayName: string | undefined;\n displayNameNormalized: string | undefined;\n statusText: string | undefined;\n statusEmoji: string | undefined;\n statusExpiration: number | undefined;\n avatarHash: string | undefined;\n email: string | undefined;\n image24: string | undefined;\n image32: string | undefined;\n image48: string | undefined;\n image72: string | undefined;\n image192: string | undefined;\n image512: string | undefined;\n image1024: string | undefined;\n imageOriginal: string | undefined;\n team: string | undefined;\n}\n\nexport interface SlackChannel {\n id: string;\n name: string;\n isChannel: boolean;\n isGroup: boolean;\n isIm: boolean;\n isMpim: boolean;\n isPrivate: boolean;\n isArchived: boolean;\n isGeneral: boolean;\n isShared: boolean;\n isOrgShared: boolean;\n isMember: boolean;\n topic: SlackChannelTopic | undefined;\n purpose: SlackChannelPurpose | undefined;\n numMembers: number | undefined;\n created: number;\n creator: string;\n}\n\nexport interface SlackChannelTopic {\n value: string;\n creator: string;\n lastSet: number;\n}\n\nexport interface SlackChannelPurpose {\n value: string;\n creator: string;\n lastSet: number;\n}\n\nexport interface SlackMessage {\n type: string;\n subtype: string | undefined;\n ts: string;\n user: string | undefined;\n text: string;\n threadTs: string | undefined;\n replyCount: number | undefined;\n replyUsersCount: number | undefined;\n latestReply: string | undefined;\n reactions: SlackReaction[] | undefined;\n files: SlackFile[] | undefined;\n attachments: SlackAttachment[] | undefined;\n blocks: SlackBlock[] | undefined;\n}\n\nexport interface SlackReaction {\n name: string;\n count: number;\n users: string[];\n}\n\nexport interface SlackAttachment {\n id: number;\n fallback: string | undefined;\n color: string | undefined;\n pretext: string | undefined;\n authorName: string | undefined;\n authorLink: string | undefined;\n authorIcon: string | undefined;\n title: string | undefined;\n titleLink: string | undefined;\n text: string | undefined;\n fields: SlackAttachmentField[] | undefined;\n imageUrl: string | undefined;\n thumbUrl: string | undefined;\n footer: string | undefined;\n footerIcon: string | undefined;\n ts: string | undefined;\n}\n\nexport interface SlackAttachmentField {\n title: string;\n value: string;\n short: boolean;\n}\n\nexport interface SlackBlock {\n type: string;\n blockId: string | undefined;\n elements: SlackBlockElement[] | undefined;\n text: SlackBlockText | undefined;\n}\n\nexport interface SlackBlockElement {\n type: string;\n text: SlackBlockText | undefined;\n actionId: string | undefined;\n url: string | undefined;\n value: string | undefined;\n style: string | undefined;\n}\n\nexport interface SlackBlockText {\n type: string;\n text: string;\n emoji: boolean | undefined;\n verbatim: boolean | undefined;\n}\n\nexport interface SlackTeam {\n id: string;\n name: string;\n domain: string;\n emailDomain: string | undefined;\n icon: SlackTeamIcon;\n}\n\nexport interface SlackTeamIcon {\n image34: string | undefined;\n image44: string | undefined;\n image68: string | undefined;\n image88: string | undefined;\n image102: string | undefined;\n image132: string | undefined;\n image230: string | undefined;\n imageDefault: boolean;\n}\n\nexport interface ISlackService {\n app: BoltApp | null;\n client: WebClient | null;\n character: Character;\n botUserId: string | null;\n teamId: string | null;\n}\n\nexport const SLACK_SERVICE_NAME = \"slack\";\n\nexport const ServiceType = {\n SLACK: \"slack\",\n} as const;\n\nexport interface SlackSettings {\n allowedChannelIds: string[] | undefined;\n shouldIgnoreBotMessages: boolean;\n shouldRespondOnlyToMentions: boolean;\n}\n\nexport interface SlackMessageSendOptions {\n threadTs: string | undefined;\n replyBroadcast: boolean | undefined;\n unfurlLinks: boolean | undefined;\n unfurlMedia: boolean | undefined;\n mrkdwn: boolean | undefined;\n attachments: SlackAttachment[] | undefined;\n blocks: SlackBlock[] | undefined;\n}\n\nexport class SlackPluginError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n ) {\n super(message);\n this.name = \"SlackPluginError\";\n }\n}\n\nexport class SlackServiceNotInitializedError extends SlackPluginError {\n constructor() {\n super(\"Slack service is not initialized\", \"SERVICE_NOT_INITIALIZED\");\n this.name = \"SlackServiceNotInitializedError\";\n }\n}\n\nexport class SlackClientNotAvailableError extends SlackPluginError {\n constructor() {\n super(\"Slack client is not available\", \"CLIENT_NOT_AVAILABLE\");\n this.name = \"SlackClientNotAvailableError\";\n }\n}\n\nexport class SlackConfigurationError extends SlackPluginError {\n constructor(missingConfig: string) {\n super(`Missing required configuration: ${missingConfig}`, \"MISSING_CONFIG\");\n this.name = \"SlackConfigurationError\";\n }\n}\n\nexport class SlackApiError extends SlackPluginError {\n constructor(\n message: string,\n public readonly apiErrorCode: string | undefined,\n ) {\n super(message, \"API_ERROR\");\n this.name = \"SlackApiError\";\n }\n}\n\n/**\n * Validates a Slack channel ID format\n */\nexport function isValidChannelId(id: string): boolean {\n // Slack channel IDs start with C (public), G (private/group), or D (DM)\n return /^[CGD][A-Z0-9]{8,}$/i.test(id);\n}\n\n/**\n * Validates a Slack user ID format\n */\nexport function isValidUserId(id: string): boolean {\n // Slack user IDs start with U or W (enterprise grid)\n return /^[UW][A-Z0-9]{8,}$/i.test(id);\n}\n\n/**\n * Validates a Slack team ID format\n */\nexport function isValidTeamId(id: string): boolean {\n // Slack team IDs start with T\n return /^T[A-Z0-9]{8,}$/i.test(id);\n}\n\n/**\n * Validates a Slack message timestamp format\n */\nexport function isValidMessageTs(ts: string): boolean {\n // Slack timestamps are in the format: 1234567890.123456\n return /^\\d+\\.\\d{6}$/.test(ts);\n}\n\n/**\n * Parses a Slack message link to extract channel and message IDs\n */\nexport function parseSlackMessageLink(\n link: string,\n): { channelId: string; messageTs: string } | null {\n // Format: https://workspace.slack.com/archives/C12345678/p1234567890123456\n const match = link.match(/\\/archives\\/([CGD][A-Z0-9]+)\\/p(\\d+)/i);\n if (!match) return null;\n\n const channelId = match[1];\n const ts = match[2];\n // Convert the timestamp: p1234567890123456 -> 1234567890.123456\n const messageTs = `${ts.slice(0, 10)}.${ts.slice(10)}`;\n\n return { channelId, messageTs };\n}\n\n/**\n * Formats a message timestamp for use in Slack links\n */\nexport function formatMessageTsForLink(ts: string): string {\n // Convert: 1234567890.123456 -> p1234567890123456\n return `p${ts.replace(\".\", \"\")}`;\n}\n\n/**\n * Gets the display name for a Slack user\n */\nexport function getSlackUserDisplayName(user: SlackUser): string {\n return user.profile.displayName || user.profile.realName || user.name;\n}\n\n/**\n * Determines the channel type from a Slack channel object\n */\nexport function getSlackChannelType(channel: SlackChannel): SlackChannelType {\n if (channel.isIm) return \"im\";\n if (channel.isMpim) return \"mpim\";\n if (channel.isGroup || channel.isPrivate) return \"group\";\n return \"channel\";\n}\n\n/**\n * Maximum message length for Slack messages\n */\nexport const MAX_SLACK_MESSAGE_LENGTH = 4000;\n\n/**\n * Maximum number of blocks per message\n */\nexport const MAX_SLACK_BLOCKS = 50;\n\n/**\n * Maximum file size for uploads (in bytes) - 1GB for paid, varies for free\n */\nexport const MAX_SLACK_FILE_SIZE = 1024 * 1024 * 1024;\n",
|
|
10
|
+
"import {\n ChannelType,\n type Character,\n type Content,\n createUniqueUuid,\n type EventPayload,\n type HandlerCallback,\n type IAgentRuntime,\n type IMessageService,\n type Media,\n type Memory,\n type MessageConnectorChatContext,\n type MessageConnectorQueryContext,\n type MessageConnectorTarget,\n type MessageConnectorUserContext,\n type Room,\n Service,\n stringToUuid,\n type TargetInfo,\n type UUID,\n type World,\n} from \"@elizaos/core\";\nimport { App, LogLevel } from \"@slack/bolt\";\nimport type { WebAPICallResult } from \"@slack/web-api\";\n\ntype WebClient = App[\"client\"];\ntype AccountScopedTargetInfo = TargetInfo & { accountId?: string };\ntype AccountScopedConnectorContext = MessageConnectorQueryContext & {\n accountId?: string;\n account?: { accountId?: string };\n};\ntype MessageConnectorRegistration = Parameters<\n IAgentRuntime[\"registerMessageConnector\"]\n>[0];\n\ntype ConnectorFetchMessagesParams = {\n target?: TargetInfo;\n accountId?: string;\n limit?: number;\n before?: string;\n after?: string;\n cursor?: string;\n channelId?: string;\n roomId?: UUID;\n threadId?: string;\n};\n\ntype ConnectorSearchMessagesParams = ConnectorFetchMessagesParams & {\n query?: string;\n};\n\ntype ConnectorMessageMutationParams = {\n target?: TargetInfo;\n accountId?: string;\n channelId?: string;\n roomId?: UUID;\n threadId?: string;\n messageId?: string;\n messageTs?: string;\n emoji?: string;\n remove?: boolean;\n pin?: boolean;\n text?: string;\n content?: Content;\n};\n\ntype ConnectorUserLookupParams = {\n target?: TargetInfo;\n userId?: string;\n username?: string;\n handle?: string;\n query?: string;\n};\n\ntype ExtendedMessageConnectorRegistration = MessageConnectorRegistration & {\n listServers?: (context: MessageConnectorQueryContext) => Promise<World[]>;\n fetchMessages?: (\n context: MessageConnectorQueryContext,\n params: ConnectorFetchMessagesParams,\n ) => Promise<Memory[]>;\n searchMessages?: (\n context: MessageConnectorQueryContext,\n params: ConnectorSearchMessagesParams,\n ) => Promise<Memory[]>;\n reactHandler?: (\n runtime: IAgentRuntime,\n params: ConnectorMessageMutationParams,\n ) => Promise<void>;\n editHandler?: (\n runtime: IAgentRuntime,\n params: ConnectorMessageMutationParams,\n ) => Promise<Memory>;\n deleteHandler?: (\n runtime: IAgentRuntime,\n params: ConnectorMessageMutationParams,\n ) => Promise<void>;\n pinHandler?: (\n runtime: IAgentRuntime,\n params: ConnectorMessageMutationParams,\n ) => Promise<void>;\n getUser?: (\n runtime: IAgentRuntime,\n params: ConnectorUserLookupParams,\n ) => Promise<unknown>;\n};\n\ntype SlackApiUserProfile = {\n title?: string;\n phone?: string;\n skype?: string;\n real_name?: string;\n real_name_normalized?: string;\n display_name?: string;\n display_name_normalized?: string;\n status_text?: string;\n status_emoji?: string;\n status_expiration?: number;\n avatar_hash?: string;\n email?: string;\n image_24?: string;\n image_32?: string;\n image_48?: string;\n image_72?: string;\n image_192?: string;\n image_512?: string;\n image_1024?: string;\n image_original?: string;\n team?: string;\n};\n\ntype SlackApiUserMember = {\n id?: string;\n team_id?: string;\n name?: string;\n deleted?: boolean;\n real_name?: string;\n tz?: string;\n tz_label?: string;\n tz_offset?: number;\n profile?: SlackApiUserProfile;\n is_admin?: boolean;\n is_owner?: boolean;\n is_primary_owner?: boolean;\n is_restricted?: boolean;\n is_ultra_restricted?: boolean;\n is_bot?: boolean;\n is_app_user?: boolean;\n updated?: number;\n};\n\nconst SLACK_CONNECTOR_CONTEXTS = [\"social\", \"connectors\"];\nconst SLACK_CONNECTOR_CAPABILITIES = [\n \"send_message\",\n \"read_messages\",\n \"search_messages\",\n \"resolve_targets\",\n \"list_rooms\",\n \"list_servers\",\n \"chat_context\",\n \"user_context\",\n \"react_message\",\n \"edit_message\",\n \"delete_message\",\n \"pin_message\",\n \"get_user\",\n];\nconst SLACK_USER_ID_PATTERN = /^[UW][A-Z0-9]{2,}$/i;\n\nfunction normalizeSlackConnectorQuery(value: string): string {\n return value\n .trim()\n .replace(/^<#([A-Z0-9]+)(?:\\|[^>]+)?>$/i, \"$1\")\n .replace(/^<@([A-Z0-9]+)>$/i, \"$1\")\n .replace(/^#/, \"\")\n .replace(/^@/, \"\")\n .toLowerCase();\n}\n\nfunction scoreSlackConnectorMatch(\n query: string,\n id: string,\n labels: Array<string | null | undefined>,\n): number {\n if (!query) {\n return 0.45;\n }\n if (id.toLowerCase() === query) {\n return 1;\n }\n\n let bestScore = 0;\n for (const label of labels) {\n const normalized = label?.trim().toLowerCase();\n if (!normalized) {\n continue;\n }\n if (normalized === query) {\n bestScore = Math.max(bestScore, 0.95);\n } else if (normalized.startsWith(query)) {\n bestScore = Math.max(bestScore, 0.85);\n } else if (normalized.includes(query)) {\n bestScore = Math.max(bestScore, 0.7);\n }\n }\n return bestScore;\n}\n\nfunction extractSlackUserIdFromMetadata(\n metadata: unknown,\n accountId?: string | null,\n): string | null {\n if (!metadata || typeof metadata !== \"object\") {\n return null;\n }\n\n const record = metadata as Record<string, unknown>;\n const slack =\n record.slack && typeof record.slack === \"object\"\n ? (record.slack as Record<string, unknown>)\n : null;\n\n const metadataAccountId =\n typeof record.accountId === \"string\"\n ? record.accountId\n : typeof slack?.accountId === \"string\"\n ? slack.accountId\n : undefined;\n if (\n accountId &&\n metadataAccountId &&\n normalizeAccountId(metadataAccountId) !== normalizeAccountId(accountId)\n ) {\n return null;\n }\n\n const candidates = [\n slack?.userId,\n slack?.id,\n record.slackUserId,\n record.originalId,\n ];\n\n for (const candidate of candidates) {\n if (\n typeof candidate === \"string\" &&\n SLACK_USER_ID_PATTERN.test(candidate)\n ) {\n return candidate;\n }\n }\n return null;\n}\n\n// Define Slack event types inline to avoid import issues\ninterface SlackMessageEventType {\n type: \"message\";\n channel: string;\n channel_type?: string;\n user?: string;\n text?: string;\n ts: string;\n thread_ts?: string;\n team?: string;\n bot_id?: string;\n files?: SlackFile[];\n}\n\ninterface SlackAppMentionEventType {\n type: \"app_mention\";\n channel: string;\n user?: string;\n text: string;\n ts: string;\n thread_ts?: string;\n event_ts: string;\n}\n\n// Helper to get message service from runtime\nconst getMessageService = (runtime: IAgentRuntime): IMessageService | null => {\n if (\"messageService\" in runtime) {\n const withMessageService = runtime as IAgentRuntime & {\n messageService?: IMessageService | null;\n };\n return withMessageService.messageService ?? null;\n }\n return null;\n};\n\nimport {\n DEFAULT_ACCOUNT_ID,\n listEnabledSlackAccounts,\n normalizeAccountId,\n type ResolvedSlackAccount,\n resolveDefaultSlackAccountId,\n} from \"./accounts\";\nimport { markdownToSlackMrkdwn } from \"./formatting\";\nimport {\n getSlackChannelType,\n getSlackUserDisplayName,\n type ISlackService,\n isValidChannelId,\n MAX_SLACK_MESSAGE_LENGTH,\n SLACK_SERVICE_NAME,\n type SlackAttachment,\n type SlackBlock,\n type SlackChannel,\n SlackEventTypes,\n type SlackFile,\n type SlackMessage,\n type SlackMessageSendOptions,\n type SlackSettings,\n type SlackUser,\n} from \"./types\";\n\ntype SlackAccountRuntime = {\n accountId: string;\n account: ResolvedSlackAccount;\n app: App;\n client: WebClient;\n botUserId: string | null;\n teamId: string | null;\n settings: SlackSettings;\n allowedChannelIds: Set<string>;\n dynamicChannelIds: Set<string>;\n userCache: Map<string, SlackUser>;\n channelCache: Map<string, SlackChannel>;\n isConnected: boolean;\n};\n\n/**\n * SlackService class for interacting with Slack via Socket Mode\n */\nexport class SlackService extends Service implements ISlackService {\n static serviceType: string = SLACK_SERVICE_NAME;\n capabilityDescription =\n \"The agent is able to send and receive messages on Slack\";\n\n app: App | null = null;\n client: WebClient | null = null;\n character: Character;\n botUserId: string | null = null;\n teamId: string | null = null;\n\n private settings: SlackSettings;\n private botToken: string | null = null;\n private appToken: string | null = null;\n private signingSecret: string | null = null;\n private defaultAccountId = DEFAULT_ACCOUNT_ID;\n private accountStates: Map<string, SlackAccountRuntime> = new Map();\n private accountStarts: Map<string, Promise<SlackAccountRuntime>> = new Map();\n private allowedChannelIds: Set<string> = new Set();\n private dynamicChannelIds: Set<string> = new Set();\n private userCache: Map<string, SlackUser> = new Map();\n private channelCache: Map<string, SlackChannel> = new Map();\n private isConnected = false;\n\n constructor(runtime: IAgentRuntime) {\n super(runtime);\n this.character = runtime.character;\n this.settings = this.loadSettings();\n\n // Parse allowed channel IDs for the legacy/default account path.\n this.allowedChannelIds = this.buildAllowedChannelSet();\n if (this.allowedChannelIds.size > 0) {\n this.runtime.logger.debug(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n allowedChannelIds: Array.from(this.allowedChannelIds),\n },\n \"Channel restrictions enabled\",\n );\n }\n }\n\n private loadSettings(account?: ResolvedSlackAccount): SlackSettings {\n const ignoreBotMessages = this.runtime.getSetting(\n \"SLACK_SHOULD_IGNORE_BOT_MESSAGES\",\n );\n const respondOnlyToMentions = this.runtime.getSetting(\n \"SLACK_SHOULD_RESPOND_ONLY_TO_MENTIONS\",\n );\n\n return {\n allowedChannelIds: account?.config.allowedChannelIds,\n shouldIgnoreBotMessages:\n account?.config.shouldIgnoreBotMessages ??\n (ignoreBotMessages === \"true\" || ignoreBotMessages === true),\n shouldRespondOnlyToMentions:\n account?.config.shouldRespondOnlyToMentions ??\n (respondOnlyToMentions === \"true\" || respondOnlyToMentions === true),\n };\n }\n\n private buildAllowedChannelSet(account?: ResolvedSlackAccount): Set<string> {\n const allowed = new Set<string>();\n const configuredIds = account?.config.allowedChannelIds;\n const channelIdsRaw =\n configuredIds && configuredIds.length > 0\n ? configuredIds.join(\",\")\n : (this.runtime.getSetting(\"SLACK_CHANNEL_IDS\") as string | undefined);\n\n if (!channelIdsRaw?.trim()) {\n return allowed;\n }\n\n channelIdsRaw\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0 && isValidChannelId(s))\n .forEach((id) => {\n allowed.add(id);\n });\n\n return allowed;\n }\n\n static async start(runtime: IAgentRuntime): Promise<SlackService> {\n const service = new SlackService(runtime);\n\n const accounts = listEnabledSlackAccounts(runtime);\n service.defaultAccountId = resolveDefaultSlackAccountId(runtime);\n\n if (accounts.length === 0) {\n runtime.logger.warn(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"No enabled Slack accounts configured, Slack service will not start\",\n );\n return service;\n }\n\n let startedAccounts = 0;\n let lastError: unknown;\n for (const account of accounts) {\n if (!account.appToken?.trim()) {\n runtime.logger.warn(\n {\n src: \"plugin:slack\",\n agentId: runtime.agentId,\n accountId: account.accountId,\n },\n \"SLACK_APP_TOKEN not provided for Slack account, Socket Mode will not work\",\n );\n continue;\n }\n\n try {\n await service.initializeAccount(account);\n startedAccounts++;\n } catch (error) {\n lastError = error;\n runtime.logger.error(\n {\n src: \"plugin:slack\",\n agentId: runtime.agentId,\n accountId: account.accountId,\n error: error instanceof Error ? error.message : String(error),\n },\n \"Failed to initialize Slack account\",\n );\n }\n }\n\n if (startedAccounts === 0) {\n if (lastError) {\n throw lastError;\n }\n runtime.logger.warn(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"Slack service started without connected accounts\",\n );\n }\n\n return service;\n }\n\n static async stop(runtime: IAgentRuntime): Promise<void> {\n const service = runtime.getService(SLACK_SERVICE_NAME) as\n | SlackService\n | undefined;\n if (service) {\n await service.shutdown();\n }\n }\n\n static registerSendHandlers(\n runtime: IAgentRuntime,\n serviceInstance: SlackService,\n ): void {\n if (!serviceInstance) {\n return;\n }\n\n const registerConnector = (accountId?: string) => {\n const normalizedAccountId = accountId\n ? normalizeAccountId(accountId)\n : undefined;\n const state = normalizedAccountId\n ? serviceInstance.getAccountState(normalizedAccountId)\n : serviceInstance.getDefaultAccountState();\n const sendHandler = async (\n handlerRuntime: IAgentRuntime,\n target: TargetInfo,\n content: Content,\n ): Promise<void> => {\n await serviceInstance.handleSendMessage(\n handlerRuntime,\n normalizedAccountId && !(target as AccountScopedTargetInfo).accountId\n ? ({ ...target, accountId: normalizedAccountId } as TargetInfo)\n : target,\n content,\n );\n };\n\n const withContextAccount = (\n context: MessageConnectorQueryContext,\n ): MessageConnectorQueryContext =>\n normalizedAccountId &&\n !(context as AccountScopedConnectorContext).accountId\n ? ({\n ...context,\n accountId: normalizedAccountId,\n account: (context as AccountScopedConnectorContext).account ?? {\n source: \"slack\",\n accountId: normalizedAccountId,\n label: state?.account.name ?? normalizedAccountId,\n },\n } as MessageConnectorQueryContext)\n : context;\n\n const registration: ExtendedMessageConnectorRegistration = {\n source: \"slack\",\n ...(normalizedAccountId ? { accountId: normalizedAccountId } : {}),\n ...(normalizedAccountId\n ? {\n account: {\n source: \"slack\",\n accountId: normalizedAccountId,\n label: state?.account.name ?? normalizedAccountId,\n authMethod: \"BOT_TOKEN\",\n metadata: {\n teamId: state?.teamId,\n },\n },\n }\n : {}),\n label: state?.account.name ? `Slack (${state.account.name})` : \"Slack\",\n description:\n \"Slack connector for sending, reading, searching, reacting to, editing, deleting, and pinning messages in channels, threads, and users.\",\n capabilities: [...SLACK_CONNECTOR_CAPABILITIES],\n supportedTargetKinds: [\"channel\", \"thread\", \"user\"],\n contexts: [...SLACK_CONNECTOR_CONTEXTS],\n metadata: {\n service: SLACK_SERVICE_NAME,\n maxMessageLength: MAX_SLACK_MESSAGE_LENGTH,\n ...(normalizedAccountId ? { accountId: normalizedAccountId } : {}),\n },\n resolveTargets: (query, context) =>\n serviceInstance.resolveConnectorTargets(\n query,\n withContextAccount(context),\n ),\n listRecentTargets: (context) =>\n serviceInstance.listRecentConnectorTargets(\n withContextAccount(context),\n ),\n listRooms: (context) =>\n serviceInstance.listConnectorRooms(withContextAccount(context)),\n listServers: (context) =>\n serviceInstance.listConnectorServers(withContextAccount(context)),\n fetchMessages: (context, params) =>\n serviceInstance.fetchConnectorMessages(withContextAccount(context), {\n ...params,\n ...(normalizedAccountId && !params.accountId\n ? { accountId: normalizedAccountId }\n : {}),\n }),\n searchMessages: (context, params) =>\n serviceInstance.searchConnectorMessages(withContextAccount(context), {\n ...params,\n ...(normalizedAccountId && !params.accountId\n ? { accountId: normalizedAccountId }\n : {}),\n }),\n reactHandler: (handlerRuntime, params) =>\n serviceInstance.reactConnectorMessage(handlerRuntime, {\n ...params,\n ...(normalizedAccountId && !params.accountId\n ? { accountId: normalizedAccountId }\n : {}),\n }),\n editHandler: (handlerRuntime, params) =>\n serviceInstance.editConnectorMessage(handlerRuntime, {\n ...params,\n ...(normalizedAccountId && !params.accountId\n ? { accountId: normalizedAccountId }\n : {}),\n }),\n deleteHandler: (handlerRuntime, params) =>\n serviceInstance.deleteConnectorMessage(handlerRuntime, {\n ...params,\n ...(normalizedAccountId && !params.accountId\n ? { accountId: normalizedAccountId }\n : {}),\n }),\n pinHandler: (handlerRuntime, params) =>\n serviceInstance.pinConnectorMessage(handlerRuntime, {\n ...params,\n ...(normalizedAccountId && !params.accountId\n ? { accountId: normalizedAccountId }\n : {}),\n }),\n getUser: (handlerRuntime, params) =>\n serviceInstance.getConnectorUser(handlerRuntime, {\n ...params,\n ...(normalizedAccountId && !params.target\n ? {\n target: {\n source: \"slack\",\n accountId: normalizedAccountId,\n } as TargetInfo,\n }\n : {}),\n }),\n getChatContext: (target, context) =>\n serviceInstance.getConnectorChatContext(\n normalizedAccountId &&\n !(target as AccountScopedTargetInfo).accountId\n ? ({ ...target, accountId: normalizedAccountId } as TargetInfo)\n : target,\n withContextAccount(context),\n ),\n getUserContext: (entityId, context) =>\n serviceInstance.getConnectorUserContext(\n entityId,\n withContextAccount(context),\n ),\n sendHandler,\n };\n\n runtime.registerMessageConnector(registration);\n };\n\n if (typeof runtime.registerMessageConnector === \"function\") {\n registerConnector();\n for (const accountId of serviceInstance.getRegisteredAccountIds()) {\n registerConnector(accountId);\n }\n runtime.logger.info(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"Registered Slack message connector\",\n );\n return;\n }\n\n runtime.registerSendHandler(\n \"slack\",\n serviceInstance.handleSendMessage.bind(serviceInstance),\n );\n runtime.logger.info(\n { src: \"plugin:slack\", agentId: runtime.agentId },\n \"Registered Slack send handler\",\n );\n }\n\n async stop(): Promise<void> {\n await this.shutdown();\n }\n\n private syncDefaultAccountAliases(): void {\n const state = this.getDefaultAccountState();\n this.app = state?.app ?? null;\n this.client = state?.client ?? null;\n this.botUserId = state?.botUserId ?? null;\n this.teamId = state?.teamId ?? null;\n this.botToken = state?.account.botToken ?? null;\n this.appToken = state?.account.appToken ?? null;\n this.signingSecret = state?.account.signingSecret ?? null;\n this.isConnected = Array.from(this.accountStates?.values?.() ?? []).some(\n (accountState) => accountState.isConnected,\n );\n }\n\n private async initializeAccount(\n account: ResolvedSlackAccount,\n ): Promise<SlackAccountRuntime> {\n const accountId = normalizeAccountId(account.accountId);\n const cached = this.accountStates.get(accountId);\n if (cached) {\n return cached;\n }\n\n const starting = this.accountStarts.get(accountId);\n if (starting) {\n return starting;\n }\n\n const startPromise = (async () => {\n if (!account.botToken || !account.appToken) {\n throw new Error(\n `Slack account ${accountId} requires bot and app tokens`,\n );\n }\n\n this.runtime.logger.info(\n { src: \"plugin:slack\", agentId: this.runtime.agentId, accountId },\n \"Initializing Slack service with Socket Mode\",\n );\n\n const app = new App({\n token: account.botToken,\n appToken: account.appToken,\n socketMode: true,\n logLevel: LogLevel.INFO,\n ...(account.signingSecret\n ? { signingSecret: account.signingSecret }\n : {}),\n });\n\n const state: SlackAccountRuntime = {\n accountId,\n account,\n app,\n client: app.client,\n botUserId: null,\n teamId: null,\n settings: this.loadSettings(account),\n allowedChannelIds: this.buildAllowedChannelSet(account),\n dynamicChannelIds: new Set(),\n userCache: new Map(),\n channelCache: new Map(),\n isConnected: false,\n };\n\n const authResult = await state.client.auth.test();\n state.botUserId = authResult.user_id as string;\n state.teamId = authResult.team_id as string;\n\n this.accountStates.set(accountId, state);\n this.syncDefaultAccountAliases();\n\n this.runtime.logger.info(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n accountId,\n botUserId: state.botUserId,\n teamId: state.teamId,\n },\n \"Slack bot authenticated\",\n );\n\n this.registerEventHandlers(state);\n\n try {\n await app.start();\n } catch (error) {\n this.accountStates.delete(accountId);\n this.syncDefaultAccountAliases();\n throw error;\n }\n state.isConnected = true;\n this.syncDefaultAccountAliases();\n\n this.runtime.logger.info(\n { src: \"plugin:slack\", agentId: this.runtime.agentId, accountId },\n \"Slack account started successfully\",\n );\n\n await this.ensureWorkspaceExists(accountId);\n return state;\n })();\n\n this.accountStarts.set(accountId, startPromise);\n try {\n return await startPromise;\n } finally {\n this.accountStarts.delete(accountId);\n }\n }\n\n private async shutdown(): Promise<void> {\n const states =\n this.accountStates instanceof Map\n ? Array.from(this.accountStates.values())\n : [];\n if (states.length > 0) {\n for (const state of states) {\n await state.app.stop();\n state.isConnected = false;\n this.runtime.logger.info(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n accountId: state.accountId,\n },\n \"Slack account stopped\",\n );\n }\n this.accountStates.clear();\n this.syncDefaultAccountAliases();\n return;\n }\n\n if (this.app) {\n await this.app.stop();\n this.app = null;\n this.client = null;\n this.isConnected = false;\n\n this.runtime.logger.info(\n { src: \"plugin:slack\", agentId: this.runtime.agentId },\n \"Slack service stopped\",\n );\n }\n }\n\n private registerEventHandlers(state?: SlackAccountRuntime): void {\n const app = state?.app ?? this.app;\n const accountId = state?.accountId ?? this.defaultAccountId;\n if (!app) return;\n\n // Handle regular messages\n app.message(async ({ message, client }) => {\n await this.handleMessage(\n message as SlackMessageEventType,\n client,\n accountId,\n );\n });\n\n // Handle app mentions\n app.event(\"app_mention\", async ({ event, client }) => {\n await this.handleAppMention(\n event as SlackAppMentionEventType,\n client,\n accountId,\n );\n });\n\n // Handle reactions\n app.event(\"reaction_added\", async ({ event }) => {\n await this.handleReactionAdded(event, accountId);\n });\n\n app.event(\"reaction_removed\", async ({ event }) => {\n await this.handleReactionRemoved(event, accountId);\n });\n\n // Handle channel joins/leaves\n app.event(\"member_joined_channel\", async ({ event }) => {\n await this.handleMemberJoinedChannel(event, accountId);\n });\n\n app.event(\"member_left_channel\", async ({ event }) => {\n await this.handleMemberLeftChannel(event, accountId);\n });\n\n // Handle file shares\n app.event(\"file_shared\", async ({ event }) => {\n await this.handleFileShared(event, accountId);\n });\n }\n\n private getDefaultAccountState(): SlackAccountRuntime | null {\n const states = this.accountStates;\n if (!(states instanceof Map) || states.size === 0) {\n return null;\n }\n const defaultId = normalizeAccountId(\n this.defaultAccountId ?? DEFAULT_ACCOUNT_ID,\n );\n return states.get(defaultId) ?? states.values().next().value ?? null;\n }\n\n private getAccountState(\n accountId?: string | null,\n ): SlackAccountRuntime | null {\n const states = this.accountStates;\n if (!(states instanceof Map) || states.size === 0) {\n return null;\n }\n if (accountId) {\n return states.get(normalizeAccountId(accountId)) ?? null;\n }\n return this.getDefaultAccountState();\n }\n\n private getClientForAccount(accountId?: string | null): WebClient | null {\n const state = this.getAccountState(accountId);\n if (state?.client) {\n return state.client;\n }\n const requested = accountId ? normalizeAccountId(accountId) : null;\n const defaultId = normalizeAccountId(\n this.defaultAccountId ?? DEFAULT_ACCOUNT_ID,\n );\n if (!requested || requested === defaultId) {\n return this.client;\n }\n return null;\n }\n\n private getSettingsForAccount(accountId?: string | null): SlackSettings {\n return this.getAccountState(accountId)?.settings ?? this.settings;\n }\n\n private getAllowedChannelIdsForAccount(\n accountId?: string | null,\n ): Set<string> {\n return (\n this.getAccountState(accountId)?.allowedChannelIds ??\n this.allowedChannelIds\n );\n }\n\n private getDynamicChannelIdsForAccount(\n accountId?: string | null,\n ): Set<string> {\n return (\n this.getAccountState(accountId)?.dynamicChannelIds ??\n this.dynamicChannelIds\n );\n }\n\n private getUserCacheForAccount(\n accountId?: string | null,\n ): Map<string, SlackUser> {\n return this.getAccountState(accountId)?.userCache ?? this.userCache;\n }\n\n private getChannelCacheForAccount(\n accountId?: string | null,\n ): Map<string, SlackChannel> {\n return this.getAccountState(accountId)?.channelCache ?? this.channelCache;\n }\n\n private getBotUserIdForAccount(accountId?: string | null): string | null {\n return this.getAccountState(accountId)?.botUserId ?? this.botUserId;\n }\n\n private getTeamIdForAccount(accountId?: string | null): string | null {\n return this.getAccountState(accountId)?.teamId ?? this.teamId;\n }\n\n private getRegisteredAccountIds(): string[] {\n const states = this.accountStates;\n if (states instanceof Map && states.size > 0) {\n return Array.from(states.keys());\n }\n return [normalizeAccountId(this.defaultAccountId ?? DEFAULT_ACCOUNT_ID)];\n }\n\n private resolveAccountIdFromContext(\n context?: MessageConnectorQueryContext | null,\n target?: TargetInfo | null,\n ): string | undefined {\n const scopedTarget = target as AccountScopedTargetInfo | null | undefined;\n const scopedContext = context as\n | AccountScopedConnectorContext\n | null\n | undefined;\n return (\n scopedTarget?.accountId ??\n (scopedContext?.target as AccountScopedTargetInfo | undefined)\n ?.accountId ??\n scopedContext?.accountId ??\n scopedContext?.account?.accountId ??\n undefined\n );\n }\n\n private async resolveAccountIdForTarget(\n runtime: IAgentRuntime,\n target?: TargetInfo | null,\n fallback?: { accountId?: string; roomId?: UUID } | null,\n ): Promise<string> {\n const direct =\n (target as AccountScopedTargetInfo | null | undefined)?.accountId ??\n fallback?.accountId ??\n undefined;\n if (direct) {\n return normalizeAccountId(direct);\n }\n\n const roomId = target?.roomId ?? fallback?.roomId;\n if (roomId && typeof runtime.getRoom === \"function\") {\n const room = await runtime.getRoom(roomId);\n const metadata = room?.metadata as Record<string, unknown> | undefined;\n if (\n typeof metadata?.accountId === \"string\" &&\n metadata.accountId.trim()\n ) {\n return normalizeAccountId(metadata.accountId);\n }\n const slack =\n metadata?.slack && typeof metadata.slack === \"object\"\n ? (metadata.slack as Record<string, unknown>)\n : undefined;\n if (typeof slack?.accountId === \"string\" && slack.accountId.trim()) {\n return normalizeAccountId(slack.accountId);\n }\n }\n\n return normalizeAccountId(this.defaultAccountId ?? DEFAULT_ACCOUNT_ID);\n }\n\n private getCandidateAccountIds(\n context?: MessageConnectorQueryContext | null,\n target?: TargetInfo | null,\n ): string[] {\n const explicit = this.resolveAccountIdFromContext(context, target);\n if (explicit) {\n return [normalizeAccountId(explicit)];\n }\n return this.getRegisteredAccountIds();\n }\n\n private scopedSlackKey(\n prefix: string,\n key: string,\n accountId?: string | null,\n ): string {\n const normalized = normalizeAccountId(\n accountId ?? this.defaultAccountId ?? DEFAULT_ACCOUNT_ID,\n );\n return normalized === DEFAULT_ACCOUNT_ID\n ? `${prefix}-${key}`\n : `${prefix}-${normalized}-${key}`;\n }\n\n private buildEventPayload(accountId?: string | null): EventPayload {\n const normalized = normalizeAccountId(\n accountId ?? this.defaultAccountId ?? DEFAULT_ACCOUNT_ID,\n );\n return {\n runtime: this.runtime,\n source: \"slack\",\n accountId: normalized,\n metadata: { accountId: normalized },\n } as EventPayload;\n }\n\n private async handleMessage(\n message: SlackMessageEventType,\n _client: WebClient,\n accountId = this.defaultAccountId,\n ): Promise<void> {\n const settings = this.getSettingsForAccount(accountId);\n const botUserId = this.getBotUserIdForAccount(accountId);\n\n // Ignore bot messages if configured\n if (settings.shouldIgnoreBotMessages && message.bot_id) {\n return;\n }\n\n // Ignore messages from self\n if (message.user === botUserId) {\n return;\n }\n\n // Check channel restrictions\n if (!this.isChannelAllowed(message.channel, accountId)) {\n this.runtime.logger.debug(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n accountId,\n channelId: message.channel,\n },\n \"Message received in non-allowed channel, ignoring\",\n );\n return;\n }\n\n // Check if we should only respond to mentions\n const isMentioned = message.text?.includes(`<@${botUserId}>`);\n // Skip @mentions in channels — handleAppMention handles those\n if (isMentioned && message.channel_type !== \"im\") {\n return;\n }\n if (settings.shouldRespondOnlyToMentions && !isMentioned) {\n return;\n }\n\n const _isThreadReply = Boolean(\n message.thread_ts && message.thread_ts !== message.ts,\n );\n\n // Build memory from message\n const memory = await this.buildMemoryFromMessage(message, accountId);\n if (!memory) return;\n\n // Get or create room\n const room = await this.ensureRoomExists(\n message.channel,\n message.thread_ts,\n accountId,\n );\n\n const existingEntity = await this.runtime.getEntityById(memory.entityId);\n if (!existingEntity) {\n const user = await this.getUser(message.user, accountId);\n const displayName = user ? getSlackUserDisplayName(user) : message.user;\n await this.runtime.createEntity({\n id: memory.entityId,\n names: [displayName],\n metadata: {\n source: \"slack\",\n accountId,\n slack: {\n accountId,\n id: message.user,\n name: displayName,\n userName: user?.name || message.user,\n },\n },\n agentId: this.runtime.agentId,\n });\n }\n\n // Store the memory\n await this.runtime.createMemory(memory, \"messages\");\n\n // Emit event\n await this.runtime.emitEvent(\n SlackEventTypes.MESSAGE_RECEIVED as string,\n this.buildEventPayload(accountId),\n );\n\n // Process the message through the agent\n await this.processAgentMessage(\n memory,\n room,\n message.channel,\n message.thread_ts || message.ts,\n accountId,\n );\n }\n\n private async handleAppMention(\n event: SlackAppMentionEventType,\n _client: WebClient,\n accountId = this.defaultAccountId,\n ): Promise<void> {\n // Skip if no user (optional in AppMentionEvent)\n if (!event.user) return;\n\n // Build memory from mention\n const memory = await this.buildMemoryFromMention(\n {\n user: event.user,\n text: event.text,\n channel: event.channel,\n ts: event.ts,\n thread_ts: event.thread_ts,\n },\n accountId,\n );\n if (!memory) return;\n\n // Get or create room\n const room = await this.ensureRoomExists(\n event.channel,\n event.thread_ts,\n accountId,\n );\n\n const existingEntity = await this.runtime.getEntityById(memory.entityId);\n if (!existingEntity) {\n const user = await this.getUser(event.user, accountId);\n const displayName = user ? getSlackUserDisplayName(user) : event.user;\n await this.runtime.createEntity({\n id: memory.entityId,\n names: [displayName],\n metadata: {\n source: \"slack\",\n accountId,\n slack: {\n accountId,\n id: event.user,\n name: displayName,\n userName: user?.name || event.user,\n },\n },\n agentId: this.runtime.agentId,\n });\n }\n\n // Store the memory\n await this.runtime.createMemory(memory, \"messages\");\n\n // Emit event\n await this.runtime.emitEvent(\n SlackEventTypes.APP_MENTION as string,\n this.buildEventPayload(accountId),\n );\n\n // Process the message\n await this.processAgentMessage(\n memory,\n room,\n event.channel,\n event.thread_ts || event.ts,\n accountId,\n );\n }\n\n private async handleReactionAdded(\n _event: {\n user: string;\n reaction: string;\n item: { type: string; channel: string; ts: string };\n item_user?: string;\n },\n accountId = this.defaultAccountId,\n ): Promise<void> {\n await this.runtime.emitEvent(\n SlackEventTypes.REACTION_ADDED as string,\n this.buildEventPayload(accountId),\n );\n }\n\n private async handleReactionRemoved(\n _event: {\n user: string;\n reaction: string;\n item: { type: string; channel: string; ts: string };\n item_user?: string;\n },\n accountId = this.defaultAccountId,\n ): Promise<void> {\n await this.runtime.emitEvent(\n SlackEventTypes.REACTION_REMOVED as string,\n this.buildEventPayload(accountId),\n );\n }\n\n private async handleMemberJoinedChannel(\n event: {\n user: string;\n channel: string;\n team?: string;\n },\n accountId = this.defaultAccountId,\n ): Promise<void> {\n // If the bot joined, add to dynamic channels\n if (event.user === this.getBotUserIdForAccount(accountId)) {\n this.getDynamicChannelIdsForAccount(accountId).add(event.channel);\n await this.ensureRoomExists(event.channel, undefined, accountId);\n }\n\n await this.runtime.emitEvent(\n SlackEventTypes.MEMBER_JOINED_CHANNEL as string,\n this.buildEventPayload(accountId),\n );\n }\n\n private async handleMemberLeftChannel(\n event: {\n user: string;\n channel: string;\n team?: string;\n },\n accountId = this.defaultAccountId,\n ): Promise<void> {\n // If the bot left, remove from dynamic channels\n if (event.user === this.getBotUserIdForAccount(accountId)) {\n this.getDynamicChannelIdsForAccount(accountId).delete(event.channel);\n }\n\n await this.runtime.emitEvent(\n SlackEventTypes.MEMBER_LEFT_CHANNEL as string,\n this.buildEventPayload(accountId),\n );\n }\n\n private async handleFileShared(\n _event: {\n file_id: string;\n user_id: string;\n channel_id: string;\n },\n accountId = this.defaultAccountId,\n ): Promise<void> {\n await this.runtime.emitEvent(\n SlackEventTypes.FILE_SHARED as string,\n this.buildEventPayload(accountId),\n );\n }\n\n private isChannelAllowed(\n channelId: string,\n accountId?: string | null,\n ): boolean {\n const allowedChannelIds = this.getAllowedChannelIdsForAccount(accountId);\n const dynamicChannelIds = this.getDynamicChannelIdsForAccount(accountId);\n\n // If no restrictions, all channels allowed\n if (allowedChannelIds.size === 0 && dynamicChannelIds.size === 0) {\n return true;\n }\n\n // Check static and dynamic allowed lists\n return allowedChannelIds.has(channelId) || dynamicChannelIds.has(channelId);\n }\n\n private async processAgentMessage(\n memory: Memory,\n room: Room,\n channelId: string,\n threadTs: string,\n accountId = this.defaultAccountId,\n ): Promise<void> {\n const callback: HandlerCallback = async (\n response: Content,\n ): Promise<Memory[]> => {\n const responseText = response.text || \"\";\n if (!responseText.trim()) {\n this.runtime.logger.warn(\n { src: \"plugin:slack\", channelId, roomId: room.id },\n \"Empty response from model, skipping sendMessage\",\n );\n return [];\n }\n\n await this.sendMessage(\n channelId,\n responseText,\n {\n threadTs,\n replyBroadcast: undefined,\n unfurlLinks: undefined,\n unfurlMedia: undefined,\n mrkdwn: undefined,\n attachments: undefined,\n blocks: undefined,\n },\n accountId,\n );\n\n // Create memory for the response\n const responseMemory: Memory = {\n id: createUniqueUuid(this.runtime, `slack-response-${Date.now()}`),\n agentId: this.runtime.agentId,\n roomId: room.id,\n entityId: this.runtime.agentId,\n content: {\n text: response.text || \"\",\n source: \"slack\",\n inReplyTo: memory.id,\n metadata: { accountId },\n },\n metadata: {\n type: \"message\",\n source: \"slack\",\n provider: \"slack\",\n accountId,\n fromBot: true,\n fromId: this.runtime.agentId,\n sourceId: this.runtime.agentId,\n slack: {\n accountId,\n channelId,\n threadTs,\n },\n } satisfies Memory[\"metadata\"],\n createdAt: Date.now(),\n };\n\n await this.runtime.createMemory(responseMemory, \"messages\");\n\n await this.runtime.emitEvent(\n SlackEventTypes.MESSAGE_SENT as string,\n this.buildEventPayload(accountId),\n );\n\n return [responseMemory];\n };\n\n const messageService = getMessageService(this.runtime);\n if (messageService) {\n await messageService.handleMessage(this.runtime, memory, callback);\n }\n }\n\n private async buildMemoryFromMessage(\n message: SlackMessageEventType,\n accountId = this.defaultAccountId,\n ): Promise<Memory | null> {\n if (!message.user) return null;\n\n const roomId = await this.getRoomId(\n message.channel,\n message.thread_ts,\n accountId,\n );\n const entityId = this.getEntityId(message.user, accountId);\n\n // Get user info for display name\n const user = await this.getUser(message.user, accountId);\n const displayName = user ? getSlackUserDisplayName(user) : message.user;\n\n // Extract media from files\n const media: Media[] = [];\n if (\"files\" in message && message.files) {\n for (const file of message.files) {\n media.push({\n id: file.id,\n url: file.urlPrivate,\n title: file.title || file.name,\n source: \"slack\",\n description: file.name,\n });\n }\n }\n\n const memory: Memory = {\n id: createUniqueUuid(\n this.runtime,\n this.scopedSlackKey(\"slack\", message.ts, accountId),\n ),\n agentId: this.runtime.agentId,\n roomId,\n entityId,\n content: {\n text: message.text || \"\",\n source: \"slack\",\n name: displayName,\n metadata: { accountId },\n ...(media.length > 0 ? { attachments: media } : {}),\n },\n metadata: {\n type: \"message\",\n source: \"slack\",\n provider: \"slack\",\n accountId,\n timestamp: this.parseSlackTimestamp(message.ts),\n entityName: displayName,\n entityUserName: user?.name ?? message.user,\n fromBot: false,\n fromId: message.user,\n sourceId: entityId,\n chatType: message.channel_type,\n messageIdFull: message.ts,\n sender: {\n id: message.user,\n name: displayName,\n username: user?.name ?? message.user,\n },\n slack: {\n accountId,\n teamId: this.getTeamIdForAccount(accountId) ?? undefined,\n channelId: message.channel,\n userId: message.user,\n messageId: message.ts,\n threadTs: message.thread_ts,\n },\n slackChannelId: message.channel,\n slackMessageTs: message.ts,\n slackThreadTs: message.thread_ts,\n } satisfies Memory[\"metadata\"],\n createdAt: this.parseSlackTimestamp(message.ts),\n };\n\n return memory;\n }\n\n private async buildMemoryFromMention(\n event: {\n user: string;\n text: string;\n channel: string;\n ts: string;\n thread_ts?: string;\n },\n accountId = this.defaultAccountId,\n ): Promise<Memory | null> {\n const roomId = await this.getRoomId(\n event.channel,\n event.thread_ts,\n accountId,\n );\n const entityId = this.getEntityId(event.user, accountId);\n\n const user = await this.getUser(event.user, accountId);\n const displayName = user ? getSlackUserDisplayName(user) : event.user;\n\n // Remove the bot mention from the text\n const cleanText = event.text\n .replace(`<@${this.getBotUserIdForAccount(accountId)}>`, \"\")\n .trim();\n\n const memory: Memory = {\n id: createUniqueUuid(\n this.runtime,\n this.scopedSlackKey(\"slack-mention\", event.ts, accountId),\n ),\n agentId: this.runtime.agentId,\n roomId,\n entityId,\n content: {\n text: cleanText,\n source: \"slack\",\n name: displayName,\n metadata: { accountId },\n mentionContext: { isMention: true, isReply: false, isThread: false },\n },\n metadata: {\n type: \"message\",\n source: \"slack\",\n provider: \"slack\",\n accountId,\n timestamp: this.parseSlackTimestamp(event.ts),\n entityName: displayName,\n entityUserName: user?.name ?? event.user,\n fromBot: false,\n fromId: event.user,\n sourceId: entityId,\n messageIdFull: event.ts,\n slack: {\n accountId,\n teamId: this.getTeamIdForAccount(accountId) ?? undefined,\n channelId: event.channel,\n userId: event.user,\n messageId: event.ts,\n threadTs: event.thread_ts,\n },\n slackChannelId: event.channel,\n slackMessageTs: event.ts,\n slackThreadTs: event.thread_ts,\n } satisfies Memory[\"metadata\"],\n createdAt: this.parseSlackTimestamp(event.ts),\n };\n\n return memory;\n }\n\n private async getRoomId(\n channelId: string,\n threadTs?: string,\n accountId?: string | null,\n ): Promise<UUID> {\n // Use thread_ts to create unique rooms for threads\n const roomKey = threadTs ? `${channelId}-${threadTs}` : channelId;\n return createUniqueUuid(\n this.runtime,\n this.scopedSlackKey(\"slack-room\", roomKey, accountId),\n );\n }\n\n private getEntityId(userId: string, accountId?: string | null): UUID {\n return stringToUuid(this.scopedSlackKey(\"slack-user\", userId, accountId));\n }\n\n private parseSlackTimestamp(ts: string): number {\n // Slack timestamps are in the format: 1234567890.123456\n const [seconds] = ts.split(\".\");\n return parseInt(seconds, 10) * 1000;\n }\n\n private async ensureWorkspaceExists(\n accountId = this.defaultAccountId,\n ): Promise<void> {\n const teamId = this.getTeamIdForAccount(accountId);\n const client = this.getClientForAccount(accountId);\n if (!teamId || !client) return;\n\n const worldId = createUniqueUuid(\n this.runtime,\n this.scopedSlackKey(\"slack-workspace\", teamId, accountId),\n );\n\n const existingWorld = await this.runtime.getWorld(worldId);\n if (existingWorld) return;\n\n // Get team info\n const teamInfo = await client.team.info();\n const team = teamInfo.team;\n\n const world: World = {\n id: worldId,\n name: (team as { name?: string })?.name || `Slack Workspace ${teamId}`,\n agentId: this.runtime.agentId,\n metadata: {\n type: \"slack\",\n source: \"slack\",\n accountId,\n extra: {\n accountId,\n teamId,\n domain: (team as { domain?: string })?.domain,\n },\n },\n };\n\n await this.runtime.createWorld(world);\n\n this.runtime.logger.info(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n accountId,\n worldId,\n teamId,\n },\n \"Created Slack workspace world\",\n );\n }\n\n private async ensureRoomExists(\n channelId: string,\n threadTs?: string,\n accountId = this.defaultAccountId,\n ): Promise<Room> {\n const roomId = await this.getRoomId(channelId, threadTs, accountId);\n\n const existingRoom = await this.runtime.getRoom(roomId);\n if (existingRoom) return existingRoom;\n\n // Get channel info\n const channel = await this.getChannel(channelId, accountId);\n const channelType = channel ? getSlackChannelType(channel) : \"channel\";\n const teamId = this.getTeamIdForAccount(accountId);\n\n const worldId = teamId\n ? createUniqueUuid(\n this.runtime,\n this.scopedSlackKey(\"slack-workspace\", teamId, accountId),\n )\n : undefined;\n\n const elizaChannelType =\n channelType === \"im\"\n ? ChannelType.DM\n : channelType === \"mpim\"\n ? ChannelType.GROUP\n : ChannelType.GROUP;\n\n const room: Room = {\n id: roomId,\n name: channel?.name || channelId,\n agentId: this.runtime.agentId,\n source: \"slack\",\n type: elizaChannelType,\n channelId,\n worldId,\n metadata: {\n source: \"slack\",\n accountId,\n slackChannelType: channelType,\n threadTs,\n topic: channel?.topic?.value,\n purpose: channel?.purpose?.value,\n serverId: teamId,\n slack: {\n accountId,\n teamId,\n channelId,\n threadTs,\n },\n },\n };\n\n await this.runtime.createRoom(room);\n\n this.runtime.logger.debug(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n accountId,\n roomId,\n channelId,\n threadTs,\n },\n \"Created Slack room\",\n );\n\n return room;\n }\n\n private buildConnectorChannelTarget(\n channel: SlackChannel,\n score = 0.5,\n accountId = this.defaultAccountId,\n ): MessageConnectorTarget | null {\n if (!channel.id || channel.isArchived) {\n return null;\n }\n if (!this.isChannelAllowed(channel.id, accountId)) {\n return null;\n }\n\n const kind = channel.isIm ? \"user\" : channel.isMpim ? \"group\" : \"channel\";\n const label = channel.name ? `#${channel.name}` : channel.id;\n const teamId = this.getTeamIdForAccount(accountId);\n return {\n target: {\n source: \"slack\",\n accountId,\n channelId: channel.id,\n serverId: teamId ?? undefined,\n } as TargetInfo,\n label,\n kind,\n description: channel.purpose?.value || channel.topic?.value || label,\n score,\n contexts: [\"social\", \"connectors\"],\n metadata: {\n accountId,\n slackChannelId: channel.id,\n slackTeamId: teamId,\n slackChannelType: getSlackChannelType(channel),\n channelName: channel.name,\n isPrivate: channel.isPrivate,\n isMember: channel.isMember,\n topic: channel.topic?.value,\n purpose: channel.purpose?.value,\n },\n };\n }\n\n private buildConnectorUserTarget(\n user: SlackUser,\n score = 0.5,\n accountId = this.defaultAccountId,\n ): MessageConnectorTarget | null {\n if (!user.id || user.deleted || user.isBot || user.isAppUser) {\n return null;\n }\n const label = getSlackUserDisplayName(user);\n return {\n target: {\n source: \"slack\",\n accountId,\n entityId: user.id as UUID,\n serverId:\n user.teamId ?? this.getTeamIdForAccount(accountId) ?? undefined,\n } as TargetInfo,\n label: `@${label}`,\n kind: \"user\",\n description: user.profile.title || \"Slack user\",\n score,\n contexts: [\"social\", \"connectors\"],\n metadata: {\n accountId,\n slackUserId: user.id,\n slackTeamId: user.teamId ?? this.getTeamIdForAccount(accountId),\n slackName: user.name,\n slackRealName: user.realName,\n slackDisplayName: user.profile.displayName,\n email: user.profile.email,\n },\n };\n }\n\n private dedupeConnectorTargets(\n targets: MessageConnectorTarget[],\n ): MessageConnectorTarget[] {\n const byKey = new Map<string, MessageConnectorTarget>();\n for (const target of targets) {\n const key = [\n (target.target as AccountScopedTargetInfo).accountId ?? \"\",\n target.kind ?? \"target\",\n target.target.channelId ?? \"\",\n target.target.entityId ?? \"\",\n target.target.threadId ?? \"\",\n ].join(\":\");\n const existing = byKey.get(key);\n if (!existing || (target.score ?? 0) > (existing.score ?? 0)) {\n byKey.set(key, target);\n }\n }\n return Array.from(byKey.values()).sort(\n (a, b) => (b.score ?? 0) - (a.score ?? 0),\n );\n }\n\n private async resolveSlackTargetUserId(\n runtime: IAgentRuntime,\n entityId: string,\n accountId?: string | null,\n ): Promise<string | null> {\n if (SLACK_USER_ID_PATTERN.test(entityId)) {\n return entityId;\n }\n\n const entity =\n typeof runtime.getEntityById === \"function\"\n ? await runtime.getEntityById(entityId as UUID)\n : null;\n const metadataUserId = extractSlackUserIdFromMetadata(\n entity?.metadata,\n accountId,\n );\n if (metadataUserId) {\n return metadataUserId;\n }\n\n if (typeof runtime.getRelationships !== \"function\") {\n return null;\n }\n\n const relationships = await runtime.getRelationships({\n entityIds: [entityId as UUID],\n tags: [\"identity_link\"],\n });\n for (const relationship of relationships) {\n const linkedEntityId =\n relationship.sourceEntityId === entityId\n ? relationship.targetEntityId\n : relationship.targetEntityId === entityId\n ? relationship.sourceEntityId\n : null;\n if (!linkedEntityId || linkedEntityId === entityId) {\n continue;\n }\n const linkedEntity =\n typeof runtime.getEntityById === \"function\"\n ? await runtime.getEntityById(linkedEntityId as UUID)\n : null;\n const linkedUserId = extractSlackUserIdFromMetadata(\n linkedEntity?.metadata,\n accountId,\n );\n if (linkedUserId) {\n return linkedUserId;\n }\n }\n\n return null;\n }\n\n private async openDirectMessageChannel(\n userId: string,\n accountId?: string | null,\n ): Promise<string> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n const result = await client.conversations.open({ users: userId });\n const channel = result.channel as { id?: string } | undefined;\n if (!channel?.id) {\n throw new Error(`Could not open Slack DM channel for user ${userId}`);\n }\n return channel.id;\n }\n\n async handleSendMessage(\n runtime: IAgentRuntime,\n target: TargetInfo,\n content: Content,\n ): Promise<void> {\n const accountId = await this.resolveAccountIdForTarget(runtime, target);\n if (!this.getClientForAccount(accountId)) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const text = typeof content.text === \"string\" ? content.text.trim() : \"\";\n if (!text) {\n throw new Error(\"Slack SendHandler requires non-empty text content.\");\n }\n\n let channelId = target.channelId;\n let threadTs = target.threadId;\n\n if (target.roomId && (!channelId || !threadTs)) {\n const room = await runtime.getRoom(target.roomId);\n channelId = channelId ?? room?.channelId;\n const metadata = room?.metadata as Record<string, unknown> | undefined;\n const metadataThreadTs =\n typeof metadata?.threadTs === \"string\" ? metadata.threadTs : undefined;\n threadTs = threadTs ?? metadataThreadTs;\n }\n\n if (channelId && SLACK_USER_ID_PATTERN.test(channelId)) {\n channelId = await this.openDirectMessageChannel(channelId, accountId);\n }\n\n if (!channelId && target.entityId) {\n const slackUserId = await this.resolveSlackTargetUserId(\n runtime,\n String(target.entityId),\n accountId,\n );\n if (!slackUserId) {\n throw new Error(\n `Could not resolve Slack user ID for entity ${target.entityId}`,\n );\n }\n channelId = await this.openDirectMessageChannel(slackUserId, accountId);\n }\n\n if (!channelId) {\n throw new Error(\n \"Slack SendHandler requires channelId, roomId, or entityId.\",\n );\n }\n\n await this.sendMessage(\n channelId,\n text,\n {\n threadTs,\n replyBroadcast: undefined,\n unfurlLinks: undefined,\n unfurlMedia: undefined,\n mrkdwn: undefined,\n attachments: undefined,\n blocks: undefined,\n },\n accountId,\n );\n }\n\n async resolveConnectorTargets(\n query: string,\n context: MessageConnectorQueryContext,\n ): Promise<MessageConnectorTarget[]> {\n const normalizedQuery = normalizeSlackConnectorQuery(query);\n const targets: MessageConnectorTarget[] = [];\n const accountIds = this.getCandidateAccountIds(context, context.target);\n\n for (const accountId of accountIds) {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n continue;\n }\n\n try {\n const channels = await this.listChannels(\n {\n types: \"public_channel,private_channel,mpim,im\",\n limit: 1000,\n },\n accountId,\n );\n for (const channel of channels) {\n const score = scoreSlackConnectorMatch(normalizedQuery, channel.id, [\n channel.name,\n channel.topic?.value,\n channel.purpose?.value,\n ]);\n if (score <= 0) {\n continue;\n }\n const target = this.buildConnectorChannelTarget(\n channel,\n score,\n accountId,\n );\n if (target) {\n targets.push(target);\n }\n }\n } catch (error) {\n this.runtime.logger.debug(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n accountId,\n error: error instanceof Error ? error.message : String(error),\n },\n \"Slack connector channel query failed\",\n );\n }\n\n try {\n const usersResult = await client.users.list({ limit: 200 });\n const members = (usersResult.members ?? []) as SlackApiUserMember[];\n for (const member of members) {\n const user: SlackUser = {\n id: member.id ?? \"\",\n teamId: member.team_id,\n name: member.name ?? \"\",\n deleted: Boolean(member.deleted),\n realName: member.real_name,\n tz: member.tz,\n tzLabel: member.tz_label,\n tzOffset: member.tz_offset,\n profile: {\n title: member.profile?.title,\n phone: member.profile?.phone,\n skype: member.profile?.skype,\n realName: member.profile?.real_name,\n realNameNormalized: member.profile?.real_name_normalized,\n displayName: member.profile?.display_name,\n displayNameNormalized: member.profile?.display_name_normalized,\n statusText: member.profile?.status_text,\n statusEmoji: member.profile?.status_emoji,\n statusExpiration: member.profile?.status_expiration,\n avatarHash: member.profile?.avatar_hash,\n email: member.profile?.email,\n image24: member.profile?.image_24,\n image32: member.profile?.image_32,\n image48: member.profile?.image_48,\n image72: member.profile?.image_72,\n image192: member.profile?.image_192,\n image512: member.profile?.image_512,\n image1024: member.profile?.image_1024,\n imageOriginal: member.profile?.image_original,\n team: member.profile?.team,\n },\n isAdmin: Boolean(member.is_admin),\n isOwner: Boolean(member.is_owner),\n isPrimaryOwner: Boolean(member.is_primary_owner),\n isRestricted: Boolean(member.is_restricted),\n isUltraRestricted: Boolean(member.is_ultra_restricted),\n isBot: Boolean(member.is_bot),\n isAppUser: Boolean(member.is_app_user),\n updated: member.updated ?? 0,\n };\n const score = scoreSlackConnectorMatch(normalizedQuery, user.id, [\n user.name,\n user.realName,\n user.profile.displayName,\n user.profile.realName,\n user.profile.email,\n ]);\n if (score <= 0) {\n continue;\n }\n const target = this.buildConnectorUserTarget(user, score, accountId);\n if (target) {\n targets.push(target);\n }\n }\n } catch (error) {\n this.runtime.logger.debug(\n {\n src: \"plugin:slack\",\n agentId: this.runtime.agentId,\n accountId,\n error: error instanceof Error ? error.message : String(error),\n },\n \"Slack connector user query failed\",\n );\n }\n\n if (context.target?.channelId) {\n const channel = await this.getChannel(\n context.target.channelId,\n accountId,\n );\n if (channel) {\n const target = this.buildConnectorChannelTarget(\n channel,\n 0.6,\n accountId,\n );\n if (target) {\n targets.push(target);\n }\n }\n }\n }\n\n return this.dedupeConnectorTargets(targets).slice(0, 25);\n }\n\n async listConnectorRooms(\n context: MessageConnectorQueryContext,\n ): Promise<MessageConnectorTarget[]> {\n const targets: MessageConnectorTarget[] = [];\n for (const accountId of this.getCandidateAccountIds(context)) {\n if (!this.getClientForAccount(accountId)) {\n continue;\n }\n const channels = await this.listChannels(\n {\n types: \"public_channel,private_channel,mpim,im\",\n limit: 1000,\n },\n accountId,\n );\n targets.push(\n ...channels\n .map((channel) =>\n this.buildConnectorChannelTarget(channel, 0.5, accountId),\n )\n .filter((target): target is MessageConnectorTarget =>\n Boolean(target),\n ),\n );\n }\n return this.dedupeConnectorTargets(targets).slice(0, 50);\n }\n\n async listRecentConnectorTargets(\n context: MessageConnectorQueryContext,\n ): Promise<MessageConnectorTarget[]> {\n const targets: MessageConnectorTarget[] = [];\n const room =\n context.roomId && typeof context.runtime.getRoom === \"function\"\n ? await context.runtime.getRoom(context.roomId)\n : null;\n const accountId = await this.resolveAccountIdForTarget(\n context.runtime,\n context.target,\n {\n accountId: (context as AccountScopedConnectorContext).accountId,\n roomId: context.roomId,\n },\n );\n const channelId =\n context.target?.channelId ??\n (room?.source === \"slack\" ? room.channelId : undefined);\n const roomMetadata = room?.metadata as Record<string, unknown> | undefined;\n const threadTs =\n context.target?.threadId ??\n (typeof roomMetadata?.threadTs === \"string\"\n ? roomMetadata.threadTs\n : undefined);\n\n if (channelId) {\n const channel = await this.getChannel(channelId, accountId);\n if (channel) {\n const target = this.buildConnectorChannelTarget(\n channel,\n 0.95,\n accountId,\n );\n if (target) {\n if (threadTs) {\n target.kind = \"thread\";\n target.target.threadId = threadTs;\n target.label = `${target.label ?? channelId} thread`;\n target.metadata = {\n ...(target.metadata ?? {}),\n slackThreadTs: threadTs,\n };\n }\n targets.push(target);\n }\n }\n }\n\n targets.push(\n ...(await this.listConnectorRooms({\n ...context,\n accountId,\n } as MessageConnectorQueryContext)),\n );\n return this.dedupeConnectorTargets(targets).slice(0, 25);\n }\n\n async getConnectorChatContext(\n target: TargetInfo,\n context: MessageConnectorQueryContext,\n ): Promise<MessageConnectorChatContext | null> {\n const accountId = await this.resolveAccountIdForTarget(\n context.runtime,\n target,\n {\n accountId: (context as AccountScopedConnectorContext).accountId,\n roomId: context.roomId,\n },\n );\n const client = this.getClientForAccount(accountId);\n if (!client) {\n return null;\n }\n\n const room =\n target.roomId && typeof context.runtime.getRoom === \"function\"\n ? await context.runtime.getRoom(target.roomId)\n : null;\n const channelId = target.channelId ?? room?.channelId;\n if (!channelId) {\n return null;\n }\n\n const metadata = room?.metadata as Record<string, unknown> | undefined;\n const threadTs =\n target.threadId ??\n (typeof metadata?.threadTs === \"string\" ? metadata.threadTs : undefined);\n const channel = await this.getChannel(channelId, accountId);\n\n const messages = threadTs\n ? await client.conversations.replies({\n channel: channelId,\n ts: threadTs,\n limit: 10,\n })\n : {\n messages: await this.readHistory(channelId, { limit: 10 }, accountId),\n };\n const rawMessages = (messages.messages ?? []) as Array<\n SlackMessage | Record<string, unknown>\n >;\n const recentMessages: MessageConnectorChatContext[\"recentMessages\"] = [];\n for (const rawMessage of rawMessages.slice().reverse()) {\n const text = String((rawMessage as SlackMessage).text ?? \"\");\n if (!text.trim()) {\n continue;\n }\n const userId =\n (rawMessage as SlackMessage).user ??\n (rawMessage as Record<string, string | undefined>).user;\n const user =\n typeof userId === \"string\"\n ? await this.getUser(userId, accountId)\n : null;\n recentMessages.push({\n entityId: userId ? (userId as UUID) : undefined,\n name: user ? getSlackUserDisplayName(user) : userId,\n text,\n timestamp: Number((rawMessage as SlackMessage).ts) * 1000 || undefined,\n metadata: {\n accountId,\n slackMessageTs: (rawMessage as SlackMessage).ts,\n slackUserId: userId,\n },\n });\n }\n\n return {\n target: {\n source: \"slack\",\n accountId,\n roomId: target.roomId ?? room?.id,\n channelId,\n serverId:\n target.serverId ?? this.getTeamIdForAccount(accountId) ?? undefined,\n threadId: threadTs,\n } as TargetInfo,\n label: channel?.name ? `#${channel.name}` : channelId,\n summary: channel?.purpose?.value || channel?.topic?.value,\n recentMessages,\n metadata: {\n accountId,\n slackChannelId: channelId,\n slackTeamId: this.getTeamIdForAccount(accountId),\n slackThreadTs: threadTs,\n channelName: channel?.name,\n },\n };\n }\n\n private async resolveConnectorMessageLocation(\n target?: TargetInfo | null,\n fallback?: ConnectorFetchMessagesParams,\n ): Promise<{ accountId: string; channelId: string; threadTs?: string }> {\n const accountId = await this.resolveAccountIdForTarget(\n this.runtime,\n target,\n fallback,\n );\n let channelId = target?.channelId ?? fallback?.channelId;\n let threadTs = target?.threadId ?? fallback?.threadId;\n const roomId = target?.roomId ?? fallback?.roomId;\n\n if (roomId && (!channelId || !threadTs)) {\n const room = await this.runtime.getRoom(roomId);\n channelId = channelId ?? room?.channelId;\n const metadata = room?.metadata as Record<string, unknown> | undefined;\n const roomThreadTs =\n typeof metadata?.threadTs === \"string\" ? metadata.threadTs : undefined;\n threadTs = threadTs ?? roomThreadTs;\n }\n\n if (channelId && SLACK_USER_ID_PATTERN.test(channelId)) {\n channelId = await this.openDirectMessageChannel(channelId, accountId);\n }\n\n if (!channelId && target?.entityId) {\n const slackUserId = await this.resolveSlackTargetUserId(\n this.runtime,\n String(target.entityId),\n accountId,\n );\n if (slackUserId) {\n channelId = await this.openDirectMessageChannel(slackUserId, accountId);\n }\n }\n\n if (!channelId) {\n throw new Error(\n \"Slack message operation requires channelId, roomId, or entityId.\",\n );\n }\n\n return { accountId, channelId, threadTs };\n }\n\n private async slackMessageToMemory(\n message: SlackMessage,\n channelId: string,\n threadTs?: string,\n accountId = this.defaultAccountId,\n ): Promise<Memory> {\n const effectiveThreadTs = threadTs ?? message.threadTs;\n const roomId = await this.getRoomId(\n channelId,\n effectiveThreadTs,\n accountId,\n );\n const botUserId = this.getBotUserIdForAccount(accountId);\n const slackUserId = message.user ?? botUserId ?? \"unknown\";\n const entityId =\n slackUserId === botUserId\n ? this.runtime.agentId\n : this.getEntityId(slackUserId, accountId);\n const user = message.user\n ? await this.getUser(message.user, accountId)\n : null;\n const displayName = user ? getSlackUserDisplayName(user) : slackUserId;\n const channel = await this.getChannel(channelId, accountId).catch(\n () => null,\n );\n const channelType = effectiveThreadTs\n ? ChannelType.THREAD\n : channel?.isIm\n ? ChannelType.DM\n : ChannelType.GROUP;\n\n const attachments: Media[] = (message.files ?? []).map((file) => ({\n id: file.id,\n url: file.urlPrivate,\n title: file.title || file.name,\n source: \"slack\",\n description: file.name,\n }));\n\n return {\n id: createUniqueUuid(\n this.runtime,\n this.scopedSlackKey(\"slack\", `${channelId}-${message.ts}`, accountId),\n ),\n agentId: this.runtime.agentId,\n roomId,\n entityId,\n content: {\n text: message.text || \"\",\n source: \"slack\",\n name: displayName,\n channelType,\n metadata: { accountId },\n ...(effectiveThreadTs && effectiveThreadTs !== message.ts\n ? {\n inReplyTo: createUniqueUuid(\n this.runtime,\n this.scopedSlackKey(\n \"slack\",\n `${channelId}-${effectiveThreadTs}`,\n accountId,\n ),\n ),\n }\n : {}),\n ...(attachments.length > 0 ? { attachments } : {}),\n },\n metadata: {\n type: \"message\",\n source: \"slack\",\n provider: \"slack\",\n accountId,\n timestamp: this.parseSlackTimestamp(message.ts),\n entityName: displayName,\n entityUserName: user?.name ?? slackUserId,\n fromBot: slackUserId === botUserId,\n fromId: slackUserId,\n sourceId: entityId,\n chatType: channelType,\n messageIdFull: message.ts,\n sender: {\n id: slackUserId,\n name: displayName,\n username: user?.name ?? slackUserId,\n },\n slack: {\n accountId,\n teamId: this.getTeamIdForAccount(accountId) ?? undefined,\n channelId,\n userId: slackUserId,\n messageId: message.ts,\n threadTs: effectiveThreadTs,\n },\n slackChannelId: channelId,\n slackMessageTs: message.ts,\n slackThreadTs: effectiveThreadTs,\n reactions: message.reactions,\n } satisfies Memory[\"metadata\"],\n createdAt: this.parseSlackTimestamp(message.ts),\n };\n }\n\n async listConnectorServers(\n context: MessageConnectorQueryContext,\n ): Promise<World[]> {\n const worlds: World[] = [];\n for (const accountId of this.getCandidateAccountIds(context)) {\n const teamId = this.getTeamIdForAccount(accountId);\n if (!teamId) {\n continue;\n }\n\n let name = `Slack Workspace ${teamId}`;\n try {\n const client = this.getClientForAccount(accountId);\n if (client) {\n const teamInfo = await client.team.info();\n const team = teamInfo.team as { name?: string } | undefined;\n name = team?.name || name;\n }\n } catch {\n // Best-effort metadata; the workspace id is still useful.\n }\n\n worlds.push({\n id: createUniqueUuid(\n this.runtime,\n this.scopedSlackKey(\"slack-workspace\", teamId, accountId),\n ),\n agentId: this.runtime.agentId,\n name,\n metadata: {\n source: \"slack\",\n accountId,\n teamId,\n },\n });\n }\n\n return worlds;\n }\n\n async fetchConnectorMessages(\n _context: MessageConnectorQueryContext,\n params: ConnectorFetchMessagesParams,\n ): Promise<Memory[]> {\n const accountId = await this.resolveAccountIdForTarget(\n _context.runtime,\n params.target,\n { accountId: params.accountId, roomId: params.roomId },\n );\n const client = this.getClientForAccount(accountId);\n if (!client) {\n return [];\n }\n\n const { channelId, threadTs } = await this.resolveConnectorMessageLocation(\n params.target,\n { ...params, accountId },\n );\n const limit = Number.isFinite(params.limit)\n ? Math.max(1, Math.min(Number(params.limit), 100))\n : 25;\n\n const rawMessages = threadTs\n ? (((\n await client.conversations.replies({\n channel: channelId,\n ts: threadTs,\n limit,\n latest: params.before,\n oldest: params.after,\n cursor: params.cursor,\n })\n ).messages as\n | Array<SlackMessage | Record<string, unknown>>\n | undefined) ?? [])\n : await this.readHistory(\n channelId,\n {\n limit,\n before: params.before,\n after: params.after,\n },\n accountId,\n );\n\n const memories: Memory[] = [];\n for (const rawMessage of rawMessages) {\n const message = rawMessage as SlackMessage;\n if (!message.ts) {\n continue;\n }\n memories.push(\n await this.slackMessageToMemory(\n message,\n channelId,\n threadTs,\n accountId,\n ),\n );\n }\n return memories.sort(\n (left, right) =>\n Number(right.createdAt ?? 0) - Number(left.createdAt ?? 0),\n );\n }\n\n async searchConnectorMessages(\n context: MessageConnectorQueryContext,\n params: ConnectorSearchMessagesParams,\n ): Promise<Memory[]> {\n const query = params.query?.trim().toLowerCase();\n if (!query) {\n return [];\n }\n\n const memories = await this.fetchConnectorMessages(context, {\n ...params,\n limit: Math.max(params.limit ?? 100, 100),\n });\n return memories\n .filter((memory) => {\n const text = String(memory.content?.text ?? \"\").toLowerCase();\n const name = String(memory.content?.name ?? \"\").toLowerCase();\n return text.includes(query) || name.includes(query);\n })\n .slice(0, params.limit ?? 25);\n }\n\n async reactConnectorMessage(\n _runtime: IAgentRuntime,\n params: ConnectorMessageMutationParams,\n ): Promise<void> {\n const { accountId, channelId } = await this.resolveConnectorMessageLocation(\n params.target,\n params,\n );\n const messageTs = params.messageTs ?? params.messageId;\n const emoji = params.emoji?.trim();\n if (!messageTs || !emoji) {\n throw new Error(\"Slack reaction requires messageId/messageTs and emoji.\");\n }\n if (params.remove) {\n await this.removeReaction(channelId, messageTs, emoji, accountId);\n return;\n }\n await this.sendReaction(channelId, messageTs, emoji, accountId);\n }\n\n async editConnectorMessage(\n _runtime: IAgentRuntime,\n params: ConnectorMessageMutationParams,\n ): Promise<Memory> {\n const { accountId, channelId, threadTs } =\n await this.resolveConnectorMessageLocation(params.target, params);\n const messageTs = params.messageTs ?? params.messageId;\n const text = params.content?.text ?? params.text;\n if (!messageTs || !text?.trim()) {\n throw new Error(\"Slack edit requires messageId/messageTs and text.\");\n }\n\n await this.editMessage(channelId, messageTs, text, accountId);\n return this.slackMessageToMemory(\n {\n type: \"message\",\n ts: messageTs,\n user: this.getBotUserIdForAccount(accountId) ?? undefined,\n text,\n threadTs,\n subtype: undefined,\n replyCount: undefined,\n replyUsersCount: undefined,\n latestReply: undefined,\n reactions: undefined,\n files: undefined,\n attachments: undefined,\n blocks: undefined,\n },\n channelId,\n threadTs,\n accountId,\n );\n }\n\n async deleteConnectorMessage(\n _runtime: IAgentRuntime,\n params: ConnectorMessageMutationParams,\n ): Promise<void> {\n const { accountId, channelId } = await this.resolveConnectorMessageLocation(\n params.target,\n params,\n );\n const messageTs = params.messageTs ?? params.messageId;\n if (!messageTs) {\n throw new Error(\"Slack delete requires messageId/messageTs.\");\n }\n await this.deleteMessage(channelId, messageTs, accountId);\n }\n\n async pinConnectorMessage(\n _runtime: IAgentRuntime,\n params: ConnectorMessageMutationParams,\n ): Promise<void> {\n const { accountId, channelId } = await this.resolveConnectorMessageLocation(\n params.target,\n params,\n );\n const messageTs = params.messageTs ?? params.messageId;\n if (!messageTs) {\n throw new Error(\"Slack pin requires messageId/messageTs.\");\n }\n if (params.pin === false) {\n await this.unpinMessage(channelId, messageTs, accountId);\n return;\n }\n await this.pinMessage(channelId, messageTs, accountId);\n }\n\n async getConnectorUser(\n runtime: IAgentRuntime,\n params: ConnectorUserLookupParams,\n ): Promise<unknown> {\n const accountId = normalizeAccountId(\n (params.target as AccountScopedTargetInfo | undefined)?.accountId ??\n this.defaultAccountId ??\n DEFAULT_ACCOUNT_ID,\n );\n const lookup =\n params.userId ?? params.handle ?? params.username ?? params.query;\n if (!lookup) {\n return null;\n }\n\n let slackUserId = SLACK_USER_ID_PATTERN.test(lookup)\n ? lookup\n : await this.resolveSlackTargetUserId(runtime, lookup, accountId);\n\n const client = this.getClientForAccount(accountId);\n if (!slackUserId && client) {\n const usersResult = await client.users.list({ limit: 200 });\n const members = (usersResult.members ?? []) as SlackApiUserMember[];\n const normalized = normalizeSlackConnectorQuery(lookup);\n const match = members.find((member) =>\n [\n member.id,\n member.name,\n member.real_name,\n member.profile?.display_name,\n member.profile?.email,\n ]\n .filter((value): value is string => Boolean(value))\n .some((value) =>\n normalizeSlackConnectorQuery(value).includes(normalized),\n ),\n );\n slackUserId = match?.id ?? null;\n }\n\n if (!slackUserId) {\n return null;\n }\n\n const user = await this.getUser(slackUserId, accountId);\n if (!user) {\n return null;\n }\n\n return {\n id: this.getEntityId(user.id, accountId),\n agentId: this.runtime.agentId,\n names: [getSlackUserDisplayName(user), user.name, user.realName].filter(\n (value): value is string => Boolean(value),\n ),\n metadata: {\n source: \"slack\",\n accountId,\n slack: {\n accountId,\n id: user.id,\n teamId: user.teamId ?? this.getTeamIdForAccount(accountId),\n name: user.name,\n realName: user.realName,\n profile: { ...user.profile },\n },\n },\n };\n }\n\n async getConnectorUserContext(\n entityId: UUID | string,\n context: MessageConnectorQueryContext,\n ): Promise<MessageConnectorUserContext | null> {\n const accountId = normalizeAccountId(\n (context.target as AccountScopedTargetInfo | undefined)?.accountId ??\n (context as AccountScopedConnectorContext).accountId ??\n (context as AccountScopedConnectorContext).account?.accountId ??\n this.defaultAccountId ??\n DEFAULT_ACCOUNT_ID,\n );\n const slackUserId = await this.resolveSlackTargetUserId(\n context.runtime,\n String(entityId),\n accountId,\n );\n if (!slackUserId) {\n return null;\n }\n const user = await this.getUser(slackUserId, accountId);\n if (!user) {\n return null;\n }\n\n return {\n entityId,\n label: getSlackUserDisplayName(user),\n aliases: [\n user.name,\n user.realName,\n user.profile.displayName,\n user.profile.realName,\n user.profile.email,\n ].filter((value): value is string => Boolean(value)),\n handles: {\n slack: user.id,\n ...(user.profile.email ? { email: user.profile.email } : {}),\n },\n metadata: {\n accountId,\n slackUserId: user.id,\n slackTeamId: user.teamId ?? this.getTeamIdForAccount(accountId),\n profile: { ...user.profile },\n },\n };\n }\n\n async getUser(\n userId: string,\n accountId?: string | null,\n ): Promise<SlackUser | null> {\n const userCache = this.getUserCacheForAccount(accountId);\n // Check cache first\n const cachedUser = userCache.get(userId);\n if (cachedUser) {\n return cachedUser;\n }\n\n const client = this.getClientForAccount(accountId);\n if (!client) return null;\n\n const result = await client.users.info({ user: userId });\n if (!result.user) return null;\n\n const user: SlackUser = {\n id: result.user.id ?? userId,\n teamId: result.user.team_id,\n name: result.user.name ?? \"\",\n deleted: result.user.deleted || false,\n realName: result.user.real_name,\n tz: result.user.tz,\n tzLabel: result.user.tz_label,\n tzOffset: result.user.tz_offset,\n profile: {\n title: result.user.profile?.title,\n phone: result.user.profile?.phone,\n skype: result.user.profile?.skype,\n realName: result.user.profile?.real_name,\n realNameNormalized: result.user.profile?.real_name_normalized,\n displayName: result.user.profile?.display_name,\n displayNameNormalized: result.user.profile?.display_name_normalized,\n statusText: result.user.profile?.status_text,\n statusEmoji: result.user.profile?.status_emoji,\n statusExpiration: result.user.profile?.status_expiration,\n avatarHash: result.user.profile?.avatar_hash,\n email: result.user.profile?.email,\n image24: result.user.profile?.image_24,\n image32: result.user.profile?.image_32,\n image48: result.user.profile?.image_48,\n image72: result.user.profile?.image_72,\n image192: result.user.profile?.image_192,\n image512: result.user.profile?.image_512,\n image1024: result.user.profile?.image_1024,\n imageOriginal: result.user.profile?.image_original,\n team: result.user.profile?.team,\n },\n isAdmin: result.user.is_admin || false,\n isOwner: result.user.is_owner || false,\n isPrimaryOwner: result.user.is_primary_owner || false,\n isRestricted: result.user.is_restricted || false,\n isUltraRestricted: result.user.is_ultra_restricted || false,\n isBot: result.user.is_bot || false,\n isAppUser: result.user.is_app_user || false,\n updated: result.user.updated || 0,\n };\n\n userCache.set(userId, user);\n return user;\n }\n\n async getChannel(\n channelId: string,\n accountId?: string | null,\n ): Promise<SlackChannel | null> {\n const channelCache = this.getChannelCacheForAccount(accountId);\n // Check cache first\n const cachedChannel = channelCache.get(channelId);\n if (cachedChannel) {\n return cachedChannel;\n }\n\n const client = this.getClientForAccount(accountId);\n if (!client) return null;\n\n const result = await client.conversations.info({ channel: channelId });\n if (!result.channel) return null;\n\n const channel: SlackChannel = {\n id: (result.channel as { id: string }).id,\n name: (result.channel as { name: string }).name || \"\",\n isChannel:\n (result.channel as { is_channel?: boolean }).is_channel || false,\n isGroup: (result.channel as { is_group?: boolean }).is_group || false,\n isIm: (result.channel as { is_im?: boolean }).is_im || false,\n isMpim: (result.channel as { is_mpim?: boolean }).is_mpim || false,\n isPrivate:\n (result.channel as { is_private?: boolean }).is_private || false,\n isArchived:\n (result.channel as { is_archived?: boolean }).is_archived || false,\n isGeneral:\n (result.channel as { is_general?: boolean }).is_general || false,\n isShared: (result.channel as { is_shared?: boolean }).is_shared || false,\n isOrgShared:\n (result.channel as { is_org_shared?: boolean }).is_org_shared || false,\n isMember: (result.channel as { is_member?: boolean }).is_member || false,\n topic: (\n result.channel as {\n topic?: { value: string; creator: string; last_set: number };\n }\n ).topic\n ? {\n value: (result.channel as { topic: { value: string } }).topic.value,\n creator: (result.channel as { topic: { creator: string } }).topic\n .creator,\n lastSet: (result.channel as { topic: { last_set: number } }).topic\n .last_set,\n }\n : undefined,\n purpose: (\n result.channel as {\n purpose?: { value: string; creator: string; last_set: number };\n }\n ).purpose\n ? {\n value: (result.channel as { purpose: { value: string } }).purpose\n .value,\n creator: (result.channel as { purpose: { creator: string } })\n .purpose.creator,\n lastSet: (result.channel as { purpose: { last_set: number } })\n .purpose.last_set,\n }\n : undefined,\n numMembers: (result.channel as { num_members?: number }).num_members,\n created: (result.channel as { created: number }).created,\n creator: (result.channel as { creator: string }).creator,\n };\n\n channelCache.set(channelId, channel);\n return channel;\n }\n\n async sendMessage(\n channelId: string,\n text: string,\n options?: SlackMessageSendOptions,\n accountId?: string | null,\n ): Promise<{ ts: string; channelId: string }> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n // Split message if too long\n const convertedText = markdownToSlackMrkdwn(text);\n const messages = this.splitMessage(convertedText);\n let lastTs = \"\";\n\n for (const msg of messages) {\n const result = await client.chat.postMessage({\n channel: channelId,\n text: msg,\n thread_ts: options?.threadTs,\n reply_broadcast: options?.replyBroadcast,\n unfurl_links: options?.unfurlLinks,\n unfurl_media: options?.unfurlMedia,\n mrkdwn: options?.mrkdwn ?? true,\n attachments: options?.attachments as never,\n blocks: options?.blocks as never,\n });\n\n lastTs = result.ts as string;\n }\n\n return { ts: lastTs, channelId };\n }\n\n async sendReaction(\n channelId: string,\n messageTs: string,\n emoji: string,\n accountId?: string | null,\n ): Promise<void> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n // Remove colons if present\n const cleanEmoji = emoji.replace(/^:/, \"\").replace(/:$/, \"\");\n\n await client.reactions.add({\n channel: channelId,\n timestamp: messageTs,\n name: cleanEmoji,\n });\n }\n\n async removeReaction(\n channelId: string,\n messageTs: string,\n emoji: string,\n accountId?: string | null,\n ): Promise<void> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const cleanEmoji = emoji.replace(/^:/, \"\").replace(/:$/, \"\");\n\n await client.reactions.remove({\n channel: channelId,\n timestamp: messageTs,\n name: cleanEmoji,\n });\n }\n\n async editMessage(\n channelId: string,\n messageTs: string,\n text: string,\n accountId?: string | null,\n ): Promise<void> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n await client.chat.update({\n channel: channelId,\n ts: messageTs,\n text,\n });\n }\n\n async deleteMessage(\n channelId: string,\n messageTs: string,\n accountId?: string | null,\n ): Promise<void> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n await client.chat.delete({\n channel: channelId,\n ts: messageTs,\n });\n }\n\n async pinMessage(\n channelId: string,\n messageTs: string,\n accountId?: string | null,\n ): Promise<void> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n await client.pins.add({\n channel: channelId,\n timestamp: messageTs,\n });\n }\n\n async unpinMessage(\n channelId: string,\n messageTs: string,\n accountId?: string | null,\n ): Promise<void> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n await client.pins.remove({\n channel: channelId,\n timestamp: messageTs,\n });\n }\n\n async listPins(\n channelId: string,\n accountId?: string | null,\n ): Promise<SlackMessage[]> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const result = await client.pins.list({ channel: channelId });\n\n return (result.items || [])\n .filter(\n (item): item is { type: \"message\"; message: Record<string, unknown> } =>\n item.type === \"message\" && \"message\" in item && !!item.message,\n )\n .map((item) => ({\n type: item.message.type as string,\n subtype: item.message.subtype as string | undefined,\n ts: item.message.ts as string,\n user: item.message.user as string | undefined,\n text: item.message.text as string,\n threadTs: item.message.thread_ts as string | undefined,\n replyCount: item.message.reply_count as number | undefined,\n replyUsersCount: item.message.reply_users_count as number | undefined,\n latestReply: item.message.latest_reply as string | undefined,\n reactions: item.message.reactions as\n | { name: string; count: number; users: string[] }[]\n | undefined,\n files: item.message.files as SlackFile[] | undefined,\n attachments: item.message.attachments as SlackAttachment[] | undefined,\n blocks: item.message.blocks as SlackBlock[] | undefined,\n }));\n }\n\n async readHistory(\n channelId: string,\n options?: { limit?: number; before?: string; after?: string },\n accountId?: string | null,\n ): Promise<SlackMessage[]> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const result = await client.conversations.history({\n channel: channelId,\n limit: options?.limit || 100,\n latest: options?.before,\n oldest: options?.after,\n });\n\n return (result.messages || []).map((msg) => ({\n type: msg.type as string,\n subtype: msg.subtype as string | undefined,\n ts: msg.ts as string,\n user: msg.user as string | undefined,\n text: msg.text as string,\n threadTs: msg.thread_ts as string | undefined,\n replyCount: msg.reply_count as number | undefined,\n replyUsersCount: msg.reply_users_count as number | undefined,\n latestReply: msg.latest_reply as string | undefined,\n reactions: msg.reactions as\n | { name: string; count: number; users: string[] }[]\n | undefined,\n files: msg.files as SlackFile[] | undefined,\n attachments: msg.attachments as SlackAttachment[] | undefined,\n blocks: msg.blocks as SlackBlock[] | undefined,\n }));\n }\n\n async listChannels(\n options?: {\n types?: string;\n limit?: number;\n },\n accountId?: string | null,\n ): Promise<SlackChannel[]> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const result = await client.conversations.list({\n types: options?.types || \"public_channel,private_channel\",\n limit: options?.limit || 1000,\n });\n\n return (result.channels || []).map((ch) => ({\n id: ch.id ?? \"\",\n name: ch.name || \"\",\n isChannel: ch.is_channel || false,\n isGroup: ch.is_group || false,\n isIm: ch.is_im || false,\n isMpim: ch.is_mpim || false,\n isPrivate: ch.is_private || false,\n isArchived: ch.is_archived || false,\n isGeneral: ch.is_general || false,\n isShared: ch.is_shared || false,\n isOrgShared: ch.is_org_shared || false,\n isMember: ch.is_member || false,\n topic: ch.topic\n ? {\n value: ch.topic.value ?? \"\",\n creator: ch.topic.creator ?? \"\",\n lastSet: ch.topic.last_set ?? 0,\n }\n : undefined,\n purpose: ch.purpose\n ? {\n value: ch.purpose.value ?? \"\",\n creator: ch.purpose.creator ?? \"\",\n lastSet: ch.purpose.last_set ?? 0,\n }\n : undefined,\n numMembers: ch.num_members,\n created: ch.created || 0,\n creator: ch.creator || \"\",\n }));\n }\n\n async getEmojiList(\n accountId?: string | null,\n ): Promise<Record<string, string>> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const result = await client.emoji.list();\n return (result.emoji || {}) as Record<string, string>;\n }\n\n async uploadFile(\n channelId: string,\n content: Buffer | string,\n filename: string,\n options?: { title?: string; initialComment?: string; threadTs?: string },\n accountId?: string | null,\n ): Promise<{ fileId: string; permalink: string }> {\n const client = this.getClientForAccount(accountId);\n if (!client) {\n throw new Error(\"Slack client not initialized\");\n }\n\n const result = await client.files.uploadV2({\n channel_id: channelId,\n content: typeof content === \"string\" ? content : undefined,\n file: typeof content !== \"string\" ? content : undefined,\n filename,\n title: options?.title,\n initial_comment: options?.initialComment,\n thread_ts: options?.threadTs,\n });\n\n const resultWithFile = result as WebAPICallResult & {\n file?: { id: string; permalink: string };\n };\n const file = resultWithFile.file;\n return {\n fileId: file?.id || \"\",\n permalink: file?.permalink || \"\",\n };\n }\n\n private splitMessage(text: string): string[] {\n if (text.length <= MAX_SLACK_MESSAGE_LENGTH) {\n return [text];\n }\n\n const messages: string[] = [];\n let remaining = text;\n\n while (remaining.length > 0) {\n if (remaining.length <= MAX_SLACK_MESSAGE_LENGTH) {\n messages.push(remaining);\n break;\n }\n\n // Find a good split point (prefer newlines, then spaces)\n let splitIndex = MAX_SLACK_MESSAGE_LENGTH;\n\n const lastNewline = remaining.lastIndexOf(\"\\n\", MAX_SLACK_MESSAGE_LENGTH);\n if (lastNewline > MAX_SLACK_MESSAGE_LENGTH / 2) {\n splitIndex = lastNewline + 1;\n } else {\n const lastSpace = remaining.lastIndexOf(\" \", MAX_SLACK_MESSAGE_LENGTH);\n if (lastSpace > MAX_SLACK_MESSAGE_LENGTH / 2) {\n splitIndex = lastSpace + 1;\n }\n }\n\n messages.push(remaining.slice(0, splitIndex));\n remaining = remaining.slice(splitIndex);\n }\n\n return messages;\n }\n\n /**\n * Add a channel to the dynamic allowed list\n */\n addAllowedChannel(channelId: string, accountId?: string | null): void {\n if (isValidChannelId(channelId)) {\n this.getDynamicChannelIdsForAccount(accountId).add(channelId);\n }\n }\n\n /**\n * Remove a channel from the dynamic allowed list\n */\n removeAllowedChannel(channelId: string, accountId?: string | null): void {\n this.getDynamicChannelIdsForAccount(accountId).delete(channelId);\n }\n\n /**\n * Get all currently allowed channel IDs\n */\n getAllowedChannelIds(accountId?: string | null): string[] {\n return [\n ...this.getAllowedChannelIdsForAccount(accountId),\n ...this.getDynamicChannelIdsForAccount(accountId),\n ];\n }\n\n /**\n * Check if the service is connected\n */\n isServiceConnected(): boolean {\n return this.isConnected && this.app !== null;\n }\n\n /**\n * Get the bot's user ID\n */\n getBotUserId(): string | null {\n return this.botUserId;\n }\n\n /**\n * Get the team/workspace ID\n */\n getTeamId(): string | null {\n return this.teamId;\n }\n\n /**\n * Clear the user cache\n */\n clearUserCache(): void {\n this.userCache.clear();\n }\n\n /**\n * Clear the channel cache\n */\n clearChannelCache(): void {\n this.channelCache.clear();\n }\n}\n",
|
|
11
|
+
"import type { SlackChannel, SlackUser } from \"./types\";\n\n/**\n * Escape special characters for Slack mrkdwn format\n * Preserves Slack's angle-bracket tokens so mentions and links stay intact\n */\nfunction escapeSlackMrkdwnSegment(text: string): string {\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n}\n\nconst SLACK_ANGLE_TOKEN_RE = /<[^>\\n]+>/g;\n\n/**\n * Checks if an angle-bracket token is an allowed Slack format\n */\nfunction isAllowedSlackAngleToken(token: string): boolean {\n if (!token.startsWith(\"<\") || !token.endsWith(\">\")) {\n return false;\n }\n const inner = token.slice(1, -1);\n return (\n inner.startsWith(\"@\") ||\n inner.startsWith(\"#\") ||\n inner.startsWith(\"!\") ||\n inner.startsWith(\"mailto:\") ||\n inner.startsWith(\"tel:\") ||\n inner.startsWith(\"http://\") ||\n inner.startsWith(\"https://\") ||\n inner.startsWith(\"slack://\")\n );\n}\n\n/**\n * Escapes Slack mrkdwn content while preserving valid Slack tokens\n */\nfunction escapeSlackMrkdwnContent(text: string): string {\n if (!text.includes(\"&\") && !text.includes(\"<\") && !text.includes(\">\")) {\n return text;\n }\n\n SLACK_ANGLE_TOKEN_RE.lastIndex = 0;\n const out: string[] = [];\n let lastIndex = 0;\n\n for (\n let match = SLACK_ANGLE_TOKEN_RE.exec(text);\n match;\n match = SLACK_ANGLE_TOKEN_RE.exec(text)\n ) {\n const matchIndex = match.index ?? 0;\n out.push(escapeSlackMrkdwnSegment(text.slice(lastIndex, matchIndex)));\n const token = match[0] ?? \"\";\n out.push(\n isAllowedSlackAngleToken(token) ? token : escapeSlackMrkdwnSegment(token),\n );\n lastIndex = matchIndex + token.length;\n }\n\n out.push(escapeSlackMrkdwnSegment(text.slice(lastIndex)));\n return out.join(\"\");\n}\n\n/**\n * Escapes Slack mrkdwn text, handling blockquotes specially\n */\nexport function escapeSlackMrkdwn(text: string): string {\n if (!text.includes(\"&\") && !text.includes(\"<\") && !text.includes(\">\")) {\n return text;\n }\n\n return text\n .split(\"\\n\")\n .map((line) => {\n if (line.startsWith(\"> \")) {\n return `> ${escapeSlackMrkdwnContent(line.slice(2))}`;\n }\n return escapeSlackMrkdwnContent(line);\n })\n .join(\"\\n\");\n}\n\n// Placeholder used during conversion to prevent bold from being matched as italic\nconst BOLD_PLACEHOLDER = \"\\u0000BOLD\\u0000\";\n\n/**\n * Converts markdown bold to Slack mrkdwn\n * Uses placeholder to prevent bold from being matched by italic converter\n */\nfunction convertBold(text: string): string {\n return text.replace(\n /\\*\\*(.+?)\\*\\*/g,\n `${BOLD_PLACEHOLDER}$1${BOLD_PLACEHOLDER}`,\n );\n}\n\n/**\n * Converts markdown italic to Slack mrkdwn\n */\nfunction convertItalic(text: string): string {\n // Markdown uses single * for italic, Slack uses _\n // Then restore bold placeholders to actual asterisks\n const converted = text.replace(\n /(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g,\n \"_$1_\",\n );\n return converted.replace(new RegExp(BOLD_PLACEHOLDER, \"g\"), \"*\");\n}\n\n/**\n * Converts markdown strikethrough to Slack mrkdwn\n */\nfunction convertStrikethrough(text: string): string {\n return text.replace(/~~(.+?)~~/g, \"~$1~\");\n}\n\n/**\n * Converts markdown code blocks to Slack mrkdwn\n */\nfunction convertCodeBlocks(text: string): string {\n // Slack code blocks don't support language hints in the same way\n return text.replace(/```(\\w*)\\n?([\\s\\S]*?)```/g, \"```\\n$2```\");\n}\n\n/**\n * Converts markdown links to Slack mrkdwn links\n */\nfunction convertLinks(text: string): string {\n return text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (_, linkText, url) => {\n const trimmedUrl = url.trim();\n const trimmedText = linkText.trim();\n // If link text matches URL, just use URL\n if (\n trimmedText === trimmedUrl ||\n trimmedText === trimmedUrl.replace(/^mailto:/, \"\")\n ) {\n return `<${escapeSlackMrkdwnSegment(trimmedUrl)}>`;\n }\n return `<${escapeSlackMrkdwnSegment(trimmedUrl)}|${escapeSlackMrkdwnSegment(trimmedText)}>`;\n });\n}\n\n/**\n * Converts markdown headings to Slack mrkdwn (bold text)\n * Uses placeholder to prevent headings from being matched by italic converter\n */\nfunction convertHeadings(text: string): string {\n return text.replace(\n /^#{1,6}\\s+(.+)$/gm,\n `${BOLD_PLACEHOLDER}$1${BOLD_PLACEHOLDER}`,\n );\n}\n\n/**\n * Converts markdown to Slack mrkdwn format\n */\nexport function markdownToSlackMrkdwn(markdown: string): string {\n if (!markdown) {\n return \"\";\n }\n\n // Process in order: code blocks -> links -> headings -> text styles -> escape\n let result = convertCodeBlocks(markdown);\n result = convertLinks(result);\n result = convertHeadings(result);\n result = convertBold(result);\n result = convertItalic(result);\n result = convertStrikethrough(result);\n result = escapeSlackMrkdwn(result);\n\n return result;\n}\n\n/**\n * Options for chunking Slack text\n */\nexport interface ChunkSlackTextOpts {\n /** Max characters per message. Default: 4000 */\n maxChars?: number;\n}\n\nconst DEFAULT_MAX_CHARS = 4000;\n\n/**\n * Chunks Slack text while preserving code blocks\n */\nexport function chunkSlackText(\n text: string,\n maxChars: number = DEFAULT_MAX_CHARS,\n): string[] {\n if (!text) {\n return [];\n }\n\n if (text.length <= maxChars) {\n return [text];\n }\n\n const chunks: string[] = [];\n let remaining = text;\n let inCodeBlock = false;\n\n while (remaining.length > 0) {\n if (remaining.length <= maxChars) {\n chunks.push(remaining);\n break;\n }\n\n // Find a good break point\n let breakPoint = maxChars;\n\n // Check if we're in a code block\n const codeBlockCount = (remaining.slice(0, maxChars).match(/```/g) || [])\n .length;\n inCodeBlock = codeBlockCount % 2 !== 0;\n\n // Try to break at a newline\n const newlineIndex = remaining.lastIndexOf(\"\\n\", maxChars);\n if (newlineIndex > maxChars * 0.5) {\n breakPoint = newlineIndex + 1;\n } else {\n // Try to break at a space\n const spaceIndex = remaining.lastIndexOf(\" \", maxChars);\n if (spaceIndex > maxChars * 0.5) {\n breakPoint = spaceIndex + 1;\n }\n }\n\n let chunk = remaining.slice(0, breakPoint);\n\n // If we're breaking inside a code block, close it\n if (inCodeBlock) {\n chunk += \"\\n```\";\n }\n\n chunks.push(chunk);\n\n remaining = remaining.slice(breakPoint);\n\n // If we were in a code block, reopen it\n if (inCodeBlock) {\n remaining = `\\`\\`\\`\\n${remaining}`;\n }\n }\n\n return chunks;\n}\n\n/**\n * Converts markdown to Slack mrkdwn and splits into chunks\n */\nexport function markdownToSlackMrkdwnChunks(\n markdown: string,\n limit: number,\n): string[] {\n return chunkSlackText(markdownToSlackMrkdwn(markdown), limit);\n}\n\n/**\n * Formats a Slack user mention\n */\nexport function formatSlackUserMention(userId: string): string {\n return `<@${userId}>`;\n}\n\n/**\n * Formats a Slack channel mention\n */\nexport function formatSlackChannelMention(channelId: string): string {\n return `<#${channelId}>`;\n}\n\n/**\n * Formats a Slack user group mention\n */\nexport function formatSlackUserGroupMention(groupId: string): string {\n return `<!subteam^${groupId}>`;\n}\n\n/**\n * Formats a Slack special mention (@here, @channel, @everyone)\n */\nexport function formatSlackSpecialMention(\n type: \"here\" | \"channel\" | \"everyone\",\n): string {\n return `<!${type}>`;\n}\n\n/**\n * Formats a Slack link\n */\nexport function formatSlackLink(url: string, text?: string): string {\n const safeUrl = escapeSlackMrkdwnSegment(url);\n if (text && text !== url) {\n return `<${safeUrl}|${escapeSlackMrkdwnSegment(text)}>`;\n }\n return `<${safeUrl}>`;\n}\n\n/**\n * Formats a Slack date\n */\nexport function formatSlackDate(\n timestamp: number | Date,\n format: string = \"{date_short_pretty} at {time}\",\n fallbackText?: string,\n): string {\n const unix = Math.floor(\n (typeof timestamp === \"number\" ? timestamp : timestamp.getTime()) / 1000,\n );\n const fallback = fallbackText || new Date(unix * 1000).toISOString();\n return `<!date^${unix}^${format}|${fallback}>`;\n}\n\n/**\n * Extracts user ID from a Slack mention\n */\nexport function extractUserIdFromMention(mention: string): string | null {\n const match = mention.match(/^<@([UW][A-Z0-9]+)(?:\\|[^>]*)?>$/i);\n return match ? match[1] : null;\n}\n\n/**\n * Extracts channel ID from a Slack mention\n */\nexport function extractChannelIdFromMention(mention: string): string | null {\n const match = mention.match(/^<#([CGD][A-Z0-9]+)(?:\\|[^>]*)?>$/i);\n return match ? match[1] : null;\n}\n\n/**\n * Extracts URL from a Slack link\n */\nexport function extractUrlFromSlackLink(link: string): string | null {\n const match = link.match(/^<(https?:\\/\\/[^|>]+)(?:\\|[^>]*)?>$/);\n return match ? match[1] : null;\n}\n\n/**\n * Formats a user's display name\n */\nexport function formatSlackUserDisplayName(user: SlackUser): string {\n return user.profile.displayName || user.profile.realName || user.name;\n}\n\n/**\n * Formats a channel for display\n */\nexport function formatSlackChannel(channel: SlackChannel): string {\n if (channel.isIm) {\n return \"Direct Message\";\n }\n if (channel.isMpim) {\n return `Group DM: ${channel.name}`;\n }\n return `#${channel.name}`;\n}\n\n/**\n * Gets the channel type as a human-readable string\n */\nexport function getChannelTypeString(channel: SlackChannel): string {\n if (channel.isIm) {\n return \"DM\";\n }\n if (channel.isMpim) {\n return \"Group DM\";\n }\n if (channel.isPrivate || channel.isGroup) {\n return \"Private Channel\";\n }\n return \"Channel\";\n}\n\n/**\n * Resolves the system location string for logging/display\n */\nexport function resolveSlackSystemLocation(\n channel: SlackChannel,\n teamName?: string,\n): string {\n const channelType = getChannelTypeString(channel);\n const channelName = formatSlackChannel(channel);\n if (teamName) {\n return `${teamName} - ${channelType}: ${channelName}`;\n }\n return `${channelType}: ${channelName}`;\n}\n\n/**\n * Checks if a channel is a direct message\n */\nexport function isDirectMessage(channel: SlackChannel): boolean {\n return channel.isIm;\n}\n\n/**\n * Checks if a channel is a group DM (multi-party IM)\n */\nexport function isGroupDm(channel: SlackChannel): boolean {\n return channel.isMpim;\n}\n\n/**\n * Checks if a channel is a private channel\n */\nexport function isPrivateChannel(channel: SlackChannel): boolean {\n return channel.isPrivate || channel.isGroup;\n}\n\n/**\n * Truncates text to a maximum length with an ellipsis\n */\nexport function truncateText(\n text: string,\n maxLength: number,\n ellipsis = \"…\",\n): string {\n if (text.length <= maxLength) {\n return text;\n }\n return text.slice(0, maxLength - ellipsis.length) + ellipsis;\n}\n\n/**\n * Strips Slack mrkdwn formatting from text\n */\nexport function stripSlackFormatting(text: string): string {\n return text\n .replace(/```[\\s\\S]*?```/g, \"\") // Code blocks (must be before inline code)\n .replace(/\\*([^*]+)\\*/g, \"$1\") // Bold\n .replace(/_([^_]+)_/g, \"$1\") // Italic\n .replace(/~([^~]+)~/g, \"$1\") // Strikethrough\n .replace(/`([^`]+)`/g, \"$1\") // Inline code\n .replace(/<@[UW][A-Z0-9]+(?:\\|[^>]*)?>/gi, \"\") // User mentions\n .replace(/<#[CGD][A-Z0-9]+(?:\\|[^>]*)?>/gi, \"\") // Channel mentions\n .replace(/<!subteam\\^[A-Z0-9]+(?:\\|[^>]*)?>/gi, \"\") // User group mentions\n .replace(/<!(?:here|channel|everyone)(?:\\|[^>]*)?>/gi, \"\") // Special mentions\n .replace(/<(https?:\\/\\/[^|>]+)(?:\\|([^>]*))?>/, \"$2\") // Links with text\n .replace(/<(https?:\\/\\/[^>]+)>/, \"$1\") // Plain links\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .trim();\n}\n\n/**\n * Builds a Slack message permalink\n */\nexport function buildSlackMessagePermalink(\n workspaceDomain: string,\n channelId: string,\n messageTs: string,\n): string {\n const formattedTs = `p${messageTs.replace(\".\", \"\")}`;\n return `https://${workspaceDomain}.slack.com/archives/${channelId}/${formattedTs}`;\n}\n\n/**\n * Parses a Slack message permalink\n */\nexport function parseSlackMessagePermalink(\n link: string,\n): { workspaceDomain: string; channelId: string; messageTs: string } | null {\n const match = link.match(\n /^https?:\\/\\/([^.]+)\\.slack\\.com\\/archives\\/([CGD][A-Z0-9]+)\\/p(\\d+)/i,\n );\n if (!match) {\n return null;\n }\n\n const ts = match[3];\n // Convert p1234567890123456 to 1234567890.123456\n const messageTs = `${ts.slice(0, 10)}.${ts.slice(10)}`;\n\n return {\n workspaceDomain: match[1],\n channelId: match[2],\n messageTs,\n };\n}\n",
|
|
12
|
+
"import { type IAgentRuntime, Service } from \"@elizaos/core\";\n\n// Inlined to avoid adding @elizaos/plugin-workflow as a compile-time dependency.\n// The runtime duck-types the service — only the serviceType string and resolve() shape matter.\nconst WORKFLOW_CREDENTIAL_PROVIDER_TYPE = \"workflow_credential_provider\";\ntype CredentialProviderResult =\n | { status: \"credential_data\"; data: Record<string, unknown> }\n | { status: \"needs_auth\"; authUrl: string }\n | null;\n\nconst SUPPORTED = [\"slackApi\", \"slackOAuth2Api\"];\n\nexport class SlackWorkflowCredentialProvider extends Service {\n static override readonly serviceType = WORKFLOW_CREDENTIAL_PROVIDER_TYPE;\n override capabilityDescription =\n \"Supplies Slack credentials to the workflow plugin.\";\n\n static async start(\n runtime: IAgentRuntime,\n ): Promise<SlackWorkflowCredentialProvider> {\n return new SlackWorkflowCredentialProvider(runtime);\n }\n\n async stop(): Promise<void> {}\n\n async resolve(\n _userId: string,\n credType: string,\n ): Promise<CredentialProviderResult> {\n // slackApi takes a bot token (xoxb-) for the legacy credential type.\n // slackOAuth2Api takes a user OAuth token (xoxp-) — NOT the Socket Mode app token (xapp-).\n // SLACK_APP_TOKEN is xapp- and only usable for Socket Mode WebSocket connections; it has no\n // API scopes, so wiring it as an OAuth2 access token would yield invalid_auth at execution.\n const botToken = this.runtime.getSetting(\"SLACK_BOT_TOKEN\") as\n | string\n | undefined;\n const userToken = this.runtime.getSetting(\"SLACK_USER_TOKEN\") as\n | string\n | undefined;\n if (credType === \"slackApi\" && botToken?.trim()) {\n return {\n status: \"credential_data\",\n data: { accessToken: botToken.trim() },\n };\n }\n if (credType === \"slackOAuth2Api\" && userToken?.trim()) {\n return {\n status: \"credential_data\",\n data: { accessToken: userToken.trim() },\n };\n }\n return null;\n }\n\n checkCredentialTypes(credTypes: string[]): {\n supported: string[];\n unsupported: string[];\n } {\n return {\n supported: credTypes.filter((t) => SUPPORTED.includes(t)),\n unsupported: credTypes.filter((t) => !SUPPORTED.includes(t)),\n };\n }\n}\n"
|
|
24
13
|
],
|
|
25
|
-
"mappings": "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",
|
|
26
|
-
"debugId": "
|
|
14
|
+
"mappings": "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",
|
|
15
|
+
"debugId": "3501C22F83015CAC64756E2164756E21",
|
|
27
16
|
"names": []
|
|
28
17
|
}
|