import { ConversationsInfoResponse, TeamInfoResponse, UsersInfoResponse, WebClient } from "@slack/web-api"; import * as ai0 from "ai"; import { UIMessage } from "ai"; import { App, KnownEventFromType } from "@slack/bolt"; import { LogLevel } from "@slack/logger"; import { AnyBlock, GenericMessageEvent, RichTextChannelMention, RichTextTeamMention, RichTextUserMention, RichTextUsergroupMention } from "@slack/types"; import { AssistantAppThreadBlock } from "@slack/web-api/dist/types/response/ChatPostMessageResponse"; import * as _slack_web_api_dist_types_response_UsersInfoResponse0 from "@slack/web-api/dist/types/response/UsersInfoResponse"; //#region src/message.d.ts /** * Helps LLMs format messages for Slack. * * @param text - The text to format. * @returns The formatted text. */ declare function formatMessage(text: string): { text: string; truncated: boolean; originalLength: number; }; /** * formattingRules to provide to LLMs that guide them on how to format messages for Slack. */ declare const formattingRules = "FORMATTING RULES:\n- *text* = bold (NOT italics like in standard markdown)\n- _text_ = italics \n- `text` = inline code\n- ``` = code blocks (do NOT put a language after the backticks)\n- ~text~ = strikethrough\n- = links\n- tables must be in a code block\n- user mentions must be in the format <@user_id> (e.g. <@U01UBAM2C4D>)\n- messages are limited to 3000 characters; if your response is longer, it will be truncated and you'll need to send follow-up messages\n\nNEVER USE:\n- Headings (#, ##, ###, etc.)\n- Double asterisks (**text**) - Slack doesn't support this\n- Standard markdown bold/italic conventions"; /** * These are the Slack event types that we currently support for automatically creating messages from events. * The list is not exhaustive - we may want to add more in the future. */ type SlackEventType = "app_mention" | "assistant_thread_started" | "file_shared" | "link_shared" | "member_joined_channel" | "message" | "reaction_added" | "reaction_removed"; /** * CreateMessageFromEventOptions extends ExtractMessageDetailsFromEventOptions. * * It exists so we can add options in the future. * Feel free to use `extractMessageDetailsFromEvent` to construct your own message. */ interface CreateMessageFromEventOptions extends Omit, "messages"> { event: KnownEventFromType; } interface CreateMessageFromEventResult { message: UIMessage; metadata: MessageMetadata; } /** * createMessageFromEvent creates a message from a Slack event. * * It just wraps `extractMessageMetadataFromEvent` and calls `createPartsFromMessageMetadata`. * * Feel free to extract metadata and construct parts yourself for full customization. */ declare const createMessageFromEvent: (options: CreateMessageFromEventOptions) => Promise; interface CreatePartsFromMessageMetadataOptions { message: { channel?: string; ts?: string; thread_ts?: string; text?: string; }; metadata: MessageMetadata; /** * botUserId can be supplied to help the bot identify itself. */ botUserId?: string; } /** * createPartsFromMessageMetadata creates UIMessage parts from message metadata. * * This provides files, mentions, and sender information. */ declare const createPartsFromMessageMetadata: ({ metadata, botUserId, message }: CreatePartsFromMessageMetadataOptions) => UIMessage["parts"]; interface MessageMetadata { /** * mentions is a list of mentions in the message. */ mentions: Array<{ type: "channel"; id: string; channel: NonNullable; } | { type: "team"; id: string; team: NonNullable; } | { type: "user"; id: string; user: NonNullable; }>; /** * files is a list of files attached to the message. */ files: Array<{ file: NonNullable[number]; result: { type: "downloaded"; content: Buffer; } | { type: "not_supported"; } | { type: "too_large"; size: number; } | { type: "error"; error: Error; } | { type: "no_url"; }; }>; /** * user is the user who sent the message. */ user: UsersInfoResponse["user"]; /** * createdAt is the timestamp of the message. */ createdAt: Date; /** * channel is the channel the message was sent in. */ channel: ConversationsInfoResponse["channel"]; /** * botTeamId is the team ID of the bot, from auth.test(). * Useful for determining if a user is external (Slack Connect). */ botTeamId?: string; } interface ExtractMessagesMetadataOptions { readonly client: WebClient; readonly messages: T[]; /** * supportedFileTypes is a list of file types that the client * will attempt to download and attach to the message. * * Defaults to `defaultSupportedFileTypes`. */ readonly supportedFileTypes?: string[]; /** * maxFileSize is the maximum file size in bytes that the client * will attempt to download and attach to the message. * * By default, this is 10MB. * * If the file is larger than this, it will not be attached to the message. */ readonly maxFileSize?: number; } type ExtractMessagesMetadataResult = Array<{ message: T; metadata: MessageMetadata; }>; /** * extractMessagesMetadata extracts metadata from messages. * * - User/team/channel mentions * - File attachments * - Sender information * - Timestamp */ declare const extractMessagesMetadata: ; user?: string; ts?: string; channel?: string; }>({ client, messages, supportedFileTypes, maxFileSize }: ExtractMessagesMetadataOptions) => Promise>; /** * extractMentionsFromMessageBlocks extracts mentions from a message blocks. * @param blocks - The message blocks. * @returns The mentions. */ declare const extractMentionsFromMessageBlocks: (blocks: AnyBlock[]) => Array; declare const defaultSupportedFileTypes: string[]; //#endregion //#region src/tools.d.ts interface CreateToolsOptions extends Pick, "supportedFileTypes" | "maxFileSize"> { readonly client: WebClient; /** * disableViewingUserProfilePictures is a boolean that, when true, will not allow * the getUser tool to return the user's profile picture. */ readonly disableViewingUserProfilePictures?: boolean; /** * disableMessagingInChannels is a boolean that, when true, will not allow * the sendMessage tool to send messages directly to channels. A thread must * be specified. */ readonly disableMessagingInChannels?: boolean; } /** * createTools creates a set of Slack tools for use with the AI SDK. * * @param options - The options for the tools. * @returns The tools for the bot user in Slack. */ declare const createTools: ({ client, supportedFileTypes, maxFileSize, disableViewingUserProfilePictures, disableMessagingInChannels }: CreateToolsOptions) => { /** * sendMessage is a tool that sends a message to Slack. */ sendMessage: ai0.Tool<{ message: string; actions: { type: "button"; text: { type: "plain_text"; text: string; }; url: string; }[]; text_snippets: { name: string; content: string; type: string; }[]; image_urls: { url: string; alt_text: string; }[]; channel: string; ts?: string | undefined; }, { snippet_errors?: { name: string; error: string; }[] | undefined; success: boolean; truncated: boolean; message: string; } | { snippet_errors?: { name: string; error: string; }[] | undefined; success: boolean; }>; reactToMessage: ai0.Tool<{ channel: string; ts: string; reaction: string; remove_reaction: boolean; }, { success: boolean; }>; readMessages: ai0.Tool<{ channel: string; limit: number; cursor: string; }, PartialMessage[]>; readMessage: ai0.Tool<{ channel: string; ts: string; }, { message: PartialMessage; files: { name: string | null; mimetype: string; result: { type: "not_supported"; } | { type: "too_large"; size: number; } | { type: "error"; error: Error; } | { type: "no_url"; } | { type: string; base64: string; }; }[]; }>; readThreadReplies: ai0.Tool<{ channel: string; ts: string; cursor: string; limit: number; }, PartialMessage[]>; getUserInfo: ai0.Tool<{ user_id: string; }, { user: _slack_web_api_dist_types_response_UsersInfoResponse0.User; image: { data: string; mediaType: string; } | undefined; }>; reportStatus: ai0.Tool<{ message: string; channel: string; thread_ts: string; }, { success: boolean; }>; }; type PartialMessage = { thread_ts?: string; ts?: string; ts_formatted?: string; text?: string; mentions: Array<{ type: "channel"; id: string; name?: string; } | { type: "team"; id: string; name?: string; } | { type: "user"; id: string; name?: string; real_name?: string; display_name?: string; }>; files: Array<{ name: string | null; mimetype: string; size: number; }>; }; //#endregion //#region src/receiver.d.ts /** * A Slack Bolt receiver implementation designed for serverless environments. * Handles Slack events, interactions, and slash commands with automatic request verification, * background processing, and timeout management. * * @example * ```typescript * import { App } from '@slack/bolt'; * import { Receiver } from '@blink-sdk/slack'; * * const app = new App({ * token: process.env.SLACK_BOT_TOKEN, * signingSecret: process.env.SLACK_SIGNING_SECRET, * }); * * const receiver = new Receiver(); * * export default async function handler(req: Request) { * return receiver.handle(app, req); * } * ``` */ declare class Receiver { private readonly signingSecret; private readonly signatureVerification; private readonly logger; private readonly ackTimeoutMs; private app?; /** * Creates a new Receiver instance. * * @param options - Configuration options for the receiver * @throws {ReceiverError} When signing secret is not provided * * @example * ```typescript * const receiver = new Receiver(); * ``` */ constructor({ signingSecret, signatureVerification, logLevel }?: { signingSecret?: string; signatureVerification?: boolean; logLevel?: LogLevel; }); /** * Initializes the receiver with a Slack Bolt app instance. * This method is called automatically by the Bolt framework. * * @param app - The Slack Bolt app instance */ init(app: App): void; /** * Starts the receiver. This method is called automatically by the Bolt framework. */ start(): Promise; /** * Stops the receiver. This method is called automatically by the Bolt framework. */ stop(): Promise; /** * Handles incoming Slack requests and returns a response. * * @param app - The Slack Bolt app instance (optional if init() was called) * @param req - The incoming request * @returns A promise that resolves to a Response */ handle(app: App | Request, req?: Request): Promise; private parseRequestBody; private handleSlackEvent; private verifyRequest; private createSlackReceiverEvent; private handleError; private createScopedLogger; } //#endregion //#region src/errors.d.ts declare const ERROR_MESSAGES: { readonly SIGNING_SECRET_REQUIRED: "SLACK_SIGNING_SECRET is required for Receiver"; readonly APP_NOT_INITIALIZED: "App not initialized"; readonly REQUEST_TIMEOUT: "Request timeout"; readonly EVENT_NOT_ACKNOWLEDGED: "Event not acknowledged within timeout period"; readonly MISSING_REQUIRED_HEADER: (header: string) => string; readonly REQUEST_VERIFICATION_FAILED: "Request verification failed"; readonly INTERNAL_SERVER_ERROR: "Internal server error"; readonly INTERNAL_SERVER_ERROR_HANDLER: "Internal Server Error"; readonly ACKNOWLEDGMENT_ERROR: "Error in acknowledgment handler"; readonly CREATE_HANDLER_ERROR: "Error in createHandler:"; readonly TYPES: { readonly RECEIVER_ERROR: "ReceiverError"; readonly SIGNATURE_VERIFICATION_ERROR: "SignatureVerificationError"; readonly REQUEST_PARSING_ERROR: "RequestParsingError"; readonly UNEXPECTED_ERROR: "UnexpectedError"; readonly HANDLER_ERROR: "HandlerError"; }; }; declare class ReceiverError extends Error { readonly statusCode: number; constructor(message: string, statusCode?: number); } declare class RequestParsingError extends ReceiverError { constructor(message?: string); } /** * Determines the appropriate HTTP status code for a given error. * @param error The error to get status code for * @returns HTTP status code */ declare function getStatusCode(error: unknown): number; /** * Gets the error message for response. * @param error The error to get message for * @returns Error message string */ declare function getErrorMessage(error: unknown): string; /** * Gets the error type for response. * @param error The error to get type for * @returns Error type string */ declare function getErrorType(error: unknown): string; //#endregion export { CreateMessageFromEventOptions, CreateMessageFromEventResult, CreatePartsFromMessageMetadataOptions, CreateToolsOptions, ERROR_MESSAGES, ExtractMessagesMetadataOptions, ExtractMessagesMetadataResult, MessageMetadata, Receiver, ReceiverError, RequestParsingError, createMessageFromEvent, createPartsFromMessageMetadata, createTools, defaultSupportedFileTypes, extractMentionsFromMessageBlocks, extractMessagesMetadata, formatMessage, formattingRules, getErrorMessage, getErrorType, getStatusCode };