Skip to content

Commit cc2e0ae

Browse files
Merge pull request #923 from mailgun/DE-1314-mailgun-php-add-support-for-metrics-endpoint
Added new API endpoint for getting metrics
2 parents 99e09e0 + 7947dc3 commit cc2e0ae

File tree

5 files changed

+280
-0
lines changed

5 files changed

+280
-0
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
44

5+
## 4.3.2
6+
- Added new API endpoint for getting metrics @see https://documentation.mailgun.com/docs/mailgun/api-reference/openapi-final/tag/Metrics/
7+
8+
## 4.3.1
9+
- Add method for retrieving stored messages by @oleksandr-mykhailenko in #920
10+
- Add missed params to the create method for DomainV4.php by @oleksandr-mykhailenko in #921
11+
512
## 4.3.0
613
- End of support php 7.3
714
- Updated properties and added types to the classes properties

README.md

+32
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,38 @@ $configurator->setApiKey('key-example');
189189
$configurator->setSubAccountId($subAccountId)
190190
```
191191

192+
### Load data from the Analytics API
193+
194+
```php
195+
<?php
196+
# Include the Autoloader (see "Libraries" for install instructions)
197+
require 'vendor/autoload.php';
198+
199+
use Mailgun\Mailgun;
200+
201+
# Instantiate the client.
202+
$mgClient = Mailgun::create('xxx');
203+
$domain = "xxx.mailgun.org";
204+
205+
$result = $mgClient->metrics()->loadMetrics([
206+
'start' => 'Wed, 11 Sep 2024 18:29:02 +0300',
207+
'end' => 'Wed, 25 Sep 2024 18:29:02 +0300',
208+
'metrics' => [
209+
"failed_count", "opened_count", "sent_count", "delivered_count"
210+
],
211+
'resolution' => 'month',
212+
'precision' => 'day',
213+
'dimensions' => [
214+
'time',
215+
],
216+
'include_aggregates' => true,
217+
'include_subaccounts' => true,
218+
]);
219+
220+
print_r($result->getItems());
221+
222+
````
223+
192224
### All usage examples
193225

194226
You will find more detailed documentation at [/doc](doc/index.md) and on

src/Api/Metrics.php

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* Copyright (C) 2013 Mailgun
7+
*
8+
* This software may be modified and distributed under the terms
9+
* of the MIT license. See the LICENSE file for details.
10+
*/
11+
12+
namespace Mailgun\Api;
13+
14+
use Exception;
15+
use Mailgun\Assert;
16+
use Mailgun\Model\Metrics\MetricsResponse;
17+
use Psr\Http\Client\ClientExceptionInterface;
18+
19+
/**
20+
* @see https://documentation.mailgun.com/docs/mailgun/api-reference/openapi-final/tag/Metrics/
21+
*/
22+
class Metrics extends HttpApi
23+
{
24+
/**
25+
* Query metrics for the total account.
26+
*
27+
* @param array $payload
28+
* @param array $requestHeaders
29+
* @return MetricsResponse
30+
* @throws ClientExceptionInterface
31+
* @throws Exception
32+
*/
33+
public function loadMetrics(array $payload = [], array $requestHeaders = []): MetricsResponse
34+
{
35+
// Validating required params
36+
if (!isset($payload['start']) || !isset($payload['end'])) {
37+
throw new Exception("The 'start' and 'end' parameters are required.");
38+
}
39+
40+
// Ensure start and end date are in RFC 2822 format
41+
Assert::string($payload['start'], "Start date must be in RFC 2822 format");
42+
Assert::stringNotEmpty($payload['end'], "End date must be in RFC 2822 format");
43+
44+
// Ensure resolution is valid (day, hour, month)
45+
if (!empty($payload['resolution'])) {
46+
Assert::oneOf($payload['resolution'], ['day', 'hour', 'month'], 'Invalid resolution format');
47+
}
48+
49+
// Check if filters are properly set up
50+
if (!empty($payload['filter']['AND'])) {
51+
foreach ($payload['filter']['AND'] as $filter) {
52+
Assert::stringNotEmpty($filter['attribute'], "Filter attribute must be specified");
53+
Assert::stringNotEmpty($filter['comparator'], "Comparator must be specified");
54+
Assert::isArray($filter['values'], "Filter values must be an array");
55+
}
56+
}
57+
58+
// Validate dimensions (must be an array and contain only valid values)
59+
if (isset($payload['dimensions'])) {
60+
Assert::isArray($payload['dimensions'], 'Dimensions must be an array');
61+
$validDimensions = ['time', 'domain', 'ip', 'ip_pool', 'recipient_domain', 'tag', 'country', 'subaccount'];
62+
foreach ($payload['dimensions'] as $dimension) {
63+
Assert::oneOf($dimension, $validDimensions, "Invalid dimension: $dimension");
64+
}
65+
}
66+
67+
$response = $this->httpPost('/v1/analytics/metrics', $payload, $requestHeaders);
68+
69+
return $this->hydrateResponse($response, MetricsResponse::class);
70+
}
71+
}

