Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit afcca88

Browse filesBrowse files
JamesHemeryOskarStark
authored andcommitted
[Notifier] [SpotHit] Add the bridge
1 parent 72a82c3 commit afcca88
Copy full SHA for afcca88

File tree

11 files changed

+348
-0
lines changed
Filter options

11 files changed

+348
-0
lines changed

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
use Symfony\Component\Notifier\Bridge\Sinch\SinchTransportFactory;
127127
use Symfony\Component\Notifier\Bridge\Slack\SlackTransportFactory;
128128
use Symfony\Component\Notifier\Bridge\Smsapi\SmsapiTransportFactory;
129+
use Symfony\Component\Notifier\Bridge\SpotHit\SpotHitTransportFactory;
129130
use Symfony\Component\Notifier\Bridge\Telegram\TelegramTransportFactory;
130131
use Symfony\Component\Notifier\Bridge\Twilio\TwilioTransportFactory;
131132
use Symfony\Component\Notifier\Bridge\Zulip\ZulipTransportFactory;
@@ -2236,6 +2237,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $
22362237
AllMySmsTransportFactory::class => 'notifier.transport_factory.allmysms',
22372238
FirebaseTransportFactory::class => 'notifier.transport_factory.firebase',
22382239
FreeMobileTransportFactory::class => 'notifier.transport_factory.freemobile',
2240+
SpotHitTransportFactory::class => 'notifier.transport_factory.spothit',
22392241
OvhCloudTransportFactory::class => 'notifier.transport_factory.ovhcloud',
22402242
SinchTransportFactory::class => 'notifier.transport_factory.sinch',
22412243
ZulipTransportFactory::class => 'notifier.transport_factory.zulip',

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier_transports.php
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Symfony\Component\Notifier\Bridge\Sinch\SinchTransportFactory;
3434
use Symfony\Component\Notifier\Bridge\Slack\SlackTransportFactory;
3535
use Symfony\Component\Notifier\Bridge\Smsapi\SmsapiTransportFactory;
36+
use Symfony\Component\Notifier\Bridge\SpotHit\SpotHitTransportFactory;
3637
use Symfony\Component\Notifier\Bridge\Telegram\TelegramTransportFactory;
3738
use Symfony\Component\Notifier\Bridge\Twilio\TwilioTransportFactory;
3839
use Symfony\Component\Notifier\Bridge\Zulip\ZulipTransportFactory;
@@ -89,6 +90,10 @@
8990
->parent('notifier.transport_factory.abstract')
9091
->tag('texter.transport_factory')
9192

