May Sale! All accounts are 40% off this week.

mstdmstd's avatar

How to test sendgrid email with mailtrap for testing?

Hello, In my Laravel 7.6 app I use sendgrid for email sending with code in control like :

  \Mail
    ::to($newContactUs->author_email)->
   send(new SendgridMail('emails/contact_us_was_sent', $newContactUs->author_email, '', $subject, $additiveVars, $attachFiles));

with class in app/Mail/SendgridMail.php :

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use Sichikawa\LaravelSendgridDriver\SendGrid;
use App\Settings;
use App\Http\Traits\funcsTrait;

class SendgridMail extends Mailable
{
    use Queueable, SerializesModels;
    use SendGrid;
    use funcsTrait;

    private  $m_view_name;
    private  $m_to;
    private  $m_cc;
    private  $m_subject;
    private  $m_additiveVars;
    private  $m_attachFiles;

    public function __construct( $view_name, $to= [], $cc= '', $subject= '', $additiveVars= [], $attachFiles= [] )
    {
        $this->m_view_name= $view_name;
        $this->m_to= $to;
        $this->m_cc= $cc;
        $this->m_subject= $subject;
        $all_emails_copy      =   \Config::get('app.all_emails_copy');

        if ( empty($this->m_cc) and !empty($all_emails_copy)) {
            $this->m_cc= $all_emails_copy;
        }


        $additiveVars['site_home_url']         = \URL::to('/');
        $additiveVars['site_name']             = Settings::getValue('site_name');
        $additiveVars['noreply_email']         = Settings::getValue('noreply_email');
        $additiveVars['support_signature']     = Settings::getValue('support_signature');
        $additiveVars['medium_slogan_img_url'] = config('app.url').config('app.medium_slogan_img_url');

        $this->m_additiveVars= $additiveVars;
        $this->m_attachFiles= $attachFiles;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build( )
    {
        $mailObject= $this
            ->view( $this->m_view_name)
            ->subject($this->m_subject)
            ->to([$this->m_to])
            ->cc([$this->m_cc])
            ->with( $this->m_additiveVars )
            ->sendgrid( $this->m_additiveVars );
        foreach( $this->m_attachFiles as $next_attach_file) {
            if ( file_exists($next_attach_file) ) {
                $mailObject->attach($next_attach_file);
            }
        }
        return $mailObject;
    }

}

and template resources/views/emails/contact_us_was_sent.blade.php:

...
<div class="wrapper">
	@inject('viewFuncs', 'App\library\viewFuncs')


	<h4 class="email_title">
		Hello, {!! $to_user_name !!} !
	</h4>
    ...

	@include( 'emails.app_footer')
	@include( 'emails.emails_style')
</div>

and it works for me now, but now with "Multiple Mail Drivers" I added mailtrap to my .env :

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=NNNNNNNN
MAIL_PASSWORD=NNNNNNNN

and I want t use mailtrap while testing the app using the same template resources/views/emails/contact_us_was_sent.blade.php and switching from mailtrap to sendgrid as easy as possible.

I tried something like :

