Closed ryanandonian closed 1 year ago
Hi, @ryanandonian! Thank you for your question! 🙌
With regards to using OAuth and Socket Mode, we have an example of that which can be seen here.
In terms of making sure your app can correctly track and recognize installations, the second option you provided is a good starting point. You can try to create a custom InstallationStore
and StateStore
that you can pass into your initialized OAuth Settings (example here).
InstallationStore: Your custom InstallationStore
can use the InstallationStore
interface from the Python SDK. In this custom store, you need to implement at least a save()
and find_installation()
function that retrieves data from where third-party OAuth stores it. You can view examples of custom InstallationStores
we've created in this directory in the Python SDK - we currently have implementations of Amazon S3, SQLite, and others. Note that in order for the InstallationStore to work, you should make sure you are storing relevant information for each installation instance like team_id
, bot_token
, and so on. You can view this function
to see how OAuth is considered "authorized" through Bolt Python and examine the AuthorizeResult
to see what data it expects.
StateStore: In addition to a custom InstallationStore
, you'll also need a custom StateStore
(using the interface). You can view examples of custom implementations also through our S3, SQLite, and SQLAlchemy offerings in this directory.
If you find that the above still isn't working for your use case, let me know and feel free to provide more details and we can dive into this deeper.
Thanks for your help so far @hello-ashleyintech . I've got a start on the custom InstallationStore, but I just want to confirm something before getting further-
If I'm reading this correctly, the first check here is just "has anyone from this Team done an Installation?" https://github.com/slackapi/bolt-python/blob/e580fda97e2ed3d9905f4e10f3821bf05049035b/slack_bolt/authorization/authorize.py#L166-L170
and then slightly down the line here - https://github.com/slackapi/bolt-python/blob/e580fda97e2ed3d9905f4e10f3821bf05049035b/slack_bolt/authorization/authorize.py#L183, this is then continuing to fetch the user-specific token from the InstallationStore if it exists?
Translating this into a more generic InstallationStore
implementer logic, there may be several different valid cases for find_installation
:
enterprise_id
& is_enterprise_install
)team_id
)enterprise_id
& user_id
& is_enterprise_install
)user_id
& team_id
)And just to clarify one thing so I'm understanding things clearly - since Bot Tokens are not tied to a user, is that why there's the "find the team and grab a bot token" check first before fetching a user's token?
@ryanandonian Yes, your understanding seems to be correct 👍
Thank you for all your quick help @hello-ashleyintech and @seratch ! I have my custom InstallationStore
now hooked up to our "off app" database and it's consuming user_status_changed
events and using the proper tokens when responding to the app_home_opened
events. There's a sufficient gap between these services to where there's no requirement for HTTP/s Ingress, which is one of the components of our security reqs here (since this app can read and write Slack users, we wanted to have a large gap between the wild west of the internet and this service).
In case I did a bad job explaining how exactly this is set up (or for anyone in the future who's finding this page), here's a rough diagram of how the "separate services" will be deployed, where that "OAuth Flow Control" piece down at the bottom is a sort of "generalized OAuth handler system" that handles OAuth flows for multiple 3rd party providers, one of which is now Slack.
I'm developing an App that will be deployed to several workspaces (via the "Add to Slack" button OAuth flow), and is not planned to be distributed and listed publicly via the public app directory. Our OAuth is handled in a separate service, which writes the OAuth tokens+some extra data to a storage layer that is accessible to this App. The App ideally will not have any publicly accessible ingress as it will be deployed inside a VPC for security reasons (but it can reach out to Slack's APIs as well as this storage layer).
I'm trying to figure out the best way to leverage the Slack Bolt SDK for Python since it handles a lot of the complexities for us, but it seems like a bot token is required for SocketModeHandler initialization (by virtue of requiring a slack_bolt.App instance).
Since this app will be installed to multiple workspaces, it doesn't seem right to use a Bot Token here to initialize the App which is passed to the SocketModeHandler, since it seems that a Bot Token is generated on a per-workspace level (eg: a bot token installed to WorkspaceA will not work with WorkspaceB, and visa versa). It seems like the
authorize
andinstallation_store
parameters are built for this use caseRight now I'm able to forego the BotToken use by building my App with the
OAuthSettings
, but that seems to assume the app will service OAuth (and uses the default InstallationStores), but I get what seems like an expected error when receiving new events:If I'm reading this correctly, this error pops up because there are no existing
Installation
s for the given users as it uses the defaultinstallation_store
, which is always empty since nothing I'm writing is populating it.It seems like I'll need to do one of two things:
slack_sdk
, or a custom websocket using the response from apps.connections.open )OAuthSettings
a customInstallationStore
which it can read/write Token updates to for the connected token storageOption 2 seems like the ideal path forward, but I am a little unsure given most of the documentation seems to be built around "If you run OAuth inside this app, there's a lot of automatic stuff you get" and I can't seem to find much in terms of "if OAuth is handled elsewhere, here's how you integrate with it".
The
slack_bolt
versionPython runtime version