diff --git a/examples/oauth-express-receiver/.gitignore b/examples/oauth-express-receiver/.gitignore new file mode 100644 index 000000000..49d69386c --- /dev/null +++ b/examples/oauth-express-receiver/.gitignore @@ -0,0 +1,3 @@ +# node / npm +node_modules/ +package-lock.json \ No newline at end of file diff --git a/examples/oauth-express-receiver/README.md b/examples/oauth-express-receiver/README.md new file mode 100644 index 000000000..73a752462 --- /dev/null +++ b/examples/oauth-express-receiver/README.md @@ -0,0 +1,56 @@ +# Bolt for JavaScript OAuth Test App + +This is a quick example app to test [OAuth](https://api.slack.com/authentication/oauth-v2) with Bolt for JavaScript's ExpressReceiver. + +If using OAuth, Slack requires a public URL where it can send requests. In this guide, we'll be using [`ngrok`](https://ngrok.com/download). Checkout [this guide](https://api.slack.com/tutorials/tunneling-with-ngrok) for setting it up. OAuth installation is only needed for public distribution. For internal apps, we recommend installing via your app configuration. + +Before we get started, make sure you have a development workspace where you have permissions to install apps. If you don’t have one setup, go ahead and [create one](https://slack.com/create). You also need to [create a new app](https://api.slack.com/apps?new_app=1) if you haven’t already. You will need to enable Socket Mode and generate an App Level Token. + +## Install Dependencies + +``` +npm install +``` + +## Setup Environment Variables + +This app requires you setup a few environment variables required for OAuth. +You can find these values in your [app configuration](https://api.slack.com/apps). + +```bash +export SLACK_CLIENT_ID=YOUR_SLACK_CLIENT_ID +export SLACK_CLIENT_SECRET=YOUR_SLACK_CLIENT_SECRET +export SLACK_SIGNING_SECRET=YOUR_SLACK_SIGNING_SECRET +``` + +## Run the App + +Start the app with the following command: + +``` +npm start +``` + +### Running with OAuth + +Only implement OAuth if you plan to distribute your application across multiple workspaces. Uncomment out the OAuth specific comments in the code. If you are on dev instance, you will have to uncomment out those options as well. + +Start `ngrok` so we can access the app on an external network and create a redirect URL for OAuth. + +``` +ngrok http 3000 +``` + +This output should include a forwarding address for `http` and `https` (we'll use the `https` one). It should look something like the following: + +``` +Forwarding https://3cb89939.ngrok.io -> http://localhost:3000 +``` + +Navigate to **OAuth & Permissions** in your app configuration and click **Add a Redirect URL**. The redirect URL should be set to your `ngrok` forwarding address with the `slack/oauth_redirect` path appended. ex: + +``` +https://3cb89939.ngrok.io/slack/oauth_redirect +``` + +Start the OAuth flow from https://{your own subdomain}.ngrok.io/slack/install \ No newline at end of file diff --git a/examples/oauth-express-receiver/app.js b/examples/oauth-express-receiver/app.js new file mode 100644 index 000000000..7a0f58572 --- /dev/null +++ b/examples/oauth-express-receiver/app.js @@ -0,0 +1,65 @@ +const { App, ExpressReceiver, LogLevel } = require('@slack/bolt'); + +// Create an ExpressReceiver +const receiver = new ExpressReceiver({ + signingSecret: process.env.SLACK_SIGNING_SECRET, + clientId: process.env.SLACK_CLIENT_ID, + clientSecret: process.env.SLACK_CLIENT_SECRET, + stateSecret: 'my-secret', + scopes: ['chat:write'], + installerOptions: { + // If below is true, /slack/install redirects installers to the Slack authorize URL + // without rendering the web page with "Add to Slack" button. + // This flag is available in @slack/bolt v3.7 or higher + // directInstall: true, + }, + installationStore: { + storeInstallation: async (installation) => { + // replace database.set so it fetches from your database + if (installation.isEnterpriseInstall && installation.enterprise !== undefined) { + // support for org wide app installation + return await database.set(installation.enterprise.id, installation); + } + if (installation.team !== undefined) { + // single team app installation + return await database.set(installation.team.id, installation); + } + throw new Error('Failed saving installation data to installationStore'); + }, + fetchInstallation: async (installQuery) => { + // replace database.get so it fetches from your database + if (installQuery.isEnterpriseInstall && installQuery.enterpriseId !== undefined) { + // org wide app installation lookup + return await database.get(installQuery.enterpriseId); + } + if (installQuery.teamId !== undefined) { + // single team app installation lookup + return await database.get(installQuery.teamId); + } + throw new Error('Failed fetching installation'); + }, + }, +}); + +// Create the Bolt App, using the receiver +const app = new App({ + receiver, + logLevel: LogLevel.DEBUG, // set loglevel at the App level +}); + +// Slack interactions like listening for events are methods on app +app.event('message', async ({ event, client }) => { + // Do some slack-specific stuff here + // await client.chat.postMessage(...); +}); + +// Set up other handling for other web requests as methods on receiver.router +receiver.router.get('/secret-page', (req, res) => { + // You're working with an express req and res now. + res.send('yay!'); +}); + +(async () => { + await app.start(8080); + console.log('Express app is running'); +})(); \ No newline at end of file diff --git a/examples/oauth-express-receiver/package.json b/examples/oauth-express-receiver/package.json new file mode 100644 index 000000000..3b07a1369 --- /dev/null +++ b/examples/oauth-express-receiver/package.json @@ -0,0 +1,15 @@ +{ + "name": "bolt-oauth-express-example", + "version": "1.0.0", + "description": "Example app using OAuth with ExpressReceiver", + "main": "app.js", + "scripts": { + "start": "node app.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Slack Technologies, Inc.", + "license": "MIT", + "dependencies": { + "@slack/bolt": "^3.6.0" + } +}