slackapi / bolt-python

A framework to build Slack apps using Python
https://slack.dev/bolt-python/
MIT License
1.02k stars 236 forks source link

Connecting an installation to the authed user of my app #1086

Closed ravi-ojha closed 2 weeks ago

ravi-ojha commented 1 month ago

What's my goal?

I'm creating a distributable slackbot app for my django project. I have followed the oauth flow from the example project and it works well.

Where am I stuck?

After the installation, I'd like to "link" the installation with the User model of my app. This will help me identify the slack installation for any user. Here's the quick view of App init.

def success(args: SuccessArgs) -> BoltResponse:
    # TODO: connect the slack's team_id with the auth'ed `User` model of my app, somewhat like this
    # But I can't figure out a way to get the authed user

    # user = get_auth_user()
    # user.slack_team_id = args.installation.team_id
    # user.save()

    return BoltResponse(
        status=200,
        body="Yay! It works.",
    )

def failure(args: FailureArgs) -> BoltResponse:
    return BoltResponse(status=args.suggested_status_code, body=args.reason)

slack_app = App(
    signing_secret=settings.SLACK_SIGNING_SECRET,
    oauth_settings=OAuthSettings(
        client_id=settings.SLACK_CLIENT_ID,
        client_secret=settings.SLACK_CLIENT_SECRET,
        scopes=[
            "app_mentions:read",
            "channels:history",
            "channels:read",
            "chat:write",
            "users:read",
        ],
        # If you want to test token rotation, enabling the following line will make it easy
        # token_rotation_expiration_minutes=1000000,
        installation_store=DjangoInstallationStore(
            client_id=settings.SLACK_CLIENT_ID,
        ),
        state_store=DjangoOAuthStateStore(
            expiration_seconds=120,
        ),
        install_page_rendering_enabled=False,
        install_path="/slack/install/",
        redirect_uri_path="/slack/oauth-redirect/",
        callback_options=CallbackOptions(success=success, failure=failure),
    ),
)

Normally, I'd get the user from django's request but since the args.request is a BoltRequest that doesn't work.

One hacky way I could think of is to use the SlackOAuthState in some way, as in attach a user attribute to the SlackOAuthState object. When it is consumed, I can get the user attached to this state object.

The slack_bolt version

1.18.1

Python runtime version

3.9.10

seratch commented 1 month ago

Hi @ravi-ojha, thanks for asking the question. You can use args.request.headers to access cookie data your app can set.

Perhaps, parsing your service's auth session cookie string and assoiate your service's user ID and Slack's enterprise_id/team_id + user_id would be good to go. I hope this helps.

ravi-ojha commented 1 month ago

Ahh.. thank you! That was a bit stupid of me not to think about raw cookies. What using request.user from Django does to a fella lol

And just wanna say thanks to everyone maintaining this package and examples. This part from django oauth example was a huge help!

ravi-ojha commented 2 weeks ago

Appreciate the help! Closing this now, I was able to build a nice custom bot for my side project Ticketping