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

Passing context/state in oauth flow #1497

Closed JoeRoddy closed 2 years ago

JoeRoddy commented 2 years ago

Description

I can't for the life of me find out how to pass arbitrary state/context through the installation process to be received at installationStore.storeInstallation. I have to imagine something like this exists, but I don't see it in the docs.

I see that you can instantiate a receiver and use generateInstallUrl but the docs on how to implement that are non-existent, at least on the main tutorial.

Is there no way to simply pass some state via the main install link that can be passed on to my installation handler? I would imagine this would be something like: https://myapi.com/slack/install?userId=user_id_from_my_system

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

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


seratch commented 2 years ago

Hi @JoeRoddy, thanks for asking this.

You can use a few callback functions to handle additional states. Please refer to the following resources:

We are sorry about the lack of enough information in the bolt-js document side. We'll consider improving that for the future. I hope this response was helpful to you.

JoeRoddy commented 2 years ago

Thank you so much for the quick reply @seratch !

After looking through the documentation that's available, I'm able to successfully pass the cookie from beforeRedirection to beforeInstallation, which is great, but as far as I can tell, beforeInstallation doesn't get access to any of the installation state (bot.token is mainly what I'm after) and my storeInstallation function doesn't get access to my cookie.

I need a place where I can access both my custom context (userId in my system) and the installation result (slack bot.token) so that I can persist the data in my system.

I see that there's an afterInstallation callback, but I can't find any documentation on how to use, does afterInstallation get access to the resulting install state? And if so, could you point me to an example of how to use afterInstallation?

I was looking through https://slack.dev/node-slack-sdk/oauth#persisting-data-during-the-oauth-flow and only see beforeRedirection and beforeInstallation examples.

Thanks so much! -Joe

seratch commented 2 years ago

@JoeRoddy For this use case, you can definitely use afterInstallation for it. Check this reference document, which is linked from https://slack.dev/node-slack-sdk/oauth#persisting-data-during-the-oauth-flow, to learn its interface.

JoeRoddy commented 2 years ago

Thanks Kazuhiro!

I stumbled upon that reference earlier, but I'm not sure where exactly to declare afterInstallation. Are there any examples that actually implement afterInstallation? I have an express app and everything else is working okay.

This is what I have so far. beforeRedirection and beforeInstallation work, but afterInstallation never ends up firing:

const installMiddleware = async function (req: any, res: any, next: any) {
  const urlEnd = req.url.indexOf('?');
  const url = req.url.substring(0, urlEnd > 0 ? urlEnd : req.url.length);

  if (url === '/slack/install') {
    await installer.handleInstallPath(req, res, {
      beforeRedirection: async (req: any, res: any) => {
        res.cookie('mycookie', 'newest-customvalue');
        next();
      },
    });
  } else if (url === '/slack/oauth_redirect') {
    await installer.handleCallback(req, res, {
      beforeInstallation: async (opts: any, req: any, res: any) => {
        console.log('before install cookie:', req.headers.cookie);
        next();
      },
      afterInstallation: async (opts: any, req: any, res: any) => {
        console.log('after install fired');
        next();
      },
    });
  }
};

app.use(installMiddleware);

Should afterInstallation be under another route, or should it be declared somewhere else entirely?

seratch commented 2 years ago

You can pass callbackOptions to your bolt app.

Please head to https://slack.dev/bolt-js/concepts#authenticating-oauth, scroll down a bit, and then click "Customizing OAuth defaults" link. You can find how to configure the callbackOptions in your app. The afterInstallation is not there but you can set it in the same way with success / failure functions.

JoeRoddy commented 2 years ago

This is EXACTLY what I was missing!!! Thank you SO much @seratch you saved me soooooo much time 🙌