Using Swift Mailer with smtp on Symfony 4 - symfony

I installed Swift Mailer on Symfony 4 to send a registration email for new users. What I noticed is that it works fine when I use my Gmail account to send emails, but it doesn't work when I use my Outlook.
So after reading the documentation, I set the MAILER_URL on my .env file like this
> MAILER_URL=smtp://localhost:25?encryption=ssl&auth_mode=login&username=*****%40live.com&password=******
I also used :
> MAILER_URL=smtp://smtp-mail.outlook.com:25/encryption=ssl&auth_mode=login&username=*******%40live.com&password=********
I have changed the port from 25 to 587 to 465 and none of those worked either.
This is the method where I call the mailer :
public function sendMail($subject, $fromEmail, $toEmail, $emailTemplate, $argumentsArray, $emailType, $imgPath)
{
$message = $this->setBasicEmailMessage($subject, $fromEmail, $emailTemplate, $argumentsArray, $emailType, $imgPath);
$message->setTo($toEmail);
$this->mailer->send($message);
}
private function setBasicEmailMessage($subject, $fromEmail, $emailTemplate, $argumentsArray, $emailType, $imgPath)
{
$message = (new \Swift_Message($subject))->setFrom($fromEmail);
$img = $message->embed(\Swift_Image::fromPath($imgPath));
$argumentsArray['img'] = $img;
$message->setBody(
$this->templating->render(
$emailTemplate,
$argumentsArray
),
$emailType
);
return $message;
}
And this is my swiftmailer.yaml:
swiftmailer:
url: '%env(MAILER_URL)%'
spool: { type: 'memory' }
The code doesn't raise an exception but the email never makes it to the users.
Does anyone have an idea how to fix this?

Put send function in try and catch block you will get definitely any clue:
try {
$this->mailer->send($message);
} catch (\Swift_RfcComplianceException $e) {
echo "\nException :: " . $e->getMessage();
}

Related

When sending emails from a worker, they are not send untill an exception is thrown

I'm placing several mails in a queue. When I run the worker, it will process all the mails successfully, however they are not send. When I add a mail that triggers an exception, the worker is killed, and all the mails are being send.
When I run bin/console swiftmailer:spool:send after handling the mails with the worker, it will show:
0 emails sent
Also tried to forceSend(), did not work as well.
The worker:
class SendQueuedMailWorker
{
/**
* #var Mailer
*/
private $mailer;
public function __construct(
Mailer $mailer
) {
$this->mailer = $mailer;
}
public function handle(SendQueuedMailCommand $command): void
{
$user = $command->getUser();
$mailContext = [
'user' => $user
];
$message = $this->mailer->compose(
'mail_template',
$mailContext,
null,
$user->getEmail()
);
if ($this->mailer->send($message) === false) {
throw QueuedMailNotSentException::withId($command->getReference());
}
}
}
Swiftmailer:
swiftmailer:
transport: '%mailer_transport%'
encryption: '%mailer_encryption%'
host: '%mailer_host%'
port: '%mailer_port%'
username: '%mailer_user%'
password: '%mailer_password%'
delivery_addresses: '%mailer_delivery_addresses%'
spool: { type: 'memory' }
disable_delivery: '%mailer_disable_delivery%'
There are no error messages thrown when the queue is being consumed.
Console output:
Consuming from mailsend queue
[1] Processing payload {"reference":2016320254, "user":"John"}
[1] processed with result: true
[2] Processing payload {"reference":2019990645, "user":"Doe"}
[2] processed with result: true
How do I get the mails to be send immediately?
Fixed with: https://stackoverflow.com/a/51730638/11830313
Turns out spooled mails that are being handled by a worker will only get send on Kernel::terminate.
This does seem like quit a drastic solution for me, so if anyone has a different solution for the issue at hand, I will be more than happy to hear it.
Final solution:
Create MailerSpoolFlusher. Inject the \Swift_MemorySpool and \Swift_Transport into it.
In the MailerSpoolFlusher add:
public function flush()
{
$this->spool->flushQueue($this->transport);
}
Then inject the MailerSpoolFlusher into the worker, and call the flush() after $mailer->send().
Works like a charm, and no need to initiate a onTerminate.

