Send message to multiple telegram groups in Symfony Notifier - symfony

I used the Symfony Notifier (https://symfony.com/doc/current/notifier.html) to send messages to telegram group with symfony/telegram-notifier. But now I want to send message to multiple group depending on the request. How can I handle this?
This is my config file:
framework:
notifier:
chatter_transports:
telegram: '%env(TELEGRAM_DSN)%'
channel_policy:
urgent: ['chat/telegram']
high: ['email']
medium: ['email']
low: ['email']
Can I have something like this:
framework:
notifier:
chatter_transports:
telegram: '%env(TELEGRAM_DSN)%'
telegram_admin: '%env(TELEGRAM_DSN_ADMIN)%'
In that case how to choose telegram_admin instead of telegram in my controller?

Related

disable transport fallback when sending emails

I have two transports, one for general emails and the other for noreply emails because of huge number
mailer.yml:
framework:
mailer:
transports:
main: '%env(MAILER_DSN)%'
noreply: '%env(MAILER_DSN_NOREPLY)%'
When MAILER_DSN_NOREPLY is down, there is one try with MAILER_DSN_NOREPLY and next it sends the email with MAILER_DSN
How can I disable this rule and just try 3 times to send with MAILER_DSN_NOREPLY and then keep mail on the failed queue?
Looking in the code of symfony/mailer, whens the transports are built, the first one founded in considered as default and will be used as fallback
so i wrote "noreply" transport on first line

How can i config properly RabbitMQ, messenger and amqp on symfony 5.2 without use docker_compose.yml?

I want to submit a form with async method using messenger component and rabbitmq. After submitting this form, an email is sent to me. But when i implement rabbitmq it does not work. I have surely a problem with configuration. Maybe i have to add something in services.yml ? I dont want to use docker.
transports:
# https://symfony.com/doc/current/messenger.html#transport-configuration
async :
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
options:
auto_setup: false
use_notify: true
check_delayed_interval: 60000
# failed: 'doctrine://default?queue_name=failed'
# sync: 'sync://'
routing:
# Route your messages to the transports
'App\Message\MailNotification': async
.env file with amqp because i want to use rabbitmq
MESSENGER_TRANSPORT_DSN=amqp://guest:guest#localhost:5672/%2f/messages
Output give me this result when i submit form
Could not connect to the AMQP server. Please verify the provided DSN. ({"host":"localhost","port":5672,"vhost":"/","auto_setup":false,"use_notify":true,"check_delayed_interval":60000,"login":"guest","password":"********"}).
In addition, Rabbitmq UI appears on webprofiler DOWN, it does not turn to UP. I can't figure out. Help me please.

How to send mail using different queues in new Symfony Mail component

I want to configure Symfony Mail component to send different types of emails using different queue priorities.
How can I do it?
So far I configured the queues:
framework:
messenger:
transports:
async_low: '%env(MESSENGER_TRANSPORT_DSN_LOW)%'
async_high: '%env(MESSENGER_TRANSPORT_DSN_HIGH)%'
routing:
'Symfony\Component\Mailer\Messenger\SendEmailMessage': async_high
Then I started the queue with async_high being processed first:
bin/console messenger:consume async_high async_low
Now I would like to send one type of email form higher priority queue than the other:
$this->mailer->send($newsletterEmail); // 10.000 times
$this->mailer->send($resetPasswordEmail); // Triggered after newsletter
Without priorities the password reset would be sent after an hour (after all the newsletters get processed).
How can I send the newsletters using the lower priority queue?

Symfony Messenger does not consume messages until stop/consume

On Symfony 5.1, I created two very basic message classes.
The first updates the database and then it calls the other to send a mail via SwiftMailer.
Both of them arrive to the consumer command as they are logged by the bin/console messenger:consume async -vv command, but while the class that updates the database is handled, the other remains suspended.
The fact is that if I stop and restart the consume command, this message becomes handled by the consumer and so the mail is sent.
I have tried with Redis and RabbitMQ transports, with the very same results.
This is the messenger configuration:
framework:
messenger:
transports:
async:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
routing:
'App\Message\FollowRequestMessage': async
'App\Message\EmailMessage': async
This is the MESSENGER_TRANSPORT_DSN in .env:
MESSENGER_TRANSPORT_DSN=amqp://guest:guest#127.0.0.1:5672/%2f/messages
UPDATE
I defined another transport to handle the FollowRequest and Email messages separately, by duplicating the "async" transport config in the yaml messenger configuration.
This has fixed the issue, but I don't know if it the right way to handle the case.
So, it is correct to create a different transport for each kind of message? Or is it a workaround because of an error in something else?

Consumer Error Handling in Symfony Messenger / RabbitMQ

I'm using the new Symfony Messenger Component 4.1 and RabbitMQ 3.6.10-1 to queue and asynchronously send email and SMS notifications from my Symfony 4.1 web application. My Messenger configuration (messenger.yaml) looks like this:
framework:
messenger:
transports:
amqp: '%env(MESSENGER_TRANSPORT_DSN_NOTIFICATIONS)%'
routing:
'App\NotificationBundle\Entity\NotificationQueueEntry': amqp
When a new notification is to be sent, I queue it like this:
use Symfony\Component\Messenger\MessageBusInterface;
// ...
$notificationQueueEntry = new NotificationQueueEntry();
// [Set notification details such as recipients, subject, and message]
$this->messageBus->dispatch($notificationQueueEntry);
Then I start the consumer like this on the command line:
$ bin/console messenger:consume-messages
I have implemented a SendNotificationHandler service where the actual delivery happens. The service configuration:
App\NotificationBundle\MessageHandler\SendNotificationHandler:
arguments:
- '#App\NotificationBundle\Service\NotificationQueueService'
tags: [ messenger.message_handler ]
And the class:
class SendNotificationHandler
{
public function __invoke(NotificationQueueEntry $entry): void
{
$this->notificationQueueService->sendNotification($entry);
}
}
Until this point, everything works smoothly and the notifications get delivered.
Now my question: It may happen that an email or SMS cannot be delivered due to a (temporary) network failure. In such a case, I would like my system to retry the delivery after a specified amount of time, up to a specified maximum number of retries. What is the way to go to achieve this?
I have read about Dead Letter Exchanges, however, I could not find any documentation or example on how to integrate this with the Symfony Messenger Component.
What you need to do is tell RabbitMQ, that the message is rejected instead of acknowledged. By default the messenger will take care of this inside the AmqpReceiver. As you can see there, if you throw an exception that implements the RejectMessageExceptionInterface inside your handler, the message will automatically be rejected for you.
You could also "simulate" this behaviour with custom middleware. I created something like it, in a small demo application. The mechanism consists of a middleware that wraps the (serialized) original message inside a new RetryMessage and sends it via a custom message bus to a different queue, used as a dead letter exchange. The handler for that message will then unpack the RetryMessage (getting the original message and deserializing it) and transmit it over the default bus:
See:
RetryMessage
RetryMiddleware
messenger.yaml
RetryMessageHandler
This is a basic setup which rejects the message and allows you to consume it again instantly(!). You probably want to add additional information such as headers for timestamps when delaying the consumption to improve on this. For this you should look at writing your own receiver, middleware and/or handler.

Resources