laravel / slack-notification-channel

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

Unable to set $elements values in Laravel Slack notification block classes #93

Open sedwardsgt opened 3 months ago

sedwardsgt commented 3 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

I am converting a Laravel app from using Nathanhelfley/laravel-slack-blocks to using the built in Illuminate\Notifications\Slack\BlockKit\Blocks blocks, and I can't figure out how to pass in the $elements value. For instance, with a SlackBlock class, I would do this for a context block;

        $block->elements([
            [
                'type' => 'mrkdwn',
                'text' => "Pursuit: *{$this->activityModel->target->name}*",
            ],
        ]);

However, with the ContextBlock class, there is no interface to pass in the entire element (e.g. type => markdown) because there is no setter for $elements and it is protected. The same is true for the other block types. How do I pass in the other values for a block other than the text and the id?

Per one suggestion, the correct implementation is something like this

$contextBlock = new ContextBlock();
$contextBlock->text(new MarkdownText("Pursuit: *{$this->activityModel->target->name}*"));
Add the block to your Slack message:
use Illuminate\Notifications\Slack\SlackMessage;

$slackMessage = (new SlackMessage)
    ->blocks(function ($block) use ($contextBlock) {
        $block->context($contextBlock);
    });

But there are two problems

Something like this doesn't work, for the same reason

        $block = new ContextBlock();

        $text_block = new TextObject("Pursuit: *{'My pursuit text}*");
        $text_block->markdown();

        $block->text($text_block);

But it's not just the markdown property. If you look at the doc block for the $elements property in ActionsBlock, you see

    /**
     * An array of interactive element objects - buttons, select menus, overflow menus, or date pickers.
     *
     * There is a maximum of 25 elements in each action block.
     *
     * @var \Illuminate\Notifications\Slack\Contracts\ElementContract[]
     */
    protected array $elements = [];

which indicates to me that there somewhere is a way to add to those elements (up to 25), since the Slack Blocks Reference indicates that there are many more things that can be added other than what these block kit classes allow.

As another example, the ActionsBlock has a button() method, but all it does is pass the text to the button:

    public function button(string $text): ButtonElement
    {
        return tap(new ButtonElement($text), function (ButtonElement $button) {
            $this->elements[] = $button;
        });
    }

with no option to pass the url. Do I have to somehow override that with a custom ButtonElement?

Yes, I've seen the Laravel Notifications docs, but that doesn't really answer this question, either (unless I'm missing something).

So it seems there is no way to build the blocks with all of the $elements values. Apologies if this is not a bug and I'm just mis-reading the code, but if it is a feature, some guidance would be appreciated.

Steps To Reproduce

  1. Implement SlackMessage class
  2. Attempt to add items to the $elements array

See above for examples

driesvints commented 3 months ago

Thanks @sedwardsgt. Again assigning @jbrooksuk but highly unlikely he'll be able to help any time soon. Would appreciate PR's if anything can be improved here. Thanks.

github-actions[bot] commented 3 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!

nathanheffley commented 3 months ago

@sedwardsgt does something like this not work?

use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
use Illuminate\Notifications\Slack\SlackMessage;

$slackMessage = (new SlackMessage)
    ->contextBlock(function (ContextBlock $block) {
        $block->text("Pursuit: *{$this->activityModel->target->name}*")->markdown();
    });
nathanheffley commented 3 months ago

The API of this implementation is quite a bit different from my package's implementation. You will probably be served better by reading the docs and recreating the messages following the doc examples than trying to convert the code used for my package.

sedwardsgt commented 3 months ago

Yeah, that's what I ended up doing.

To answer your question above, yes, that was what I ended up doing.

However, it seems that there are many options available for Slack message customization that are not available via the new implementation, that are allowed by allowing direct access to the elements array.

princejohnsantillan commented 3 days ago

I believe this update https://github.com/laravel/slack-notification-channel/pull/98 will help with this issue. You should now be able to use anything you find in https://app.slack.com/block-kit-builder.