Client.php
3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
namespace Lackoxygen\TiktokShop\Transmit;
use Lackoxygen\TiktokShop\Attribute\Config;
use Lackoxygen\TiktokShop\Attribute\Request;
use Lackoxygen\TiktokShop\Exception\ClientException;
use Lackoxygen\TiktokShop\Exception\RetryException;
use Lackoxygen\TiktokShop\Util\Json;
use Lackoxygen\TiktokShop\Util\Signature;
use Lackoxygen\TiktokShop\Util\Sort;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\RequestOptions;
use Illuminate\Support\Str;
class Client
{
public static function create(): Client
{
return new self;
}
/**
* @param string $service
*
* @return string
*/
protected function serviceToPath(string $service): string
{
return '/' . ltrim(Str::replace('.', '/', $service), '/');
}
/**
* @param Request $request
*
* @return false|string
*/
protected function signature(Request $request): ?string
{
$sig = new Signature;
$sig->setTimestamp($request->getTimestamp());
$sig->setMethod($request->getService());
$sig->setAppKey($request->getConfig()->getAppKey());
$sig->setAppSecret($request->getConfig()->getAppSecret());
$sig->setVersion($request->getV());
$params = $request->getParams();
Sort::ksort($params);
$sig->setParamJson(Json::marshal($params));
return $sig->generate();
}
/**
* @param Request $request
*
* @return array
*/
protected function withSignatureQuery(Request $request): array
{
$params = $request->getParams();
Sort::ksort($params);
return [
'method' => $request->getService(), 'app_key' => $request->getConfig()->getAppKey(),
'access_token' => $request->getConfig()->getAccessToken(), 'param_json' => Json::marshal($params),
'timestamp' => $request->getTimestamp(), 'v' => $request->getV(), 'sign' => $this->signature($request),
'sign_method' => 'hmac-sha256',
];
}
protected function withQuery(Request $request): array
{
return [
'app_id' => $request->getConfig()->getAppKey(), 'app_secret' => $request->getConfig()->getAppSecret(),
];
}
public function guzzleHttp(Config $config): \GuzzleHttp\Client
{
return new \GuzzleHttp\Client([
'base_uri' => $config->getBaseUri(), 'timeout' => $config->getTimeout(), 'verify' => false
]);
}
/**
* @param Request $request
*
* @return \Psr\Http\Message\ResponseInterface
* @throws ClientException
* @throws RetryException
*/
public function request(Request $request): \Psr\Http\Message\ResponseInterface
{
if ($request->isSignature()) {
$query = $this->withSignatureQuery($request);
} else {
$query = $this->withQuery($request);
}
$options = [
RequestOptions::HEADERS => [
'Content-type' => 'application/json'
]
];
$options[RequestOptions::QUERY] = $query;
$options[RequestOptions::JSON] = $request->getParams();
$retry = new Retry(function () use ($request, $options) {
return $this->guzzleHttp($request->getConfig())
->request($request->getMethod(), $request->getPath() ?: $this->serviceToPath($request->getService()),
$options);
}, function ($e) {
return $e instanceof ConnectException;
});
return $retry();
}
}