    \Mail::mailer('smtp')
    ->to($newContactUs->author_email)
    ->send( \Mail('emails/contact_us_was_sent', $newContactUs->author_email, '', $subject, $additiveVars, $attachFiles) );

But got error as \Mail does not support templates. Are there something to use support templates for mail Method? Some wrapper?

Thanks!

0 likes
3 replies
mstdmstd's avatar

I founbd a link to video how to implement multiple mail drivers: https://www.youtube.com/watch?v=HCONO0cwsoI

I tried to follow it, but with I always got email at mailtrap.

Priorly, I worked with sendgrid and for this in file config/mail.php I wrote all sendgrid parameters. Now I want to write 2 emeil servers and fi=or this in .env I wrote:

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=mailtrip_id
MAIL_PASSWORD=mailtrip_password

SENDGRID_HOST=smtp.sendgrid.net
SENDGRID_PORT=587
SENDGRID_ENCRYPTION=tls
SENDGRID_USERNAME=sendgrid_user
SENDGRID_PASSWORD=sendgrid_user_password

and I remade config/mail.php (I got a sample from https://github.com/laravel/laravel/blob/master/config/mail.php):

<?php
return [


    'driver' => env('MAIL_DRIVER', 'smtp'),


    'host' => env('MAIL_HOST', 'smtp.mailgun.org'),


    'port' => env('MAIL_PORT', 587),


    'from' => [
        'address' => env('MAIL_FROM_ADDRESS', '[email protected]'),
        'name' => env('MAIL_FROM_NAME', 'Example'),
    ],


    'encryption' => env('MAIL_ENCRYPTION', 'tls'),

    'username' => env('MAIL_USERNAME'),

    'password' => env('MAIL_PASSWORD'),

    'sendmail' => '/usr/sbin/sendmail -bs',

    'markdown' => [
        'theme' => 'default',

        'paths' => [
            resource_path('views/vendor/mail'),
        ],
    ],

    'log_channel' => env('MAIL_LOG_CHANNEL'),

    'mailers' => [
        'smtp' => [
            'transport' => 'smtp',
            'host' => env('MAIL_HOST'),
            'port' => env('MAIL_PORT'),
            'encryption' => env('MAIL_ENCRYPTION', 'tls'),
            'username' => env('MAIL_USERNAME'),
            'password' => env('MAIL_PASSWORD'),
            'timeout' => null,
            'auth_mode' => null,
        ],

        'sendgrid' => [
            'transport' => 'sendgrid',
            'host' => env('SENDGRID_HOST', 'smtp.sendgrid.net'),
            'port' => env('SENDGRID_PORT', 587),
            'encryption' => env('SENDGRID_ENCRYPTION', 'tls'),
            'username' => env('SENDGRID_USERNAME'),
            'password' => env('SENDGRID_PASSWORD'),
            'timeout' => null,
            'auth_mode' => null,
        ],

        'ses' => [
            'transport' => 'ses',
        ],

        'mailgun' => [
            'transport' => 'mailgun',
        ],

        'postmark' => [
            'transport' => 'postmark',
        ],

        'sendmail' => [
            'transport' => 'sendmail',
            'path' => '/usr/sbin/sendmail -bs',
        ],

        'log' => [
            'transport' => 'log',
            'channel' => env('MAIL_LOG_CHANNEL'),
        ],

        'array' => [
            'transport' => 'array',
        ],
    ],

];

I am not sure that this config file is valid? Are mail config parameters are read from mailers array ? Looks like default(mailtrip) mail config is used always. Is it invalid format ?

In my control I do:

        $email_mode= 'live';
//        $email_mode= 'debug';

        if( $email_mode== 'debug' ) {
            \Log::info( '-10 Send to mailtrap ::' );

            \Mail
                ::mailer('smtp')
                ->to('[email protected]') // DEBUG
                ->send(new TestEmail);  // 
            \Log::info( '-10 Send to mailtrap AFTER::' );
        }

        // sendgrid
        if( $email_mode== 'live') {
            \Log::info( '-11 Send to sendgrid ::' );
            \Mail
                ::mailer('sendgrid')
                ->to('[email protected]') // DEBUG
                ->send(new SendgridMail('emails/contact_us_was_sent', $newContactUs->author_email, '', $subject, $additiveVars, $attachFiles));
            \Log::info( '-11 Send to sendgrid AFTER::' );
        }

I check in logs that live flow is run but anyway I got email at mailtrap.

guybrush_threepwood's avatar
Level 33

It seems like you have a mix of the old and the new config file structure.

This is the correct one for Laravel 7.0:

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Default Mailer
    |--------------------------------------------------------------------------
    |
    | This option controls the default mailer that is used to send any email
    | messages sent by your application. Alternative mailers may be setup
    | and used as needed; however, this mailer will be used by default.
    |
    */

    'default' => env('MAIL_MAILER', 'smtp'),

    /*
    |--------------------------------------------------------------------------
    | Mailer Configurations
    |--------------------------------------------------------------------------
    |
    | Here you may configure all of the mailers used by your application plus
    | their respective settings. Several examples have been configured for
    | you and you are free to add your own as your application requires.
    |
    | Laravel supports a variety of mail "transport" drivers to be used while
    | sending an e-mail. You will specify which one you are using for your
    | mailers below. You are free to add additional mailers as required.
    |
    | Supported: "smtp", "sendmail", "mailgun", "ses",
    |            "postmark", "log", "array"
    |
    */

    'mailers' => [
        'smtp' => [
            'transport' => 'smtp',
            'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
            'port' => env('MAIL_PORT', 587),
            'encryption' => env('MAIL_ENCRYPTION', 'tls'),
            'username' => env('MAIL_USERNAME'),
            'password' => env('MAIL_PASSWORD'),
            'timeout' => null,
            'auth_mode' => null,
        ],

        'ses' => [
            'transport' => 'ses',
        ],

        'mailgun' => [
            'transport' => 'mailgun',
        ],

        'postmark' => [
            'transport' => 'postmark',
        ],

        'sendmail' => [
            'transport' => 'sendmail',
            'path' => '/usr/sbin/sendmail -bs',
        ],

        'log' => [
            'transport' => 'log',
            'channel' => env('MAIL_LOG_CHANNEL'),
        ],

        'array' => [
            'transport' => 'array',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | 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', '[email protected]'),
        'name' => env('MAIL_FROM_NAME', 'Example'),
    ],

    /*
    |--------------------------------------------------------------------------
    | 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'),
        ],
    ],

];

See how on the top Level you should only have "default", "mailers", "from" and "markdown".

1 like
guybrush_threepwood's avatar

According to Laravel 7.0 upgrade guide:

In order to support multiple mailers, the default mail configuration file has changed in Laravel 7.x to include an array of mailers. However, in order to preserve backwards compatibility, the Laravel 6.x format of this configuration file is still supported. So, no changes are required when upgrading to Laravel 7.x; however, you may wish to examine the new mail configuration file structure and update your file to reflect the changes.

If you leave items such as "host", "driver", etc on the top level Laravel will use those instead of the ones defined in the "mailer" key.

1 like

Please or to participate in this conversation.