Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new API endpoint for getting metrics #923

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

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

## 4.3.2
- Added new API endpoint for getting metrics @see https://documentation.mailgun.com/docs/mailgun/api-reference/openapi-final/tag/Metrics/

## 4.3.1
- Add method for retrieving stored messages by @oleksandr-mykhailenko in #920
- Add missed params to the create method for DomainV4.php by @oleksandr-mykhailenko in #921

## 4.3.0
- End of support php 7.3
- Updated properties and added types to the classes properties
Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,38 @@ $configurator->setApiKey('key-example');
$configurator->setSubAccountId($subAccountId)
```

### Load data from the Analytics API

```php
<?php
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';

use Mailgun\Mailgun;

# Instantiate the client.
$mgClient = Mailgun::create('xxx');
$domain = "xxx.mailgun.org";

$result = $mgClient->metrics()->loadMetrics([
'start' => 'Wed, 11 Sep 2024 18:29:02 +0300',
'end' => 'Wed, 25 Sep 2024 18:29:02 +0300',
'metrics' => [
"failed_count", "opened_count", "sent_count", "delivered_count"
],
'resolution' => 'month',
'precision' => 'day',
'dimensions' => [
'time',
],
'include_aggregates' => true,
'include_subaccounts' => true,
]);

print_r($result->getItems());

````

### All usage examples

You will find more detailed documentation at [/doc](doc/index.md) and on
Expand Down
71 changes: 71 additions & 0 deletions src/Api/Metrics.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/

namespace Mailgun\Api;

use Exception;
use Mailgun\Assert;
use Mailgun\Model\Metrics\MetricsResponse;
use Psr\Http\Client\ClientExceptionInterface;

/**
* @see https://documentation.mailgun.com/docs/mailgun/api-reference/openapi-final/tag/Metrics/
*/
class Metrics extends HttpApi
{
/**
* Query metrics for the total account.
*
* @param array $payload
* @param array $requestHeaders
* @return MetricsResponse
* @throws ClientExceptionInterface
* @throws Exception
*/
public function loadMetrics(array $payload = [], array $requestHeaders = []): MetricsResponse
{
// Validating required params
if (!isset($payload['start']) || !isset($payload['end'])) {
throw new Exception("The 'start' and 'end' parameters are required.");
}

// Ensure start and end date are in RFC 2822 format
Assert::string($payload['start'], "Start date must be in RFC 2822 format");
Assert::stringNotEmpty($payload['end'], "End date must be in RFC 2822 format");

// Ensure resolution is valid (day, hour, month)
if (!empty($payload['resolution'])) {
Assert::oneOf($payload['resolution'], ['day', 'hour', 'month'], 'Invalid resolution format');
}

// Check if filters are properly set up
if (!empty($payload['filter']['AND'])) {
foreach ($payload['filter']['AND'] as $filter) {
Assert::stringNotEmpty($filter['attribute'], "Filter attribute must be specified");
Assert::stringNotEmpty($filter['comparator'], "Comparator must be specified");
Assert::isArray($filter['values'], "Filter values must be an array");
}
}

// Validate dimensions (must be an array and contain only valid values)
if (isset($payload['dimensions'])) {
Assert::isArray($payload['dimensions'], 'Dimensions must be an array');
$validDimensions = ['time', 'domain', 'ip', 'ip_pool', 'recipient_domain', 'tag', 'country', 'subaccount'];
foreach ($payload['dimensions'] as $dimension) {
Assert::oneOf($dimension, $validDimensions, "Invalid dimension: $dimension");
}
}

$response = $this->httpPost('/v1/analytics/metrics', $payload, $requestHeaders);

return $this->hydrateResponse($response, MetricsResponse::class);
}
}
9 changes: 9 additions & 0 deletions src/Mailgun.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Mailgun\Api\Mailboxes;
use Mailgun\Api\MailingList;
use Mailgun\Api\Message;
use Mailgun\Api\Metrics;
use Mailgun\Api\Route;
use Mailgun\Api\Stats;
use Mailgun\Api\SubAccounts;
Expand Down Expand Up @@ -254,4 +255,12 @@ public function templates(): Templates
{
return new Templates($this->httpClient, $this->requestBuilder, $this->hydrator);
}

/**
* @return Metrics
*/
public function metrics(): Metrics
{
return new Metrics($this->httpClient, $this->requestBuilder, $this->hydrator);
}
}
161 changes: 161 additions & 0 deletions src/Model/Metrics/MetricsResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<?php

declare(strict_types=1);

/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/

namespace Mailgun\Model\Metrics;

use Mailgun\Model\ApiResponse;

final class MetricsResponse implements ApiResponse
{
private string $start;
private string $end;
private string $resolution;
private array $dimensions;
private array $pagination;
private array $items;
private array $aggregates;


private function __construct()
{
}

/**
* @param array $data
* @return self
* @throws \Exception
*/
public static function create(array $data): MetricsResponse
{
$model = new MetricsResponse();
$model->setDimensions($data['dimensions'] ?? []);
$model->setStart($data['start']);
$model->setEnd($data['end']);
$model->setAggregates($data['aggregates'] ?? []);
$model->setItems($data['items'] ?? []);
$model->setPagination($data['pagination'] ?? []);
$model->setResolution($data['resolution']);

return $model;
}

/**
* @return string
*/
public function getStart(): string
{
return $this->start;
}

/**
* @param string $start
*/
public function setStart(string $start): void
{
$this->start = $start;
}

/**
* @return string
*/
public function getEnd(): string
{
return $this->end;
}

/**
* @param string $end
*/
public function setEnd(string $end): void
{
$this->end = $end;
}

/**
* @return string
*/
public function getResolution(): string
{
return $this->resolution;
}

/**
* @param string $resolution
*/
public function setResolution(string $resolution): void
{
$this->resolution = $resolution;
}

/**
* @return array
*/
public function getDimensions(): array
{
return $this->dimensions;
}

/**
* @param array $dimensions
*/
public function setDimensions(array $dimensions): void
{
$this->dimensions = $dimensions;
}

/**
* @return array
*/
public function getPagination(): array
{
return $this->pagination;
}

/**
* @param array $pagination
*/
public function setPagination(array $pagination): void
{
$this->pagination = $pagination;
}

/**
* @return array
*/
public function getItems(): array
{
return $this->items;
}

/**
* @param array $items
*/
public function setItems(array $items): void
{
$this->items = $items;
}

/**
* @return array
*/
public function getAggregates(): array
{
return $this->aggregates;
}

/**
* @param array $aggregates
*/
public function setAggregates(array $aggregates): void
{
$this->aggregates = $aggregates;
}
}
Loading