Closed stantonius closed 2 years ago
Hi @stantonius, thanks for asking the question! Also, we're glad to hear that you like bolt-python!
App is installed to entire workspace. Bot token is generated and embedded in the Bolt code
As your app implements the OAuth for app installations, your installation data is managed in the InstallationStore
(in your example code, it's local file system based FileInstallationStore
). Thus, you don't need to pass the token
argument to your App
initialization. Bolt automatically resolves relevant bot tokens for each incoming request from Slack.
Also, if you use the installation from the Slack app admin page, the generated token does not work in this way. As your app offers the OAuth flow, all the installations must be done from the /slack/install
endpoint.
user scopes
You are passing "users:read", "users:read.email"
as both bot scopes and user scopes to the OAuth authorize URL. However, if you need only these scopes, having them in bot scopes would be enough. Also, for app_home_opened
events and views.publish
API call, you don't need any user scopes.
I hope this helps!
Hey @seratch thanks for getting back to me so quickly.
Thus, you don't need to pass the token argument to your App initialization.
Makes sense.
However, if you need only these scopes, having them in bot scopes would be enough. Also, for app_home_opened events and views.publish API call, you don't need any user scopes.
Agreed. Sorry I should have been more explicit - the code I shared was a sample and I had removed some of the Scopes for readability. But this validates my understanding.
generated token does not work in this way. As your app offers the OAuth flow, all the installations must be done from the /slack/install endpoint.
OK so this is where my issue is then. Are you aware of any way to have this integrated approach, where the Bot is available to the workspace and offers this Install button as part of its chat or on its Home page? Otherwise I would need to either:
/slack/install
endpoint). Not ideal as these are really the same AppsThanks again for your help with this
@stantonius I may not fully understand what you want to do here but if you mean you need two OAuth installation flows for 1) enabling your app in the workspace (=bot installation) and 2) individual user installation with user scopes, I would suggest:
App
instances with the same set of client_id/client_secret
App
with the oauth_settings
for bot installation (with bot scopes)App
with the oauth_settings
for user scope installation (with user scopes)/slack/app_install
and /slack/app_oauth_redirect
/slack/user_install
and /slack/user_oauth_redirect
and use corresponding App
instance for eachInstallationStore
among themInstallationStore
manages all installations, either of 1: or 2: can serve /slack/events
. If you want to have a different App
for /slack/events
, it's also fine.context.user_token
as long as the user already installed the app via 2) OAuth flow see also authorize
using InstallationStore
under the hoodIf you are fine to have two Slack apps, of course, things can be much simpler. You can run those apps either in different processes or in different sets of FastAPI endpoints. Either way, having two App
instances would be the same.
Does this make sense to you?
@stantonius Let us know if you have more to ask/discuss here 👋 We'll close this issue after waiting for your response for a few more days.
Apologies for the delay and thanks for following up - this team is on it!
The sharing of client ids and installations was an awesome idea. I think I have this working as you mentioned, however I'm still working through a few details when I have time.
For what it is worth, what really tripped me up (which you rightfully mentioned in your response) was that the tokens generated in the App admin portal cannot be referenced in your Bolt code if you are also using Oauth unless you write your own authorization flow for each request - which defeats some of the purpose of using Bolt. I hadn't understood that tokens generated in the admin page do not update in your app's installation yet tokens generated via Oauth do flow back to Slack and are reflected in the admin page. Basically if using Oauth and installations in your app, do not generate the tokens in the admin page - go to the /slack/install
endpoint and install this way, and the tokens will still appear in the admin page but also in the installation.
It was the above misunderstanding that caused this MultiTeamsAuthorization
/AuthorizeResult
error - even when I provided legit tokens generated from the admin portal directly to the App
instance, it was ignored and only looked via the default authorize
function.
Finally, I did notice some of the feedback to your PR was that this was a complicated workflow/scenario. I had made some additional notes on what I was trying to do in case it was helpful as to why all this was necessary.
The app I am building requires a few scopes be accessible by user_token for additional functionality - I am trying to create a single app that fits the following criteria:
The rationale for this workflow is to me a good mix of maximizing App engagement (already pre-installed and visible, can nudge and provide more context) while being transparent on permissions and giving the end user full control (progressive permission flow started by the organization, left with the users to ultimately decide on any privileged access) - all within a single app package.
Thanks for all your hard work
Thanks for your reply!
the token generated via admin page installation vs the OAuth flow
Yes, we have been observing that this difference is one of the confusing points for new Slack app developers. Glad to know you've figured it out but, in the future, our team may be able to improve the documents to help new developers more easily understand this.
the scenario you mentioned in the comment
The pull request #576 should resolve one blocker for your use case. Please try the latest version out. If you have anything further to ask/clarify in your app development, please feel free to open a new question issue.
It seems that there is nothing else we can offer here. Let us close this issue now. Thanks again for your time to write in here!
First of all, loving the Slack Bolt dev experience. And really appreciate the community and responsiveness from maintainers.
I have put this as a question because I'm pretty sure I am missing a fundamental Oauth step here - I just can't figure it out.
As described in the Expected Result section below, I am trying to create an App that is both a Bot and also uses the Web API that requires user_tokens. The Bot and Home page are meant to be present regardless of whether the user has a user_token stored or not - the Home Page UI and Bot responses will just depend on whether the user_token exists. While I have the whole setup working, the flow is really choppy. I can create the App for the workspace, however when a user then goes to interact with the App (either via the Home page or the Bot), the Bolt App returns the error
slack_bolt.MultiTeamsAuthorization:Although the app should be installed into this workspace, the AuthorizeResult (returned value from authorize) for it was not found.
Note that if the user first goes to the
/slack/install
route from a browser, the user_tokens are generated and if you allow Slack to be opened, the permissions are recognised and the user can interact with the App's advanced functionality that requires the user_tokensI know from the Bolt docs that apps that span multiple workspaces may require an
authorize
function, however I had never selected or implied that this was a multi-workspace app, so I am unsure why the App is expecting anAuthorizeResult
returned.I also know there have been similar questions asked before, however what I am experiencing is that this error is introduced before any of the event callbacks are triggered. Ie. I can't do any of my own validation on the "app_home_opened" event callback as this is never triggered, and thus I don't have access to the
client
object unless I recreate one somehow. As you can see in the screenshot below, the only object I have access to currently (without the customauthorize
function) is the initial Request json. Even the Oauth_flow callbacks are not triggered (where I could also set some custom logic), which suggests thisMultiTeamsAuthorization
error occurs before the Oauth_flow is validated.Is my only solution for this to create a custom
authorize
function to handle all of the permission checks each time? This is not ideal as one of the advantages of using Bolt is that it handles the Oauth protocol and token verification for us, which I would like to avoid writing myself (and possibly introducing security vulnerabilities)Many thanks for any guidance available
Reproducible in:
uvicorn main:api --reload --port 3000 --log-level warning
The
slack_bolt
versionslack-bolt==1.11.1 slack-sdk==3.13.0
Note that FastAPI adapter is used
Python runtime version
3.9.9
OS info
ProductName: macOS ProductVersion: 12.0.1 BuildVersion: 21A559
Steps to reproduce:
See below
Expected result:
Actual result:
slack_bolt.MultiTeamsAuthorization:Although the app should be installed into this workspace, the AuthorizeResult (returned value from authorize) for it was not found.
The Home page never loads and the Bot is not functional.