93+
->set('notifier.transport_factory.spothit', SpotHitTransportFactory::class)
94+
->parent('notifier.transport_factory.abstract')
95+
->tag('texter.transport_factory')
96+
9297
->set('notifier.transport_factory.ovhcloud', OvhCloudTransportFactory::class)
9398
->parent('notifier.transport_factory.abstract')
9499
->tag('texter.transport_factory')
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CHANGELOG
2+
=========
3+
4+
5.3
5+
---
6+
7+
* Add the bridge
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Spot-Hit Notifier
2+
=================
3+
4+
Provides [Spot-Hit](https://www.spot-hit.fr/) integration for Symfony Notifier.
5+
6+
#### DSN example
7+
8+
```
9+
SPOTHIT_DSN=spothit://TOKEN@default?from=FROM
10+
```
11+
12+
where:
13+
- `TOKEN` is your Spot-Hit API key
14+
- `FROM` is the custom sender (3-11 letters, default is a 5 digits phone number)
15+
16+
Resources
17+
---------
18+
19+
* [Spot-Hit API doc](https://www.spot-hit.fr/documentation-api).
20+
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
21+
* [Report issues](https://github.com/symfony/symfony/issues) and
22+
[send Pull Requests](https://github.com/symfony/symfony/pulls)
23+
in the [main Symfony repository](https://github.com/symfony/symfony)
+96Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Notifier\Bridge\SpotHit;
13+
14+
use Symfony\Component\Notifier\Exception\TransportException;
15+
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
16+
use Symfony\Component\Notifier\Message\MessageInterface;
17+
use Symfony\Component\Notifier\Message\SentMessage;
18+
use Symfony\Component\Notifier\Message\SmsMessage;
19+
use Symfony\Component\Notifier\Transport\AbstractTransport;
20+
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
21+
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
22+
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
23+
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
24+
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
25+
use Symfony\Contracts\HttpClient\HttpClientInterface;
26+
27+
/**
28+
* @author James Hemery <james@yieldstudio.fr>
29+
*/
30+
final class SpotHitTransport extends AbstractTransport
31+
{
32+
protected const HOST = 'spot-hit.fr';
33+
34+
private $token;
35+
private $from;
36+
37+
public function __construct(string $token, ?string $from = null, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null)
38+
{
39+
$this->token = $token;
40+
$this->from = $from;
41+
42+
parent::__construct($client, $dispatcher);
43+
}
44+
45+
public function __toString(): string
46+
{
47+
if (!$this->from) {
48+
return sprintf('spothit://%s', $this->getEndpoint());
49+
}
50+
51+
return sprintf('spothit://%s?from=%s', $this->getEndpoint(), $this->from);
52+
}
53+
54+
public function supports(MessageInterface $message): bool
55+
{
56+
return $message instanceof SmsMessage;
57+
}
58+
59+
/**
60+
* @param MessageInterface|SmsMessage $message
61+
*
62+
* @throws TransportExceptionInterface
63+
* @throws ClientExceptionInterface
64+
* @throws RedirectionExceptionInterface
65+
* @throws ServerExceptionInterface
66+
*/
67+
protected function doSend(MessageInterface $message): SentMessage
68+
{
69+
if (!$this->supports($message)) {
70+
throw new UnsupportedMessageTypeException(__CLASS__, SmsMessage::class, $message);
71+
}
72+
73+
$endpoint = sprintf('https://www.%s/api/envoyer/sms', $this->getEndpoint());
74+
$response = $this->client->request('POST', $endpoint, [
75+
'body' => [
76+
'key' => $this->token,
77+
'destinataires' => $message->getPhone(),
78+
'type' => 'premium',
79+
'message' => $message->getSubject(),
80+
'expediteur' => $this->from,
81+
],
82+
]);
83+
84+
$data = json_decode($response->getContent(), true);
85+
86+
if (!$data['resultat']) {
87+
$errors = \is_array($data['erreurs']) ? implode(',', $data['erreurs']) : $data['erreurs'];
88+
throw new TransportException(sprintf('[HTTP %d] Unable to send the SMS: error(s) "%s".', $response->getStatusCode(), $errors), $response);
89+
}
90+
91+
$sentMessage = new SentMessage($message, (string) $this);
92+
$sentMessage->setMessageId($data['id']);
93+
94+
return $sentMessage;
95+
}
96+
}
+47Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Notifier\Bridge\SpotHit;
13+
14+
use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
15+
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
16+
use Symfony\Component\Notifier\Transport\Dsn;
17+
use Symfony\Component\Notifier\Transport\TransportInterface;
18+
19+
/**
20+
* @author James Hemery <james@yieldstudio.fr>
21+
*/
22+
final class SpotHitTransportFactory extends AbstractTransportFactory
23+
{
24+
/**
25+
* @return SpotHitTransport
26+
*/
27+
public function create(Dsn $dsn): TransportInterface
28+
{
29+
$scheme = $dsn->getScheme();
30+
31+
if ('spothit' !== $scheme) {
32+
throw new UnsupportedSchemeException($dsn, 'spothit', $this->getSupportedSchemes());
33+
}
34+
35+
$token = $this->getUser($dsn);
36+
$from = $dsn->getOption('from');
37+
$host = 'default' === $dsn->getHost() ? null : $dsn->getHost();
38+
$port = $dsn->getPort();
39+
40+
return (new SpotHitTransport($token, $from, $this->client, $this->dispatcher))->setHost($host)->setPort($port);
41+
}
42+
43+
protected function getSupportedSchemes(): array
44+
{
45+
return ['spothit'];
46+
}
47+
}
+51Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Notifier\Bridge\SpotHit\Tests;
13+
14+
use Symfony\Component\Notifier\Bridge\SpotHit\SpotHitTransportFactory;
15+
use Symfony\Component\Notifier\Tests\TransportFactoryTestCase;
16+
use Symfony\Component\Notifier\Transport\TransportFactoryInterface;
17+
18+
final class SpotHitTransportFactoryTest extends TransportFactoryTestCase
19+
{
20+
/**
21+
* @return SpotHitTransportFactory
22+
*/
23+
public function createFactory(): TransportFactoryInterface
24+
{
25+
return new SpotHitTransportFactory();
26+
}
27+
28+
public function createProvider(): iterable
29+
{
30+
yield [
31+
'spothit://spot-hit.fr',
32+
'spothit://api_token@default',
33+
];
34+
yield [
35+
'spothit://spot-hit.fr?from=MyCompany',
36+
'spothit://api_token@default?from=MyCompany',
37+
];
38+
}
39+
40+
public function supportsProvider(): iterable
41+
{
42+
yield [true, 'spothit://api_token@default?from=MyCompany'];
43+
yield [false, 'somethingElse://api_token@default?from=MyCompany'];
44+
}
45+
46+
public function unsupportedSchemeProvider(): iterable
47+
{
48+
yield ['foobar://api_token@default?from=MyCompany'];
49+
yield ['foobar://api_token@default'];
50+
}
51+
}
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Notifier\Bridge\SpotHit\Tests;
13+
14+
use Symfony\Component\Notifier\Bridge\SpotHit\SpotHitTransport;
15+
use Symfony\Component\Notifier\Message\ChatMessage;
16+
use Symfony\Component\Notifier\Message\MessageInterface;
17+
use Symfony\Component\Notifier\Message\SmsMessage;
18+
use Symfony\Component\Notifier\Tests\TransportTestCase;
19+
use Symfony\Component\Notifier\Transport\TransportInterface;
20+
use Symfony\Contracts\HttpClient\HttpClientInterface;
21+
22+
final class SpotHitTransportTest extends TransportTestCase
23+
{
24+
/**
25+
* @return SpotHitTransport
26+
*/
27+
public function createTransport(?HttpClientInterface $client = null): TransportInterface
28+
{
29+
return (new SpotHitTransport('api_token', 'MyCompany', $client ?: $this->createMock(HttpClientInterface::class)))->setHost('host.test');
30+
}
31+
32+
public function toStringProvider(): iterable
33+
{
34+
yield ['spothit://host.test?from=MyCompany', $this->createTransport()];
35+
}
36+
37+
public function supportedMessagesProvider(): iterable
38+
{
39+
yield [new SmsMessage('0611223344', 'Hello!')];
40+
yield [new SmsMessage('+33611223344', 'Hello!')];
41+
}
42+
43+
public function unsupportedMessagesProvider(): iterable
44+
{
45+
yield [new ChatMessage('Hello!')];
46+
yield [$this->createMock(MessageInterface::class)];
47+
}
48+
}
+34Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "symfony/spothit-notifier",
3+
"type": "symfony-bridge",
4+
"description": "Symfony Spot-Hit Notifier Bridge",
5+
"keywords": ["sms", "spot-hit", "notifier", "symfony"],
6+
"homepage": "https://symfony.com",
7+
"license": "MIT",
8+
"authors": [
9+
{
10+
"name": "James Hemery",
11+
"homepage": "https://github.com/JamesHemery"
12+
},
13+
{
14+
"name": "Yield Studio",
15+
"homepage": "https://github.com/YieldStudio"
16+
},
17+
{
18+
"name": "Symfony Community",
19+
"homepage": "https://symfony.com/contributors"
20+
}
21+
],
22+
"require": {
23+
"php": ">=7.2.5",
24+
"symfony/http-client": "^4.3|^5.1",
25+
"symfony/notifier": "^5.3"
26+
},
27+
"autoload": {
28+
"psr-4": { "Symfony\\Component\\Notifier\\Bridge\\SpotHit\\": "" },
29+
"exclude-from-classmap": [
30+
"/Tests/"
31+
]
32+
},
33+
"minimum-stability": "dev"
34+
}
+31Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
5+
backupGlobals="false"
6+
colors="true"
7+
bootstrap="vendor/autoload.php"
8+
failOnRisky="true"
9+
failOnWarning="true"
10+
>
11+
<php>
12+
<ini name="error_reporting" value="-1" />
13+
</php>
14+
15+
<testsuites>
16+
<testsuite name="Symfony Spot-Hit Notifier Test Suite">
17+
<directory>./Tests/</directory>
18+
</testsuite>
19+
</testsuites>
20+
21+
<filter>
22+
<whitelist>
23+
<directory>./</directory>
24+
<exclude>
25+
<directory>./Resources</directory>
26+
<directory>./Tests</directory>
27+
<directory>./vendor</directory>
28+
</exclude>
29+
</whitelist>
30+
</filter>
31+
</phpunit>

‎src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ class UnsupportedSchemeException extends LogicException
6868
'class' => Bridge\FreeMobile\FreeMobileTransportFactory::class,
6969
'package' => 'symfony/free-mobile-notifier',
7070
],
71+
'spothit' => [
72+
'class' => Bridge\SpotHit\SpotHitTransportFactory::class,
73+
'package' => 'symfony/spothit-notifier',
74+
],
7175
'ovhcloud' => [
7276
'class' => Bridge\OvhCloud\OvhCloudTransportFactory::class,
7377
'package' => 'symfony/ovh-cloud-notifier',

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.