symfony/slack-notifier使ってみた



[Symfony Advent Calendar 2022](https://qiita.com/advent-calendar/2022/symfony) 14日目の記事です✨

`symfony/slack-notifier`を使ってみたよーって記事です。


## `symfony/slack-notifier`はどんなもの？

https://github.com/symfony/slack-notifier

まず、`symfony/notifier`という通知するためのコンポーネントがもあります。
このコンポーネントは、

 - SMS Channel
 - Chat Channel   👈Slackはココ
 - Email Channel
 - Browser Channel
 - Push Channel

をサポートしており、Slackなどは`Chat Channel`に該当します。
これらは[Chatterクラス](https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Notifier/Chatter.php)を使うことでメッセージを送信できるとのことです。
<https://symfony.com/doc/current/notifier.html#chat-channel>


そこで送信するSlackメッセージを組み立てるために提供されているのが今回使う`symfony/slack-notifier`です🙌🔥

では、実際に使ってみた手順をご紹介します。

## `composer require symfony/slack-notifier`

`symfony/slack-notifier`をrequireすると、`symfony/notifier`もinstallされます。

```bash
$ composer require symfony/slack-notifier
Info from https://repo.packagist.org: #StandWithUkraine
./composer.json has been updated
Running composer update symfony/slack-notifier
Loading composer repositories with package information
Info from https://repo.packagist.org: #StandWithUkraine
Restricting packages listed in "symfony/symfony" to "6.2.*"
Updating dependencies
Lock file operations: 4 installs, 0 updates, 0 removals
  - Locking symfony/http-client (v6.2.0)
  - Locking symfony/http-client-contracts (v3.1.1)
  - Locking symfony/notifier (v6.2.0)
  - Locking symfony/slack-notifier (v6.2.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 4 installs, 0 updates, 0 removals
  - Installing symfony/http-client-contracts (v3.1.1): Extracting archive
  - Installing symfony/notifier (v6.2.0): Extracting archive
  - Installing symfony/http-client (v6.2.0): Extracting archive
  - Installing symfony/slack-notifier (v6.2.0): Extracting archive
Generating autoload files
30 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

Symfony operations: 2 recipes (abfafcc985784e830f69f608b281401d)
  - Configuring symfony/notifier (>=5.0): From github.com/symfony/recipes:main
  - Configuring symfony/slack-notifier (>=5.2): From github.com/symfony/recipes:main
Executing script cache:clear [OK]
Executing script assets:install public [OK]
              
...
```

## .envを調整
```yaml
###> symfony/slack-notifier ###
SLACK_DSN=slack://xoxb-xxxx@default?channel=xxxx
###< symfony/slack-notifier ###
```

## notifier.yamlのコメントアウトをはずす
```diff:yaml
framework:
    notifier:
        chatter_transports:
- #            slack: '%env(SLACK_DSN)%'
+             slack: '%env(SLACK_DSN)%'
```

## 実際にSlack通知してみる

```php
<?php
declare(strict_types=1);

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Notifier\Bridge\Slack\Block\SlackContextBlock;
use Symfony\Component\Notifier\Bridge\Slack\Block\SlackImageBlockElement;
use Symfony\Component\Notifier\Bridge\Slack\Block\SlackSectionBlock;
use Symfony\Component\Notifier\Bridge\Slack\SlackOptions;
use Symfony\Component\Notifier\ChatterInterface;
use Symfony\Component\Notifier\Exception\TransportExceptionInterface;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Routing\Annotation\Route;

class SlackNotifierController extends AbstractController
{
    /**
     * @throws TransportExceptionInterface
     */
    #[Route(path: '/send-chat', name: 'app_send_chat')]
    public function sendChat(ChatterInterface $chatter): Response
    {
        $slackSectionBlock = new SlackSectionBlock();
        $slackSectionBlock->text('A message *with some bold text* and _some italicized text_.');

        $slackContextBlock = new SlackContextBlock();
        $slackContextBlock->text('*This* is :smile: markdown');
        $slackContextBlock->image(
            'https://pbs.twimg.com/profile_images/625633822235693056/lNGUneLX_400x400.jpg',
            'cute cat'
        );
        $slackContextBlock->image(
            'https://pbs.twimg.com/profile_images/625633822235693056/lNGUneLX_400x400.jpg',
            'cute cat'
        );
        $slackContextBlock->text(
            'Author: K A Applegate',
            false,
        );

        $slackOptions = new SlackOptions();
        $slackOptions->block($slackSectionBlock);
        $slackOptions->block($slackContextBlock);

        $chatMessage = new ChatMessage('subject');
        $chatMessage->options($slackOptions);

        $chatter->send($chatMessage);

        return new Response('slack done', 200, []);
    }
}
```

以下のメッセージ通知ができました🎉

![スクリーンショット 2022-12-13 14.53.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83896/9b57d75c-a9d5-2e04-4057-118df43e1ab3.png)



### [おまけ] section block with an accessory image
![スクリーンショット 2022-12-13 14.53.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83896/132bff1a-9655-7280-1765-a734342d4ef7.png)

```php
$slackImageBlockElement = new SlackImageBlockElement(
    'https://pbs.twimg.com/profile_images/625633822235693056/lNGUneLX_400x400.jpg',
    'cute cat'
);

$slackSectionBlock = new SlackSectionBlock();
$slackSectionBlock->text('This is a section block with an accessory image.');
$slackSectionBlock->accessory($slackImageBlockElement);

$slackOptions = new SlackOptions();
$slackOptions->block($slackSectionBlock);

$chatMessage = new ChatMessage('subject image section');
$chatMessage->options($slackOptions);

$chatter->send($chatMessage);
```


## 感想
配列を書くのは大変なので、Symfony公式であるの助かります :bow:
buttonとimageはあるのですが、input系はまだないので自分で作る必要がありそうでした。