slackapi / java-slack-sdk

Slack Developer Kit (including Bolt for Java) for any JVM language

Home Page:https://slack.dev/java-slack-sdk/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't install / auth Slack app: No request pattern detected for

ChristopherVennemann opened this issue · comments

I've built a Slack app and ran it successfully as single installation. Now I want to enable installation across mutliple workspaces.
After some failed attemps, I copied the Spring 3 example from this very repo, changed the scope in the AppConfig bean and the slash command to match my app. Ran it and got the same error as before: when I use the install / auth link and then click "allow", I get

WARN [http-nio-3000-exec-4] com.slack.api.bolt.util.SlackRequestParser No request pattern detected for 

Reproducible in:

the Spring 3 example from this very repo
Java 17

The Slack SDK version

\--- com.slack.api:bolt-jakarta-servlet:[1.27,) -> 1.35.0
     +--- com.slack.api:slack-api-model:1.35.0
     +--- com.slack.api:slack-api-client:1.35.0
     |    +--- com.slack.api:slack-api-model:1.35.0 (*)
     +--- com.slack.api:slack-app-backend:1.35.0
     |    +--- com.slack.api:slack-api-model:1.35.0 (*)
     |    +--- com.slack.api:slack-api-client:1.35.0 (*)
     \--- com.slack.api:bolt:1.35.0
          +--- com.slack.api:slack-api-model:1.35.0 (*)
          +--- com.slack.api:slack-api-client:1.35.0 (*)
          +--- com.slack.api:slack-app-backend:1.35.0 (*)
\--- com.slack.api:bolt-jakarta-servlet:[1.27,) (n)
\--- com.slack.api:bolt-jakarta-servlet:[1.27,) -> 1.35.0
     +--- com.slack.api:slack-api-model:1.35.0
     +--- com.slack.api:slack-api-client:1.35.0
     |    +--- com.slack.api:slack-api-model:1.35.0 (*)
     +--- com.slack.api:slack-app-backend:1.35.0
     |    +--- com.slack.api:slack-api-model:1.35.0 (*)
     |    +--- com.slack.api:slack-api-client:1.35.0 (*)
     \--- com.slack.api:bolt:1.35.0
          +--- com.slack.api:slack-api-model:1.35.0 (*)
          +--- com.slack.api:slack-api-client:1.35.0 (*)
          +--- com.slack.api:slack-app-backend:1.35.0 (*)
\--- com.slack.api:bolt-jakarta-servlet:[1.27,) -> 1.35.0
     +--- com.slack.api:slack-api-model:1.35.0
     +--- com.slack.api:slack-api-client:1.35.0
     |    +--- com.slack.api:slack-api-model:1.35.0 (*)
     +--- com.slack.api:slack-app-backend:1.35.0
     |    +--- com.slack.api:slack-api-model:1.35.0 (*)
     |    +--- com.slack.api:slack-api-client:1.35.0 (*)
     \--- com.slack.api:bolt:1.35.0
          +--- com.slack.api:slack-api-model:1.35.0 (*)
          +--- com.slack.api:slack-api-client:1.35.0 (*)
          +--- com.slack.api:slack-app-backend:1.35.0 (*)
\--- com.slack.api:bolt-jakarta-servlet:[1.27,) -> 1.35.0
     +--- com.slack.api:slack-api-model:1.35.0
     +--- com.slack.api:slack-api-client:1.35.0
     |    +--- com.slack.api:slack-api-model:1.35.0 (*)
     +--- com.slack.api:slack-app-backend:1.35.0
     |    +--- com.slack.api:slack-api-model:1.35.0 (*)
     |    +--- com.slack.api:slack-api-client:1.35.0 (*)
     \--- com.slack.api:bolt:1.35.0
          +--- com.slack.api:slack-api-model:1.35.0 (*)
          +--- com.slack.api:slack-api-client:1.35.0 (*)
          +--- com.slack.api:slack-app-backend:1.35.0 (*)
\--- com.slack.api:bolt-jakarta-servlet:[1.27,) -> 1.35.0
     +--- com.slack.api:slack-api-model:1.35.0
     +--- com.slack.api:slack-api-client:1.35.0
     |    +--- com.slack.api:slack-api-model:1.35.0 (*)
     +--- com.slack.api:slack-app-backend:1.35.0
     |    +--- com.slack.api:slack-api-model:1.35.0 (*)
     |    +--- com.slack.api:slack-api-client:1.35.0 (*)
     \--- com.slack.api:bolt:1.35.0
          +--- com.slack.api:slack-api-model:1.35.0 (*)
          +--- com.slack.api:slack-api-client:1.35.0 (*)
          +--- com.slack.api:slack-app-backend:1.35.0 (*)

