herpaderpaldent/seat-notifications

View on GitHub
src/Channels/Slack/SlackChannel.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php
/**
 * MIT License.
 *
 * Copyright (c) 2019. Felix Huber
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

namespace Herpaderpaldent\Seat\SeatNotifications\Channels\Slack;

use Exception;
use Herpaderpaldent\Seat\SeatNotifications\Jobs\SendSlackNotification;
use Illuminate\Notifications\Notification;

class SlackChannel
{
    /**
     * The HTTP client instance.
     *
     * @var \JoliCode\Slack\Api\Client
     */
    protected $client;

    /**
     * Create a new Slack channel instance.
     */
    public function __construct()
    {

        $this->client = app('slack');
    }

    /**
     * @param                                        $notifiable
     * @param \Illuminate\Notifications\Notification $notification
     *
     * @throws \Exception
     */
    public function send($notifiable, Notification $notification)
    {

        if (! $channel = $notifiable->driver_id) {
            throw new Exception('Channel could not be found.');
        }

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

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

        $parameters = array_filter([
            'channel'     => $channel,
            'text'        => $payload['json']['text'],
            'attachments' => json_encode($payload['json']['attachments']),
        ]);

        $job = new SendSlackNotification($parameters);

        dispatch($job)->onQueue('high');
    }

    /**
     * Build up a JSON payload for the Slack webhook.
     *
     * @param \Herpaderpaldent\Seat\SeatNotifications\Channels\Slack\SlackMessage $message
     *
     * @return array
     */
    protected function buildJsonPayload(SlackMessage $message)
    {

        $optionalFields = array_filter([
            'channel'      => data_get($message, 'channel'),
            'icon_emoji'   => data_get($message, 'icon'),
            'icon_url'     => data_get($message, 'image'),
            'link_names'   => data_get($message, 'linkNames'),
            'unfurl_links' => data_get($message, 'unfurlLinks'),
            'unfurl_media' => data_get($message, 'unfurlMedia'),
            'username'     => data_get($message, 'username'),
        ]);

        return array_merge([
            'json' => array_merge([
                'text'        => $message->content,
                'attachments' => $this->attachments($message),
            ], $optionalFields),
        ], $message->http);
    }

    /**
     * Format the message's attachments.
     *
     * @param \Herpaderpaldent\Seat\SeatNotifications\Channels\Slack\SlackMessage $message
     *
     * @return array
     */
    protected function attachments(SlackMessage $message)
    {

        return collect($message->attachments)->map(function ($attachment) use ($message) {

            return array_filter([
                'author_icon' => $attachment->authorIcon,
                'author_link' => $attachment->authorLink,
                'author_name' => $attachment->authorName,
                'color'       => $attachment->color ?: $message->color(),
                'fallback'    => $attachment->fallback,
                'fields'      => $this->fields($attachment),
                'footer'      => $attachment->footer,
                'footer_icon' => $attachment->footerIcon,
                'image_url'   => $attachment->imageUrl,
                'mrkdwn_in'   => $attachment->markdown,
                'text'        => $attachment->content,
                'thumb_url'   => $attachment->thumbUrl,
                'title'       => $attachment->title,
                'title_link'  => $attachment->url,
                'ts'          => $attachment->timestamp,
            ]);
        })->all();
    }

    /**
     * Format the attachment's fields.
     *
     * @param \Herpaderpaldent\Seat\SeatNotifications\Channels\Slack\SlackAttachment $attachment
     *
     * @return array
     */
    protected function fields(SlackAttachment $attachment)
    {

        return collect($attachment->fields)->map(function ($value, $key) {

            if ($value instanceof SlackAttachmentField) { //SlackAttachmentField
                return $value->toArray();
            }

            return ['title' => $key, 'value' => $value, 'short' => true];
        })->values()->all();
    }
}