Repository navigation
403 Error when executing 'slack/install' in GCP cloud functions #646
Description
Activity
- addedquestionFurther information is requestedFurther information is requested
on May 12, 2022 Hi @ggm1207 👋🏻
Thanks for the question and your English was easy to read and very well written! 👌🏻
The error message "Error: Forbidden" is returned by GCP. I'm not very experienced with GCP, but it looks like you will need configure the role that can access your Cloud Function. I came across this Stackoverflow article that explains how to configure GCP.
I know other maintainer's are more experience with GCP and may be able to add more help, but I wanted to first make this suggestion.
Reacted by Goo GunmoHi @ggm1207, the reason why the example uses the Flask adapter is that Google Cloud Functions runtime provides Flask compatible request and response interface. Unfortunately, the HTTP endpoint routing in the Flask app layer does not work for Cloud Functions.
To serve the OAuth URLs on Google Cloud Functions , there are two options as below:
- Implement your own adapter that handles both GET and POST requests like our AWS Lambda adapter does, plus use a single endpoint URL for both the OAuth flow (/slack/install + /slack/oauth_redirect) and event delivery (/slack/events)
- Deploy three functions for GET /slack/install, GET /slack/oauth_redirect, and POST /slack/events
I hope this helps.
Hi @mwbrooks 👋
I've already tried the suggested method in the link you've attached. But I had time to check it again and it was useful to check the issue again. 👍 👍
Thank you for your answer !!
Thank you for adding the question label.
Hi @seratch 👋
I think the first option is the answer that I can try.
The second option is, I don't know if I can explicitly deploy
slack/installandslack/oauth_redirect. (I'll have to look for related examples.)Does it mean that there is another way as Flask app layer explicitly specifies Endpoint?
Thank you for your answer and I let's try the first option.
Does it mean that there is another way as Flask app layer explicitly specifies Endpoint?
No, it doesn't. You cannot use Flask's routes on Google Cloud Functions.
I meant that you need to deploy three different functions for the three endpoints - /slack/install, /slack/oauth_redirect, and /slack/events . You may be able to use the same function for these three, but it does not mean you can use Flask routes.
Also, you may need to adjust oauth_settings.install_path and oauth_settings.redirect_uri_path to make them functional (perhaps, you cannot use
/slack/xxxpath in Cloud Functions): https://github.com/slackapi/bolt-python/blob/main/slack_bolt/oauth/oauth_settings.pyOh, I understand.
While trying the first option, I looked at the SlackRequestHandler class' detailed code and found that the features we wanted were already implemented. (Code below)
I added some code for Debug.
class SlackRequestHandler: def __init__(self, app: App): # type: ignore self.app = app def handle(self, req: Request) -> Response: if req.method == "GET": print("[execute] GET") print(f"oauth_flow.install_path: {self.app.oauth_flow.install_path}") print( f"oauth_flow.redirect_uri_path: {self.app.oauth_flow.redirect_uri_path}" ) bolt_req = to_bolt_request(req) print(f"bolt_request.error: {bolt_req.query.get('error', [None])[0]}") print(f"bolt_request.state: {bolt_req.query.get('state', [None])[0]}") print(f"bolt_request.headers: {bolt_req.headers}") print(f"bolt_request.code: {bolt_req.query.get('code', [None])[0]}") if self.app.oauth_flow is not None: print("[execute] app.oauth_flow") oauth_flow: OAuthFlow = self.app.oauth_flow if req.path == oauth_flow.install_path: print("[execute] oauth_flow.install_path") bolt_resp = oauth_flow.handle_installation(to_bolt_request(req)) return to_flask_response(bolt_resp) elif req.path == oauth_flow.redirect_uri_path: print("[execute] oauth_flow.redirect_uri_path") bolt_resp = oauth_flow.handle_callback(to_bolt_request(req)) return to_flask_response(bolt_resp) elif req.method == "POST": bolt_resp: BoltResponse = self.app.dispatch(to_bolt_request(req)) return to_flask_response(bolt_resp) return make_response("Not Found", 404)
So I might not be aware of the issues I'm experiencing, so I'm going to explain the error in detail again.
Steps to reproduce:
- Sample File Deploy to Cloud Functions
- Click on the 'Sharable URL' suggested by Slack to download the bot to the workspace.
- When you click on 'Sharable Url', the bot installs in the workspace with the steps below.
As mentioned above, it will be installed when deployed in a local environment. However, it does not work when deployed as Cloud Functions.
- Installation Steps
- Request permission to access the {YOUR WORKSPACE} from the {MY BOT}.
- If you allow permission, the following error page appears:
- And when you click here, it goes to
{SERVER_ENDPOINT}/slack/installand the Slackbot is installed in the workspace. (Only when I deployed it on my MacBook)
Information that may be useful
This is the result of the print code that I wrote when I proceeded with the installation step as above.
You can see that
elif req.path == oauth_flow.redirect_uri_pathhas entered, but you can see thatif req.path == oauth_flow.install_pathhas not even entered.I may have written the wrong code, and there may be less authorization to the IAM or other causes. The important thing is that I have difficulty identifying the problem. What do you think is the cause?
Thank you for solving this problem with me. It's really helpful. 👍 👍
Reacted by Goo GunmoReacted by Ike Kim@ggm1207 Thanks for your response. I just submitted a pull request that adds a new adapter for Google Cloud Functions. Please check the PR: #649
You can use the adapter and with it, you can use only a single endpoint like
https://us-central1-YOUR_PROJECT_NAME.cloudfunctions.net/YOUR_FUNCTION_NAMEfor everything. Please don't use the sharable URL in the Slack app admin page. As long as you set the client_id, client_secret, scopes, and signing secret to your app usingenv.ymlfile, you can just use the Cloud Functions public endpoint for all.In the next release, we will add the adapter. Until then, please copy the
handler.pyto your project.Let me close this issue now but please don't hesitate to write in if you have anything further to share.
Reacted by Goo Gunmo- added a commit that references this issue
on May 18, 2022



First of all, I apologize that I may not be able to write smoothly because my English skill is not good. I will write in as much detail as possible, so please ask again if there are any missing parts.
I'm implementing and debugging a slackbot in 2 environments. One is my Macbook and the other is GCP Cloud Functions.
As mentioned in the title, if I try to download(in workspace) the Slack bot using the url below, I will get a 403 Error (see the picture below). However, the problem is fine when I run Server using ngrok + flask on Macbook, but it only occurs when I run it in Cloud Functions.
{SERVER_ENDPOINT}/slack/installI'm not sure if this is an Oauth issue or a GCP permission issue or something.
Reproducible in:
The
slack_boltversionPython runtime version
OS info
Steps to reproduce:
gcloud functions deploy {FUNCTION_NAME} \ --region {REGION} \ --allow-unauthenticated \ --entry-point handler \ --runtime python39 \ --service-account {SERVICE_ACCOUNT} \ --project {PROJECT_NAME} \ --trigger-http \ --env-vars-file ".env.json"{SERVER_ENDPOINT}/slack/install) in the search bar to install Slackbot.(I think it might be helpful) service-acoount has permisssions below:
An easier reproduction would be to insert the code below into this tutorial.
Expected result:
I want 'slack/install' to be called well on the slack server deployed to Cloud Functions.
My goal is to implement and deploy a Slackbot.
Actual result:
This is an error that occurs before entering slack/install, so the above image is all.
Requirements
Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.