Java Runtime version

openjdk version "17.0.8.1" 2023-08-22 LTS
OpenJDK Runtime Environment Corretto-17.0.8.8.1 (build 17.0.8.1+8-LTS)
OpenJDK 64-Bit Server VM Corretto-17.0.8.8.1 (build 17.0.8.1+8-LTS, mixed mode, sharing)

OS info

Ubuntu 22.04.3 LTS

Steps to reproduce:

(Share the commands to run, source code, and project settings (e.g., pom.xml/build.gradle))

  1. run Spring
  2. hit the shareable link I got from my app.slack.com/app-settings
  3. "[MyApp] is requesting permission..." -> "Allow"

Expected result:

App is added to workspace and I receive auth code / token

Actual result:

WARN [http-nio-3000-exec-1] com.slack.api.bolt.util.SlackRequestParser No request pattern detected for 

What am I missing?

Hi, @ChristopherVennemann!

At first glance, this seems like an issue with setting up OAuth correctly, especially if your app is working on a single-installation level. To verify, did you set up OAuth according to the instructions here? Note that you'll need to do two things to get it working:

  • You need to configure your app at https://api.slack.com/apps/{your app id}
  • You need to set up the following env variable before running your app:
export SLACK_CLIENT_ID=(Settings > Basic Information > App Credentials > Client ID)
export SLACK_CLIENT_SECRET=(Settings > Basic Information > App Credentials > Client Secret)
export SLACK_SIGNING_SECRET=(Settings > Basic Information > App Credentials > Signing Secret)

I hope this helps! Let me know if you have any further issues.

Hi, @hello-ashleyintech and thanks for your help!

I had previously followed these instructions, and followed some other instructions, too, and I guess I got some thing mixed up and that's where things went wrong.

I started from scratch, created a new app, started with a fresh copy of the spring boot 3 example code and followed the instructions you posted. Huzzah, the app can now be installed to other workspaces and it replies to its command.

Where do I go from here? I had previously followed these instructions to take care of OAuth and end up with a team specific access token. Do I still need to do this?

Hi, @ChristopherVennemann!

Since you set up OAuth using the instructions in the SDK and verified that the app can be installed to multiple workspaces and is working as expected, you should be good to go!

Follow up question:
I fixed my original app with what I learned and it now installs to new workspaces. It reacts to its slash command, which opens a modal. Great. On modal submission it is supposed to make a post into a public channel via chat.postMessage. This worked fine in single workspace, and it still works in multi workspace installation, but only in the "original" workspace where the app was conceived.

In the other, new workspace, when I submit the modal, I get
{"ok":false,"error":"channel_not_found"}
I am sure that the channelId passed to chat.postMessage is correct. It is the same id I see in the slack client when I inspect the channel.

I also noticed that I didn't pass a token argument to chat.postMessage even though documentation says it's required.
I assume that the env variable SLACK_BOT_TOKEN is fetched automatically and that is why it works for the original workspace?
I added the env variable SLACK_BOT_TOKEN as an explicit argument to chat.postMessage and the behavior didn't change, which kinda confirms my suspicion.

If that's the case, where / how do I get the access token specific to each individual workspace?

Hi, @ChristopherVennemann!

Are you using an installation store of some kind to store the credentials from your OAuth installations? It sounds like it's having trouble retrieving the correct workspace information as you mentioned. I would recommend checking out this guide for more information on how to store credentials for each installation so that they are pulled appropriately for each instance. Let me know if that helps!

Hi @hello-ashleyintech,

under "Choose Proper Storage Services" it says "By default, OAuth flow supported Bolt apps uses the local file system ...".
Under "Build Slack OAuth using Spring Boot" it says "If you want to use different implementations of InstallationService and OAuthStateService, you can have them as Spring components..."

I took that as it should work even if I don't specify a way to store data. Was my assumption incorrect?

Out of the listed options, only local file system seems appropriate for me (as JDBC is coming soon)

I have added local file system implementations of InstallationService and OAuthStateService to my Spring Boot project similar to the the way Amazon Services are implemented in the example:

