ahmedwaleed / mailmerge
This library provides handful of api's to send all sorts of email using different mail services
Requires
- php: ^7.4
- ext-curl: *
- ext-fileinfo: *
- ext-json: *
- guzzlehttp/guzzle: ^6.3
- kriswallsmith/buzz: ^1.0
- mailgun/mailgun-php: ^3.0
- nyholm/psr7: ^1.2
- predis/predis: ^1.1
- sendgrid/sendgrid: ^7.3
- spatie/temporary-directory: ^1.2
- symfony/psr-http-message-bridge: ^1.2
Requires (Dev)
- mockery/mockery: ^1.3
- orchestra/testbench: ^4.0
- phpunit/phpunit: ^8
README
MailMerge is meant to provide a handful of APIs to send all sorts of emails including (batch mails, single mail) using different mail service providers such as mailgun, pepipost, and sendgrid. It also defines the strategy for resending the failed emails using different mail services.
Requirements
- PHP >= 7.4
- Laravel >= 6.0
- Redis
MailMerge uses redis for saving events and logs so you must have redis install on your host.
Installation
composer require ahmedwaleed/mailmerge
MailMerge will automatically register itself using package discovery.
Once Composer is done, run the following command, it will migrate mailmerge migrations:
php artisan mailmerge:migrate
Configuring the package
You can publish the config file with:
php artisan vendor:publish --tag="mailmerge-config"
This is the contents of the file that will be published at config/mailmerge.php
:
<?php return [ /* |-------------------------------------------------------------------------- | MailMerge Path |-------------------------------------------------------------------------- | | This is the URI prefix where Wink will be accessible from. Feel free to | change this path to anything you like. | */ 'path' => env('MAILMERGE_PATH', 'mailmerge'), /* |-------------------------------------------------------------------------- | MailMerge Services Credentials |-------------------------------------------------------------------------- | */ 'services' => [ 'default' => env('DEFAULT_SERVICE', 'mailgun'), 'mailgun' => [ 'api_key' => env('MAILGUN_API_KEY'), 'api_domain' => env('MAILGUN_API_DOMAIN'), 'api_endpoint' => env('MAILGUN_API_ENDPOINT', 'https://api.mailgun.net'), 'api_base_url' => env('MAILGUN_API_BASE_URL'), ], 'pepipost' => [ 'api_key' => env('PEPIPOST_API_KEY'), 'api_endpoint' => env('PEPIPOST_API_ENDPOINT'), ], 'sendgrid' => [ 'api_key' => env('SENDGRID_API_KEY'), 'api_endpoint' => env('SENDGRID_API_ENDPOINT'), ], ], /* |-------------------------------------------------------------------------- | MailMerge Middleware Group |-------------------------------------------------------------------------- | | This is the middleware group that mailmerge uses for package web routes. | */ 'middleware_group' => env('MAILMERGE_MIDDLEWARE_GROUP', 'web'), ];
Please set your required env vars for all services specified in the config files. 'default' => env('DEFAULT_SERVICE', 'mailgun')
set this options for your default service which will be used when no service is explicitly specified when using mailmerge api.
Usage
This package registered all api endpoint you need, run php artisan route:list
to see all available endpoints.
Method | URI | Action | Middleware |
---|---|---|---|
GET HEAD | api/log | MailMerge\Http\Controllers\Api\MailLogsController@index | MailMerge\Http\Middleware\ApiAuth,MailMerge\Http\Middleware\ClientSwitcher |
POST | api/logs/mailgun-webhook | MailMerge\Http\Controllers\Api\MailgunWebhookController@handle | Mailmerge\Http\Middleware\VerifyMailgunWebhook |
POST | api/logs/pepipost-webhook | MailMerge\Http\Controllers\Api\PepipostWebhookController@handle | |
POST | api/logs/sendgrid-webhook | MailMerge\Http\Controllers\Api\SendGridWebhookController@handle | |
POST | api/mails/batch | MailMerge\Http\Controllers\Api\SendBatchController@handle | MailMerge\Http\Middleware\ApiAuth,MailMerge\Http\Middleware\ClientSwitcher |
POST | api/mails/message | MailMerge\Http\Controllers\Api\SendMailMessageController@handle | MailMerge\Http\Middleware\ApiAuth,MailMerge\Http\Middleware\ClientSwitcher |
POST | mailmerge/resend-batch | MailMerge\Http\Controllers\ResendBatchController@handle | web,Illuminate\Auth\Middleware\Authenticate |
Authentication
MailMerge uses very simple authentication method all you have to do is pass an authorization signature in the request header.
{ "signature": "90gMPhN7Q3bQYJgFGZufYo7y6DLSSDDurEvFO4EFksA=" }
Send Single Email Message
- Api Endpoint
/api/mails/message
- Example Request Parameters
{ "from": "john.snow@thewall.north", "to": "john.snow@behindthewall.north", "subject": "Hi John", "body": "The winters is comming..." }
- Example Response
{ "status":200, "message":"Email has been sent successfully." }
- Example Code
$payload = [ 'from' => 'john.snow@thewall.north', 'to' => 'john.snow@behindthewall.north', 'subject' => 'Hi John', 'body' => 'The winters is comming...' ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://domain.com/api/mails/message"); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "signature: 80PhN7Q3bQFSDFDSF333fYo7y6DLSSDDKKDK885dvFO4EFksA=" // your auth signature here ]); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $server_output = curl_exec($ch)
Send Batch (Bulk Emails) Message
- Api Endpoint
/api/mails/batch
- Example Request Parameters
{ "recipients":[ { "email": "john.doe@example.com", "attributes": { "first":"John", "last":"Doe", "id":"1" } }, { "email": "sally.doe@example.com", "attributes": { "first":"sally", "last":"Doe", "id":"2" } } ], "from":"janedoe@example.com", "subject":"Hey <%attribute.first%>", "body":"If you wish to unsubscribe,click https://domain.com/unsubscribe/<%attribute.id%>" }
- Example Response
{ "status":200, "message":"Batch message processed successfully." }
- Example Code
$payload = [ 'from' => 'john.snow@thewall.north', 'recipients' => [ [ 'email' => 'john_doe@example.com', 'attributes' => [ 'first' => 'john', 'last' => 'doe' ], [ 'email' => 'jane_doe@example.com', 'attributes' => [ 'first' => 'jane', 'last' => 'doe' ] ] ], 'subject' => 'Hi <%attribute.first%>', 'body' => 'This this test body with last name <%attribute.last%>.' ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://domain.com/api/mails/batch"); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "signature: 80PhN7Q3bQFSDFDSF333fYo7y6DLSSDDKKDK885dvFO4EFksA=" ]); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $server_output = curl_exec($ch)
- service
-
You can specify service in the api headers which you want to use for sending message
For example:
curl_setopt($ch, CURLOPT_HTTPHEADER, [ "API-SERVICE: sendgrid", // suported (mailgun, pepipost, sendgrid) ]);
- cc, bcc
-
MailMerge also allows you to add cc and bcc to your message, you can add those in your request body.
For example.
$payload = [ // ... "cc": "cc1@example.com,cc2@example.com", "bcc": "bcc1@example.com,bcc2@example.com", // ... ];
- attachment
-
With MailMerge you can send one or more attachments with batch message.
$payload = [ // ... 'attachments' = [ 'https://site.com/uploads/sample1.pdf', 'https://site.com/uploads/sample2.pdf' ], // ... ];
- Batch Mail Template
MailMerge uses its own email placeholder template for recipients custom attributes (variables) because of different integration of MSP so you don't have to worry about syntax different services.
- Syntax
<% attribute.custom_attribute_name %>
- Example
'recipients' => [ [ 'email' => 'jane_doe@example.com', 'attributes' => [ 'id' => '1', 'first' => 'jane', 'last' => 'doe' ] ]
Subject: Hey <%attribute.first%> <%attribute.last%> <%attribute.id%>
Re-Send Batch Message
- Api Endpoint
/resend-batch
Sending a batch message can be a time taking task on user end, it may take time for you to arrange all the recipents list that you want to send as batch message and what if your batch message failed so instead of doing all the heavy work again and again with MailMerge its now possible to resend your batch message using different service (mailgun, pepipost, sendgrid). MailMerge saves all of your sent batch messages so you can retry that batch message in future in case of some system failure or if there are so many failed or bounced emails, when you retry or resend batch message it handle the logic of sending that batch message only for failed recipients from last batch so you can retry that batch message as many times as you want until all the emails from that batch are sent successfully.
MailMerge provide a default view for handling your batch messages. but you're free to modify it as per your need. You can run below command to publish MailMerge default view of resending batch messages.
php artisan vendor:publish --tag='mailmerge-views' --force
Once the view is published you can find it inside
resources/views/vendors/mailmerge
directory.Logging
MailMerge provides centralized logging system for all supported email services using webhooks support, MailMerge register endpoint for each services so that you can add that url into your mail api webhook settings. You can find related docs for webhooks in following links: mailgun, pepipost, sendgrid.
Whenever there is new log your mail service will hit that webhook url and MailMerge handle that request and saves that log into redis server.
Get Logs
-
Request Query Parameters
-
Items: (optional)
/api/logs?items=100
By default, the API will return 10 items but you can pass items param in a query to get items as per your need.
- Service (required)
/api/logs?service=mailgun
- Example Response
{ 'original_response': { //.. }, 'nomalized_response': { //.. }, }
-
Original Response: It include original payload from mail service.
-
Normalized Response: Normalized response that will be consistent across multiple services.
License
MailMerge is licensed under the MIT License.