how to get HTTPS headers from webhook requester

I have a webhook to receive updates that I am trying to configure. I need to get the bearer token from the header, but I am not able to retrieve it. Can someone shed some light on this issue? I am stumped!
receiving url is https://example.com/receive
$data = file_get_contents("php://input",true);
$events= json_decode($data, true);
If you're looking for an OAuth bearer token these are usually transferred in the request HTTP Authorization header. In PHP these can be a little tricky to read since different web servers have different approaches to reading the Authorization header.
There's a good example of how to read a bearer token in this answer. Copied here for convenience:
<?PHP
/**
* Get hearder Authorization
* */
function getAuthorizationHeader() {
$headers = null;
if (isset($_SERVER['Authorization'])) {
$headers = trim($_SERVER["Authorization"]);
} else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
$headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
} elseif (function_exists('apache_request_headers')) {
$requestHeaders = apache_request_headers();
// Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
$requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
if (isset($requestHeaders['Authorization'])) {
$headers = trim($requestHeaders['Authorization']);
}
}
return $headers;
}
/**
* get access token from header
* */
function getBearerToken() {
$headers = getAuthorizationHeader();
// HEADER: Get the access token from the header
if (!empty($headers)) {
if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
return $matches[1];
}
}
return null;
}
?>

Swiftmailer send status

How to check send status in swiftmailer with symfony?
I send mails this way:
$res = $this->get('mailer')->send($message)
Now $res has always status 1 even if I set wrong password in parameters. Email isn't send and status is 1 :/
I'd like to throw some kind of information if there is any problem with sending :/
You can use second argument in send()
$res = $this->get('mailer')->send($message, $errors)
try {
$this->get('mailer')->send($message);
}
catch (\Exception $exception) {
$errors = $exception->getMessage();
}
The $errors variable will contain the message if sending fails.

Sending mails with laravel for android app forgot password functionality

I am trying to create a forgot password module for my android project which has laravel running as backend. What I'm trying to achieve is to create a random string and send it as a mail but I don't know how to do it.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App;
class FgtPswdController extends Controller
{
public function CheckEmail(Request $request){
$email = $request['email'];
$checkEmail = App\Login::where('email', '=', $email)->first();
if ($checkEmail){
$randomString = str_random(6);
App\Forgot_Password::where('email', $email)->update('reset_code', $randomString);
}
else{
$response['verification'] = false;
return json_encode($response);
}
}
}
But how do I send a mail using inbuilt functions of laravel
You can use this
Mail::raw('Your Text', function($message){
$message->to(to#host.com)->subject('Your Subject');
$message->from('email#host.com', 'Your Name');
});

Silex - my error handler isn't working

I am trying to set up a error handler on my controller to catch anything that might cause my page to malfunction. For example: in this scenario I am trying to catch any error that could possibly happen once my method calls a external API with a bad parameter but it doesn't seem to do anything except give me the typical ClientException in Middleware.php line 69:
Client error: 400 which isn't what I am exactly aiming for. Any advice will be greatly be appreciated or better ways of handling errors in Silex.
private function getSIS($url, $session, Application $app)
{
$message = "You don't have permission to access this!";
if($app['security']->isGranted('ROLE_SUPER_ADMIN'))
{
$client = new Client(['base_uri' => 'https://***********.ca/api/SIS/']);
if (!empty($session))
$response = $client->get($url, ['query' => 'session=' . $session]);
else
$response = $client->get($url);
return $response;
}
$app->error(function (\Exception $e, $code) {
switch($code) {
case 404:
$message = 'The requested page could not be found';
break;
default:
$message = 'We are sorry, but something went terribly wrong.';
}
return new Response($message);
});
return new Response($message);
}
The $app->error method might need to be placed outside the context of your controller actions. I'm not sure exactly how you have your application structured but maybe try placing the error block right before $app->run();
$app->error(function (\Exception $e, $code) use ($app) {
switch($code) {
case 404:
$message = 'The requested page could not be found';
break;
default:
$message = 'We are sorry, but something went terribly wrong.';
}
return new Response($message, $code);
});
$app->run();

Resources