{"id":13484975,"url":"https://github.com/slackapi/bolt-js","last_synced_at":"2026-04-07T00:01:50.925Z","repository":{"id":36992713,"uuid":"63654176","full_name":"slackapi/bolt-js","owner":"slackapi","description":"A framework to build Slack apps using JavaScript","archived":false,"fork":false,"pushed_at":"2026-04-03T15:59:15.000Z","size":14125,"stargazers_count":2897,"open_issues_count":77,"forks_count":426,"subscribers_count":37,"default_branch":"main","last_synced_at":"2026-04-03T19:31:58.214Z","etag":null,"topics":["framework","javascript","slack","slack-apps","socket-mode","typescript","websocket","websocket-client","websockets"],"latest_commit_sha":null,"homepage":"https://docs.slack.dev/tools/bolt-js/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/slackapi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2016-07-19T02:46:33.000Z","updated_at":"2026-04-03T15:59:21.000Z","dependencies_parsed_at":"2023-12-20T20:28:55.591Z","dependency_job_id":"d88902dc-a7c9-4dd9-a689-b20fddc202f1","html_url":"https://github.com/slackapi/bolt-js","commit_stats":{"total_commits":1359,"total_committers":129,"mean_commits":"10.534883720930232","dds":0.8425312729948491,"last_synced_commit":"f5234dd7b126aa58aaae743c8d9faa080cfd4efe"},"previous_names":["slackapi/bolt","missionsai/slapp","beepboophq/slackapp-js","beepboophq/slapp"],"tags_count":163,"template":false,"template_full_name":null,"purl":"pkg:github/slackapi/bolt-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slackapi%2Fbolt-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slackapi%2Fbolt-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slackapi%2Fbolt-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slackapi%2Fbolt-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slackapi","download_url":"https://codeload.github.com/slackapi/bolt-js/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slackapi%2Fbolt-js/sbom","scorecard":{"id":20814,"data":{"date":"2025-08-04","repo":{"name":"github.com/slackapi/bolt-js","commit":"94bbc94a67b1764280bddb2391398e4693c9ba80"},"scorecard":{"version":"v5.2.1-28-gc1d103a9","commit":"c1d103a9bb9f635ec7260bf9aa0699466fa4be0e"},"score":5.9,"checks":[{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 9 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#packaging"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#cii-best-practices"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/ci-build.yml:24","Info: jobLevel 'contents' permission set to 'read': .github/workflows/samples.yml:21","Info: jobLevel 'contents' permission set to 'read': .github/workflows/samples.yml:48","Warn: no topLevel permission defined: .github/workflows/ci-build.yml:1","Warn: no topLevel permission defined: .github/workflows/samples.yml:1","Warn: no topLevel permission defined: .github/workflows/triage-issues.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#binary-artifacts"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#security-policy"}},{"name":"Pinned-Dependencies","score":1,"reason":"dependency not pinned by hash detected -- score normalized to 1","details":["Warn: npmCommand not pinned by hash: examples/custom-properties/link.sh:6","Warn: npmCommand not pinned by hash: examples/custom-properties/link.sh:10","Warn: npmCommand not pinned by hash: examples/custom-receiver/link.sh:6","Warn: npmCommand not pinned by hash: examples/custom-receiver/link.sh:10","Warn: npmCommand not pinned by hash: examples/oauth-express-receiver/link.sh:6","Warn: npmCommand not pinned by hash: examples/oauth-express-receiver/link.sh:10","Warn: npmCommand not pinned by hash: examples/oauth/link.sh:6","Warn: npmCommand not pinned by hash: examples/oauth/link.sh:10","Warn: npmCommand not pinned by hash: examples/socket-mode-oauth/link.sh:6","Warn: npmCommand not pinned by hash: examples/socket-mode-oauth/link.sh:10","Warn: npmCommand not pinned by hash: examples/socket-mode/link.sh:6","Warn: npmCommand not pinned by hash: examples/socket-mode/link.sh:10","Warn: npmCommand not pinned by hash: .github/workflows/ci-build.yml:34","Warn: npmCommand not pinned by hash: .github/workflows/samples.yml:32","Warn: npmCommand not pinned by hash: .github/workflows/samples.yml:35","Warn: npmCommand not pinned by hash: .github/workflows/samples.yml:35","Warn: npmCommand not pinned by hash: .github/workflows/samples.yml:62","Warn: npmCommand not pinned by hash: .github/workflows/samples.yml:71","Warn: npmCommand not pinned by hash: .github/workflows/samples.yml:71","Info:   8 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   2 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of  19 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#pinned-dependencies"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#signed-releases"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-14T16:46:14.509Z","repository_id":36992713,"created_at":"2025-08-14T16:46:14.510Z","updated_at":"2025-08-14T16:46:14.510Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31494177,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T17:22:55.647Z","status":"ssl_error","status_checked_at":"2026-04-06T17:22:54.741Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["framework","javascript","slack","slack-apps","socket-mode","typescript","websocket","websocket-client","websockets"],"created_at":"2024-07-31T17:01:41.204Z","updated_at":"2026-04-07T00:01:50.857Z","avatar_url":"https://github.com/slackapi.png","language":"TypeScript","readme":"# Bolt \u003cimg src=\"https://raw.githubusercontent.com/slackapi/bolt-js/main/docs/img/bolt.svg\" alt=\"Bolt logo\" width=\"32\"/\u003e for JavaScript\n\n[![codecov](https://codecov.io/gh/slackapi/bolt-js/branch/main/graph/badge.svg?token=x4oCgiexvp)](https://codecov.io/gh/slackapi/bolt-js)\n[![Node.js CI](https://github.com/slackapi/bolt-js/actions/workflows/ci-build.yml/badge.svg)](https://github.com/slackapi/bolt-js/actions/workflows/ci-build.yml)\n\nA JavaScript framework to build Slack apps in a flash with the latest platform features. Read the [getting started guide](https://docs.slack.dev/tools/bolt-js/getting-started) to set-up and run your first Bolt app.\n\nRead [the documentation](https://docs.slack.dev/tools/bolt-js) to explore the basic and advanced concepts of Bolt for JavaScript.\n\n## Setup\n\n```bash\nnpm install @slack/bolt\n```\n\n## Initialization\n\nCreate an app by calling the constructor, which is a top-level export.\n\n```js\nconst { App } = require('@slack/bolt');\n\nconst app = new App({\n  signingSecret: process.env.SLACK_SIGNING_SECRET,\n  token: process.env.SLACK_BOT_TOKEN,\n});\n\n/* Add functionality here */\n\n(async () =\u003e {\n  // Start the app\n  await app.start(process.env.PORT || 3000);\n\n  app.logger.info('⚡️ Bolt app is running!');\n})();\n```\n\n## Listening for events\n\nThe Slack **Request URL** for a Bolt app must have the path set to `/slack/events`.  \nFor example: `https://my-slack-app.example.com/slack/events`.  \nOtherwise, all incoming requests from Slack won't be handled.\n\nApps typically react to a collection of incoming events, which can correspond [Events API events](https://api.slack.com/events-api), [actions](https://api.slack.com/interactivity/components), [shortcuts](https://api.slack.com/interactivity/shortcuts), [slash commands](https://api.slack.com/interactivity/slash-commands) or [options requests](https://api.slack.com/reference/block-kit/block-elements#external_select). For each type of\nrequest, there's a method to build a listener function.\n\n```js\n// Listen for an action from a Block Kit element (buttons, select menus, date pickers, etc)\napp.action(actionId, fn);\n\n// Listen for dialog submissions\napp.action({ callback_id: callbackId }, fn);\n\n// Listen for slash commands\napp.command(commandName, fn);\n\n// Listen for an event from the Events API\napp.event(eventType, fn);\n\n// Listen for a custom step execution from a workflow\napp.function(callbackId, fn)\n\n// Convenience method to listen to only `message` events using a string or RegExp\napp.message([pattern ,] fn);\n\n// Listen for options requests (from select menus with an external data source)\napp.options(actionId, fn);\n\n// Listen for a global or message shortcuts\napp.shortcut(callbackId, fn);\n\n// Listen for view_submission modal events\napp.view(callbackId, fn);\n\n```\n\n## Making things happen\n\nMost of the app's functionality will be inside listener functions (the `fn` parameters above). These functions are called with a set of arguments.\n\n| Argument  | Description  |\n| :---: | :--- |\n| `payload` | Contents of the incoming event. The payload structure depends on the listener. For example, for an Events API event, `payload` will be the [event type structure](https://api.slack.com/events-api#event_type_structure). For a block action, it will be the action from within the `actions` array. The `payload` object is also accessible via the alias corresponding to the listener (`message`, `event`, `action`, `shortcut`, `view`, `command`, or `options`). For example, if you were building a `message()` listener, you could use the `payload` and `message` arguments interchangeably. **An easy way to understand what's in a payload is to log it**, or use TypeScript. |\n| `say` | Function to send a message to the channel associated with the incoming event. This argument is only available when the listener is triggered for events that contain a `channel_id` (the most common being `message` events). `say` accepts simple strings (for plain-text messages) and objects (for messages containing blocks). `say` returns a promise that will resolve with a [`chat.postMessage` response](https://api.slack.com/methods/chat.postMessage).\n| `ack` | Function that **must** be called to acknowledge that an incoming event was received by your app. `ack` exists for all actions, shortcuts, view, slash command and options requests. `ack` returns a promise that resolves when complete. Read more in [Acknowledging events](#acknowledging-events)\n| `client` | Web API client that uses the token associated with that event. For single-workspace installations, the token is provided to the constructor. For multi-workspace installations, the token is returned by the `authorize` function.\n| `respond` | Function that responds to an incoming event **if** it contains a `response_url` (actions, shortcuts, view submissions, and slash commands). `respond` returns a promise that resolves with the results of responding using the `response_url`.\n| `context` | Event context. This object contains data about the event and the app, such as the `botId`. Middleware can add additional context before the event is passed to listeners.\n| `body` | Object that contains the entire body of the request (superset of `payload`). Some accessory data is only available outside of the payload (such as `trigger_id` and `authorizations`).\n| `complete` | Function used to signal the successful completion of a custom step execution. This tells Slack to proceed with the next steps in the workflow. This argument is only available with the `.function` and `.action` listener when handling custom workflow step executions.\n| `fail` | Function used to signal that a custom step failed to complete. This tells Slack to stop the workflow execution. This argument is only available with the `.function` and `.action` listener when handling custom workflow step executions.\n\n\nThe arguments are grouped into properties of one object, so that it's easier to pick just the ones your listener needs (using\n[object destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Unpacking_fields_from_objects_passed_as_function_parameter)). Here is an example where the app sends a simple response, so there's no need for most of these arguments:\n\n```js\n// Reverse all messages the app can hear\napp.message(async ({ message, say }) =\u003e {\n  // Filter out message events with subtypes (see https://api.slack.com/events/message)\n  if (message.subtype === undefined || message.subtype === 'bot_message') {\n    const reversedText = [...message.text].reverse().join(\"\");\n    await say(reversedText);\n  }\n});\n```\n\n### Calling the Web API\n\nIn addition to the [`client` property passed to listeners](#making-things-happen), each app has a top-level `client` that can be used to call methods. Unlike the `client` passed to listeners, the top-level client must be passed a `token`. [Read the documentation](https://docs.slack.dev/tools/bolt-js/concepts#web-api) for more details.\n\n### Acknowledging events\n\nSome types of events need to be acknowledged in order to ensure a consistent user experience inside the Slack client (web, mobile, and desktop apps). This includes all action, shortcut, view, command, and options requests. Listeners for these events need to call the `ack()` function, which is passed in as an argument.\n\nIn general, the Slack platform expects an acknowledgement within 3 seconds, so listeners should call this function as soon as possible.\n\nDepending on the type of incoming event a listener is meant for, `ack()` should be called with a parameter:\n\n*  Block actions, global shortcuts, and message shortcuts: Call `ack()` with no parameters.\n\n* View submissions: Call `ack()` with no parameters or with a [response action](https://api.slack.com/surfaces/modals/using#updating_response).\n\n*  Options requests: Call `ack()` with an object containing the options for the user to see.\n\n*  Legacy message button clicks, menu selections, and slash commands: Either call `ack()` with no parameters, a `string` to to update the message with a simple message, or an `object` to replace it with a complex message. Replacing the message to remove the interactive elements is a best practice for any action that should only be performed once.\n\n* Events API events **do not** need an `ack()` function since they are automatically acknowledged by your app.\n\n## Getting Help\n\n[The documentation](https://docs.slack.dev/tools/bolt-js) has more information on basic and advanced concepts for Bolt for JavaScript.\n\nIf you otherwise get stuck, we're here to help. The following are the best ways to get assistance working through your issue:\n\n  * [Issue Tracker](http://github.com/slackapi/bolt-js/issues) for questions, bug reports, feature requests, and general discussion related to Bolt for JavaScript. Try searching for an existing issue before creating a new one.\n  * [Email](mailto:support@slack.com) our developer support team: `support@slack.com`\n## Contributing\n\nWe welcome contributions from everyone! Please check out our\n[Contributor's Guide](.github/contributing.md) for how to contribute in a\nhelpful and collaborative way.\n","funding_links":[],"categories":["TypeScript","HarmonyOS",":hammer_and_wrench: \u0026nbsp; Libraries and SDKs"],"sub_categories":["Windows Manager","JavaScript/TypeScript"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslackapi%2Fbolt-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslackapi%2Fbolt-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslackapi%2Fbolt-js/lists"}