Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Laravel Mail response after send function called?

Is it possible to get Mail response in Laravel after Mail:to a method called? Where is the best place to do that?

Mail::to($order->email)
  ->send(new ThankYouMail($order->fresh())); 

I am using Sendgrid as a Laravel Mail driver and want to get messageID in order to use for afterward Sendgrid hooks (get email delivery status etc).

public function build()
{
    $from = '[email protected]';
    $subject = 'Thank You for Ordering';
    $name = 'Name XYZ';

    $order_id = (string)$this->order->id;
    $headerData = [
      'category' => 'Order',
      'unique_args' => [
          'OrderID' => $order_id
      ]
    ];

    $header = $this->asString($headerData);

    $this->withSwiftMessage(function ($message) use ($header) {
      $message->getHeaders()
              ->addTextHeader('X-SMTPAPI', $header);
    });

    return $this->view('mails.thank-you')
                ->from($from, $name)
                ->replyTo($from, $name)
                ->subject($subject);
}

UPDATE: 2019/06/25

If anyone wants to get and store Mail statuses it is the best solution to use Sendgrid Event Webhook.

  • Probably you will attach (to the email) an unique arg like OrderID during the email send process (Check the Sendgrid API or my example from above).
  • After that you have to create API POST route in order to receive/store Webhook Email data where you can filter/aim and connect status data.

UPDATE #2: 2021/01/21

In order to receive data from Sendgrid it is required to create some logic:

Route:

Route::post('sendgrid/events','SendgridOrderEventController@store');

Controller:

/**
* Store a sendgrid event in database.
* @param  App\Http\Requests\API\CreateSendgridOrderEventRequest $request
* @return Response
*/
public function store(CreateSendgridOrderEventRequest $request)
{
  $sendgrid_request = $request->all()[0];

  if($sendgrid_request['OrderID']) {
    
    $sendgrid_request['order_id'] = $sendgrid_request['OrderID'];
    $sendgrid_request['sendgrid_timestamp'] = $sendgrid_request['timestamp'];
    $sendgrid_request['sendgrid_message_id'] = $sendgrid_request['sg_message_id'];

    $sendgridOrderEvent = SendgridOrderEvent::create($sendgrid_request);
  }

  return $this->sendResponse($sendgridOrderEvent, 'SendGrid Order Event created successfully');
}

Within the Sendgrid dashboard, find webhooks settings and place your API POST endpoint: api.yourdomain.com/sendgrid/events so after that, Sendgrid will be able to generate events and send a POST request to your API endpoint where your logic can receive and handle incoming data.

More details: https://sendgrid.com/docs/for-developers/tracking-events/event/

like image 513
SlavisaPetkovic Avatar asked Jan 26 '23 12:01

SlavisaPetkovic


2 Answers

An Illuminate\Mail\Events\MessageSent is dispatched after the mail is sent [1]

This event is dispatched with the instance of the swift message instance. [2]

You can listen on this event and get the message id.

This event can be subscribed to by registering in the boot method of the EventServiceProvider an event listener. [3]

protected $listen = [
    'Illuminate\Mail\Events\MessageSent' => [
        'App\Handlers\Events\MessageIdTranscript',
    ],
];

The MessageIdTranscript is a plain PHP class with a handle method that is called with the event. Instances of Swift_Message expose the message Id via a public getter method named getId.

namespace App\Handlers\Events;

use Illuminate\Mail\Events\MessageSent;

class MessageIdTranscript {

    /**
     * Handle the event.
     *
     * @param  MessageSent  $event
     * @return void
     */
    public function handle(MessageSent $event)
    {
        $messageId = $event->message->getId();
        // continue handling...
    }

}
like image 148
Oluwafemi Sule Avatar answered Jan 29 '23 07:01

Oluwafemi Sule


Attach a listener to the sendgrid api response not the build.

like image 36
Jamie Ross Avatar answered Jan 29 '23 07:01

Jamie Ross