how to send email with a HTML view/template using Mailgun on Lumen - lumen

I setup email notifications on my Lumen project using Mailgun.
I have a trait for sending emails, see the code below;
trait SendEmailTrait {
public function sendEmail($to, $subject, $body) {
Mail::raw($body, function ($message) use ($to, $subject, $body) {
$message->to($to)
->subject($subject);
});
if (Mail::flushMacros()) {
return 'Sorry! Please try again latter :(';
} else {
return 'Great! eMail successfully sent ;)';
}
}
}
and then I use the trait as follows;
$this->sendEmail($user->email, 'Welcome to ...', 'Your registration was successful');
I want to send the emails using an HTML template, does mailgun support that? and if it's possible, how can I get it done?

Related

recipient receives same mail twice while sending mail in yii 1.1

I am trying to send mail to recipient one at a time.My code is like this:
$message = new YiiMailMessage;
$message->view = "mail";
$params = array('sendEmail'=>$values);
$message->subject = $values['subject'];
$message->setBody($params, 'text/html');
$message->from =$values['email_from'] ;
$message->addTo($values['email_to']);
if(Yii::app()->mail->send($message)){
Yii::app()->user->setFlash('success','Success sending email. ');
$this->redirect(array('mail/admin'));
}else{
Yii::app()->user->setFlash('error','Error while sending email. ');
}
Mail is received by recipient but same mail is received twice.
Maybe you are using a create action to notify the user each time a new record is created. Verify Yii::app()->mail->send($message) appears one time in your action, for example:
public function actionCreate()
{
$model= new MyModel;
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
if(isset($_POST['SomeForm']))
{
$model->attributes=$_POST['SomeForm'];
if($model->validate()){
if($model->save()){
$message = new YiiMailMessage;
$message->setBody('<h1>mets-blog.com</h1>','text/html');
$message->subject = 'Service';
$message->addTo('mets#blog.com');
$message->from = 'your#email.com' you want
Yii::app()->mail->send($message);
$this->redirect(array('view','id'=>$model->id));
}
}
}
$this->render('create',array(
'model'=>$model,
));
}
maybe you are calling your action twice in your controller by render your view.

cakephp 3.x how to check if mail send or not

i am sending mail using cakephp 3.0 this is my code
$email = new Email();
$siteEmail = "test#example.com";
$subject = "Message subject";
$email = new Email();
$email->from($siteEmail)
->to($userEmail)
->subject($subject);
$response = $email->send($message);
if($response) {
$this->Flash->success(__('mail send'));
} else {
$this->Flash->error(__('mail send fail'));
}
but how to check if mail is send or not if i print the $response variable than its print the array of all mail related data like to from message and subject no response like message is send or not how to check so that print the success or failure flash message when i use if else as shown above its always return true either mail sent or not
thanks
Send failures are causing exceptions, \Cake\Network\Exception\SocketException to be exact, so wrap your send() call in a try block, and evaluate possible catched exceptions.
use Cake\Network\Exception\SocketException;
// ...
try {
$email->send($message);
// success
} catch (SocketException $exception) {
// failure
}

How to handle invalide email exception in cakephp?

I have a list of array. There are some invalid emails inside an array. i.e:
$to = array('sattar.kuet#gmail.com','sas dsad .com');
Here sattar.kuet#gmail.com is an valid mail but sas dsad .com is not a valid email. So if I want to send email with this recipients ($to) there will be occurred a fatal error for sas dsad .com. So How can I ignore these invalid email?
N.B: I am using cakephp 2.6.7
CakeEmail throws SocketException if the email address is not well constructed. Just catch the exception and ignore it.
Option 1: Send multiple emails
$email = new CakeEmail();
$to = array('sattar.kuet#gmail.com','sas dsad .com');
foreach ($to as $emailAddress) {
try {
$email->to($emailAddress);
$email->send();
} catch(SocketException $e) {
//Do nothing
}
$email->reset();
}
Option 2: Send a single email
$email = new CakeEmail();
$to = array('sattar.kuet#gmail.com','sas dsad .com');
foreach ($to as $emailAddress) {
try {
$email->addTo($emailAddress);
} catch(SocketException $e) {
//Do nothing
}
}
$email->send();
See CakeEmail::addTo().
You can remove all invalid email with following code :
<?php
$len=count($array);
for ($i=0;$i<$len;$i++)
if (preg_match('^[a-z0-9!#$%&*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+(?:[a-z]{2,4}|museum|travel)$/i',$array[$i]))
echo $array[$i];
?>
Remove invalid email format in PHP

Sending from multiple Mailgun domains using Laravel Mail facade

