use Symfony\Bridge\Twig\Mime\SystemEmail; $email = (new SystemEmail()) ->from('[email protected]') ->to('[email protected]') ->subject('You have a new customer!') ->lines( 'Fabien has just signed up for the most expensive plan.', 'That\'s an additional revenue of 1€ per year.' ) ->action( 'Check the invoice' $urlGen->generate('invoice', ['id' => 1], UrlGeneratorInterface::ABSOLUTE_URL), ) ->importance(SystemEmail::HIGH) ; $mailer->send($email); A typical System Email
/** * @Route("/checkout/thankyou") */ public function thankyou(Texter $texter /* ... */) { $sms = new SmsMessage('+1415999888', 'Revenue has just increased by 1€ per year!'); $texter->send($sms); return $this->render('checkout/thankyou.html.twig', [ // ... ]); } Sending SMS Messages the easy way
$sms = new SmsMessage('+1415999888', 'Revenue has just increased!'); $twilio = Transport::fromDsn('twilio://SID:[email protected]?from=FROM'); $twilio->send($sms); $nexmo = Transport::fromDsn('nexmo://KEY:[email protected]?from=FROM'); $nexmo->send($sms); SMS... low-level API Similar infrastructure as Mailer
$dsn = 'failover(twilio://SID:[email protected]?from=FROM nexmo://KEY:[email protected]?from=FROM)'; SMS... higher-level API Similar infrastructure as Mailer
/** * @Route("/checkout/thankyou") */ public function thankyou(Chatter $chatter /* ... */) { $message = new ChatMessage('Revenue increased by 1€ per year...'); $chatter->send($message); return $this->render('checkout/thankyou.html.twig', [ // ... ]); } Sending Messages the easy way
interface TransportInterface { public function send(MessageInterface $message): void; public function supports(MessageInterface $message): bool; public function __toString(): string; } A common transport layer interface MessageInterface { public function getRecipientId(): ?string; public function getText(): string; public function getOptions(): ?MessageOptionsInterface; public function getTransport(): ?string; }
class InvoiceNotification extends Notification { private $price; public function __construct(int $price) { parent::__construct('You have a new invoice.'); $this->price = $price; } public function getChannels(Receiver $receiver): array { if ($this->price > 1000 && $receiver->hasPhone()) { return ['sms', 'email']; } return ['email']; } } Customize Notifications
... including DSN support Each integration is a few LOCs namespace Symfony\Component\Notifier\Bridge\Twilio; final class TwilioTransport extends AbstractTransport { protected const HOST = 'api.twilio.com'; public function __construct(string $accountSid, string $authToken, string $from, HttpClientInter { $this->accountSid = $accountSid; $this->authToken = $authToken; $this->from = $from; parent::__construct($client, $dispatcher); } public function __toString(): string { return sprintf('twilio://%s?from=%s', $this->getEndpoint(), $this->from); } public function supports(MessageInterface $message): bool { return $message instanceof SmsMessage; } protected function doSend(MessageInterface $message): void { if (!$message instanceof SmsMessage) { throw new LogicException(sprintf('The "%s" transport only support instances of "%s".', _ } $endpoint = sprintf('https://%s/2010-04-01/Accounts/%s/Messages.json', $this->getEndpoint(), $response = $this->client->request('POST', $endpoint, [ 'auth_basic' => $this->accountSid.':'.$this->authToken, 'body' => ['From' => $this->from, 'To' => $message->getPhone(), 'Body' => $message->getT ], ]); if (201 !== $response->getStatusCode()) { $error = json_decode($response->getContent(false), true); throw new TransportException(sprintf('Unable to send the SMS: %s (see %s).', $error['mes } } } Help needed to support more transports ❤
Many Possibilities Go fast with the Notifier and the Full-Stack framework Be creative with the standalone low-level classes SystemEmail, TwilioTransport, Texter, SlackTransport, Chatter, ...