I've configured Lumen 5.4.6 to send emails with Mailgun. I saw several other answers but they were incomplete or had unnecessary statements or they were more complicated than needed.
I put below complete and detailed steps to get Lumen to work with Mailgun as easy and clean as I've found.
If you know an easier, cleaner, eleganter way, please add your answers and comments.
UPDATE: I'm developing an open source quick-start boilerplate Lumen project with some useful functionality out of the box like
emailing as well as user register and login:
https://github.com/AMS777/ams-bl
It can be used as a starting point for a JSON API Lumen project or as a reference for the steps described
below. There you can find also some notes to test and preview emails on browsers.
Configure Lumen
Add Laravel's Composer packages on command line:
composer require illuminate/mail
composer require guzzlehttp/guzzle
I was using Lumen 5.4.6, so I had to install an old mail package:
composer require illuminate/mail:5.4.*
On file bootstrap/app.php add:
bootstrap/app.php: (At Register Service Providers section.)
$app->register(\Illuminate\Mail\MailServiceProvider::class);
bootstrap/app.php: (At the end of the file, above the return.)
$app->configure('services');
$app->configure('mail');
If you want to use the easy interface Facades to send the email, you have to uncomment:
bootstrap/app.php: (Uncomment.)
$app->withFacades();
Create following files on your project:
config/mail.php
config/services.php
Copy and arrange the contents of Laravel's files:
https://github.com/laravel/laravel/blob/master/config/mail.php
Here I've changed the default mail driver to mailgun. username and password are not used with mailgun driver, they may be removed.
config/mail.php:
<?php
return [
/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "sendmail", "mailgun", "mandrill", "ses",
| "sparkpost", "log", "array"
|
*/
'driver' => env('MAIL_DRIVER', 'mailgun'),
/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Mailgun mail service which will provide reliable deliveries.
|
*/
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to deliver e-mails to
| users of the application. Like the host we have set this value to
| stay compatible with the Mailgun e-mail application by default.
|
*/
'port' => env('MAIL_PORT', 587),
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello#example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Markdown Mail Settings
|--------------------------------------------------------------------------
|
| If you are using Markdown based email rendering, you may configure your
| theme and component paths here, allowing you to customize the design
| of the emails. Or, you may simply stick with the Laravel defaults!
|
*/
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
];
https://github.com/laravel/laravel/blob/master/config/services.php
Here I've stripped unnecessary lines.
config/services.php:
<?php
return [
/*
|--------------------------------------------------------------------------
| Third Party Services
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Stripe, Mailgun, SparkPost and others. This file provides a sane
| default location for this type of information, allowing packages
| to have a conventional place to find your various credentials.
|
*/
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
],
];
Then you'll need to set the environment variables on your .env file:
.env:
MAIL_DRIVER=mailgun
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=your#email.es
MAIL_FROM_NAME="Your email sender name"
MAILGUN_DOMAIN=sandbox_EXAMPLE.mailgun.org
MAILGUN_SECRET=key-EXAMPLE
Well, so far is the email functionality is ready on Lumen.
Create and send email in Lumen
Once the mail functionality is set up, the steps to create and send emails in Lumen are the same as in Laravel, and can be checked on its documentation:
https://laravel.com/docs/5.4/mail
To send an email in Lumen you need 3 files:
Mail class. Extends Mailable. Build the email from a view.
Email template. A view. May be html or Blade engine.
Class that uses the mail class and send an email.
This example of mail class only imports the packages required to build emails. If you want to use queues, you'll need to import more packages.
app/mail/RegisterConfirmationEmail.php:
<?php
namespace App\Mail;
use Illuminate\Mail\Mailable;
class RegisterConfirmation extends Mailable
{
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('RegisterConfirmationEmail');
}
}
Views were removed from Lumen at 5.2 version, but were recovered soon after. As of Lumen 5.4 views work, but there is no clue of it on the documentation.
The raw() function may be used if you don't want to use views.
resources/views/RegisterConfirmationEmail.blade.php:
<html>
<body>
<h1>Test</h1>
</body>
</html>
The class that sends the email must import the mail class. Remember that this example uses the interface Facades, that must be enabled on bootstrap/app.php.
app/Http/Controllers/RegisterController.php:
<?php
namespace App\Http\Controllers;
use App\Mail\RegisterConfirmation;
use Illuminate\Support\Facades\Mail;
class RegisterController extends Controller
{
public function sendRegisterConfirmationEmail()
{
Mail::to('test+receiver#email.es')->send(new RegisterConfirmation());
}
}
Mailgun
On Mailgun you have to create an account with some data of yours and of your company.
Mailgun will ask for your mobile phone number to proceed with your account verification:
"To prevent abuse, Mailgun requires you to verify your account through
the use of SMS."
For a development account it's not required credit card nor domain verification, but you'll need to authorize up to 5 email addresses.
You can use a sandbox domain provided by Mailgun.
Related
Stage
I have a web application which I deployed recently. Application needs to send emails for several reasons.
I am using yandex business email service for my domain, have many email accounts for my domain, and I can use those email addresses without any problem.
I have written some code to send email on my Laravel application, using Laravel's Mail::send. See it below at #2. And you can see my config/mail.php settings at #1 below.
I am testing my application on my windows computer, with WAMP server.
My production server is VPS server running Linux. PHP version 5.5.29.
Problem
Everything works perfectly on my local test environment;
I can send mails, and they are delivered to hotmail, gmail or my domain's emails without any problem.
On the server however, I receive an error when I try to send an email. See #3 for error.
On the same server, I am able to send emails using PHPMailer with same email accounts, email settings and credentials, and without any problem.
Question and thoughts
Everything works on my local environment as expected and that makes me think it is a problem with my server configurations, PHP version, configuration or extensions, but I do not have the knowledge to judge that.
What have I tried and did not worked
Commented these lines to send email from default mail address.
And also changed my default email address with another one, which is also working everywhere except on production server of this project;
//$transport = Mail::getSwiftMailer()->getTransport();
//$transport->setUsername($username);
//$transport->setPassword($password);
Disabled mail encryption. Set;
'encryption' => '',
Tried different driver;
'driver' => 'mail',
1) My config/mail.php
'driver' => 'smtp',
'host' => 'smtp.yandex.com',
'port' => 587,
'from' => ['address' => 'name#domain.com', 'name' => 'name'],
'encryption' => 'tls',
'username' => 'name#domain.com',
'password' => 'password',
'sendmail' => '/usr/sbin/sendmail -bs',
'pretend' => false,
2) Code I use
Mail::send($message, $data, function ($message) use ($account, $to, $subject)
{
$acc = config("mail.accounts.$account");
$senderAddress = array_get($acc, 'address');
$username = array_get($acc, 'username', $senderAddress);
$password = array_get($acc, 'password', '');
$senderName = array_get($acc, 'name', $acc['address'], $senderAddress);
$replyToAddress = array_get($acc, 'replyTo.0', $senderAddress);
$replyToName = array_get($acc, 'replyTo.1', $senderName);
$message->from($senderAddress, $senderName)
->replyTo($replyToAddress, $replyToName)
->subject($subject)
->to($to);
$transport = Mail::getSwiftMailer()->getTransport();
$transport->setUsername($username);
$transport->setPassword($password);
});
Explanation for code above:
This code basically allows me to send emails to any email account,
and from many email accounts I have. And like I said, this works perfectly on my local test environment.
3) The Error
Swift_TransportException in AuthHandler.php line 181:
Failed to authenticate on SMTP server with username
"name#domain.com" using 2 possible authenticators
4) Working PHPMailer Script
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->SMTPAuth = true;
$mail->Host = "smtp.yandex.com";
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->Username = $sender; // SMTP account username
$mail->Password = $password; // SMTP account password
$mail->SetFrom($sender, 'Name');
$mail->AddReplyTo($sender, 'Name');
$mail->Subject = $subject;
$mail->MsgHTML($message);
$mail->AddAddress($to, $to);
$mail->Send();
It's hard to say what the problem can be. Or why it works on your development environment. But a quick google search gave me the following settings for smpt.yandex.com:
mail server address — smtp.yandex.com;
connection security — SSL;
port — 465.
So, it shouldn't work on your dev environment. Why it does work is a mystery to me.
see: https://yandex.com/support/mail/mail-clients.xml
I just moved my Laravel 4.2. application from WAMP into IIS web server, and the email-function just stopped working - no idea why.
I use external SMTP server from a hosting service, so I didn't thought it was going to cause any problem.
My settings:
return array(
/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "mail", "sendmail", "mailgun", "mandrill", "log"
|
*/
'driver' => 'smtp',
/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Mailgun mail service which will provide reliable deliveries.
|
*/
'host' => 'smtp.*my-host*.se',
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to deliver e-mails to
| users of the application. Like the host we have set this value to
| stay compatible with the Mailgun e-mail application by default.
|
*/
'port' => 587,
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => array('address' => "example#mail.com", 'name' => "Example name"),
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
'encryption' => 'tls',
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => "user#host.se",
/*
|--------------------------------------------------------------------------
| SMTP Server Password
|--------------------------------------------------------------------------
|
| Here you may set the password required by your SMTP server to send out
| messages from your application. This will be given to the server on
| connection so that the application will be able to send messages.
|
*/
'password' => "********",
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Mail "Pretend"
|--------------------------------------------------------------------------
|
| When this option is enabled, e-mail will not actually be sent over the
| web and will instead be written to your application's logs files so
| you may inspect the message. This is great for local development.
|
*/
'pretend' => false,
I changed the auth properties above.
The error i get from Laravel.
{"error":{"type":"ErrorException","message":"stream_socket_enable_crypto(): Peer certificate CN=`*.my-host-name.se' did not match expected CN=`smtp.my-host.se'","file":"D:\\Dir1\\Dir2\\vendor\\swiftmailer\\swiftmailer\\lib\\classes\\Swift\\Transport\\StreamBuffer.php","line":95}}
Any ideas? Should I maybe install a local SMTP service instead?
It looks like a SSL certificate issue between your server and the smtp email server.
I believe the issue is related to this: https://github.com/swiftmailer/swiftmailer/issues/544
There is a pull-request here you can try and see if that resolves the problem: https://github.com/swiftmailer/swiftmailer/issues/571
I'm using Jenkins and I would like to send an email after finished job. The problem I have is that I want to use the username defined before into a parameter in the configuration. I try to use then ${username} but i doesn't work. This is the error I get:
Sending e-mails to: ${username}#email.es
ERROR: Invalid Addresses
javax.mail.SendFailedException: Invalid Addresses;
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <${username}#email.es>... User unknown
at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1835)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1098)
at javax.mail.Transport.send0(Transport.java:195)
at javax.mail.Transport.send(Transport.java:124)
at hudson.tasks.MailSender.run(MailSender.java:126)
at hudson.tasks.MailSender.execute(MailSender.java:101)
at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.cleanUp(MavenModuleSetBuild.java:1064)
at hudson.model.Run.execute(Run.java:1764)
at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:531)
at hudson.model.ResourceController.execute(ResourceController.java:89)
at hudson.model.Executor.run(Executor.java:240)
Caused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <${username}#email.es>... User unknown
at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1686)
... 10 more
It is not taking the value of the parameter. Is thera any plugin or way to do this ?
Thanks for your help.
instead of ${username} - use $username
Ex: $username#$domain.com
Here, username and domain are two parameters for build
(defined by selecting checkbox-This build is parameterized)
Configure Jenkins System for Email Notifications
To do this:
"Jenkins Dashboard -> Manage Jenkins -> Configure System"
At the bottom of the page- find : Email Notification
Then give email notification details
I have configured like this:
SMTP server : smtp.gmail.com
Default user e-mail suffix : #gmail.com
select checkbox USE smtp authentication
give: username (without #gmail.com) -eg: enter mike for mike#gmail.com
give your password
Select checkbox Use SSL
SMTP port : 465
try your email settings by sending a test mail
If your able to send it successfuly. its done
/* In the Build - The Build is Parameterized */
1st parameter
Name : username
Default Value : mike
2nd Parameter
Name: domain
Default Value: gmail
//Post-Build Actions - Email Notification
(able to see this only when you have Mailer plugin installed)
Recipients : $username#$domain.com
This should work ..
I 'found' the solution. With a maven project, it doesn' work with the simply Email notification inside the Build properties. I must use a plugin 'Ext-mail plugin' to do it. Thanks for all.
I'm trying to use CakeEmail in a web application, but I keep running into a timeout error. All my Googling and Stacking only give me the idea that something is not configured correctly, but I can't seem to find what config option I'm missing or filling incorrectly. I'm trying to send using my Gmail account.
Gmail Config:
public $gmail = array(
'host' => 'ssl://66.249.93.111',
'port' => 465,
'timeout' => 30,
'username' => 'my_gmail_account_name',
'password' => 'my_gmail_account_password',
'transport' => 'Smtp'
);
in app/Config/email.php
Email code:
$Email = new CakeEmail('gmail');
$Email->from(array('my_gmail_account_name' => 'Dev'));
$Email->to('my_gmail_account_name');
$Email->subject('Export Email Test');
$Email->send('This is a test email for ExportJobs.');
(As an additional note, the code that runs here is as part of a Cake Console program, so these methods are called when I run Console/cake file_name from the command line; also, that IP is the Gmail SMTP IP. When I try using the name, I get some DNS issue).
Does anyone happen to see what I'm missing?
Thanks for your time!
I found the problem I was having; it's a pretty silly error.
I completely forgot that to use the gmail domain for SMTP, I have to preface the domain name as "smtp.gmail.com". Once I did that it used SMTP and worked just fine.
I have created some forms using zendframework on my local machine that send the form content via email.
I would like to test the functionality locally and have read some posts regarding configuring the php.ini file to do this but not sure which is the correct method ?
can anyone help me with this, many thanks
On Windows you will have to use SMTP to send the message. There is a drop in fake sendmail for Windows but it still requires an SMTP server.
You could use your ISP's sendmail server if they offer one, or you can set one up on the local machine. 1, 2, 3, 4
Since you are using Zend Framework, you can alternatively use Zend_Mail to send through an SMTP server (Zend_Mail can also use sendmail, but since it isn't configured, you can't use that transport). In that case see Sending via SMTP, SMTP Authentication, and Securing SMTP Transport.
Here is some sample code for sending an SMTP message with AUTH and TLS security.
<?php
require_once 'Zend/Mail.php';
require_once 'Zend/Mail/Transport/Smtp.php';
$config = array('ssl' => 'tls',
'port' => '465', // 25 if no ssl
'auth' => 'login',
'username' => 'user',
'password' => 'password');
$transport = new Zend_Mail_Transport_Smtp('smtp.example.com', $config);
$mail = new Zend_Mail();
$mail->addTo('user#domain')
->setSubject('Mail Test')
->setBodyText("Hello,\nThis is a Zend Mail message...\n")
->setFrom('sender#domain');
try {
$mail->send($transport);
echo "Message sent!<br />\n";
} catch (Exception $ex) {
echo "Failed to send mail! " . $ex->getMessage() . "<br />\n";
}
Also note, your ISP may not require you to auth at all if you are sending from one of their IP addresses, but you probably do have to authenticate with your username and password, in which case you will want to use TLS.