slackapi / bolt-js

A framework to build Slack apps using JavaScript
https://tools.slack.dev/bolt-js/
MIT License
2.74k stars 393 forks source link

Oauth endpoints not created #583

Closed jparr721 closed 4 years ago

jparr721 commented 4 years ago

Description

I followed the documentation here, and I cannot seem to get the oauth module working as is specified. In the docs, it says it sets up the following endpoints:

However, it appears neither is actually configured. I followed the default config (subbing in my own configs, of course), and have yet to see it return anything other than a cannot GET... message. Am I perhaps doing something wrong? Are the docs out of date or perhaps showing for a future release? I would love some guidance here.

What type of issue is this? (place an x in one of the [ ])

Requirements (place an x in each of the [ ])


Bug Report

Filling out the following details about bugs will help us solve your issue sooner.

Reproducible in:

package version: 2.2.3

node version: 14.4

OS version(s): Linux pop-os 5.4.0-7634-generic #38~1592497129~20.04~9a1ea2e-Ubuntu SMP Fri Jun 19 22:43:37 UTC x86_64 x86_64 x86_64 GNU/Linux

Steps to reproduce:

  1. Follow the docs
  2. Attempt to set up redirect
  3. Try to use oauth to authenticate
  4. Cry :cry:

Expected result:

Authentication to work

Actual result:

Great sadness

Attachments:

Logs, screenshots, screencast, sample project, funny gif, etc.

stevengill commented 4 years ago

Are you defining your own receiver? If so, the OAuth options (clientId, clientSecret, stateSecrect, etc) need to be passed to ExpressReceiver instead.

const receiver = new ExpressReceiver({ 
  signingSecret: process.env.SLACK_SIGNING_SECRET 
  clientId: process.env.SLACK_CLIENT_ID,
  clientSecret: process.env.SLACK_CLIENT_SECRET
  stateSecret: 'my-state-secret',
  scopes: ['channels:read', 'groups:read', 'channels:manage', 'chat:write', 'incoming-webhook'],
  installationStore: {
    storeInstallation: async (installation) => {
      // change the line below so it saves to your database
      return await database.set(installation.team.id, installation);
    },
    fetchInstallation: async (InstallQuery) => {
      // change the line below so it fetches from your database
      return await database.get(InstallQuery.teamId);
    },
  },
});

const app = new App({
  receiver: receiver,
});
jparr721 commented 4 years ago

I am not. I just followed the instructions exactly. Is it required to define a custom receiver? I didn't need to do this to use the events endpoint.

stevengill commented 4 years ago

@jparr721 it isn't required. It is just a common reason for people to run into issues.

I need a bit more info to help you debug. Can you share your code initializing App?

Once you start your bolt app in terminal, if you go to https://localhost:3000/slack/install in your browser, does it fail?

jparr721 commented 4 years ago

Yes, I get the cannot GET /slack/install message. Here is my code for initializing:

async function startSlackBot(): Promise<void> {
  const slackPort = dotenvValue(DotenvVariable.SlackPort, '8080');
  const slackClientId = dotenvValue(DotenvVariable.SlackClientId, '');
  const slackSigningSecret = dotenvValue(DotenvVariable.SlackSigningSecret, '');
  const slackbotUserSigningToken = dotenvValue(
    DotenvVariable.SlackbotUserSigningToken,
    '',
  );
  const organizationPrivateKey = dotenvValue(
    DotenvVariable.OrganizationPrivateKey,
    '',
  );

  const bot = new App({
    token: slackbotUserSigningToken,
    signingSecret: slackSigningSecret,
    clientId: slackClientId,
    stateSecret: organizationPrivateKey,
    scopes: ['channels:history', 'reactions:read', 'bot'],
    installationStore: {
      storeInstallation,
      fetchInstallation,
    },
  });

  await bot.start(slackPort);
}
stevengill commented 4 years ago

@jparr721 you are missing clientSecret. Try adding that and let me know if it works

jparr721 commented 4 years ago

@stevengill That seems to have worked flawlessly, to anyone copying my config, I also had to remove the token field. Very sorry about this mistake, thanks so much for taking the time to review my error.

Ali559 commented 1 year ago

could someone Help me with this? I'm super confused about this, here is my code:

import { config } from "dotenv";
import { webSockets } from "./websockets/websocket.js";
config();
import appManifest from "./manifest.json" assert { type: "json" };
import cors from "cors";
import express, { json, urlencoded } from "express";
import bolt from "@slack/bolt";
import slackOauth from "@slack/oauth";
const { FileInstallationStore } = slackOauth;
const { SocketModeReceiver, App } = bolt;
const addToSlackButton = `<a href="https://slack.com/oauth/v2/authorize?state=${process.env.SLACK_STATE_SECRET}&client_id=4010931555619.4065974536337&scope=&user_scope=channels:history,chat:write,files:read,groups:history,im:history,im:read,im:write,links.embed:write,links:read,links:write,mpim:history,mpim:read,mpim:write,pins:write,search:read,stars:read,users:read,users:read.email,channels:read,channels:write"><img alt="Add to Slack" height="40" width="139" src="https://platform.slack-edge.com/img/add_to_slack.png" srcSet="https://platform.slack-edge.com/img/add_to_slack.png 1x, https://platform.slack-edge.com/img/add_to_slack@2x.png 2x" /></a>`;
const app = express();
const socketModeReciever = new SocketModeReceiver({
  appToken: process.env.SLACK_SOCKET_MODE_TOKEN,

});
export const slackApp = new App({
  signingSecret: process.env.SLACK_SIGNING_SECRET,
  clientId: process.env.SLACK_CLIENT_ID,
  clientSecret: process.env.SLACK_CLIENT_SECRET,
  scopes: appManifest.oauth_config.scopes,
  receiver: socketModeReciever,
  customRoutes: [
    {
      path: "/slack/install",
      method: ["GET"],
      handler: (req, res) => {
        res.writeHead(200);
        res.end(addToSlackButton);
      },
    },
  ],
  installationStore: new FileInstallationStore(),
});
import { apiRouter } from "./api/index.js";
const port = process.env.PORT || 5000;
app.use(cors({ origin: true }));
app.use(json());
app.use(urlencoded({ extended: true }));
app.use("/api", apiRouter);

const server = app.listen(port, () => console.log(`http://localhost:${port}`));
const socketServer = webSockets(server, slackApp);

the code does not run without authorize or an oauth token, if one of those are provided then I constantly get 404 error when trying to access /slack/install route on ngrok