slackapi / bolt-js

A framework to build Slack apps using JavaScript
https://slack.dev/bolt-js
MIT License
2.73k stars 390 forks source link

`client.chat.postMessage` with a user token throws `invalid_auth` error #2168

Closed dianexjeong closed 1 month ago

dianexjeong commented 1 month ago

@slack/bolt version

^3.19.0

Your App and Receiver Configuration

const receiver = new ExpressReceiver({
  signingSecret: process.env.SLACK_SIGNING_SECRET,
  port: process.env.SLACK_APP_PORT,
  clientId: process.env.SLACK_CLIENT_ID,
  clientSecret: process.env.SLACK_CLIENT_SECRET,
  stateSecret: "my-state-secret",
  scopes: ["chat:write", "chat:write.customize", "im:history", "im:write", "users:read", "users:read.email"],
  installerOptions: {
    userScopes: ["im:write", "chat:write"]
  }
...
})

const app = new App({
  receiver,
});

Node.js runtime version

v18.17.1

Steps to reproduce:

Hi, I am making a Slack Bot that requires the Slack Bot to send some messages on behalf of the user, using the user's identity.

To do this, I am a) using a OAuth flow to issue user tokens b) granting the chat:write user scope and the chat:write.customize bot scope and c) saving the user scope generated when each user confirms the usage of their tokens (allowing my bot to perform actions on their behalf).

What I tried to do is calling the client.chat.postMessage method in my code, trying to pass the userToken as a token override, like this:

   await client.chat.postMessage({
          token: userToken,
          channel: user.member_id,
          blocks: [], // my blocks here
        });

However, when I try to invoke the postMessage method I am getting the following error.

Screenshot 2024-07-17 at 9 12 06 PM

I have logged the userToken beforehand and have checked that I am using a valid token that starts with xoxp-. I do understand that I will be able to achieve the expected result using the HTTP method, but I'm worried that I would be facing harsher rate limits while doing so. I would like to be able to use the client object provided by Bolt to invoke the postMessage method.

How can I call the client.chat.postMessage method using a userToken and thus send messages as users with my bot?

Expected result:

I want to be able to send a message as the user with the user's userToken.

Actual result:

getting the invalid_auth error

Requirements

For general questions/issues about Slack API platform or its server-side, could you submit questions at https://my.slack.com/help/requests/new instead. :bow:

Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

WilliamBergamin commented 1 month ago

Hi @dianexjeong thanks for writing in 💯

I am unable to reproduce your behavior, the user token used to make the request may be invalid

If you've logged the token being used to make the request, you can try using it in the method tester for chat.postMessage and see if a message gets posted with it.

dianexjeong commented 1 month ago

Thank you @WilliamBergamin for following up!

After trying it in the method tester for chat.postMessage, it does seems that the token may be invalid -

Screenshot 2024-07-18 at 9 01 15 AM

I am currently saving the token in my database during my App's installation process - and I am collecting each user's user token each time a new user reinstalls the app in the workspace.

The installerOptions that I have configured in the app.js file is as follows:

installerOptions: {
    userScopes: ["im:write", "chat:write"], // user scopes
    directInstall: true,
    callbackOptions: {
      success: (installation, installOptions, req, res) => {
        (async () => {
          try {
            const userId = installation.user.id;
            const userToken = installation.user.token;
...
})}}}

I'm saving the user token that I can find in the installation object.

Perhaps this is the issue - which user token am I supposed to save, and in which process can I access & save the valid user token?

dianexjeong commented 1 month ago

Turned out to be a simple mistake on my side - I was trying to fit in the user token in my database where the column's size was smaller than the actual token's size and was cutting off the user token short.

Sorry for the inconvenience! I'll be happy to close this issue.