A

Moloco reporting ads api

public
andrei.k Feb 12, 2024 Never 19
Clone
PHP MolocoAdClient.php 160 lines (124 loc) | 5.22 KB
1
<?php
2
3
namespace App\Components\Moloco;
4
5
use App\DTO\RangDateDTO;
6
use App\Entity\MolocoAccount;
7
use Doctrine\ORM\EntityManagerInterface;
8
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
9
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
10
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
11
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
12
use Symfony\Contracts\HttpClient\HttpClientInterface;
13
14
class MolocoAdClient
15
{
16
private HttpClientInterface $httpClient;
17
18
private EntityManagerInterface $em;
19
20
private $accessToken;
21
22
private int $tries = 5;
23
24
public const ENDPOINT = 'https://api.moloco.cloud';
25
26
private const DATE_FORMAT = 'Y-m-d';
27
public const FORMAT = 'json';
28
29
public const STATUS_ACCEPTED = 'ACCEPTED';
30
public const STATUS_READY = 'READY';
31
32
public function __construct(HttpClientInterface $httpClient, EntityManagerInterface $em)
33
{
34
$this->httpClient = $httpClient;
35
$this->em = $em;
36
}
37
38
public function getAccessToken(AuthRequest $request)
39
{
40
if ($this->accessToken) {
41
return $this->accessToken;
42
}
43
44
$account = $request->getAccount();
45
46
if ($account->getTokenUpdate()
47
&& $account->getTokenUpdate()->add(\DateInterval::createFromDateString('+1 hour'))->getTimestamp() > time()
48
) {
49
return $this->accessToken = $account->getToken();
50
}
51
52
$response = $this->httpClient->request(
53
$request->getMethod(),
54
$request->getRoute(),
55
[
56
'json' => $request->getParams(),
57
'headers' => ['Accept' => 'application/json'],
58
]
59
);
60
61
if (200 === $response->getStatusCode()) {
62
$content = $response->toArray();
63
64
$token = $content['token'];
65
66
$account->setToken($token);
67
$account->setTokenUpdate(new \DateTime());
68
69
$this->em->persist($account);
70
$this->em->flush();
71
72
return $this->accessToken = $account->getToken();
73
}
74
75
throw new \RuntimeException('Moloco: get access token fail');
76
}
77
78
public function getData(MolocoAccount $account, string $statusURI)
79
{
80
$accessToken = $this->getAccessToken(new AuthRequest($account));
81
82
$response = $this->httpClient->request(
83
'GET',
84
$statusURI,
85
[
86
'headers' => [
87
'Accept' => 'application/json',
88
'Authorization' => 'Bearer ' . $accessToken,
89
],
90
]
91
);
92
93
if (200 === $response->getStatusCode()) {
94
$content = $response->toArray();
95
96
if ($content['status'] === self::STATUS_READY) {
97
return $this->httpClient->request('GET', $content['location_json'])->toArray();
98
}
99
100
if (!$this->tries) {
101
throw new \Exception('Moloco: report not ready');
102
}
103
104
$this->tries--;
105
106
sleep(20);
107
108
return $this->getData($account, $statusURI);
109
}
110
111
throw new \RuntimeException('Moloco: get data fail. Code: ' . $response->getStatusCode());
112
}
113
114
public function makeReport(MolocoAccount $account, RangDateDTO $rangDateDTO): string
115
{
116
try {
117
$accessToken = $this->getAccessToken(new AuthRequest($account));
118
119
$response = $this->httpClient->request(
120
'POST',
121
self::ENDPOINT . '/cm/v1/reports',
122
[
123
'json' => [
124
'ad_account_id' => $account->getAdAccountId(),
125
'date_range' => [
126
'start' => $rangDateDTO->getSince()->format(self::DATE_FORMAT),
127
'end' => $rangDateDTO->getSince()->format(self::DATE_FORMAT),
128
],
129
'dimensions' => ['APP_OR_SITE', 'CAMPAIGN']
130
],
131
'headers' => [
132
'Accept' => 'application/json',
133
'Authorization' => 'Bearer ' . $accessToken,
134
],
135
]
136
);
137
138
if (202 === $response->getStatusCode()) {
139
$content = $response->toArray();
140
141
return $content['status'];
142
}
143
} catch (\Exception | ClientExceptionInterface | RedirectionExceptionInterface | ServerExceptionInterface | TransportExceptionInterface $e) {
144
throw new \RuntimeException($e->getMessage());
145
}
146
147
throw new \RuntimeException('Response status: ' . $response->getStatusCode());
148
}
149
150
public function getExpenses(MolocoAccount $account, RangDateDTO $rangDateDTO)
151
{
152
try {
153
$reportURI = $this->makeReport($account, $rangDateDTO);
154
155
return $this->getData($account, $reportURI);
156
} catch (\Exception | ClientExceptionInterface | RedirectionExceptionInterface | ServerExceptionInterface | TransportExceptionInterface $e) {
157
throw new \RuntimeException($e->getMessage());
158
}
159
}
160
}