Last active
July 6, 2017 05:32
-
-
Save loburets/a6452e77550467d5796b53af3c80770f to your computer and use it in GitHub Desktop.
Pagination for Mailgun events API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Mailgun\Mailgun; | |
use Setting; | |
/** | |
* Pagination for Mailgun events API | |
* Retrieves all new (not have retrieved yet) events for each run | |
* See main code at processNewEvents() | |
* | |
* Used, but can be replaced by any implementation: | |
* "mailgun/mailgun-php": "^2.3", | |
* "anlutro/l4-settings": "^0.5.0", | |
*/ | |
class EmailProcessor | |
{ | |
/** | |
* Pagination step for api calls, max 300 | |
* @var int | |
*/ | |
private static $step = 300; | |
public function sendEmails() | |
{ | |
$this->processNewEmails(function($response) { | |
/** @var \Mailgun\Model\Message\ShowResponse $response */ | |
// any code what you want | |
// $response->getBodyPlain(); | |
}); | |
} | |
/** | |
* Make some action with all new inbounded emails | |
* | |
* @param \Closure $callback | |
*/ | |
private function processNewEmails(\Closure $callback) | |
{ | |
$this->processNewEvents(function($event) use($callback) { | |
/** @var \Mailgun\Model\Event\Event $event */ | |
$storage = $event->getStorage(); | |
if (empty($storage) ||empty($storage['url'])) { | |
return; | |
} | |
$mailgun = Mailgun::create(env('MAILGUN_SECRET')); | |
$response = $mailgun->messages()->show($storage['url']); | |
$callback($response); | |
}, 'stored'); | |
} | |
/** | |
* Make some actions with all new events | |
* | |
* @param \Closure $callback | |
* @param string $type | |
*/ | |
private function processNewEvents(\Closure $callback, $type) | |
{ | |
$domain = env('MAILGUN_DOMAIN'); | |
$mailgun = Mailgun::create(env('MAILGUN_SECRET')); | |
$latestEventOfPreviousRunSetting = 'latest_processed_mailgun_event_' . $type; | |
$latestEventOfPreviousRun = Setting::get($latestEventOfPreviousRunSetting, '0'); | |
$begin = time(); | |
$processed = []; | |
$latestEventIsWritten = false; | |
do { | |
$eventsResponse = $mailgun->events() | |
->get( | |
$domain, | |
[ | |
'begin' => $begin, | |
'event' => $type, | |
'ascending' => 'no', | |
'limit' => self::$step, | |
] | |
); | |
$needToMakeNextApiStep = false; | |
foreach ($eventsResponse->getItems() as $event) { | |
//already processed last run | |
if ($latestEventOfPreviousRun === $event->getId()) { | |
break(2); | |
} | |
// because after the step of api pagination first part of current batch can contain the same events as previous | |
// it depends on crossing of events with the same timestamp (peculiarity of the mailgun API) | |
if (in_array($event->getId(), $processed)) { | |
continue; | |
} | |
$needToMakeNextApiStep = true; | |
$processed[] = $event->getId(); | |
$begin = $event->getTimestamp(); | |
if (!$latestEventIsWritten) { | |
Setting::set($latestEventOfPreviousRunSetting, $event->getId()); | |
Setting::save(); | |
$latestEventIsWritten = true; | |
} | |
$callback($event); | |
} | |
} while($needToMakeNextApiStep); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment