From eaba6a507cf898b4f78585799cf920fe981668a1 Mon Sep 17 00:00:00 2001 From: Emanuele Panzeri Date: Sun, 6 Oct 2019 17:16:15 +0200 Subject: [PATCH] Add Mattermost notifier bridge --- .../FrameworkExtension.php | 2 + .../Resources/config/notifier_transports.xml | 4 + .../Notifier/Bridge/Mattermost/.gitattributes | 2 + .../Notifier/Bridge/Mattermost/CHANGELOG.md | 7 ++ .../Notifier/Bridge/Mattermost/LICENSE | 19 +++++ .../Bridge/Mattermost/MattermostTransport.php | 78 +++++++++++++++++++ .../Mattermost/MattermostTransportFactory.php | 45 +++++++++++ .../Notifier/Bridge/Mattermost/README.md | 12 +++ .../Notifier/Bridge/Mattermost/composer.json | 35 +++++++++ .../Bridge/Mattermost/phpunit.xml.dist | 31 ++++++++ .../Notifier/Bridge/Slack/SlackTransport.php | 4 +- .../Bridge/Telegram/TelegramTransport.php | 4 +- src/Symfony/Component/Notifier/CHANGELOG.md | 1 + .../Exception/UnsupportedSchemeException.php | 4 + src/Symfony/Component/Notifier/Transport.php | 2 + 15 files changed, 246 insertions(+), 4 deletions(-) create mode 100644 src/Symfony/Component/Notifier/Bridge/Mattermost/.gitattributes create mode 100644 src/Symfony/Component/Notifier/Bridge/Mattermost/CHANGELOG.md create mode 100644 src/Symfony/Component/Notifier/Bridge/Mattermost/LICENSE create mode 100644 src/Symfony/Component/Notifier/Bridge/Mattermost/MattermostTransport.php create mode 100644 src/Symfony/Component/Notifier/Bridge/Mattermost/MattermostTransportFactory.php create mode 100644 src/Symfony/Component/Notifier/Bridge/Mattermost/README.md create mode 100644 src/Symfony/Component/Notifier/Bridge/Mattermost/composer.json create mode 100644 src/Symfony/Component/Notifier/Bridge/Mattermost/phpunit.xml.dist diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 590d69ee95..442acb9dab 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -90,6 +90,7 @@ use Symfony\Component\Messenger\Transport\TransportFactoryInterface; use Symfony\Component\Messenger\Transport\TransportInterface; use Symfony\Component\Mime\MimeTypeGuesserInterface; use Symfony\Component\Mime\MimeTypes; +use Symfony\Component\Notifier\Bridge\Mattermost\MattermostTransportFactory; use Symfony\Component\Notifier\Bridge\Nexmo\NexmoTransportFactory; use Symfony\Component\Notifier\Bridge\Slack\SlackTransportFactory; use Symfony\Component\Notifier\Bridge\Telegram\TelegramTransportFactory; @@ -1997,6 +1998,7 @@ class FrameworkExtension extends Extension $classToServices = [ SlackTransportFactory::class => 'notifier.transport_factory.slack', TelegramTransportFactory::class => 'notifier.transport_factory.telegram', + MattermostTransportFactory::class => 'notifier.transport_factory.mattermost', NexmoTransportFactory::class => 'notifier.transport_factory.nexmo', TwilioTransportFactory::class => 'notifier.transport_factory.twilio', ]; diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.xml index c4d9cf892a..4625458280 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.xml @@ -18,6 +18,10 @@ + + + + diff --git a/src/Symfony/Component/Notifier/Bridge/Mattermost/.gitattributes b/src/Symfony/Component/Notifier/Bridge/Mattermost/.gitattributes new file mode 100644 index 0000000000..aa02dc6518 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Mattermost/.gitattributes @@ -0,0 +1,2 @@ +/Tests export-ignore +/phpunit.xml.dist export-ignore diff --git a/src/Symfony/Component/Notifier/Bridge/Mattermost/CHANGELOG.md b/src/Symfony/Component/Notifier/Bridge/Mattermost/CHANGELOG.md new file mode 100644 index 0000000000..7bd5e9a57f --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Mattermost/CHANGELOG.md @@ -0,0 +1,7 @@ +CHANGELOG +========= + +5.1.0 +----- + + * Added the bridge diff --git a/src/Symfony/Component/Notifier/Bridge/Mattermost/LICENSE b/src/Symfony/Component/Notifier/Bridge/Mattermost/LICENSE new file mode 100644 index 0000000000..5593b1d84f --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Mattermost/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2020 Fabien Potencier + +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. diff --git a/src/Symfony/Component/Notifier/Bridge/Mattermost/MattermostTransport.php b/src/Symfony/Component/Notifier/Bridge/Mattermost/MattermostTransport.php new file mode 100644 index 0000000000..123abe8348 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Mattermost/MattermostTransport.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Mattermost; + +use Symfony\Component\Notifier\Exception\LogicException; +use Symfony\Component\Notifier\Exception\TransportException; +use Symfony\Component\Notifier\Message\ChatMessage; +use Symfony\Component\Notifier\Message\MessageInterface; +use Symfony\Component\Notifier\Transport\AbstractTransport; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * @author Emanuele Panzeri + * + * @experimental in 5.1 + */ +final class MattermostTransport extends AbstractTransport +{ + private $token; + private $channel; + + public function __construct(string $token, string $channel, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null) + { + $this->token = $token; + $this->channel = $channel; + + parent::__construct($client, $dispatcher); + } + + public function __toString(): string + { + return sprintf('mattermost://%s?channel=%s', $this->getEndpoint(), $this->channel); + } + + public function supports(MessageInterface $message): bool + { + return $message instanceof ChatMessage; + } + + /** + * @see https://api.mattermost.com + */ + protected function doSend(MessageInterface $message): void + { + if (!$message instanceof ChatMessage) { + throw new LogicException(sprintf('The "%s" transport only supports instances of "%s" (instance of "%s" given).', __CLASS__, ChatMessage::class, \get_class($message))); + } + + $endpoint = sprintf('https://%s/api/v4/post', $this->getEndpoint()); + + $options = ($opts = $message->getOptions()) ? $opts->toArray() : []; + $options['message'] = $message->getSubject(); + + if (!isset($options['channel_id'])) { + $options['channel_id'] = $message->getRecipientId() ?: $this->channel; + } + $response = $this->client->request('POST', $endpoint, [ + 'bearer' => $this->token, + 'json' => array_filter($options), + ]); + + if (200 !== $response->getStatusCode()) { + $result = $response->toArray(false); + + throw new TransportException(sprintf('Unable to post the Mattermost message: %s (%s).', $result['message'], $result['id']), $response); + } + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Mattermost/MattermostTransportFactory.php b/src/Symfony/Component/Notifier/Bridge/Mattermost/MattermostTransportFactory.php new file mode 100644 index 0000000000..884d470ddc --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Mattermost/MattermostTransportFactory.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Mattermost; + +use Symfony\Component\Notifier\Exception\UnsupportedSchemeException; +use Symfony\Component\Notifier\Transport\AbstractTransportFactory; +use Symfony\Component\Notifier\Transport\Dsn; +use Symfony\Component\Notifier\Transport\TransportInterface; + +/** + * @author Emanuele Panzeri + * + * @experimental in 5.1 + */ +final class MattermostTransportFactory extends AbstractTransportFactory +{ + public function create(Dsn $dsn): TransportInterface + { + $scheme = $dsn->getScheme(); + $token = $this->getUser($dsn); + $channel = $dsn->getOption('channel'); + $host = $dsn->getHost(); + $port = $dsn->getPort(); + + if ('mattermost' === $scheme) { + return (new MattermostTransport($token, $channel, $this->client, $this->dispatcher))->setHost($host)->setPort($port); + } + + throw new UnsupportedSchemeException($dsn, 'mattermost', $this->getSupportedSchemes()); + } + + protected function getSupportedSchemes(): array + { + return ['mattermost']; + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Mattermost/README.md b/src/Symfony/Component/Notifier/Bridge/Mattermost/README.md new file mode 100644 index 0000000000..0ed0fc00a7 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Mattermost/README.md @@ -0,0 +1,12 @@ +Mattermost Notifier +=================== + +Provides Mattermost integration for Symfony Notifier. + +Resources +--------- + + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/src/Symfony/Component/Notifier/Bridge/Mattermost/composer.json b/src/Symfony/Component/Notifier/Bridge/Mattermost/composer.json new file mode 100644 index 0000000000..932033c303 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Mattermost/composer.json @@ -0,0 +1,35 @@ +{ + "name": "symfony/mattermost-notifier", + "type": "symfony-bridge", + "description": "Symfony Mattermost Notifier Bridge", + "keywords": ["mattermost", "notifier"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Emanuele Panzeri", + "email": "thepanz@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^7.2.5", + "symfony/http-client": "^4.3|^5.0", + "symfony/notifier": "^5.0" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Notifier\\Bridge\\Mattermost\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Mattermost/phpunit.xml.dist b/src/Symfony/Component/Notifier/Bridge/Mattermost/phpunit.xml.dist new file mode 100644 index 0000000000..c7f3582812 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Mattermost/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/src/Symfony/Component/Notifier/Bridge/Slack/SlackTransport.php b/src/Symfony/Component/Notifier/Bridge/Slack/SlackTransport.php index 566ee7a25f..fb18f7c913 100644 --- a/src/Symfony/Component/Notifier/Bridge/Slack/SlackTransport.php +++ b/src/Symfony/Component/Notifier/Bridge/Slack/SlackTransport.php @@ -33,10 +33,10 @@ final class SlackTransport extends AbstractTransport private $accessToken; private $chatChannel; - public function __construct(string $accessToken, string $chatChannel = null, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null) + public function __construct(string $accessToken, string $channel = null, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null) { $this->accessToken = $accessToken; - $this->chatChannel = $chatChannel; + $this->chatChannel = $channel; $this->client = $client; parent::__construct($client, $dispatcher); diff --git a/src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransport.php b/src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransport.php index 7856938187..4f9cb3b374 100644 --- a/src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransport.php +++ b/src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransport.php @@ -38,10 +38,10 @@ final class TelegramTransport extends AbstractTransport private $token; private $chatChannel; - public function __construct(string $token, string $chatChannel = null, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null) + public function __construct(string $token, string $channel = null, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null) { $this->token = $token; - $this->chatChannel = $chatChannel; + $this->chatChannel = $channel; $this->client = $client; parent::__construct($client, $dispatcher); diff --git a/src/Symfony/Component/Notifier/CHANGELOG.md b/src/Symfony/Component/Notifier/CHANGELOG.md index ce86089d2f..1501819392 100644 --- a/src/Symfony/Component/Notifier/CHANGELOG.md +++ b/src/Symfony/Component/Notifier/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 5.1.0 ----- + * Added the Mattermost notifier bridge * [BC BREAK] The `ChatMessage::fromNotification()` method's `$recipient` and `$transport` arguments were removed. * [BC BREAK] The `EmailMessage::fromNotification()` and `SmsMessage::fromNotification()` diff --git a/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php b/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php index c61446339a..24bdebeb17 100644 --- a/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php +++ b/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php @@ -30,6 +30,10 @@ class UnsupportedSchemeException extends LogicException 'class' => Bridge\Telegram\TelegramTransportFactory::class, 'package' => 'symfony/telegram-notifier', ], + 'mattermost' => [ + 'class' => Bridge\Mattermost\MattermostTransportFactory::class, + 'package' => 'symfony/mattermost-notifier', + ], 'nexmo' => [ 'class' => Bridge\Nexmo\NexmoTransportFactory::class, 'package' => 'symfony/nexmo-notifier', diff --git a/src/Symfony/Component/Notifier/Transport.php b/src/Symfony/Component/Notifier/Transport.php index c8e6a8ad39..1671fca2c9 100644 --- a/src/Symfony/Component/Notifier/Transport.php +++ b/src/Symfony/Component/Notifier/Transport.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Notifier; +use Symfony\Component\Notifier\Bridge\Mattermost\MattermostTransportFactory; use Symfony\Component\Notifier\Bridge\Nexmo\NexmoTransportFactory; use Symfony\Component\Notifier\Bridge\Slack\SlackTransportFactory; use Symfony\Component\Notifier\Bridge\Telegram\TelegramTransportFactory; @@ -36,6 +37,7 @@ class Transport private const FACTORY_CLASSES = [ SlackTransportFactory::class, TelegramTransportFactory::class, + MattermostTransportFactory::class, NexmoTransportFactory::class, TwilioTransportFactory::class, ];