laravel / slack-notification-channel

Slack Notification Channel for laravel.
https://laravel.com/docs/notifications#slack-notifications
MIT License
864 stars 59 forks source link

500 Missing Scope error when using incoming-webhook bot token scope #92

Open sedwardsgt opened 2 months ago

sedwardsgt commented 2 months ago

Slack Notification Channel Version

3.2.0

Laravel Version

11.9.2

PHP Version

8.2

Database Driver & Version

mongodb/laravel-mongodb v4.4

Description

In converting my app from Laravel 10 to 11, I am converting from using nathanheffley/laravel-slack-blocks to this library. We. have a working published app that our users have installed and enabled that uses OAuth to get a bot token and incoming-webhook URL. and then sends notifications to the designated Slack channel.

Per the Laravel docs, I have obtained a token and channel name from the oauth response and stored them in the database, and then written my routeNotificationForSlack in my notifiable model like so:

    public function routeNotificationForSlack($notification): mixed
    {
        return SlackRoute::make($this->getAttribute('slackChannelName'), $this->getAttribute('slackBotToken'));
    }

However, when I use SlackMessage to make the call, I get a 500 error saying

Slack API call failed with error [missing_scope].

Per the docs - and what has always worked - the only bot scope that needs to be defined is incoming-webhook.

The reason I'm filing this here is that the only thing that has changed is my Laravel library/code, not anything on the Slack side.

Steps To Reproduce

  1. Enable incoming-webhook scope for bot token in Slack app.
  2. Obtain bot token and channel name from OAuth response, and store locally
  3. Implement routeNotificationForSlack in notifiable model per docs using token and channel value
  4. Send message using Illuminate\Notifications\Slack\SlackMessage from toSlack() implementation in notification class.

Update

Digging further into the code and response from this call

$response = $this->http->asJson()
    ->withToken($route->token)
    ->post('https://slack.com/api/chat.postMessage', $payload)
    ->throw();

in Illuminate\Http\Client\Response->json(), I get the following array returned from $response->json()

decoded = [
    ok = false
    error = "missing_scope"
    needed = "chat:write:bot"
    provided="incoming-webhook"
    warning="missing_charset"
]

However, the issues are

  1. There is no chat:write:bot permission/scope available in the app
  2. If I add it as a scope param in my OAuth URL, it overwrites the incoming-webhooks settings.

What's even more confusing is that with the nathanheffley/laravel-slack-blocks library, my notifiable model call looked like this

    public function routeNotificationForSlack($notification): ?string
    {
        return $this->getAttribute('slackWebhookUrl');
    }

and works fine. However, if I do the same thing with this tool , I get this issue, which a) doesn't have a definite answer and b) was closed for some reason, even though it wasn't totally solved (the same is true for this similar issue). As noted above, this library is calling https://slack.com/api/chat.postMessage, which is what is giving me the missing_scope error.

Looking at this and the other linked issues, this really needs either some fixing or clarification.

jbrooksuk commented 2 months ago

@sedwardsgt I'm afraid I'm not going to have time to look at this for a couple of weeks.

Also, it looks like this is only part of the error response? Are you able to attach the complete response from the Slack API - which is typically a JSON object.

In the meantime, if someone else is able to look into this, I'd appreciate a PR.

github-actions[bot] commented 2 months ago

Thank you for reporting this issue!

As Laravel is an open source project, we rely on the community to help us diagnose and fix issues as it is not possible to research and fix every issue reported to us via GitHub.

If possible, please make a pull request fixing the issue you have described, along with corresponding tests. All pull requests are promptly reviewed by the Laravel team.

Thank you!

sedwardsgt commented 2 months ago

With some more work, I am now able to send messages, with a couple of caveats. After a few re-authorizations, I started getting the [not_in_channel] error message, which indicated that my bot had to be invited to my designated channel. Once I went to my channel in my workspace and did /invite @myappname, I was able to successfully send messages. But again, this raises two issues.

First, with our current implementation with nathanheffley/laravel-slack-blocks, we don't have to do any bot invites. As I pointed out above, our routeNotificationForSlack() implementation just returns the slack URL that we got from OAuth (e.g. https://hooks.slack.com/services/whatever), and that's all that's needed. We don't have to make a conversations.invite call to do it.

Second, along the lines of the first point, this is now the call that is made in SlackChannel->send()

    public function send(mixed $notifiable, Notification $notification): ?Response
    {
        $route = $this->determineRoute($notifiable, $notification);

        $message = $notification->toSlack($notifiable);

        $payload = $this->buildJsonPayload($message, $route);

        if (! $payload['channel']) {
            throw new LogicException('Slack notification channel is not set.');
        }

        if (! $route->token) {
            throw new LogicException('Slack API authentication token is not set.');
        }

        $response = $this->http->asJson()
            ->withToken($route->token)
            ->post('https://slack.com/api/chat.postMessage', $payload)
            ->throw();

        if ($response->successful() && $response->json('ok') === false) {
            throw new RuntimeException('Slack API call failed with error ['.$response->json('error').'].');
        }

        return $response;
    }

So what it's now doing is using routeNotificationForSlack() hook to just get the token and channel, and then posting to https://slack.com/api/chat.postMessage .

I don't understand the reason for the difference (and now the extra steps).

Ticket-Master commented 1 month ago

i dont know if this is relevant to your problem but to get a grasp of basics of setting up, you can visit this article from Ralph. I found it useful and when i setup according to it. i fixed my problem https://ralphjsmit.com/laravel-slack-webhook-notifications