I'm using the Laravel 4's Mail::queue() to send emails, using the built in Mailgun driver. The problem is that there are multiple Mailgun domains I would like to be able to send emails from, but the domain must be set in app/config/services.php. Since I'm using Mail::queue(), I can't see how to dynamically set that configuration variable.
Is there any way to do what I'm asking? Ideally, I'd like to be able to pass in the domain when I call Mail::queue() (the Mailgun api key is the same for all the domains I want to send from).
I used Macros to add dynamic configuration. I don't remember if this can be done in Laravel 4 but works on 5.
Register macro in service provider (AppServiceProvider)
public function boot()
{
Mail::macro('setConfig', function (string $key, string $domain) {
$transport = $this->getSwiftMailer()->getTransport();
$transport->setKey($key);
$transport->setDomain($domain);
return $this;
});
}
Then I can use like this:
\Mail::setConfig($mailgunKey, $mailgunDomain)->to(...)->send(...)
In your case
\Mail::setConfig($mailgunKey, $mailgunDomain)->to(...)->queue(...)
Switching the configuration details of the Laravel Mailer at runtime is not that hard, however I don't know of any way it can be done using the Mail::queue facade. It can be done by using a combination of Queue::push and Mail::send (which is what Mail::queue does anyway).
The problem with the Mail::queue facade is that the $message parameter passed to the closure, is of type Illuminate\Mail\Message and we need to modify the mailer transport, which is only accessible through the Swift_Mailer instance (and that is readonly within the Message class).
You need to create a class responsible for sending the email, using a Mailgun transport instance that uses the domain you want:
use Illuminate\Mail\Transport\MailgunTransport;
use Illuminate\Support\SerializableClosure;
class SendQueuedMail {
public function fire($job, $params)
{
// Get the needed parameters
list($domain, $view, $data, $callback) = $params;
// Backup your default mailer
$backup = Mail::getSwiftMailer();
// Setup your mailgun transport
$transport = new MailgunTransport(Config::get('services.mailgun.secret'), $domain);
$mailer = new Swift_Mailer($transport);
// Set the new mailer with the domain
Mail::setSwiftMailer($mailer);
// Send your message
Mail::send($view, $data, unserialize($callback)->getClosure());
// Restore the default mailer instance
Mail::setSwiftMailer($backup);
}
}
And now you can queue emails like this:
use Illuminate\Support\SerializableClosure;
...
Queue::push('SendQueuedMail', ['domain.com', 'view', $data, serialize(new SerializableClosure(function ($message)
{
// do your email sending stuff here
}))]);
While it's not using Mail::queue, this alternative is just as compact and easy to read. This code is not tested but should work.
This works in Laravel 5.4:
// Get the existing SwiftMailer
$swiftMailer = Mail::getSwiftMailer();
// Update the domain in the transporter (Mailgun)
$transport = $swiftMailer->getTransport();
$transport->setDomain('YOUR-DOMAIN.HERE');
// Use the updated version
$mailer = Swift_Mailer::newInstance($transport);
Mail::setSwiftMailer($mailer);
My use case was similar to this, in short I just wanted to automatically configure the mailgun sending domain at runtime, by looking at the domain set in the from address field of the message (which I set on the fly before sending using Mail::from(...)->send(...)). This would solve the OP's use case if they are setting the from address in the message to match the mailgun sending domain, which likely should be done.
My solution registers an alternate MailgunTransport which overrides the built in MailgunTransport and sets the domain before sending. This way I only need to register the new driver in my mail.php, and call Mail::send or Mail::queue.
config\mail.php:
'driver' => env('MAIL_DRIVER', 'mailgun-magic-domain')
providers\MailgunMagicDomainProvider:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Mail\Transport\MailgunTransport;
use Swift_Mime_Message;
use Illuminate\Support\Arr;
use GuzzleHttp\Client as HttpClient;
class MailgunMagicDomainProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
$swiftTransport = $this->app['swift.transport'];
$swiftTransport->extend('mailgun-magic-domain', function($app) {
$config = $app['config']->get('services.mailgun', []);
$client = new HttpClient(Arr::add(
Arr::get($config, 'guzzle', []), 'connect_timeout', 60
));
return new MailgunTransportWithDomainFromMessage(
$client,
$config['secret'],
$config['domain'] // <- we have to pass this in to avoid re-writing the whole transport, but we'll be dynamically setting this before each send anyway
);
});
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
}
}
/**
* Overrides the built in Illuminate\Mail\Transport\MailgunTransport but doesnt pull the
* mailgun sending domain from the config, instead it uses the domain in the from address
* to dynamically set the mailgun sending domain
*/
class MailgunTransportWithDomainFromMessage extends MailgunTransport
{
/**
* {#inheritdoc}
*/
public function send(Swift_Mime_Message $message, &$failedRecipients = null)
{
$this->setDomain($this->getDomainFromMessage($message));
return parent::send($message, $failedRecipients);
}
protected function getDomainFromMessage(Swift_Mime_Message $message)
{
$fromArray = $message->getFrom();
if (count($fromArray) !== 1) {
throw new \Exception('Cannot use the mailgun-magic-domain driver when there isn\'t exactly one from address');
}
return explode('#', array_keys($fromArray)[0])[1];
}
}
config/app.php:
'providers' => [
...
\App\Providers\MailgunMagicDomainProvider::class
],
Maybe it's useful to somebody, I solved it as follows;
In a ServiceProvider under the boot function/method;
public function boot()
{
Mail::macro('setConfig', function (string $key, string $domain) {
config()->set('services', array_merge(config('services'), [
'mailgun' => [
'domain' => $domain,
'secret' => $key
]
]));
});
}
Call to queue
Mail::setConfig($key, $domain)->to(...)->queue(...)

Add BCC to all emails in Magento

As in the title, I need to have a copy of all emails through Magento to a specific email address.
In which file I've to work and how can I obtain the result?
Thanks in advance
System > Configuration > Sales > Sales E-Mails. Navigate to each email type then Send Order Email Copy To and set the Method to BCC via Send Order Email Copy Method.
Or
$mailTemplate->setTemplateSubject($mailSubject)->addBCC('youremail#add.ress')
->s‌​endTransactional($templateId, $sender, $email, $cus_name, $data, $storeId);
Unlike addBcc,addCc is not defined in class Mage_Core_Model_Email_Template. You can either extend Mage_Core_Model_Email_Template class to include addCc method in a similar fashion as addBcc, or modify your code like this:
// Send Transactional Email
try{
$mail = Mage::getModel('core/email_template');
$mail->getMail()->addCc('abc#gmail.com');
$mail->addBcc('abcd2#gmail.com')
->sendTransactional($templateId, $sender, $recepientEmail, $recepientName, $vars, $storeId);
}
catch(Exception $e){
print_r($e);
}