src/Mailgun.php

+9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Mailgun\Api\Mailboxes;
2323
use Mailgun\Api\MailingList;
2424
use Mailgun\Api\Message;
25+
use Mailgun\Api\Metrics;
2526
use Mailgun\Api\Route;
2627
use Mailgun\Api\Stats;
2728
use Mailgun\Api\SubAccounts;
@@ -254,4 +255,12 @@ public function templates(): Templates
254255
{
255256
return new Templates($this->httpClient, $this->requestBuilder, $this->hydrator);
256257
}
258+
259+
/**
260+
* @return Metrics
261+
*/
262+
public function metrics(): Metrics
263+
{
264+
return new Metrics($this->httpClient, $this->requestBuilder, $this->hydrator);
265+
}
257266
}

src/Model/Metrics/MetricsResponse.php

+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* Copyright (C) 2013 Mailgun
7+
*
8+
* This software may be modified and distributed under the terms
9+
* of the MIT license. See the LICENSE file for details.
10+
*/
11+
12+
namespace Mailgun\Model\Metrics;
13+
14+
use Mailgun\Model\ApiResponse;
15+
16+
final class MetricsResponse implements ApiResponse
17+
{
18+
private string $start;
19+
private string $end;
20+
private string $resolution;
21+
private array $dimensions;
22+
private array $pagination;
23+
private array $items;
24+
private array $aggregates;
25+
26+
27+
private function __construct()
28+
{
29+
}
30+
31+
/**
32+
* @param array $data
33+
* @return self
34+
* @throws \Exception
35+
*/
36+
public static function create(array $data): MetricsResponse
37+
{
38+
$model = new MetricsResponse();
39+
$model->setDimensions($data['dimensions'] ?? []);
40+
$model->setStart($data['start']);
41+
$model->setEnd($data['end']);
42+
$model->setAggregates($data['aggregates'] ?? []);
43+
$model->setItems($data['items'] ?? []);
44+
$model->setPagination($data['pagination'] ?? []);
45+
$model->setResolution($data['resolution']);
46+
47+
return $model;
48+
}
49+
50+
/**
51+
* @return string
52+
*/
53+
public function getStart(): string
54+
{
55+
return $this->start;
56+
}
57+
58+
/**
59+
* @param string $start
60+
*/
61+
public function setStart(string $start): void
62+
{
63+
$this->start = $start;
64+
}
65+
66+
/**
67+
* @return string
68+
*/
69+
public function getEnd(): string
70+
{
71+
return $this->end;
72+
}
73+
74+
/**
75+
* @param string $end
76+
*/
77+
public function setEnd(string $end): void
78+
{
79+
$this->end = $end;
80+
}
81+
82+
/**
83+
* @return string
84+
*/
85+
public function getResolution(): string
86+
{
87+
return $this->resolution;
88+
}
89+
90+
/**
91+
* @param string $resolution
92+
*/
93+
public function setResolution(string $resolution): void
94+
{
95+
$this->resolution = $resolution;
96+
}
97+
98+
/**
99+
* @return array
100+
*/
101+
public function getDimensions(): array
102+
{
103+
return $this->dimensions;
104+
}
105+
106+
/**
107+
* @param array $dimensions
108+
*/
109+
public function setDimensions(array $dimensions): void
110+
{
111+
$this->dimensions = $dimensions;
112+
}
113+
114+
/**
115+
* @return array
116+
*/
117+
public function getPagination(): array
118+
{
119+
return $this->pagination;
120+
}
121+
122+
/**
123+
* @param array $pagination
124+
*/
125+
public function setPagination(array $pagination): void
126+
{
127+
$this->pagination = $pagination;
128+
}
129+
130+
/**
131+
* @return array
132+
*/
133+
public function getItems(): array
134+
{
135+
return $this->items;
136+
}
137+
138+
/**
139+
* @param array $items
140+
*/
141+
public function setItems(array $items): void
142+
{
143+
$this->items = $items;
144+
}
145+
146+
/**
147+
* @return array
148+
*/
149+
public function getAggregates(): array
150+
{
151+
return $this->aggregates;
152+
}
153+
154+
/**
155+
* @param array $aggregates
156+
*/
157+
public function setAggregates(array $aggregates): void
158+
{
159+
$this->aggregates = $aggregates;
160+
}
161+
}

0 commit comments

Comments
 (0)