Replace custom ShortMessage usage with Symfony’s SmsMessage.

Switched the entire short message notification system to leverage Symfony's Notifier component and its TexterInterface with SmsMessage. This update simplifies the implementation, removes custom short message handling, and aligns with Symfony's standardized approach.
This commit is contained in:
Julien Fastré 2025-01-17 13:25:38 +01:00
parent 88fbf7bc1c
commit 594ed4a5b4
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
8 changed files with 54 additions and 42 deletions

View File

@ -1,7 +1,7 @@
framework: framework:
notifier: notifier:
texter_transports: texter_transports:
twilio: '%env(resolve:SHORT_MESSAGE_DSN)%' ovhcloud: '%env(SHORT_MESSAGE_DSN)%'
channel_policy: channel_policy:
# use chat/slack, chat/telegram, sms/twilio or sms/nexmo # use chat/slack, chat/telegram, sms/twilio or sms/nexmo
urgent: ['email'] urgent: ['email']

View File

@ -21,9 +21,7 @@ namespace Chill\CalendarBundle\Command;
use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Entity\Calendar;
use Chill\CalendarBundle\Service\ShortMessageNotification\ShortMessageForCalendarBuilderInterface; use Chill\CalendarBundle\Service\ShortMessageNotification\ShortMessageForCalendarBuilderInterface;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Phonenumber\PhoneNumberHelperInterface;
use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Repository\UserRepositoryInterface;
use Chill\MainBundle\Service\ShortMessage\ShortMessageTransporterInterface;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Repository\PersonRepository; use Chill\PersonBundle\Repository\PersonRepository;
use libphonenumber\PhoneNumber; use libphonenumber\PhoneNumber;
@ -36,6 +34,7 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Question\Question;
use Symfony\Component\Notifier\TexterInterface;
class SendTestShortMessageOnCalendarCommand extends Command class SendTestShortMessageOnCalendarCommand extends Command
{ {
@ -44,9 +43,8 @@ class SendTestShortMessageOnCalendarCommand extends Command
public function __construct( public function __construct(
private readonly PersonRepository $personRepository, private readonly PersonRepository $personRepository,
private readonly PhoneNumberUtil $phoneNumberUtil, private readonly PhoneNumberUtil $phoneNumberUtil,
private readonly PhoneNumberHelperInterface $phoneNumberHelper,
private readonly ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder, private readonly ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder,
private readonly ShortMessageTransporterInterface $transporter, private readonly TexterInterface $transporter,
private readonly UserRepositoryInterface $userRepository, private readonly UserRepositoryInterface $userRepository,
) { ) {
parent::__construct('chill:calendar:test-send-short-message'); parent::__construct('chill:calendar:test-send-short-message');
@ -152,10 +150,6 @@ class SendTestShortMessageOnCalendarCommand extends Command
return $phone; return $phone;
}); });
$phone = $helper->ask($input, $output, $question);
$question = new ConfirmationQuestion('really send the message to the phone ?');
$reallySend = (bool) $helper->ask($input, $output, $question);
$messages = $this->messageForCalendarBuilder->buildMessageForCalendar($calendar); $messages = $this->messageForCalendarBuilder->buildMessageForCalendar($calendar);
@ -165,8 +159,12 @@ class SendTestShortMessageOnCalendarCommand extends Command
foreach ($messages as $key => $message) { foreach ($messages as $key => $message) {
$output->writeln("The short message for SMS {$key} will be: "); $output->writeln("The short message for SMS {$key} will be: ");
$output->writeln($message->getContent()); $output->writeln($message->getSubject());
$message->setPhoneNumber($phone); $output->writeln('The destination number will be:');
$output->writeln($message->getPhone());
$question = new ConfirmationQuestion('really send the message to the phone ?');
$reallySend = (bool) $helper->ask($input, $output, $question);
if ($reallySend) { if ($reallySend) {
$this->transporter->send($message); $this->transporter->send($message);

View File

@ -21,11 +21,17 @@ namespace Chill\CalendarBundle\Service\ShortMessageNotification;
use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Entity\Calendar;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Notifier\TexterInterface;
class BulkCalendarShortMessageSender class BulkCalendarShortMessageSender
{ {
public function __construct(private readonly CalendarForShortMessageProvider $provider, private readonly EntityManagerInterface $em, private readonly LoggerInterface $logger, private readonly MessageBusInterface $messageBus, private readonly ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder) {} public function __construct(
private readonly CalendarForShortMessageProvider $provider,
private readonly EntityManagerInterface $em,
private readonly LoggerInterface $logger,
private readonly TexterInterface $texter,
private readonly ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder,
) {}
public function sendBulkMessageToEligibleCalendars() public function sendBulkMessageToEligibleCalendars()
{ {
@ -36,7 +42,7 @@ class BulkCalendarShortMessageSender
$smses = $this->messageForCalendarBuilder->buildMessageForCalendar($calendar); $smses = $this->messageForCalendarBuilder->buildMessageForCalendar($calendar);
foreach ($smses as $sms) { foreach ($smses as $sms) {
$this->messageBus->dispatch($sms); $this->texter->send($sms);
++$countSms; ++$countSms;
} }

View File

@ -19,12 +19,26 @@ declare(strict_types=1);
namespace Chill\CalendarBundle\Service\ShortMessageNotification; namespace Chill\CalendarBundle\Service\ShortMessageNotification;
use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Entity\Calendar;
use Chill\MainBundle\Service\ShortMessage\ShortMessage; use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;
use Symfony\Component\Notifier\Message\SmsMessage;
class DefaultShortMessageForCalendarBuilder implements ShortMessageForCalendarBuilderInterface class DefaultShortMessageForCalendarBuilder implements ShortMessageForCalendarBuilderInterface
{ {
public function __construct(private readonly \Twig\Environment $engine) {} private readonly PhoneNumberUtil $phoneUtil;
public function __construct(private readonly \Twig\Environment $engine)
{
$this->phoneUtil = PhoneNumberUtil::getInstance();
}
/**
* @return list<SmsMessage>
*
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*/
public function buildMessageForCalendar(Calendar $calendar): array public function buildMessageForCalendar(Calendar $calendar): array
{ {
if (true !== $calendar->getSendSMS()) { if (true !== $calendar->getSendSMS()) {
@ -39,16 +53,14 @@ class DefaultShortMessageForCalendarBuilder implements ShortMessageForCalendarBu
} }
if (Calendar::SMS_PENDING === $calendar->getSmsStatus()) { if (Calendar::SMS_PENDING === $calendar->getSmsStatus()) {
$toUsers[] = new ShortMessage( $toUsers[] = new SmsMessage(
$this->phoneUtil->format($person->getMobilenumber(), PhoneNumberFormat::E164),
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message.txt.twig', ['calendar' => $calendar]), $this->engine->render('@ChillCalendar/CalendarShortMessage/short_message.txt.twig', ['calendar' => $calendar]),
$person->getMobilenumber(),
ShortMessage::PRIORITY_LOW
); );
} elseif (Calendar::SMS_CANCEL_PENDING === $calendar->getSmsStatus()) { } elseif (Calendar::SMS_CANCEL_PENDING === $calendar->getSmsStatus()) {
$toUsers[] = new ShortMessage( $toUsers[] = new SmsMessage(
$this->phoneUtil->format($person->getMobilenumber(), PhoneNumberFormat::E164),
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message_canceled.txt.twig', ['calendar' => $calendar]), $this->engine->render('@ChillCalendar/CalendarShortMessage/short_message_canceled.txt.twig', ['calendar' => $calendar]),
$person->getMobilenumber(),
ShortMessage::PRIORITY_LOW
); );
} }
} }

View File

@ -19,12 +19,12 @@ declare(strict_types=1);
namespace Chill\CalendarBundle\Service\ShortMessageNotification; namespace Chill\CalendarBundle\Service\ShortMessageNotification;
use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Entity\Calendar;
use Chill\MainBundle\Service\ShortMessage\ShortMessage; use Symfony\Component\Notifier\Message\SmsMessage;
interface ShortMessageForCalendarBuilderInterface interface ShortMessageForCalendarBuilderInterface
{ {
/** /**
* @return array|ShortMessage[] * @return list<SmsMessage>
*/ */
public function buildMessageForCalendar(Calendar $calendar): array; public function buildMessageForCalendar(Calendar $calendar): array;
} }

View File

@ -23,17 +23,16 @@ use Chill\CalendarBundle\Service\ShortMessageNotification\BulkCalendarShortMessa
use Chill\CalendarBundle\Service\ShortMessageNotification\CalendarForShortMessageProvider; use Chill\CalendarBundle\Service\ShortMessageNotification\CalendarForShortMessageProvider;
use Chill\CalendarBundle\Service\ShortMessageNotification\ShortMessageForCalendarBuilderInterface; use Chill\CalendarBundle\Service\ShortMessageNotification\ShortMessageForCalendarBuilderInterface;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Service\ShortMessage\ShortMessage;
use Chill\MainBundle\Test\PrepareUserTrait; use Chill\MainBundle\Test\PrepareUserTrait;
use Chill\PersonBundle\DataFixtures\Helper\PersonRandomHelper; use Chill\PersonBundle\DataFixtures\Helper\PersonRandomHelper;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use libphonenumber\PhoneNumberUtil;
use Prophecy\Argument; use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\PhpUnit\ProphecyTrait;
use Psr\Log\NullLogger; use Psr\Log\NullLogger;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Messenger\Envelope; use Symfony\Component\Notifier\Message\SentMessage;
use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\TexterInterface;
/** /**
* @internal * @internal
@ -101,24 +100,23 @@ final class BulkCalendarShortMessageSenderTest extends KernelTestCase
$messageBuilder->buildMessageForCalendar(Argument::type(Calendar::class)) $messageBuilder->buildMessageForCalendar(Argument::type(Calendar::class))
->willReturn( ->willReturn(
[ [
new ShortMessage( new SmsMessage(
'+32470123456',
'content', 'content',
PhoneNumberUtil::getInstance()->parse('+32470123456', 'BE'),
ShortMessage::PRIORITY_MEDIUM
), ),
] ]
); );
$bus = $this->prophesize(MessageBusInterface::class); $texter = $this->prophesize(TexterInterface::class);
$bus->dispatch(Argument::type(ShortMessage::class)) $texter->send(Argument::type(SmsMessage::class))
->willReturn(new Envelope(new \stdClass())) ->will(fn ($args): SentMessage => new SentMessage($args[0], 'sms'))
->shouldBeCalledTimes(1); ->shouldBeCalledTimes(1);
$bulk = new BulkCalendarShortMessageSender( $bulk = new BulkCalendarShortMessageSender(
$provider->reveal(), $provider->reveal(),
$em, $em,
new NullLogger(), new NullLogger(),
$bus->reveal(), $texter->reveal(),
$messageBuilder->reveal() $messageBuilder->reveal()
); );

View File

@ -23,7 +23,6 @@ use Chill\CalendarBundle\Service\ShortMessageNotification\DefaultShortMessageFor
use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil; use libphonenumber\PhoneNumberUtil;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Prophecy\Argument; use Prophecy\Argument;
@ -90,10 +89,9 @@ final class DefaultShortMessageForCalendarBuilderTest extends TestCase
$this->assertCount(1, $sms); $this->assertCount(1, $sms);
$this->assertEquals( $this->assertEquals(
'+32470123456', '+32470123456',
$this->phoneNumberUtil->format($sms[0]->getPhoneNumber(), PhoneNumberFormat::E164) $sms[0]->getPhone()
); );
$this->assertEquals('message content', $sms[0]->getContent()); $this->assertEquals('message content', $sms[0]->getSubject());
$this->assertEquals('low', $sms[0]->getPriority());
// if the calendar is canceled // if the calendar is canceled
$calendar $calendar
@ -105,9 +103,8 @@ final class DefaultShortMessageForCalendarBuilderTest extends TestCase
$this->assertCount(1, $sms); $this->assertCount(1, $sms);
$this->assertEquals( $this->assertEquals(
'+32470123456', '+32470123456',
$this->phoneNumberUtil->format($sms[0]->getPhoneNumber(), PhoneNumberFormat::E164) $sms[0]->getRecipientId(),
); );
$this->assertEquals('message canceled', $sms[0]->getContent()); $this->assertEquals('message canceled', $sms[0]->getSubject());
$this->assertEquals('low', $sms[0]->getPriority());
} }
} }

View File

@ -33,6 +33,7 @@ class ShortMessageCompilerPass implements CompilerPassInterface
{ {
public function process(ContainerBuilder $container) public function process(ContainerBuilder $container)
{ {
return;
$config = $container->resolveEnvPlaceholders($container->getParameter('chill_main.short_messages'), true); $config = $container->resolveEnvPlaceholders($container->getParameter('chill_main.short_messages'), true);
// weird fix for special characters // weird fix for special characters
$config['dsn'] = str_replace(['%%'], ['%'], (string) $config['dsn']); $config['dsn'] = str_replace(['%%'], ['%'], (string) $config['dsn']);