@vercel/slack-bolt 1.0.0 → 1.0.2

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/README.md CHANGED
@@ -2,34 +2,28 @@
2
2
 
3
3
  A custom [Slack Bolt](https://slack.dev/bolt-js/) receiver built for Vercel's [Fluid Compute](https://vercel.com/docs/fluid-compute).
4
4
 
5
- - **Vercel Fluid Compute** Fully compabatible with Vercel Fluid Compute and [Active CPU Pricing](https://vercel.com/changelog/lower-pricing-with-active-cpu-pricing-for-fluid-compute)
6
- - **Easy integration:** Use with your existing Bolt app code
7
- - **Customizable:** Supports custom response handlers and property extraction
8
- - **TypeScript ready:** Fully typed for modern development
9
- - **Node.js Compatible:** The library is compatible with any framework or function using the Node.js Request object.
5
+ ## Getting Started
10
6
 
11
- ## Installation
12
-
13
- ```bash
14
- pnpm add @vercel/slack-bolt @slack/bolt
15
- ```
7
+ Visit our [template](https://vercel.com/templates/backend/slack-bolt-with-nitro) to get started building a Slack app.
16
8
 
17
- ## Quick Start
18
-
19
- ### 1. Environment Setup
20
-
21
- Add your `SLACK_SIGNING_SECRET` and `SLACK_BOT_TOKEN` to your environment variables:
22
9
 
10
+ ## Installation
23
11
  ```bash
24
- SLACK_SIGNING_SECRET=your_slack_signing_secret_here
25
- SLACK_BOT_TOKEN=your_slack_bot_token
12
+ npm install @vercel/slack-bolt
13
+ # or
14
+ yarn add @vercel/slack-bolt
15
+ # or
16
+ pnpm add @vercel/slack-bolt
17
+ # or
18
+ bun add @vercel/slack-bolt
26
19
  ```
27
20
 
28
- ### 2. Add the Vercel Receiver to your Bolt app
21
+ ## API Reference
29
22
 
30
- ```typescript
31
- // app.ts
23
+ ### `VercelReceiver`
24
+ Responsible for handling and parsing any incoming requests from Slack and then forwarding them to your Bolt app for event processing.
32
25
 
26
+ ```typescript
33
27
  import { App } from "@slack/bolt";
34
28
  import { VercelReceiver } from "@vercel/slack-bolt";
35
29
 
@@ -48,84 +42,45 @@ app.message(/^(hi|hello|hey).*/, async ({ say }) => {
48
42
 
49
43
  export { app, receiver };
50
44
  ```
45
+ #### Parameters
51
46
 
52
- ### 3. Create an API folder and events.ts route
47
+ | Name | Type | Default Value | Required | Description |
48
+ | --- | --- | --- | --- | --- |
49
+ | `signingSecret` | `string` | `process.env.SLACK_SIGNING_SECRET` | No<sup>1</sup> | Signing secret for your Slack app used to verify requests. |
50
+ | `signatureVerification` | `boolean` | `true` | No | Enable or disable request signature verification. |
51
+ | `logger` | `Logger`<sup>2</sup> | `new ConsoleLogger()` | No | Logger used for diagnostics. |
52
+ | `logLevel` | `LogLevel`<sup>2</sup> | `LogLevel.INFO` | No | Minimum log level for the logger. |
53
+ | `customPropertiesExtractor` | `(req: Request) => StringIndexed` | `undefined` | No | Return value is merged into Bolt event `customProperties`<sup>2</sup>. |
54
+ | `ackTimeoutMs` | `number` | `3001` | No | Milliseconds to wait for `ack()` before returning a timeout error. |
53
55
 
54
- Your project structure should look like this:
56
+ <sup>1</sup> Optional if `process.env.SLACK_SIGNING_SECRET` is provided.
55
57
 
56
- ```
57
- root/
58
- ├── api/
59
- │ └── events.ts # Vercel API endpoint to handle requests
60
- ├── app.ts # Bolt app
61
- ├── package.json
62
- └── .env # Environment variables
63
- ```
64
-
65
- ### 4. Create a POST request handler using `createHandler` from `@vercel/slack-bolt`
66
-
67
- ```typescript
68
- // api/events.ts
58
+ <sup>2</sup> Provided by the [`@slack/bolt`](https://www.npmjs.com/package/@slack/bolt) library. More information [here](https://docs.slack.dev/tools/bolt-js/reference#app-options).
69
59
 
70
- import { createHandler } from "@vercel/slack-bolt";
71
- import { app, receiver } from "../app";
72
60
 
73
- const handler = createHandler(app, receiver);
61
+ ### `createHandler`
62
+ A function that returns a Vercel-compatible request handler that will initialize and start your Bolt app to process the event.
74
63
 
75
- export const POST = async (req: Request) => {
76
- return handler(req);
77
- };
78
- ```
79
-
80
- > **Note:**
81
- > The `handler` returned by `createHandler` works with standard Node.js `Request` objects.
82
- > You can use it directly in your Vercel API routes or with any framework that provides compatible request objects.
83
-
84
- ### 5. Update your Slack App Manifest
85
-
86
- - Disable socket mode on your app
87
- - Update your `request_url` to match your Vercel deployment
88
- - If using features such as `commands`, `shortcuts`, and `interactivity` you must update their `urls` as well.
89
-
90
- See the [example](./manifest.example.json) for reference.
91
-
92
- ## Local Development
93
-
94
- This package is compatible with the Slack CLI and can be used with the `slack run` command.
95
-
96
- ### 1. Update the `start` command in your `./slack/hooks.json` file
97
-
98
- ```jsonc
99
- // ./slack/hooks.json
100
- {
101
- "hooks": {
102
- "get-hooks": "npx -q --no-install -p @slack/cli-hooks slack-cli-get-hooks",
103
- "start": "vc dev" // or the start command for your framework
104
- }
105
- }
106
- ```
64
+ ```typescript
65
+ // An example using Next.js route handlers
107
66
 
108
- ### 2. If you'd like to use your local `manifest.json`, update your `config.json` file. (optional)
67
+ import { createHandler } from "@vercel/slack-bolt"
68
+ import { app, receiver } from "./app"
109
69
 
110
- ```jsonc
111
- {
112
- // ./slack/config.json
113
- "manifest": {
114
- "source": "local" // remote pulls the manifest from your Slack's remote manifest
115
- },
116
- "project_id": "<your-project-id>"
117
- }
70
+ export const POST = createHandler(app, receiver)
118
71
  ```
119
72
 
120
- ### 3. Expose your local server with `ngrok` or a similar tunneling tool
73
+ #### Parameters
121
74
 
122
- ```bash
123
- ngrok http 3000
124
- ```
75
+ | Name | Type | Required | Description |
76
+ |-------------|-------------|----------|----------------------------------------------------------------------|
77
+ | `app` | `App`<sup>1</sup> | Yes | Your Bolt app |
78
+ | `receiver` | `VercelReceiver` | Yes | The Vercel receiver instance used to process Slack requests. |
125
79
 
126
- ### 4. Update your app manifest to use your tunnel URL
80
+ <sup>1</sup> Provided by the [`@slack/bolt`](https://www.npmjs.com/package/@slack/bolt) library. More information [here](https://docs.slack.dev/tools/bolt-js/reference#app-options).
127
81
 
128
- Example: https://slack-agent.ngrok.dev/api/events
82
+ ## Examples
83
+ Starter templates: [Next.js](https://github.com/vercel-labs/slack-bolt/tree/examples/examples/nextjs), [Hono](https://github.com/vercel-labs/slack-bolt/tree/examples/examples/hono), [Nitro](https://github.com/vercel-labs/slack-bolt/tree/examples/examples/nitro).
129
84
 
130
85
  ## Contributing
131
86
 
@@ -137,4 +92,4 @@ For issues and questions:
137
92
 
138
93
  - Check the [Slack Bolt documentation](https://slack.dev/bolt-js/)
139
94
  - Review [Vercel Functions documentation](https://vercel.com/docs/functions)
140
- - Open an issue in this repository
95
+ - [Open an issue](https://github.com/vercel-labs/slack-bolt/issues) in this repository
package/dist/index.js CHANGED
@@ -417,8 +417,7 @@ function createHandler(app, receiver) {
417
417
  const handler = yield receiver.start();
418
418
  return handler(req);
419
419
  } catch (error) {
420
- const logger = receiver.getLogger();
421
- logger.error(ERROR_MESSAGES.CREATE_HANDLER_ERROR, error);
420
+ console.error(ERROR_MESSAGES.CREATE_HANDLER_ERROR, error);
422
421
  return new Response(
423
422
  JSON.stringify({
424
423
  error: ERROR_MESSAGES.INTERNAL_SERVER_ERROR_HANDLER,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/index.ts"],"names":["logger","LogLevel","ConsoleLogger","ReceiverMultipleAckError","body","waitUntil","ReceiverAuthenticityError","verifySlackRequest"],"mappings":"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","file":"index.js","sourcesContent":["// Error messages constants\nexport const ERROR_MESSAGES = {\n // VercelReceiver errors\n SIGNING_SECRET_REQUIRED:\n \"SLACK_SIGNING_SECRET is required for VercelReceiver\",\n APP_NOT_INITIALIZED: \"App not initialized\",\n REQUEST_TIMEOUT: \"Request timeout\",\n EVENT_NOT_ACKNOWLEDGED: \"Event not acknowledged within timeout period\",\n\n // Header validation errors\n MISSING_REQUIRED_HEADER: (header: string) =>\n `Missing required header: ${header}`,\n\n // Generic fallback errors\n REQUEST_VERIFICATION_FAILED: \"Request verification failed\",\n INTERNAL_SERVER_ERROR: \"Internal server error\",\n INTERNAL_SERVER_ERROR_HANDLER: \"Internal Server Error\",\n ACKNOWLEDGMENT_ERROR: \"Error in acknowledgment handler\",\n CREATE_HANDLER_ERROR: \"Error in createHandler:\",\n\n // Error type names\n TYPES: {\n VERCEL_RECEIVER_ERROR: \"VercelReceiverError\",\n SIGNATURE_VERIFICATION_ERROR: \"SignatureVerificationError\",\n REQUEST_PARSING_ERROR: \"RequestParsingError\",\n UNEXPECTED_ERROR: \"UnexpectedError\",\n HANDLER_ERROR: \"HandlerError\",\n },\n} as const;\n\nexport class VercelReceiverError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number = 500,\n ) {\n super(message);\n this.name = ERROR_MESSAGES.TYPES.VERCEL_RECEIVER_ERROR;\n }\n}\n\nexport class RequestParsingError extends VercelReceiverError {\n constructor(message: string = \"Failed to parse request\") {\n super(message, 400);\n this.name = ERROR_MESSAGES.TYPES.REQUEST_PARSING_ERROR;\n }\n}\n\n/**\n * Determines the appropriate HTTP status code for a given error.\n * @param error The error to get status code for\n * @returns HTTP status code\n */\nexport function getStatusCode(error: unknown): number {\n if (error instanceof VercelReceiverError) {\n return error.statusCode;\n }\n\n // External error types from @slack/bolt\n if (error && typeof error === \"object\") {\n const errorName =\n error.constructor?.name || (error as { name?: string }).name;\n switch (errorName) {\n case \"ReceiverAuthenticityError\":\n return 401;\n case \"ReceiverMultipleAckError\":\n return 500;\n case \"RequestParsingError\":\n return 400;\n case \"SignatureVerificationError\":\n return 400;\n default:\n return 500;\n }\n }\n\n return 500;\n}\n\n/**\n * Gets the error message for response.\n * @param error The error to get message for\n * @returns Error message string\n */\nexport function getErrorMessage(error: unknown): string {\n if (error && typeof error === \"object\" && \"message\" in error) {\n return String(error.message);\n }\n return ERROR_MESSAGES.INTERNAL_SERVER_ERROR;\n}\n\n/**\n * Gets the error type for response.\n * @param error The error to get type for\n * @returns Error type string\n */\nexport function getErrorType(error: unknown): string {\n if (error && typeof error === \"object\") {\n const ctorName = (error as { constructor?: { name?: string } }).constructor\n ?.name;\n const nameProp = (error as { name?: string }).name;\n const errorName =\n ctorName ?? nameProp ?? ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;\n // Use \"UnexpectedError\" for generic Error instances, otherwise use the actual name\n return errorName === \"Error\"\n ? ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR\n : errorName;\n }\n return ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;\n}\n","import {\n type AckFn,\n type App,\n type Receiver,\n ReceiverAuthenticityError,\n type ReceiverEvent,\n ReceiverMultipleAckError,\n type StringIndexed,\n verifySlackRequest,\n} from \"@slack/bolt\";\nimport { ConsoleLogger, type Logger, LogLevel } from \"@slack/logger\";\nimport { waitUntil } from \"@vercel/functions\";\nimport {\n ERROR_MESSAGES,\n getErrorMessage,\n getErrorType,\n getStatusCode,\n RequestParsingError,\n VercelReceiverError,\n} from \"./errors\";\n\n// Types\n/**\n * A function to handle the request from the Slack app.\n * @param req - The request from the Slack app.\n * @returns A response object.\n */\nexport type VercelHandler = (req: Request) => Promise<Response>;\n\n/**\n * Configuration options for the VercelReceiver.\n * @property signingSecret - The signing secret for the Slack app.\n * @property signatureVerification - If true, verifies the Slack request signature.\n * @property logger - The logger to use for the VercelReceiver.\n * @property logLevel - The log level to use for the VercelReceiver.\n * @property customPropertiesExtractor - A function to extract custom properties from the request.\n */\nexport interface VercelReceiverOptions {\n /**\n * The signing secret for the Slack app.\n * @default process.env.SLACK_SIGNING_SECRET\n */\n signingSecret?: string;\n /**\n * If true, verifies the Slack request signature.\n * @default true\n */\n signatureVerification?: boolean;\n /**\n * The logger to use for the VercelReceiver.\n * @default new ConsoleLogger()\n */\n logger?: Logger;\n /**\n * The log level to use for the VercelReceiver.\n * @default LogLevel.INFO\n */\n logLevel?: LogLevel;\n /**\n * A function to extract custom properties from incoming events.\n * @default undefined\n * @returns An object with custom properties.\n */\n customPropertiesExtractor?: (req: Request) => StringIndexed;\n /**\n * The timeout in milliseconds for event acknowledgment.\n * @default 3001\n */\n ackTimeoutMs?: number;\n}\n\nconst LOG_PREFIX = \"[@vercel/slack-bolt]\";\nconst ACK_TIMEOUT_MS = 3001;\nconst SLACK_RETRY_NUM_HEADER = \"x-slack-retry-num\";\nconst SLACK_RETRY_REASON_HEADER = \"x-slack-retry-reason\";\nconst SLACK_TIMESTAMP_HEADER = \"x-slack-request-timestamp\";\nconst SLACK_SIGNATURE_HEADER = \"x-slack-signature\";\n\n/**\n * A Slack Bolt receiver implementation designed for Vercel's serverless environment.\n * Handles Slack events, interactions, and slash commands with automatic request verification,\n * background processing, and timeout management.\n *\n * @example\n * ```typescript\n * import { App } from '@slack/bolt';\n * import { VercelReceiver, createHandler } from '@vercel/slack-bolt';\n *\n * const receiver = new VercelReceiver();\n *\n * const app = new App({\n * receiver,\n * token: process.env.SLACK_BOT_TOKEN,\n * signingSecret: process.env.SLACK_SIGNING_SECRET,\n * });\n * ```\n *\n */\nexport class VercelReceiver implements Receiver {\n private readonly signingSecret: string;\n private readonly signatureVerification: boolean;\n private readonly logger: Logger;\n private readonly customPropertiesExtractor?: (req: Request) => StringIndexed;\n private readonly ackTimeoutMs: number;\n private app?: App;\n\n /**\n * Gets the logger instance used by this receiver.\n * @returns The logger instance\n */\n public getLogger(): Logger {\n return this.logger;\n }\n\n /**\n * Creates a new VercelReceiver instance.\n *\n * @param options - Configuration options for the receiver\n * @throws {VercelReceiverError} When signing secret is not provided\n *\n * @example\n * ```typescript\n * const receiver = new VercelReceiver();\n * ```\n */\n public constructor({\n signingSecret = process.env.SLACK_SIGNING_SECRET,\n signatureVerification = true,\n logger,\n logLevel = LogLevel.INFO,\n customPropertiesExtractor,\n ackTimeoutMs = ACK_TIMEOUT_MS,\n }: VercelReceiverOptions = {}) {\n if (!signingSecret) {\n throw new VercelReceiverError(ERROR_MESSAGES.SIGNING_SECRET_REQUIRED);\n }\n\n this.signingSecret = signingSecret;\n this.signatureVerification = signatureVerification;\n this.logger = this.createScopedLogger(\n logger ?? new ConsoleLogger(),\n logLevel,\n );\n this.customPropertiesExtractor = customPropertiesExtractor;\n this.ackTimeoutMs = ackTimeoutMs;\n\n this.logger.debug(\"VercelReceiver initialized\");\n }\n\n /**\n * Initializes the receiver with a Slack Bolt app instance.\n * This method is called automatically by the Bolt framework.\n *\n * @param app - The Slack Bolt app instance\n */\n public init(app: App): void {\n this.app = app;\n this.logger.debug(\"App initialized in VercelReceiver\");\n }\n\n /**\n * Starts the receiver and returns a handler function for processing requests.\n * This method is called automatically by the Bolt framework.\n *\n * @returns A handler function that processes incoming Slack requests\n */\n public async start(): Promise<VercelHandler> {\n this.logger.debug(\"VercelReceiver started\");\n return this.toHandler();\n }\n\n /**\n * Stops the receiver. This method is called automatically by the Bolt framework.\n */\n public async stop(): Promise<void> {\n this.logger.debug(\"VercelReceiver stopped\");\n }\n\n /**\n * Creates a handler function that processes incoming Slack requests.\n * This is the main entry point for handling Slack events in Vercel.\n * It is called automatically by the Bolt framework in the start() method.\n *\n * @returns A handler function compatible with Vercel's function signature\n */\n public toHandler(): VercelHandler {\n return async (req: Request): Promise<Response> => {\n try {\n const rawBody = await req.text();\n\n if (this.signatureVerification) {\n this.verifyRequest(req, rawBody);\n }\n\n const body = await this.parseRequestBody(req, rawBody);\n\n if (body.type === \"url_verification\") {\n this.logger.debug(\"Handling URL verification challenge\");\n return Response.json({ challenge: body.challenge });\n }\n\n return await this.handleSlackEvent(req, body);\n } catch (error) {\n return this.handleError(error);\n }\n };\n }\n\n private async parseRequestBody(\n req: Request,\n rawBody: string,\n ): Promise<StringIndexed> {\n const contentType = req.headers.get(\"content-type\");\n\n try {\n if (contentType === \"application/x-www-form-urlencoded\") {\n const parsedBody: StringIndexed = {};\n const params = new URLSearchParams(rawBody);\n\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n\n if (typeof parsedBody.payload === \"string\") {\n return JSON.parse(parsedBody.payload);\n }\n return parsedBody;\n }\n if (contentType === \"application/json\") {\n return JSON.parse(rawBody);\n }\n\n this.logger.warn(`Unexpected content-type detected: ${contentType}`);\n\n return JSON.parse(rawBody);\n } catch (e) {\n throw new RequestParsingError(\n `Failed to parse body as JSON data for content-type: ${contentType}. Error: ${\n e instanceof Error ? e.message : String(e)\n }`,\n );\n }\n }\n\n private async handleSlackEvent(\n req: Request,\n body: StringIndexed,\n ): Promise<Response> {\n if (!this.app) {\n throw new VercelReceiverError(ERROR_MESSAGES.APP_NOT_INITIALIZED, 500);\n }\n\n let isAcknowledged = false;\n let responseResolver: (value: Response) => void;\n let responseRejecter: (error: Error) => void;\n\n const responsePromise = new Promise<Response>((resolve, reject) => {\n responseResolver = resolve;\n responseRejecter = reject;\n });\n\n // Slack requires an acknowledgment from your app within 3 seconds\n const timeoutId = setTimeout(() => {\n if (!isAcknowledged) {\n this.logger.error(ERROR_MESSAGES.EVENT_NOT_ACKNOWLEDGED);\n const error = new VercelReceiverError(\n ERROR_MESSAGES.REQUEST_TIMEOUT,\n 408,\n );\n responseRejecter(error);\n }\n }, this.ackTimeoutMs);\n\n // Create acknowledgment function\n const ackFn: AckFn<StringIndexed> = async (responseBody) => {\n this.logger.debug(`ack() call begins (body: ${responseBody})`);\n if (isAcknowledged) {\n throw new ReceiverMultipleAckError();\n }\n\n isAcknowledged = true;\n clearTimeout(timeoutId);\n\n try {\n let body: string | undefined;\n if (typeof responseBody === \"undefined\") {\n body = undefined;\n } else if (typeof responseBody === \"string\") {\n body = responseBody;\n } else {\n body = JSON.stringify(responseBody);\n }\n const response = new Response(body, {\n status: 200,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n responseResolver(response);\n } catch (error) {\n this.logger.error(ERROR_MESSAGES.ACKNOWLEDGMENT_ERROR, error);\n responseRejecter(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n };\n\n const event = this.createSlackReceiverEvent({\n body,\n headers: req.headers,\n ack: ackFn,\n request: req,\n });\n\n // Process event in background using waitUntil from Vercel Functions\n // https://vercel.com/docs/functions/functions-api-reference/vercel-functions-package#waituntil\n waitUntil(\n this.app.processEvent(event).catch((error) => {\n return this.handleError(error);\n }),\n );\n\n try {\n return await responsePromise;\n } catch (error) {\n return this.handleError(error);\n }\n }\n\n private verifyRequest(req: Request, body: string): void {\n const timestamp = req.headers.get(SLACK_TIMESTAMP_HEADER);\n const signature = req.headers.get(SLACK_SIGNATURE_HEADER);\n\n if (!signature) {\n throw new ReceiverAuthenticityError(\n ERROR_MESSAGES.MISSING_REQUIRED_HEADER(SLACK_SIGNATURE_HEADER),\n );\n }\n\n if (!timestamp) {\n throw new ReceiverAuthenticityError(\n ERROR_MESSAGES.MISSING_REQUIRED_HEADER(SLACK_TIMESTAMP_HEADER),\n );\n }\n\n try {\n verifySlackRequest({\n signingSecret: this.signingSecret,\n body,\n headers: {\n \"x-slack-signature\": signature,\n \"x-slack-request-timestamp\": Number.parseInt(timestamp, 10),\n },\n logger: this.logger,\n });\n } catch (error) {\n throw new ReceiverAuthenticityError(\n error instanceof Error\n ? error.message\n : \"Failed to verify request signature\",\n );\n }\n }\n\n private createSlackReceiverEvent({\n body,\n headers,\n ack,\n request,\n }: {\n body: StringIndexed;\n headers: Headers;\n ack: AckFn<StringIndexed>;\n request: Request;\n }): ReceiverEvent {\n const customProperties = this.customPropertiesExtractor\n ? this.customPropertiesExtractor(request)\n : {};\n\n const retryNum = headers.get(SLACK_RETRY_NUM_HEADER) || \"0\";\n\n const retryReason = headers.get(SLACK_RETRY_REASON_HEADER) || \"\";\n\n return {\n body,\n ack,\n retryNum: Number(retryNum),\n retryReason,\n customProperties,\n };\n }\n\n public handleError(error: unknown): Response {\n const errorMessage = getErrorMessage(error);\n const errorType = getErrorType(error);\n const errorStatusCode = getStatusCode(error);\n\n this.logger.error(error);\n return new Response(\n JSON.stringify({\n error: errorMessage,\n type: errorType,\n }),\n {\n status: errorStatusCode,\n headers: { \"content-type\": \"application/json\" },\n },\n );\n }\n\n private createScopedLogger(logger: Logger, logLevel: LogLevel): Logger {\n logger.setLevel(logLevel);\n\n return {\n ...logger,\n error: (...args) => logger.error?.(LOG_PREFIX, ...args),\n warn: (...args) => logger.warn?.(LOG_PREFIX, ...args),\n info: (...args) => logger.info?.(LOG_PREFIX, ...args),\n debug: (...args) => logger.debug?.(LOG_PREFIX, ...args),\n setLevel: logger.setLevel,\n getLevel: logger.getLevel,\n };\n }\n}\n\n/**\n * Creates a Vercel-compatible handler function for a Slack Bolt app.\n * This is the recommended way to create handlers for deployment on Vercel.\n *\n * @param {App} app - The initialized Slack Bolt app instance.\n * @param {VercelReceiver} receiver - The VercelReceiver instance.\n * @returns {VercelHandler} A handler function compatible with Vercel's function signature.\n *\n * @example\n * ```typescript\n * // api/events.ts\n * import { createHandler } from '@vercel/slack-bolt';\n * import { app, receiver } from '../app';\n *\n * const handler = createHandler(app, receiver);\n *\n * export const POST = async (req: Request) => {\n * return handler(req);\n * };\n * ```\n *\n * @throws {Error} If app initialization fails.\n * @throws {VercelReceiverError} If request processing fails.\n */\nexport function createHandler(\n app: App,\n receiver: VercelReceiver,\n): VercelHandler {\n let initPromise: Promise<void> | null = null;\n\n return async (req: Request) => {\n try {\n if (!initPromise) {\n initPromise = app.init();\n }\n await initPromise;\n\n receiver.init(app);\n const handler = await receiver.start();\n return handler(req);\n } catch (error) {\n const logger = receiver.getLogger();\n logger.error(ERROR_MESSAGES.CREATE_HANDLER_ERROR, error);\n return new Response(\n JSON.stringify({\n error: ERROR_MESSAGES.INTERNAL_SERVER_ERROR_HANDLER,\n type: ERROR_MESSAGES.TYPES.HANDLER_ERROR,\n }),\n { status: 500, headers: { \"content-type\": \"application/json\" } },\n );\n }\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/index.ts"],"names":["logger","LogLevel","ConsoleLogger","ReceiverMultipleAckError","body","waitUntil","ReceiverAuthenticityError","verifySlackRequest"],"mappings":"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","file":"index.js","sourcesContent":["// Error messages constants\nexport const ERROR_MESSAGES = {\n // VercelReceiver errors\n SIGNING_SECRET_REQUIRED:\n \"SLACK_SIGNING_SECRET is required for VercelReceiver\",\n APP_NOT_INITIALIZED: \"App not initialized\",\n REQUEST_TIMEOUT: \"Request timeout\",\n EVENT_NOT_ACKNOWLEDGED: \"Event not acknowledged within timeout period\",\n\n // Header validation errors\n MISSING_REQUIRED_HEADER: (header: string) =>\n `Missing required header: ${header}`,\n\n // Generic fallback errors\n REQUEST_VERIFICATION_FAILED: \"Request verification failed\",\n INTERNAL_SERVER_ERROR: \"Internal server error\",\n INTERNAL_SERVER_ERROR_HANDLER: \"Internal Server Error\",\n ACKNOWLEDGMENT_ERROR: \"Error in acknowledgment handler\",\n CREATE_HANDLER_ERROR: \"Error in createHandler:\",\n\n // Error type names\n TYPES: {\n VERCEL_RECEIVER_ERROR: \"VercelReceiverError\",\n SIGNATURE_VERIFICATION_ERROR: \"SignatureVerificationError\",\n REQUEST_PARSING_ERROR: \"RequestParsingError\",\n UNEXPECTED_ERROR: \"UnexpectedError\",\n HANDLER_ERROR: \"HandlerError\",\n },\n} as const;\n\nexport class VercelReceiverError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number = 500,\n ) {\n super(message);\n this.name = ERROR_MESSAGES.TYPES.VERCEL_RECEIVER_ERROR;\n }\n}\n\nexport class RequestParsingError extends VercelReceiverError {\n constructor(message: string = \"Failed to parse request\") {\n super(message, 400);\n this.name = ERROR_MESSAGES.TYPES.REQUEST_PARSING_ERROR;\n }\n}\n\n/**\n * Determines the appropriate HTTP status code for a given error.\n * @param error The error to get status code for\n * @returns HTTP status code\n */\nexport function getStatusCode(error: unknown): number {\n if (error instanceof VercelReceiverError) {\n return error.statusCode;\n }\n\n // External error types from @slack/bolt\n if (error && typeof error === \"object\") {\n const errorName =\n error.constructor?.name || (error as { name?: string }).name;\n switch (errorName) {\n case \"ReceiverAuthenticityError\":\n return 401;\n case \"ReceiverMultipleAckError\":\n return 500;\n case \"RequestParsingError\":\n return 400;\n case \"SignatureVerificationError\":\n return 400;\n default:\n return 500;\n }\n }\n\n return 500;\n}\n\n/**\n * Gets the error message for response.\n * @param error The error to get message for\n * @returns Error message string\n */\nexport function getErrorMessage(error: unknown): string {\n if (error && typeof error === \"object\" && \"message\" in error) {\n return String(error.message);\n }\n return ERROR_MESSAGES.INTERNAL_SERVER_ERROR;\n}\n\n/**\n * Gets the error type for response.\n * @param error The error to get type for\n * @returns Error type string\n */\nexport function getErrorType(error: unknown): string {\n if (error && typeof error === \"object\") {\n const ctorName = (error as { constructor?: { name?: string } }).constructor\n ?.name;\n const nameProp = (error as { name?: string }).name;\n const errorName =\n ctorName ?? nameProp ?? ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;\n // Use \"UnexpectedError\" for generic Error instances, otherwise use the actual name\n return errorName === \"Error\"\n ? ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR\n : errorName;\n }\n return ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;\n}\n","import {\n type AckFn,\n type App,\n type Receiver,\n ReceiverAuthenticityError,\n type ReceiverEvent,\n ReceiverMultipleAckError,\n type StringIndexed,\n verifySlackRequest,\n} from \"@slack/bolt\";\nimport { ConsoleLogger, type Logger, LogLevel } from \"@slack/logger\";\nimport { waitUntil } from \"@vercel/functions\";\nimport {\n ERROR_MESSAGES,\n getErrorMessage,\n getErrorType,\n getStatusCode,\n RequestParsingError,\n VercelReceiverError,\n} from \"./errors\";\n\n// Types\n/**\n * A function to handle the request from the Slack app.\n * @param req - The request from the Slack app.\n * @returns A response object.\n */\nexport type VercelHandler = (req: Request) => Promise<Response>;\n\n/**\n * Configuration options for the VercelReceiver.\n * @property signingSecret - The signing secret for the Slack app.\n * @property signatureVerification - If true, verifies the Slack request signature.\n * @property logger - The logger to use for the VercelReceiver.\n * @property logLevel - The log level to use for the VercelReceiver.\n * @property customPropertiesExtractor - A function to extract custom properties from the request.\n */\nexport interface VercelReceiverOptions {\n /**\n * The signing secret for the Slack app.\n * @default process.env.SLACK_SIGNING_SECRET\n */\n signingSecret?: string;\n /**\n * If true, verifies the Slack request signature.\n * @default true\n */\n signatureVerification?: boolean;\n /**\n * The logger to use for the VercelReceiver.\n * @default new ConsoleLogger()\n */\n logger?: Logger;\n /**\n * The log level to use for the VercelReceiver.\n * @default LogLevel.INFO\n */\n logLevel?: LogLevel;\n /**\n * A function to extract custom properties from incoming events.\n * @default undefined\n * @returns An object with custom properties.\n */\n customPropertiesExtractor?: (req: Request) => StringIndexed;\n /**\n * The timeout in milliseconds for event acknowledgment.\n * @default 3001\n */\n ackTimeoutMs?: number;\n}\n\nconst LOG_PREFIX = \"[@vercel/slack-bolt]\";\nconst ACK_TIMEOUT_MS = 3001;\nconst SLACK_RETRY_NUM_HEADER = \"x-slack-retry-num\";\nconst SLACK_RETRY_REASON_HEADER = \"x-slack-retry-reason\";\nconst SLACK_TIMESTAMP_HEADER = \"x-slack-request-timestamp\";\nconst SLACK_SIGNATURE_HEADER = \"x-slack-signature\";\n\n/**\n * A Slack Bolt receiver implementation designed for Vercel's serverless environment.\n * Handles Slack events, interactions, and slash commands with automatic request verification,\n * background processing, and timeout management.\n *\n * @example\n * ```typescript\n * import { App } from '@slack/bolt';\n * import { VercelReceiver, createHandler } from '@vercel/slack-bolt';\n *\n * const receiver = new VercelReceiver();\n *\n * const app = new App({\n * receiver,\n * token: process.env.SLACK_BOT_TOKEN,\n * signingSecret: process.env.SLACK_SIGNING_SECRET,\n * });\n * ```\n *\n */\nexport class VercelReceiver implements Receiver {\n private readonly signingSecret: string;\n private readonly signatureVerification: boolean;\n private readonly logger: Logger;\n private readonly customPropertiesExtractor?: (req: Request) => StringIndexed;\n private readonly ackTimeoutMs: number;\n private app?: App;\n\n /**\n * Gets the logger instance used by this receiver.\n * @returns The logger instance\n */\n public getLogger(): Logger {\n return this.logger;\n }\n\n /**\n * Creates a new VercelReceiver instance.\n *\n * @param options - Configuration options for the receiver\n * @throws {VercelReceiverError} When signing secret is not provided\n *\n * @example\n * ```typescript\n * const receiver = new VercelReceiver();\n * ```\n */\n public constructor({\n signingSecret = process.env.SLACK_SIGNING_SECRET,\n signatureVerification = true,\n logger,\n logLevel = LogLevel.INFO,\n customPropertiesExtractor,\n ackTimeoutMs = ACK_TIMEOUT_MS,\n }: VercelReceiverOptions = {}) {\n if (!signingSecret) {\n throw new VercelReceiverError(ERROR_MESSAGES.SIGNING_SECRET_REQUIRED);\n }\n\n this.signingSecret = signingSecret;\n this.signatureVerification = signatureVerification;\n this.logger = this.createScopedLogger(\n logger ?? new ConsoleLogger(),\n logLevel,\n );\n this.customPropertiesExtractor = customPropertiesExtractor;\n this.ackTimeoutMs = ackTimeoutMs;\n\n this.logger.debug(\"VercelReceiver initialized\");\n }\n\n /**\n * Initializes the receiver with a Slack Bolt app instance.\n * This method is called automatically by the Bolt framework.\n *\n * @param app - The Slack Bolt app instance\n */\n public init(app: App): void {\n this.app = app;\n this.logger.debug(\"App initialized in VercelReceiver\");\n }\n\n /**\n * Starts the receiver and returns a handler function for processing requests.\n * This method is called automatically by the Bolt framework.\n *\n * @returns A handler function that processes incoming Slack requests\n */\n public async start(): Promise<VercelHandler> {\n this.logger.debug(\"VercelReceiver started\");\n return this.toHandler();\n }\n\n /**\n * Stops the receiver. This method is called automatically by the Bolt framework.\n */\n public async stop(): Promise<void> {\n this.logger.debug(\"VercelReceiver stopped\");\n }\n\n /**\n * Creates a handler function that processes incoming Slack requests.\n * This is the main entry point for handling Slack events in Vercel.\n * It is called automatically by the Bolt framework in the start() method.\n *\n * @returns A handler function compatible with Vercel's function signature\n */\n public toHandler(): VercelHandler {\n return async (req: Request): Promise<Response> => {\n try {\n const rawBody = await req.text();\n\n if (this.signatureVerification) {\n this.verifyRequest(req, rawBody);\n }\n\n const body = await this.parseRequestBody(req, rawBody);\n\n if (body.type === \"url_verification\") {\n this.logger.debug(\"Handling URL verification challenge\");\n return Response.json({ challenge: body.challenge });\n }\n\n return await this.handleSlackEvent(req, body);\n } catch (error) {\n return this.handleError(error);\n }\n };\n }\n\n private async parseRequestBody(\n req: Request,\n rawBody: string,\n ): Promise<StringIndexed> {\n const contentType = req.headers.get(\"content-type\");\n\n try {\n if (contentType === \"application/x-www-form-urlencoded\") {\n const parsedBody: StringIndexed = {};\n const params = new URLSearchParams(rawBody);\n\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n\n if (typeof parsedBody.payload === \"string\") {\n return JSON.parse(parsedBody.payload);\n }\n return parsedBody;\n }\n if (contentType === \"application/json\") {\n return JSON.parse(rawBody);\n }\n\n this.logger.warn(`Unexpected content-type detected: ${contentType}`);\n\n return JSON.parse(rawBody);\n } catch (e) {\n throw new RequestParsingError(\n `Failed to parse body as JSON data for content-type: ${contentType}. Error: ${\n e instanceof Error ? e.message : String(e)\n }`,\n );\n }\n }\n\n private async handleSlackEvent(\n req: Request,\n body: StringIndexed,\n ): Promise<Response> {\n if (!this.app) {\n throw new VercelReceiverError(ERROR_MESSAGES.APP_NOT_INITIALIZED, 500);\n }\n\n let isAcknowledged = false;\n let responseResolver: (value: Response) => void;\n let responseRejecter: (error: Error) => void;\n\n const responsePromise = new Promise<Response>((resolve, reject) => {\n responseResolver = resolve;\n responseRejecter = reject;\n });\n\n // Slack requires an acknowledgment from your app within 3 seconds\n const timeoutId = setTimeout(() => {\n if (!isAcknowledged) {\n this.logger.error(ERROR_MESSAGES.EVENT_NOT_ACKNOWLEDGED);\n const error = new VercelReceiverError(\n ERROR_MESSAGES.REQUEST_TIMEOUT,\n 408,\n );\n responseRejecter(error);\n }\n }, this.ackTimeoutMs);\n\n // Create acknowledgment function\n const ackFn: AckFn<StringIndexed> = async (responseBody) => {\n this.logger.debug(`ack() call begins (body: ${responseBody})`);\n if (isAcknowledged) {\n throw new ReceiverMultipleAckError();\n }\n\n isAcknowledged = true;\n clearTimeout(timeoutId);\n\n try {\n let body: string | undefined;\n if (typeof responseBody === \"undefined\") {\n body = undefined;\n } else if (typeof responseBody === \"string\") {\n body = responseBody;\n } else {\n body = JSON.stringify(responseBody);\n }\n const response = new Response(body, {\n status: 200,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n responseResolver(response);\n } catch (error) {\n this.logger.error(ERROR_MESSAGES.ACKNOWLEDGMENT_ERROR, error);\n responseRejecter(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n };\n\n const event = this.createSlackReceiverEvent({\n body,\n headers: req.headers,\n ack: ackFn,\n request: req,\n });\n\n // Process event in background using waitUntil from Vercel Functions\n // https://vercel.com/docs/functions/functions-api-reference/vercel-functions-package#waituntil\n waitUntil(\n this.app.processEvent(event).catch((error) => {\n return this.handleError(error);\n }),\n );\n\n try {\n return await responsePromise;\n } catch (error) {\n return this.handleError(error);\n }\n }\n\n private verifyRequest(req: Request, body: string): void {\n const timestamp = req.headers.get(SLACK_TIMESTAMP_HEADER);\n const signature = req.headers.get(SLACK_SIGNATURE_HEADER);\n\n if (!signature) {\n throw new ReceiverAuthenticityError(\n ERROR_MESSAGES.MISSING_REQUIRED_HEADER(SLACK_SIGNATURE_HEADER),\n );\n }\n\n if (!timestamp) {\n throw new ReceiverAuthenticityError(\n ERROR_MESSAGES.MISSING_REQUIRED_HEADER(SLACK_TIMESTAMP_HEADER),\n );\n }\n\n try {\n verifySlackRequest({\n signingSecret: this.signingSecret,\n body,\n headers: {\n \"x-slack-signature\": signature,\n \"x-slack-request-timestamp\": Number.parseInt(timestamp, 10),\n },\n logger: this.logger,\n });\n } catch (error) {\n throw new ReceiverAuthenticityError(\n error instanceof Error\n ? error.message\n : \"Failed to verify request signature\",\n );\n }\n }\n\n private createSlackReceiverEvent({\n body,\n headers,\n ack,\n request,\n }: {\n body: StringIndexed;\n headers: Headers;\n ack: AckFn<StringIndexed>;\n request: Request;\n }): ReceiverEvent {\n const customProperties = this.customPropertiesExtractor\n ? this.customPropertiesExtractor(request)\n : {};\n\n const retryNum = headers.get(SLACK_RETRY_NUM_HEADER) || \"0\";\n\n const retryReason = headers.get(SLACK_RETRY_REASON_HEADER) || \"\";\n\n return {\n body,\n ack,\n retryNum: Number(retryNum),\n retryReason,\n customProperties,\n };\n }\n\n public handleError(error: unknown): Response {\n const errorMessage = getErrorMessage(error);\n const errorType = getErrorType(error);\n const errorStatusCode = getStatusCode(error);\n\n this.logger.error(error);\n return new Response(\n JSON.stringify({\n error: errorMessage,\n type: errorType,\n }),\n {\n status: errorStatusCode,\n headers: { \"content-type\": \"application/json\" },\n },\n );\n }\n\n private createScopedLogger(logger: Logger, logLevel: LogLevel): Logger {\n logger.setLevel(logLevel);\n\n return {\n ...logger,\n error: (...args) => logger.error?.(LOG_PREFIX, ...args),\n warn: (...args) => logger.warn?.(LOG_PREFIX, ...args),\n info: (...args) => logger.info?.(LOG_PREFIX, ...args),\n debug: (...args) => logger.debug?.(LOG_PREFIX, ...args),\n setLevel: logger.setLevel,\n getLevel: logger.getLevel,\n };\n }\n}\n\n/**\n * Creates a Vercel-compatible handler function for a Slack Bolt app.\n * This is the recommended way to create handlers for deployment on Vercel.\n *\n * @param {App} app - The initialized Slack Bolt app instance.\n * @param {VercelReceiver} receiver - The VercelReceiver instance.\n * @returns {VercelHandler} A handler function compatible with Vercel's function signature.\n *\n * @example\n * ```typescript\n * // api/events.ts\n * import { createHandler } from '@vercel/slack-bolt';\n * import { app, receiver } from '../app';\n *\n * const handler = createHandler(app, receiver);\n *\n * export const POST = async (req: Request) => {\n * return handler(req);\n * };\n * ```\n *\n * @throws {Error} If app initialization fails.\n * @throws {VercelReceiverError} If request processing fails.\n */\nexport function createHandler(\n app: App,\n receiver: VercelReceiver,\n): VercelHandler {\n let initPromise: Promise<void> | null = null;\n\n return async (req: Request) => {\n try {\n if (!initPromise) {\n initPromise = app.init();\n }\n await initPromise;\n\n receiver.init(app);\n const handler = await receiver.start();\n return handler(req);\n } catch (error) {\n // if app.init fails, we use console.error instead of logger.error because the logger is not available\n console.error(ERROR_MESSAGES.CREATE_HANDLER_ERROR, error);\n return new Response(\n JSON.stringify({\n error: ERROR_MESSAGES.INTERNAL_SERVER_ERROR_HANDLER,\n type: ERROR_MESSAGES.TYPES.HANDLER_ERROR,\n }),\n { status: 500, headers: { \"content-type\": \"application/json\" } },\n );\n }\n };\n}\n"]}
package/dist/index.mjs CHANGED
@@ -415,8 +415,7 @@ function createHandler(app, receiver) {
415
415
  const handler = yield receiver.start();
416
416
  return handler(req);
417
417
  } catch (error) {
418
- const logger = receiver.getLogger();
419
- logger.error(ERROR_MESSAGES.CREATE_HANDLER_ERROR, error);
418
+ console.error(ERROR_MESSAGES.CREATE_HANDLER_ERROR, error);
420
419
  return new Response(
421
420
  JSON.stringify({
422
421
  error: ERROR_MESSAGES.INTERNAL_SERVER_ERROR_HANDLER,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/index.ts"],"names":["body"],"mappings":"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","file":"index.mjs","sourcesContent":["// Error messages constants\nexport const ERROR_MESSAGES = {\n // VercelReceiver errors\n SIGNING_SECRET_REQUIRED:\n \"SLACK_SIGNING_SECRET is required for VercelReceiver\",\n APP_NOT_INITIALIZED: \"App not initialized\",\n REQUEST_TIMEOUT: \"Request timeout\",\n EVENT_NOT_ACKNOWLEDGED: \"Event not acknowledged within timeout period\",\n\n // Header validation errors\n MISSING_REQUIRED_HEADER: (header: string) =>\n `Missing required header: ${header}`,\n\n // Generic fallback errors\n REQUEST_VERIFICATION_FAILED: \"Request verification failed\",\n INTERNAL_SERVER_ERROR: \"Internal server error\",\n INTERNAL_SERVER_ERROR_HANDLER: \"Internal Server Error\",\n ACKNOWLEDGMENT_ERROR: \"Error in acknowledgment handler\",\n CREATE_HANDLER_ERROR: \"Error in createHandler:\",\n\n // Error type names\n TYPES: {\n VERCEL_RECEIVER_ERROR: \"VercelReceiverError\",\n SIGNATURE_VERIFICATION_ERROR: \"SignatureVerificationError\",\n REQUEST_PARSING_ERROR: \"RequestParsingError\",\n UNEXPECTED_ERROR: \"UnexpectedError\",\n HANDLER_ERROR: \"HandlerError\",\n },\n} as const;\n\nexport class VercelReceiverError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number = 500,\n ) {\n super(message);\n this.name = ERROR_MESSAGES.TYPES.VERCEL_RECEIVER_ERROR;\n }\n}\n\nexport class RequestParsingError extends VercelReceiverError {\n constructor(message: string = \"Failed to parse request\") {\n super(message, 400);\n this.name = ERROR_MESSAGES.TYPES.REQUEST_PARSING_ERROR;\n }\n}\n\n/**\n * Determines the appropriate HTTP status code for a given error.\n * @param error The error to get status code for\n * @returns HTTP status code\n */\nexport function getStatusCode(error: unknown): number {\n if (error instanceof VercelReceiverError) {\n return error.statusCode;\n }\n\n // External error types from @slack/bolt\n if (error && typeof error === \"object\") {\n const errorName =\n error.constructor?.name || (error as { name?: string }).name;\n switch (errorName) {\n case \"ReceiverAuthenticityError\":\n return 401;\n case \"ReceiverMultipleAckError\":\n return 500;\n case \"RequestParsingError\":\n return 400;\n case \"SignatureVerificationError\":\n return 400;\n default:\n return 500;\n }\n }\n\n return 500;\n}\n\n/**\n * Gets the error message for response.\n * @param error The error to get message for\n * @returns Error message string\n */\nexport function getErrorMessage(error: unknown): string {\n if (error && typeof error === \"object\" && \"message\" in error) {\n return String(error.message);\n }\n return ERROR_MESSAGES.INTERNAL_SERVER_ERROR;\n}\n\n/**\n * Gets the error type for response.\n * @param error The error to get type for\n * @returns Error type string\n */\nexport function getErrorType(error: unknown): string {\n if (error && typeof error === \"object\") {\n const ctorName = (error as { constructor?: { name?: string } }).constructor\n ?.name;\n const nameProp = (error as { name?: string }).name;\n const errorName =\n ctorName ?? nameProp ?? ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;\n // Use \"UnexpectedError\" for generic Error instances, otherwise use the actual name\n return errorName === \"Error\"\n ? ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR\n : errorName;\n }\n return ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;\n}\n","import {\n type AckFn,\n type App,\n type Receiver,\n ReceiverAuthenticityError,\n type ReceiverEvent,\n ReceiverMultipleAckError,\n type StringIndexed,\n verifySlackRequest,\n} from \"@slack/bolt\";\nimport { ConsoleLogger, type Logger, LogLevel } from \"@slack/logger\";\nimport { waitUntil } from \"@vercel/functions\";\nimport {\n ERROR_MESSAGES,\n getErrorMessage,\n getErrorType,\n getStatusCode,\n RequestParsingError,\n VercelReceiverError,\n} from \"./errors\";\n\n// Types\n/**\n * A function to handle the request from the Slack app.\n * @param req - The request from the Slack app.\n * @returns A response object.\n */\nexport type VercelHandler = (req: Request) => Promise<Response>;\n\n/**\n * Configuration options for the VercelReceiver.\n * @property signingSecret - The signing secret for the Slack app.\n * @property signatureVerification - If true, verifies the Slack request signature.\n * @property logger - The logger to use for the VercelReceiver.\n * @property logLevel - The log level to use for the VercelReceiver.\n * @property customPropertiesExtractor - A function to extract custom properties from the request.\n */\nexport interface VercelReceiverOptions {\n /**\n * The signing secret for the Slack app.\n * @default process.env.SLACK_SIGNING_SECRET\n */\n signingSecret?: string;\n /**\n * If true, verifies the Slack request signature.\n * @default true\n */\n signatureVerification?: boolean;\n /**\n * The logger to use for the VercelReceiver.\n * @default new ConsoleLogger()\n */\n logger?: Logger;\n /**\n * The log level to use for the VercelReceiver.\n * @default LogLevel.INFO\n */\n logLevel?: LogLevel;\n /**\n * A function to extract custom properties from incoming events.\n * @default undefined\n * @returns An object with custom properties.\n */\n customPropertiesExtractor?: (req: Request) => StringIndexed;\n /**\n * The timeout in milliseconds for event acknowledgment.\n * @default 3001\n */\n ackTimeoutMs?: number;\n}\n\nconst LOG_PREFIX = \"[@vercel/slack-bolt]\";\nconst ACK_TIMEOUT_MS = 3001;\nconst SLACK_RETRY_NUM_HEADER = \"x-slack-retry-num\";\nconst SLACK_RETRY_REASON_HEADER = \"x-slack-retry-reason\";\nconst SLACK_TIMESTAMP_HEADER = \"x-slack-request-timestamp\";\nconst SLACK_SIGNATURE_HEADER = \"x-slack-signature\";\n\n/**\n * A Slack Bolt receiver implementation designed for Vercel's serverless environment.\n * Handles Slack events, interactions, and slash commands with automatic request verification,\n * background processing, and timeout management.\n *\n * @example\n * ```typescript\n * import { App } from '@slack/bolt';\n * import { VercelReceiver, createHandler } from '@vercel/slack-bolt';\n *\n * const receiver = new VercelReceiver();\n *\n * const app = new App({\n * receiver,\n * token: process.env.SLACK_BOT_TOKEN,\n * signingSecret: process.env.SLACK_SIGNING_SECRET,\n * });\n * ```\n *\n */\nexport class VercelReceiver implements Receiver {\n private readonly signingSecret: string;\n private readonly signatureVerification: boolean;\n private readonly logger: Logger;\n private readonly customPropertiesExtractor?: (req: Request) => StringIndexed;\n private readonly ackTimeoutMs: number;\n private app?: App;\n\n /**\n * Gets the logger instance used by this receiver.\n * @returns The logger instance\n */\n public getLogger(): Logger {\n return this.logger;\n }\n\n /**\n * Creates a new VercelReceiver instance.\n *\n * @param options - Configuration options for the receiver\n * @throws {VercelReceiverError} When signing secret is not provided\n *\n * @example\n * ```typescript\n * const receiver = new VercelReceiver();\n * ```\n */\n public constructor({\n signingSecret = process.env.SLACK_SIGNING_SECRET,\n signatureVerification = true,\n logger,\n logLevel = LogLevel.INFO,\n customPropertiesExtractor,\n ackTimeoutMs = ACK_TIMEOUT_MS,\n }: VercelReceiverOptions = {}) {\n if (!signingSecret) {\n throw new VercelReceiverError(ERROR_MESSAGES.SIGNING_SECRET_REQUIRED);\n }\n\n this.signingSecret = signingSecret;\n this.signatureVerification = signatureVerification;\n this.logger = this.createScopedLogger(\n logger ?? new ConsoleLogger(),\n logLevel,\n );\n this.customPropertiesExtractor = customPropertiesExtractor;\n this.ackTimeoutMs = ackTimeoutMs;\n\n this.logger.debug(\"VercelReceiver initialized\");\n }\n\n /**\n * Initializes the receiver with a Slack Bolt app instance.\n * This method is called automatically by the Bolt framework.\n *\n * @param app - The Slack Bolt app instance\n */\n public init(app: App): void {\n this.app = app;\n this.logger.debug(\"App initialized in VercelReceiver\");\n }\n\n /**\n * Starts the receiver and returns a handler function for processing requests.\n * This method is called automatically by the Bolt framework.\n *\n * @returns A handler function that processes incoming Slack requests\n */\n public async start(): Promise<VercelHandler> {\n this.logger.debug(\"VercelReceiver started\");\n return this.toHandler();\n }\n\n /**\n * Stops the receiver. This method is called automatically by the Bolt framework.\n */\n public async stop(): Promise<void> {\n this.logger.debug(\"VercelReceiver stopped\");\n }\n\n /**\n * Creates a handler function that processes incoming Slack requests.\n * This is the main entry point for handling Slack events in Vercel.\n * It is called automatically by the Bolt framework in the start() method.\n *\n * @returns A handler function compatible with Vercel's function signature\n */\n public toHandler(): VercelHandler {\n return async (req: Request): Promise<Response> => {\n try {\n const rawBody = await req.text();\n\n if (this.signatureVerification) {\n this.verifyRequest(req, rawBody);\n }\n\n const body = await this.parseRequestBody(req, rawBody);\n\n if (body.type === \"url_verification\") {\n this.logger.debug(\"Handling URL verification challenge\");\n return Response.json({ challenge: body.challenge });\n }\n\n return await this.handleSlackEvent(req, body);\n } catch (error) {\n return this.handleError(error);\n }\n };\n }\n\n private async parseRequestBody(\n req: Request,\n rawBody: string,\n ): Promise<StringIndexed> {\n const contentType = req.headers.get(\"content-type\");\n\n try {\n if (contentType === \"application/x-www-form-urlencoded\") {\n const parsedBody: StringIndexed = {};\n const params = new URLSearchParams(rawBody);\n\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n\n if (typeof parsedBody.payload === \"string\") {\n return JSON.parse(parsedBody.payload);\n }\n return parsedBody;\n }\n if (contentType === \"application/json\") {\n return JSON.parse(rawBody);\n }\n\n this.logger.warn(`Unexpected content-type detected: ${contentType}`);\n\n return JSON.parse(rawBody);\n } catch (e) {\n throw new RequestParsingError(\n `Failed to parse body as JSON data for content-type: ${contentType}. Error: ${\n e instanceof Error ? e.message : String(e)\n }`,\n );\n }\n }\n\n private async handleSlackEvent(\n req: Request,\n body: StringIndexed,\n ): Promise<Response> {\n if (!this.app) {\n throw new VercelReceiverError(ERROR_MESSAGES.APP_NOT_INITIALIZED, 500);\n }\n\n let isAcknowledged = false;\n let responseResolver: (value: Response) => void;\n let responseRejecter: (error: Error) => void;\n\n const responsePromise = new Promise<Response>((resolve, reject) => {\n responseResolver = resolve;\n responseRejecter = reject;\n });\n\n // Slack requires an acknowledgment from your app within 3 seconds\n const timeoutId = setTimeout(() => {\n if (!isAcknowledged) {\n this.logger.error(ERROR_MESSAGES.EVENT_NOT_ACKNOWLEDGED);\n const error = new VercelReceiverError(\n ERROR_MESSAGES.REQUEST_TIMEOUT,\n 408,\n );\n responseRejecter(error);\n }\n }, this.ackTimeoutMs);\n\n // Create acknowledgment function\n const ackFn: AckFn<StringIndexed> = async (responseBody) => {\n this.logger.debug(`ack() call begins (body: ${responseBody})`);\n if (isAcknowledged) {\n throw new ReceiverMultipleAckError();\n }\n\n isAcknowledged = true;\n clearTimeout(timeoutId);\n\n try {\n let body: string | undefined;\n if (typeof responseBody === \"undefined\") {\n body = undefined;\n } else if (typeof responseBody === \"string\") {\n body = responseBody;\n } else {\n body = JSON.stringify(responseBody);\n }\n const response = new Response(body, {\n status: 200,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n responseResolver(response);\n } catch (error) {\n this.logger.error(ERROR_MESSAGES.ACKNOWLEDGMENT_ERROR, error);\n responseRejecter(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n };\n\n const event = this.createSlackReceiverEvent({\n body,\n headers: req.headers,\n ack: ackFn,\n request: req,\n });\n\n // Process event in background using waitUntil from Vercel Functions\n // https://vercel.com/docs/functions/functions-api-reference/vercel-functions-package#waituntil\n waitUntil(\n this.app.processEvent(event).catch((error) => {\n return this.handleError(error);\n }),\n );\n\n try {\n return await responsePromise;\n } catch (error) {\n return this.handleError(error);\n }\n }\n\n private verifyRequest(req: Request, body: string): void {\n const timestamp = req.headers.get(SLACK_TIMESTAMP_HEADER);\n const signature = req.headers.get(SLACK_SIGNATURE_HEADER);\n\n if (!signature) {\n throw new ReceiverAuthenticityError(\n ERROR_MESSAGES.MISSING_REQUIRED_HEADER(SLACK_SIGNATURE_HEADER),\n );\n }\n\n if (!timestamp) {\n throw new ReceiverAuthenticityError(\n ERROR_MESSAGES.MISSING_REQUIRED_HEADER(SLACK_TIMESTAMP_HEADER),\n );\n }\n\n try {\n verifySlackRequest({\n signingSecret: this.signingSecret,\n body,\n headers: {\n \"x-slack-signature\": signature,\n \"x-slack-request-timestamp\": Number.parseInt(timestamp, 10),\n },\n logger: this.logger,\n });\n } catch (error) {\n throw new ReceiverAuthenticityError(\n error instanceof Error\n ? error.message\n : \"Failed to verify request signature\",\n );\n }\n }\n\n private createSlackReceiverEvent({\n body,\n headers,\n ack,\n request,\n }: {\n body: StringIndexed;\n headers: Headers;\n ack: AckFn<StringIndexed>;\n request: Request;\n }): ReceiverEvent {\n const customProperties = this.customPropertiesExtractor\n ? this.customPropertiesExtractor(request)\n : {};\n\n const retryNum = headers.get(SLACK_RETRY_NUM_HEADER) || \"0\";\n\n const retryReason = headers.get(SLACK_RETRY_REASON_HEADER) || \"\";\n\n return {\n body,\n ack,\n retryNum: Number(retryNum),\n retryReason,\n customProperties,\n };\n }\n\n public handleError(error: unknown): Response {\n const errorMessage = getErrorMessage(error);\n const errorType = getErrorType(error);\n const errorStatusCode = getStatusCode(error);\n\n this.logger.error(error);\n return new Response(\n JSON.stringify({\n error: errorMessage,\n type: errorType,\n }),\n {\n status: errorStatusCode,\n headers: { \"content-type\": \"application/json\" },\n },\n );\n }\n\n private createScopedLogger(logger: Logger, logLevel: LogLevel): Logger {\n logger.setLevel(logLevel);\n\n return {\n ...logger,\n error: (...args) => logger.error?.(LOG_PREFIX, ...args),\n warn: (...args) => logger.warn?.(LOG_PREFIX, ...args),\n info: (...args) => logger.info?.(LOG_PREFIX, ...args),\n debug: (...args) => logger.debug?.(LOG_PREFIX, ...args),\n setLevel: logger.setLevel,\n getLevel: logger.getLevel,\n };\n }\n}\n\n/**\n * Creates a Vercel-compatible handler function for a Slack Bolt app.\n * This is the recommended way to create handlers for deployment on Vercel.\n *\n * @param {App} app - The initialized Slack Bolt app instance.\n * @param {VercelReceiver} receiver - The VercelReceiver instance.\n * @returns {VercelHandler} A handler function compatible with Vercel's function signature.\n *\n * @example\n * ```typescript\n * // api/events.ts\n * import { createHandler } from '@vercel/slack-bolt';\n * import { app, receiver } from '../app';\n *\n * const handler = createHandler(app, receiver);\n *\n * export const POST = async (req: Request) => {\n * return handler(req);\n * };\n * ```\n *\n * @throws {Error} If app initialization fails.\n * @throws {VercelReceiverError} If request processing fails.\n */\nexport function createHandler(\n app: App,\n receiver: VercelReceiver,\n): VercelHandler {\n let initPromise: Promise<void> | null = null;\n\n return async (req: Request) => {\n try {\n if (!initPromise) {\n initPromise = app.init();\n }\n await initPromise;\n\n receiver.init(app);\n const handler = await receiver.start();\n return handler(req);\n } catch (error) {\n const logger = receiver.getLogger();\n logger.error(ERROR_MESSAGES.CREATE_HANDLER_ERROR, error);\n return new Response(\n JSON.stringify({\n error: ERROR_MESSAGES.INTERNAL_SERVER_ERROR_HANDLER,\n type: ERROR_MESSAGES.TYPES.HANDLER_ERROR,\n }),\n { status: 500, headers: { \"content-type\": \"application/json\" } },\n );\n }\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/index.ts"],"names":["body"],"mappings":"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","file":"index.mjs","sourcesContent":["// Error messages constants\nexport const ERROR_MESSAGES = {\n // VercelReceiver errors\n SIGNING_SECRET_REQUIRED:\n \"SLACK_SIGNING_SECRET is required for VercelReceiver\",\n APP_NOT_INITIALIZED: \"App not initialized\",\n REQUEST_TIMEOUT: \"Request timeout\",\n EVENT_NOT_ACKNOWLEDGED: \"Event not acknowledged within timeout period\",\n\n // Header validation errors\n MISSING_REQUIRED_HEADER: (header: string) =>\n `Missing required header: ${header}`,\n\n // Generic fallback errors\n REQUEST_VERIFICATION_FAILED: \"Request verification failed\",\n INTERNAL_SERVER_ERROR: \"Internal server error\",\n INTERNAL_SERVER_ERROR_HANDLER: \"Internal Server Error\",\n ACKNOWLEDGMENT_ERROR: \"Error in acknowledgment handler\",\n CREATE_HANDLER_ERROR: \"Error in createHandler:\",\n\n // Error type names\n TYPES: {\n VERCEL_RECEIVER_ERROR: \"VercelReceiverError\",\n SIGNATURE_VERIFICATION_ERROR: \"SignatureVerificationError\",\n REQUEST_PARSING_ERROR: \"RequestParsingError\",\n UNEXPECTED_ERROR: \"UnexpectedError\",\n HANDLER_ERROR: \"HandlerError\",\n },\n} as const;\n\nexport class VercelReceiverError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number = 500,\n ) {\n super(message);\n this.name = ERROR_MESSAGES.TYPES.VERCEL_RECEIVER_ERROR;\n }\n}\n\nexport class RequestParsingError extends VercelReceiverError {\n constructor(message: string = \"Failed to parse request\") {\n super(message, 400);\n this.name = ERROR_MESSAGES.TYPES.REQUEST_PARSING_ERROR;\n }\n}\n\n/**\n * Determines the appropriate HTTP status code for a given error.\n * @param error The error to get status code for\n * @returns HTTP status code\n */\nexport function getStatusCode(error: unknown): number {\n if (error instanceof VercelReceiverError) {\n return error.statusCode;\n }\n\n // External error types from @slack/bolt\n if (error && typeof error === \"object\") {\n const errorName =\n error.constructor?.name || (error as { name?: string }).name;\n switch (errorName) {\n case \"ReceiverAuthenticityError\":\n return 401;\n case \"ReceiverMultipleAckError\":\n return 500;\n case \"RequestParsingError\":\n return 400;\n case \"SignatureVerificationError\":\n return 400;\n default:\n return 500;\n }\n }\n\n return 500;\n}\n\n/**\n * Gets the error message for response.\n * @param error The error to get message for\n * @returns Error message string\n */\nexport function getErrorMessage(error: unknown): string {\n if (error && typeof error === \"object\" && \"message\" in error) {\n return String(error.message);\n }\n return ERROR_MESSAGES.INTERNAL_SERVER_ERROR;\n}\n\n/**\n * Gets the error type for response.\n * @param error The error to get type for\n * @returns Error type string\n */\nexport function getErrorType(error: unknown): string {\n if (error && typeof error === \"object\") {\n const ctorName = (error as { constructor?: { name?: string } }).constructor\n ?.name;\n const nameProp = (error as { name?: string }).name;\n const errorName =\n ctorName ?? nameProp ?? ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;\n // Use \"UnexpectedError\" for generic Error instances, otherwise use the actual name\n return errorName === \"Error\"\n ? ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR\n : errorName;\n }\n return ERROR_MESSAGES.TYPES.UNEXPECTED_ERROR;\n}\n","import {\n type AckFn,\n type App,\n type Receiver,\n ReceiverAuthenticityError,\n type ReceiverEvent,\n ReceiverMultipleAckError,\n type StringIndexed,\n verifySlackRequest,\n} from \"@slack/bolt\";\nimport { ConsoleLogger, type Logger, LogLevel } from \"@slack/logger\";\nimport { waitUntil } from \"@vercel/functions\";\nimport {\n ERROR_MESSAGES,\n getErrorMessage,\n getErrorType,\n getStatusCode,\n RequestParsingError,\n VercelReceiverError,\n} from \"./errors\";\n\n// Types\n/**\n * A function to handle the request from the Slack app.\n * @param req - The request from the Slack app.\n * @returns A response object.\n */\nexport type VercelHandler = (req: Request) => Promise<Response>;\n\n/**\n * Configuration options for the VercelReceiver.\n * @property signingSecret - The signing secret for the Slack app.\n * @property signatureVerification - If true, verifies the Slack request signature.\n * @property logger - The logger to use for the VercelReceiver.\n * @property logLevel - The log level to use for the VercelReceiver.\n * @property customPropertiesExtractor - A function to extract custom properties from the request.\n */\nexport interface VercelReceiverOptions {\n /**\n * The signing secret for the Slack app.\n * @default process.env.SLACK_SIGNING_SECRET\n */\n signingSecret?: string;\n /**\n * If true, verifies the Slack request signature.\n * @default true\n */\n signatureVerification?: boolean;\n /**\n * The logger to use for the VercelReceiver.\n * @default new ConsoleLogger()\n */\n logger?: Logger;\n /**\n * The log level to use for the VercelReceiver.\n * @default LogLevel.INFO\n */\n logLevel?: LogLevel;\n /**\n * A function to extract custom properties from incoming events.\n * @default undefined\n * @returns An object with custom properties.\n */\n customPropertiesExtractor?: (req: Request) => StringIndexed;\n /**\n * The timeout in milliseconds for event acknowledgment.\n * @default 3001\n */\n ackTimeoutMs?: number;\n}\n\nconst LOG_PREFIX = \"[@vercel/slack-bolt]\";\nconst ACK_TIMEOUT_MS = 3001;\nconst SLACK_RETRY_NUM_HEADER = \"x-slack-retry-num\";\nconst SLACK_RETRY_REASON_HEADER = \"x-slack-retry-reason\";\nconst SLACK_TIMESTAMP_HEADER = \"x-slack-request-timestamp\";\nconst SLACK_SIGNATURE_HEADER = \"x-slack-signature\";\n\n/**\n * A Slack Bolt receiver implementation designed for Vercel's serverless environment.\n * Handles Slack events, interactions, and slash commands with automatic request verification,\n * background processing, and timeout management.\n *\n * @example\n * ```typescript\n * import { App } from '@slack/bolt';\n * import { VercelReceiver, createHandler } from '@vercel/slack-bolt';\n *\n * const receiver = new VercelReceiver();\n *\n * const app = new App({\n * receiver,\n * token: process.env.SLACK_BOT_TOKEN,\n * signingSecret: process.env.SLACK_SIGNING_SECRET,\n * });\n * ```\n *\n */\nexport class VercelReceiver implements Receiver {\n private readonly signingSecret: string;\n private readonly signatureVerification: boolean;\n private readonly logger: Logger;\n private readonly customPropertiesExtractor?: (req: Request) => StringIndexed;\n private readonly ackTimeoutMs: number;\n private app?: App;\n\n /**\n * Gets the logger instance used by this receiver.\n * @returns The logger instance\n */\n public getLogger(): Logger {\n return this.logger;\n }\n\n /**\n * Creates a new VercelReceiver instance.\n *\n * @param options - Configuration options for the receiver\n * @throws {VercelReceiverError} When signing secret is not provided\n *\n * @example\n * ```typescript\n * const receiver = new VercelReceiver();\n * ```\n */\n public constructor({\n signingSecret = process.env.SLACK_SIGNING_SECRET,\n signatureVerification = true,\n logger,\n logLevel = LogLevel.INFO,\n customPropertiesExtractor,\n ackTimeoutMs = ACK_TIMEOUT_MS,\n }: VercelReceiverOptions = {}) {\n if (!signingSecret) {\n throw new VercelReceiverError(ERROR_MESSAGES.SIGNING_SECRET_REQUIRED);\n }\n\n this.signingSecret = signingSecret;\n this.signatureVerification = signatureVerification;\n this.logger = this.createScopedLogger(\n logger ?? new ConsoleLogger(),\n logLevel,\n );\n this.customPropertiesExtractor = customPropertiesExtractor;\n this.ackTimeoutMs = ackTimeoutMs;\n\n this.logger.debug(\"VercelReceiver initialized\");\n }\n\n /**\n * Initializes the receiver with a Slack Bolt app instance.\n * This method is called automatically by the Bolt framework.\n *\n * @param app - The Slack Bolt app instance\n */\n public init(app: App): void {\n this.app = app;\n this.logger.debug(\"App initialized in VercelReceiver\");\n }\n\n /**\n * Starts the receiver and returns a handler function for processing requests.\n * This method is called automatically by the Bolt framework.\n *\n * @returns A handler function that processes incoming Slack requests\n */\n public async start(): Promise<VercelHandler> {\n this.logger.debug(\"VercelReceiver started\");\n return this.toHandler();\n }\n\n /**\n * Stops the receiver. This method is called automatically by the Bolt framework.\n */\n public async stop(): Promise<void> {\n this.logger.debug(\"VercelReceiver stopped\");\n }\n\n /**\n * Creates a handler function that processes incoming Slack requests.\n * This is the main entry point for handling Slack events in Vercel.\n * It is called automatically by the Bolt framework in the start() method.\n *\n * @returns A handler function compatible with Vercel's function signature\n */\n public toHandler(): VercelHandler {\n return async (req: Request): Promise<Response> => {\n try {\n const rawBody = await req.text();\n\n if (this.signatureVerification) {\n this.verifyRequest(req, rawBody);\n }\n\n const body = await this.parseRequestBody(req, rawBody);\n\n if (body.type === \"url_verification\") {\n this.logger.debug(\"Handling URL verification challenge\");\n return Response.json({ challenge: body.challenge });\n }\n\n return await this.handleSlackEvent(req, body);\n } catch (error) {\n return this.handleError(error);\n }\n };\n }\n\n private async parseRequestBody(\n req: Request,\n rawBody: string,\n ): Promise<StringIndexed> {\n const contentType = req.headers.get(\"content-type\");\n\n try {\n if (contentType === \"application/x-www-form-urlencoded\") {\n const parsedBody: StringIndexed = {};\n const params = new URLSearchParams(rawBody);\n\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n\n if (typeof parsedBody.payload === \"string\") {\n return JSON.parse(parsedBody.payload);\n }\n return parsedBody;\n }\n if (contentType === \"application/json\") {\n return JSON.parse(rawBody);\n }\n\n this.logger.warn(`Unexpected content-type detected: ${contentType}`);\n\n return JSON.parse(rawBody);\n } catch (e) {\n throw new RequestParsingError(\n `Failed to parse body as JSON data for content-type: ${contentType}. Error: ${\n e instanceof Error ? e.message : String(e)\n }`,\n );\n }\n }\n\n private async handleSlackEvent(\n req: Request,\n body: StringIndexed,\n ): Promise<Response> {\n if (!this.app) {\n throw new VercelReceiverError(ERROR_MESSAGES.APP_NOT_INITIALIZED, 500);\n }\n\n let isAcknowledged = false;\n let responseResolver: (value: Response) => void;\n let responseRejecter: (error: Error) => void;\n\n const responsePromise = new Promise<Response>((resolve, reject) => {\n responseResolver = resolve;\n responseRejecter = reject;\n });\n\n // Slack requires an acknowledgment from your app within 3 seconds\n const timeoutId = setTimeout(() => {\n if (!isAcknowledged) {\n this.logger.error(ERROR_MESSAGES.EVENT_NOT_ACKNOWLEDGED);\n const error = new VercelReceiverError(\n ERROR_MESSAGES.REQUEST_TIMEOUT,\n 408,\n );\n responseRejecter(error);\n }\n }, this.ackTimeoutMs);\n\n // Create acknowledgment function\n const ackFn: AckFn<StringIndexed> = async (responseBody) => {\n this.logger.debug(`ack() call begins (body: ${responseBody})`);\n if (isAcknowledged) {\n throw new ReceiverMultipleAckError();\n }\n\n isAcknowledged = true;\n clearTimeout(timeoutId);\n\n try {\n let body: string | undefined;\n if (typeof responseBody === \"undefined\") {\n body = undefined;\n } else if (typeof responseBody === \"string\") {\n body = responseBody;\n } else {\n body = JSON.stringify(responseBody);\n }\n const response = new Response(body, {\n status: 200,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n responseResolver(response);\n } catch (error) {\n this.logger.error(ERROR_MESSAGES.ACKNOWLEDGMENT_ERROR, error);\n responseRejecter(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n };\n\n const event = this.createSlackReceiverEvent({\n body,\n headers: req.headers,\n ack: ackFn,\n request: req,\n });\n\n // Process event in background using waitUntil from Vercel Functions\n // https://vercel.com/docs/functions/functions-api-reference/vercel-functions-package#waituntil\n waitUntil(\n this.app.processEvent(event).catch((error) => {\n return this.handleError(error);\n }),\n );\n\n try {\n return await responsePromise;\n } catch (error) {\n return this.handleError(error);\n }\n }\n\n private verifyRequest(req: Request, body: string): void {\n const timestamp = req.headers.get(SLACK_TIMESTAMP_HEADER);\n const signature = req.headers.get(SLACK_SIGNATURE_HEADER);\n\n if (!signature) {\n throw new ReceiverAuthenticityError(\n ERROR_MESSAGES.MISSING_REQUIRED_HEADER(SLACK_SIGNATURE_HEADER),\n );\n }\n\n if (!timestamp) {\n throw new ReceiverAuthenticityError(\n ERROR_MESSAGES.MISSING_REQUIRED_HEADER(SLACK_TIMESTAMP_HEADER),\n );\n }\n\n try {\n verifySlackRequest({\n signingSecret: this.signingSecret,\n body,\n headers: {\n \"x-slack-signature\": signature,\n \"x-slack-request-timestamp\": Number.parseInt(timestamp, 10),\n },\n logger: this.logger,\n });\n } catch (error) {\n throw new ReceiverAuthenticityError(\n error instanceof Error\n ? error.message\n : \"Failed to verify request signature\",\n );\n }\n }\n\n private createSlackReceiverEvent({\n body,\n headers,\n ack,\n request,\n }: {\n body: StringIndexed;\n headers: Headers;\n ack: AckFn<StringIndexed>;\n request: Request;\n }): ReceiverEvent {\n const customProperties = this.customPropertiesExtractor\n ? this.customPropertiesExtractor(request)\n : {};\n\n const retryNum = headers.get(SLACK_RETRY_NUM_HEADER) || \"0\";\n\n const retryReason = headers.get(SLACK_RETRY_REASON_HEADER) || \"\";\n\n return {\n body,\n ack,\n retryNum: Number(retryNum),\n retryReason,\n customProperties,\n };\n }\n\n public handleError(error: unknown): Response {\n const errorMessage = getErrorMessage(error);\n const errorType = getErrorType(error);\n const errorStatusCode = getStatusCode(error);\n\n this.logger.error(error);\n return new Response(\n JSON.stringify({\n error: errorMessage,\n type: errorType,\n }),\n {\n status: errorStatusCode,\n headers: { \"content-type\": \"application/json\" },\n },\n );\n }\n\n private createScopedLogger(logger: Logger, logLevel: LogLevel): Logger {\n logger.setLevel(logLevel);\n\n return {\n ...logger,\n error: (...args) => logger.error?.(LOG_PREFIX, ...args),\n warn: (...args) => logger.warn?.(LOG_PREFIX, ...args),\n info: (...args) => logger.info?.(LOG_PREFIX, ...args),\n debug: (...args) => logger.debug?.(LOG_PREFIX, ...args),\n setLevel: logger.setLevel,\n getLevel: logger.getLevel,\n };\n }\n}\n\n/**\n * Creates a Vercel-compatible handler function for a Slack Bolt app.\n * This is the recommended way to create handlers for deployment on Vercel.\n *\n * @param {App} app - The initialized Slack Bolt app instance.\n * @param {VercelReceiver} receiver - The VercelReceiver instance.\n * @returns {VercelHandler} A handler function compatible with Vercel's function signature.\n *\n * @example\n * ```typescript\n * // api/events.ts\n * import { createHandler } from '@vercel/slack-bolt';\n * import { app, receiver } from '../app';\n *\n * const handler = createHandler(app, receiver);\n *\n * export const POST = async (req: Request) => {\n * return handler(req);\n * };\n * ```\n *\n * @throws {Error} If app initialization fails.\n * @throws {VercelReceiverError} If request processing fails.\n */\nexport function createHandler(\n app: App,\n receiver: VercelReceiver,\n): VercelHandler {\n let initPromise: Promise<void> | null = null;\n\n return async (req: Request) => {\n try {\n if (!initPromise) {\n initPromise = app.init();\n }\n await initPromise;\n\n receiver.init(app);\n const handler = await receiver.start();\n return handler(req);\n } catch (error) {\n // if app.init fails, we use console.error instead of logger.error because the logger is not available\n console.error(ERROR_MESSAGES.CREATE_HANDLER_ERROR, error);\n return new Response(\n JSON.stringify({\n error: ERROR_MESSAGES.INTERNAL_SERVER_ERROR_HANDLER,\n type: ERROR_MESSAGES.TYPES.HANDLER_ERROR,\n }),\n { status: 500, headers: { \"content-type\": \"application/json\" } },\n );\n }\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/slack-bolt",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A Vercel receiver for building Slack apps with Bolt and deploying them to Vercel",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -34,12 +34,12 @@
34
34
  "license": "MIT",
35
35
  "dependencies": {
36
36
  "@slack/logger": "^4.0.0",
37
- "@vercel/functions": "^2.2.12"
37
+ "@vercel/functions": "^3.1.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@biomejs/biome": "2.2.2",
41
- "@changesets/cli": "^2.29.6",
42
- "@types/node": "^24.3.0",
41
+ "@changesets/cli": "^2.29.7",
42
+ "@types/node": "^24.4.0",
43
43
  "husky": "^9.1.7",
44
44
  "tsup": "^8.5.0",
45
45
  "typescript": "^5.9.2",