Skip to content

Commit

Permalink
Merge pull request #432 from mailgun/add-metrics-enpoint
Browse files Browse the repository at this point in the history
Add support for metrics
  • Loading branch information
olexandr-mazepa authored Dec 30, 2024
2 parents 28351e1 + a724689 commit 5c5802a
Show file tree
Hide file tree
Showing 19 changed files with 29,992 additions and 8 deletions.
146 changes: 144 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,12 @@ The following service methods are available to instantiated clients. The example
- [get](#get-1)
- [Example with Date and *Filter field*](#example-with-date-and-filter-field)
- [stats](#stats)
- [Stats Options](#stats-options)
- [getDomain](#getdomain)
- [getAccount](#getaccount)
- [Metrics](#metrics)
- [getAccount](#getaccount-1)
- [getAccountUsage](#getaccountusage)
- [suppressions](#suppressions)
- [list](#list-1)
- [Bounces Example](#bounces-example)
Expand Down Expand Up @@ -1023,7 +1027,7 @@ The following service methods are available to instantiated clients. The example
```

### Stats
- Stats Options
- #### Stats Options

| Parameter | Description |
|:-----------|:---------------------------------------------------------------------------------------------------------------------------|
Expand Down Expand Up @@ -1110,6 +1114,145 @@ The following service methods are available to instantiated clients. The example
}
```


```
### Metrics
Mailgun collects many different events and generates event metrics which are available in your Control Panel. This data is also available via our analytics metrics [API endpoint](https://documentation.mailgun.com/docs/mailgun/api-reference/openapi-final/tag/Metrics/#tag/Metrics).
- #### getAccount
Gets filtered metrics for an account
`mg.metrics.getAccount(MetricsQuery);`
Example:
```JS
mg.metrics.getAccount({
start: '2024-12-16T10:47:51.661Z',
end: '2024-12-23T10:47:51.661Z',
resolution: 'hour',
metrics: ['opened_count'],
filter: {
AND: [{
attribute: 'domain',
comparator: 'contains',
values: [{
value: 'mailgun'
}]
}]
},
include_subaccounts: true,
include_aggregates: true
})
.then(data => console.log(data)) // logs response data
.catch(err => console.error(err)); //logs any error
```
*getAccount* method accepts data object with next properties:
| Property | Type |Description |
|:--------------|:-----|:-----------------------------------------------------------------------------------------------------------------------------------|
| start | String that contains date in RFC 2822 format: https://datatracker.ietf.org/doc/html/rfc2822.html#page-14 or JS Date object | A start date (default: 7 days before current time)|
| end | String that contains date in RFC 2822 format: https://datatracker.ietf.org/doc/html/rfc2822.html#page-14 or JS Date object | An end date (default: current time)|
| resolution | String | A resolution in the format of 'day' 'hour' 'month'. Default is day.|
| duration | String | A duration in the format of '1d' '2h' '2m'. If duration is provided then it is calculated from the end date and overwrites the start date.|
| dimensions | Array of strings | Attributes of the metric data such as 'subaccount'.|
| metrics | Array of strings | Name of the metrics to receive the stats for such as 'processed_count'.|
| filter | object | Filters to apply to the query. The 'AND' property is required and should contains array of filters objects. See this [document](https://documentation.mailgun.com/docs/mailgun/api-reference/openapi-final/tag/Metrics/#tag/Metrics/operation/api.(*MetricsAPI).PostMetricQuery-fm-3!path=filter&t=request) for an object shape. |
| include_subaccounts | Boolean | Include stats from all subaccounts. |
| include_aggregates | Boolean | Include top-level aggregate metrics.|
Promise returns: MetricsResult
```JS
{
start: new Date('2024-12-16T01:00:00.000Z'),
end: new Date('2024-12-23T00:00:00.000Z'),
resolution: 'hour',
dimensions: [ 'time' ],
pagination: { sort: '', skip: 0, limit: 1500, total: 1 },
items: [
{
dimensions: [{
{
dimension: 'time',
value: 'Sat, 21 Dec 2024 17:00:00 +0000',
display_value: 'Sat, 21 Dec 2024 17:00:00 +0000'
}
}],
metrics: { opened_count: 1 }
},
...
],
aggregates: { metrics: { opened_count: 1 } },
status: 200
}
```
- #### getAccountUsage
Gets filtered **usage metrics** for an account
`mg.metrics.getAccountUsage(MetricsQuery);`
Example:
```JS
mg.metrics.getAccountUsage({
start: '2024-12-16T10:47:51.661Z',
end: '2024-12-23T10:47:51.661Z',
resolution: 'hour',
metrics: ['opened_count'],
filter: {
AND: [{
attribute: 'domain',
comparator: 'contains',
values: [{
value: 'mailgun'
}]
}]
},
include_subaccounts: true,
include_aggregates: true
})
.then(data => console.log(data)) // logs response data
.catch(err => console.error(err)); //logs any error
```
*getAccountUsage* method accepts data object with next properties:
| Property | Type |Description |
|:--------------|:-----|:-----------------------------------------------------------------------------------------------------------------------------------|
| start | String that contains date in RFC 2822 format: https://datatracker.ietf.org/doc/html/rfc2822.html#page-14 or JS Date object | A start date (default: 7 days before current time)|
| end | String that contains date in RFC 2822 format: https://datatracker.ietf.org/doc/html/rfc2822.html#page-14 or JS Date object | An end date (default: current time)|
| resolution | String | A resolution in the format of 'day' 'hour' 'month'. Default is day.|
| duration | String | A duration in the format of '1d' '2h' '2m'. If duration is provided then it is calculated from the end date and overwrites the start date.|
| dimensions | Array of strings | Attributes of the metric data such as 'subaccount'.|
| metrics | Array of strings | Name of the metrics to receive the stats for such as 'processed_count'.|
| filter | object | Filters to apply to the query. The 'AND' property is required and should contains array of filters objects. See this [document](https://documentation.mailgun.com/docs/mailgun/api-reference/openapi-final/tag/Metrics/#tag/Metrics/operation/api.(*MetricsAPI).PostMetricQuery-fm-3!path=filter&t=request) for an object shape. |
| include_subaccounts | Boolean | Include stats from all subaccounts. |
| include_aggregates | Boolean | Include top-level aggregate metrics.|
Promise returns: MetricsResult
```JS
{
start: new Date('2024-12-16T01:00:00.000Z'),
end: new Date('2024-12-23T00:00:00.000Z'),
resolution: 'hour',
dimensions: [ 'time' ],
pagination: { sort: '', skip: 0, limit: 1500, total: 1 },
items: [
{
dimensions: [{
{
dimension: 'time',
value: 'Sat, 21 Dec 2024 17:00:00 +0000',
display_value: 'Sat, 21 Dec 2024 17:00:00 +0000'
}
}],
metrics: { opened_count: 1 }
},
...
],
aggregates: { metrics: { opened_count: 1 } },
status: 200
}
```
### Suppressions
- #### list
Expand Down Expand Up @@ -3165,7 +3308,6 @@ A client to manage members within a specific mailing list.
results: 'link to result page',
}
}
```

## Navigation thru lists
Most of the methods that return items in a list support pagination.
Expand Down
2 changes: 2 additions & 0 deletions dist/Classes/MailgunClient.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { MailgunClientOptions, InputFormData } from '../Types';
import { IDomainsClient, IWebHooksClient, IMailgunClient, IMailingListsClient, IEventClient, IStatsClient, ISuppressionClient, IMessagesClient, IRoutesClient, IValidationClient, IIPsClient, IIPPoolsClient, ISubaccountsClient, IInboxPlacementsClient } from '../Interfaces';
import { IMetricsClient } from '../Interfaces/Metrics/MetricsClient';
export default class MailgunClient implements IMailgunClient {
private request;
domains: IDomainsClient;
webhooks: IWebHooksClient;
events: IEventClient;
stats: IStatsClient;
metrics: IMetricsClient;
suppressions: ISuppressionClient;
messages: IMessagesClient;
routes: IRoutesClient;
Expand Down
14 changes: 14 additions & 0 deletions dist/Classes/Metrics/MetricsClient.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Request from '../common/Request';
import { ILogger } from '../../Interfaces/Common';
import { IMetricsClient } from '../../Interfaces/Metrics/MetricsClient';
import { MetricsQuery, MetricsResult } from '../../Types/Metrics';
export default class MetricsClient implements IMetricsClient {
request: Request;
private logger;
constructor(request: Request, logger?: ILogger);
private convertDateToUTC;
private prepareQuery;
private handleResponse;
getAccount(query?: MetricsQuery): Promise<MetricsResult>;
getAccountUsage(query?: MetricsQuery): Promise<MetricsResult>;
}
2 changes: 2 additions & 0 deletions dist/Interfaces/MailgunClient/IMailgunClient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import { IIPPoolsClient } from '../IPPools';
import { IMailingListsClient } from '../MailingLists';
import { ISubaccountsClient } from '../Subaccounts';
import { IInboxPlacementsClient } from '../InboxPlacements';
import { IMetricsClient } from '../Metrics/MetricsClient';
export interface IMailgunClient {
domains: IDomainsClient;
webhooks: IWebHooksClient;
events: IEventClient;
stats: IStatsClient;
metrics: IMetricsClient;
suppressions: ISuppressionClient;
messages: IMessagesClient;
routes: IRoutesClient;
Expand Down
5 changes: 5 additions & 0 deletions dist/Interfaces/Metrics/MetricsClient.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { MetricsQuery, MetricsResult } from '../../Types/Metrics';
export interface IMetricsClient {
getAccount(query?: MetricsQuery): Promise<MetricsResult>;
getAccountUsage(query?: MetricsQuery): Promise<MetricsResult>;
}
100 changes: 100 additions & 0 deletions dist/Types/Metrics/Metrics.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { Resolution } from '../../Enums';
export type MetricsFilterValue = {
label?: string;
value: string;
};
export type MetricsFilter = {
attribute: string;
comparator: string;
values: MetricsFilterValue[];
};
export type MetricsQuery = {
start?: Date | string;
end?: Date | string;
resolution?: Resolution;
duration?: string;
dimensions?: string[];
metrics?: string[];
filter?: {
AND: MetricsFilter[];
};
include_subaccounts?: boolean;
include_aggregates?: boolean;
};
export type Metrics = {
accepted_outgoing_count?: number;
delivered_smtp_count?: number;
accepted_count?: number;
delivered_http_count?: number;
accepted_incoming_count?: number;
delivered_optimized_count?: number;
stored_count?: number;
delivered_count?: number;
processed_count?: number;
sent_count?: number;
opened_count?: number;
unique_opened_count?: number;
clicked_count?: number;
unique_clicked_count?: number;
complained_count?: number;
permanent_failed_count?: number;
failed_count?: number;
rate_limit_count?: number;
unsubscribed_count?: number;
temporary_failed_count?: number;
permanent_failed_optimized_count?: number;
bounced_count?: number;
esp_block_count?: number;
webhook_count?: number;
delayed_bounce_count?: number;
soft_bounces_count?: number;
permanent_failed_old_count?: number;
suppressed_bounces_count?: number;
delivered_subsequent_count?: number;
delivered_rate?: string;
delayed_first_attempt_count?: number;
unsubscribed_rate?: string;
delivered_first_attempt_count?: number;
opened_rate?: string;
suppressed_complaints_count?: number;
delivered_two_plus_attempts_count?: number;
hard_bounces_count?: number;
suppressed_unsubscribed_count?: number;
unique_opened_rate?: string;
fail_rate?: string;
complained_rate?: string;
clicked_rate?: string;
unique_clicked_rate?: string;
bounce_rate?: string;
delayed_rate?: string;
permanent_fail_rate?: string;
temporary_fail_rate?: string;
};
export type MetricsPagination = {
sort: string;
skip: number;
limit: number;
total: number;
};
export type MetricsDimension = {
dimension: string;
value: string;
display_value: string;
};
export type MetricsResponseItem = {
dimensions: MetricsDimension[];
metrics: Metrics;
};
export type MetricsResult = {
items: MetricsResponseItem[];
resolution: string;
start: Date | null;
aggregates: {
metrics: Metrics;
};
dimensions: string[];
pagination: MetricsPagination;
end: Date | null;
duration?: string;
status: number;
};
20 changes: 20 additions & 0 deletions dist/Types/Metrics/MetricsAPI.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Metrics, MetricsPagination, MetricsQuery, MetricsResponseItem } from './Metrics';
export type MetricsAPIQuery = Omit<MetricsQuery, 'start' | 'end'> & {
start?: string;
end?: string;
};
export type MetricsAPIResponse = {
status: number;
body: {
items: MetricsResponseItem[];
resolution: string;
start: string;
aggregates: {
metrics: Metrics;
};
dimensions: string[];
pagination: MetricsPagination;
end: string;
duration?: string;
};
};
2 changes: 2 additions & 0 deletions dist/Types/Metrics/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './Metrics';
export * from './MetricsAPI';
17,030 changes: 17,027 additions & 3 deletions dist/mailgun.node.js

Large diffs are not rendered by default.

12,286 changes: 12,283 additions & 3 deletions dist/mailgun.web.js

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions lib/Classes/MailgunClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ import InboxPlacementsAttributesClient from './InboxPlacements/AttributesClient'
import InboxPlacementsFiltersClient from './InboxPlacements/FiltersClient';
import IPRSharingClient from './InboxPlacements/Results/InboxPlacementsResultsSharingClient';
import InboxPlacementsProvidersClient from './InboxPlacements/providers/InboxPlacementsProviders';
import MetricsClient from './Metrics/MetricsClient';
import { IMetricsClient } from '../Interfaces/Metrics/MetricsClient';

export default class MailgunClient implements IMailgunClient {
private request;
Expand All @@ -51,6 +53,7 @@ export default class MailgunClient implements IMailgunClient {
public webhooks: IWebHooksClient;
public events: IEventClient;
public stats: IStatsClient;
public metrics: IMetricsClient;
public suppressions: ISuppressionClient;
public messages: IMessagesClient;
public routes: IRoutesClient;
Expand Down Expand Up @@ -117,6 +120,7 @@ export default class MailgunClient implements IMailgunClient {
this.webhooks = new WebhooksClient(this.request);
this.events = new EventClient(this.request);
this.stats = new StatsClient(this.request);
this.metrics = new MetricsClient(this.request);
this.suppressions = new SuppressionClient(this.request);
this.messages = new MessagesClient(this.request);
this.routes = new RoutesClient(this.request);
Expand Down
Loading

0 comments on commit 5c5802a

Please sign in to comment.