My SlackApp code looks like this:

public class SlackApp {

    @Bean
    public AppConfig loadOAuthConfig() {
        return AppConfig.builder()
            .singleTeamBotToken(null)
            .clientId(System.getenv("SLACK_CLIENT_ID"))
            .clientSecret(System.getenv("SLACK_CLIENT_SECRET"))
            .signingSecret(System.getenv("SLACK_SIGNING_SECRET"))
            .scope("chat:write,chat:write.public,commands,metadata.message:read")
            .oauthInstallPath("/slack/install")
            .oauthRedirectUriPath("/slack/oauth_redirect")
            .build();
    }

    @Bean
    public InstallationService initInstallationService(AppConfig config) {
        FileInstallationService fileInstallationService = new FileInstallationService(config);
        fileInstallationService.setHistoricalDataEnabled(true);
        return fileInstallationService;
    }

    @Bean
    public OAuthStateService initStateService(AppConfig config) {
        return new FileOAuthStateService(config);
    }

    @Bean
    public App initSlackApp(AppConfig config, InstallationService, OAuthStateService stateService) {
        App app = new App(config);
        if (config.getClientId() != null) {
            app.asOAuthApp(true);
        }

        app.service(installationService);
        app.service(stateService);

        // app.command(mycommand, myeventhandler);

        return app;
    }
}

And I keep getting "auth.test result: null, io error: null, api error: null"

@ChristopherVennemann Probably, your situation should be the same with this issue. Could you check my response here and try the steps I mentioned there? #1171 (comment)

Hi @seratch,
thank you for your reply!

I don't see how the issue that you linked is related.
The other user seemed to have trouble completing the OAuth process, and the solution was to set a single redirect url in the api.slack.com OAuth and Permissions tab.

I've had a single reditect url from the start, and for me OAuth appears to complete just fine. I end up at my SLACK_OAUTH_COMPLETION_URL.
I receive the response
{ "ok":true, "url":"https:\/\/myteam.slack.com\/", "team":"myworkspacename", "user":"myappname", "team_id":"myteamid", "user_id":"someuserid", "bot_id":"somebotid", "is_enterprise_install":false }

The bot appears in the workspace. The /command works fine. It opens a modal just fine. Both the slash command and the modal submission seem to trigger a POST https://slack.com/api/auth.test which gets answered with an [Response Status] 200 .

ngrok gives me:

POST /slack/events             200  // modal submission -> chat.PostMessage call                                                                                      
POST /slack/events             200 // slash command -> viewsOpen call                                                                                       
GET  /slack/oauth_redirect     302                                                                                      
GET  /slack/install            200   

It's only at the last step, chatPostMessage, that it fails and gives me {"ok":false,"error":"channel_not_found"}. According to https://api.slack.com/methods/chat.postMessage, that means an incorrect channelId has been passed to the chatPostMessage method. But I know the channel is correct for sure. I can see the correct channelId right here in the outgoing request.

It also lists the auth token as a required parameter, but since the framework seems to manage auth tokens behind the scenes I do not know how to deal with that information other than assuming that the framework will also pass the appropriate token to chatPostMessage?

If I understand correctly, I do not need to set up an installation service and state service myself? The framework should default to a local file service?

I was thinking, maybe I am missing the correct oauth scope to post to / find the correct channel, but then why would it work in the original workspace?
"chat:write,chat:write.public,commands,metadata.message:read" should be enough to have slash command that creates a modal, submit the modal and make a chat post to the channel, right?

👋 It looks like this issue has been open for 30 days with no activity. We'll mark this as stale for now, and wait 10 days for an update or for further comment before closing this issue out. If you think this issue needs to be prioritized, please comment to get the thread going again! Maintainers also review issues marked as stale on a regular basis and comment or adjust status if the issue needs to be reprioritized.

As this issue has been inactive for more than one month, we will be closing it. Thank you to all the participants! If you would like to raise a related issue, please create a new issue which includes your specific details and references this issue number.

In case anyone comes across this issue, by searching "No request pattern detected for":
I couldn't get my OAuth installation starting page on /slack/install to load, getting this error and seeing an empty screen.
After debugging my app and investigating SlackRequestParser, I realised that AppConfig was not returning the oauthInstallPath that I had set, because it had found a SLACK_INSTALL_PATH environment variable (residue of my previous testing). I spent hours on this because of this silly mistake I made. I wish the error message gave me a bit more direction.