mirror of
https://gh.wpcy.net/https://github.com/hayBIT/freescout2ant.git
synced 2026-05-25 20:34:06 +08:00
277 lines
10 KiB
PHP
277 lines
10 KiB
PHP
<?php
|
|
|
|
namespace Modules\AmeiseModule\Services;
|
|
|
|
use GuzzleHttp\Client;
|
|
use GuzzleHttp\Exception\RequestException as Exception;
|
|
|
|
class CrmApiClient
|
|
{
|
|
private $base_url;
|
|
private $tokenService;
|
|
private $ameiseLogStatus;
|
|
private $client;
|
|
|
|
public function __construct(TokenService $tokenService)
|
|
{
|
|
$this->tokenService = $tokenService;
|
|
$this->base_url = (config('ameisemodule.ameise_mode') == 'test' ? 'https://mitarbeiterwebservice-maklerinfo.inte.dionera.dev/service/bd/employee/1.0/rest/' : 'https://mitarbeiterwebservice.maklerinfo.biz/service/bd/employee/1.0/rest/');
|
|
$this->ameiseLogStatus = config('ameisemodule.ameise_log_status');
|
|
$this->client = new Client();
|
|
}
|
|
|
|
private function getAccessToken()
|
|
{
|
|
return $this->tokenService->getAccessToken();
|
|
}
|
|
|
|
private function checkTokenError()
|
|
{
|
|
$result = $this->getAccessToken();
|
|
if ($result && ($resultArray = json_decode($result, true)) && isset($resultArray['error'])) {
|
|
return $resultArray;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private function apiGet($path, $logContext, array $options = [], $errorReturn = [], $useBaseOnly = false)
|
|
{
|
|
try {
|
|
$tokenError = $this->checkTokenError();
|
|
if ($tokenError) {
|
|
return $tokenError;
|
|
}
|
|
$url = $useBaseOnly ? $this->base_url . $path : $this->maUrl($path);
|
|
$this->ameiseLogStatus && \Helper::log($logContext, 'Sending GET request to: ' . $url);
|
|
$requestOptions = array_merge([
|
|
'headers' => [
|
|
'Authorization' => 'Bearer ' . $this->getAccessToken(),
|
|
],
|
|
], $options);
|
|
$response = $this->client->get($url, $requestOptions);
|
|
$this->ameiseLogStatus && \Helper::log($logContext, 'Response status: ' . $response->getStatusCode());
|
|
if ($response->getStatusCode() === 200) {
|
|
return json_decode($response->getBody(), true);
|
|
} elseif ($response->getStatusCode() === 401) {
|
|
$this->tokenService->disconnectAmeise();
|
|
} else {
|
|
$errorResponse = json_decode($response->getBody(), true);
|
|
$this->ameiseLogStatus && \Helper::log($logContext, 'Request failed with status code: ' . $response->getStatusCode());
|
|
$this->ameiseLogStatus && \Helper::log(
|
|
$logContext,
|
|
'Error response: ' . json_encode($this->sanitizeLogData($errorResponse))
|
|
);
|
|
}
|
|
$this->ameiseLogStatus && \Helper::log($logContext, 'Request completed.');
|
|
} catch (Exception $e) {
|
|
$this->ameiseLogStatus && \Helper::logException($e, $logContext);
|
|
if ($e->getCode() === 401) {
|
|
$this->tokenService->disconnectAmeise();
|
|
}
|
|
if ($e->hasResponse()) {
|
|
$body = (string) $e->getResponse()->getBody();
|
|
$this->ameiseLogStatus && \Helper::log($logContext, 'Error body: ' . $this->sanitizeLogText($body));
|
|
}
|
|
return $errorReturn;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
private function apiPost($path, $logContext, array $options = [], $errorReturn = [], $useBaseOnly = false)
|
|
{
|
|
try {
|
|
$tokenError = $this->checkTokenError();
|
|
if ($tokenError) {
|
|
return $tokenError;
|
|
}
|
|
$url = $useBaseOnly ? $this->base_url . $path : $this->maUrl($path);
|
|
$this->ameiseLogStatus && \Helper::log($logContext, 'Sending POST request to: ' . $url);
|
|
$requestOptions = array_merge([
|
|
'headers' => [
|
|
'Authorization' => 'Bearer ' . $this->getAccessToken(),
|
|
],
|
|
], $options);
|
|
$response = $this->client->post($url, $requestOptions);
|
|
$this->ameiseLogStatus && \Helper::log($logContext, 'Response status: ' . $response->getStatusCode());
|
|
if ($response->getStatusCode() === 200) {
|
|
return json_decode($response->getBody(), true);
|
|
} elseif ($response->getStatusCode() === 401) {
|
|
$this->tokenService->disconnectAmeise();
|
|
} else {
|
|
$errorResponse = json_decode($response->getBody(), true);
|
|
$this->ameiseLogStatus && \Helper::log($logContext, 'Request failed with status code: ' . $response->getStatusCode());
|
|
$this->ameiseLogStatus && \Helper::log(
|
|
$logContext,
|
|
'Error response: ' . json_encode($this->sanitizeLogData($errorResponse))
|
|
);
|
|
}
|
|
$this->ameiseLogStatus && \Helper::log($logContext, 'Request completed.');
|
|
} catch (Exception $e) {
|
|
$this->ameiseLogStatus && \Helper::logException($e, $logContext);
|
|
if ($e->getCode() === 401) {
|
|
$this->tokenService->disconnectAmeise();
|
|
}
|
|
if ($e->hasResponse()) {
|
|
$body = (string) $e->getResponse()->getBody();
|
|
$this->ameiseLogStatus && \Helper::log($logContext, 'Error body: ' . $this->sanitizeLogText($body));
|
|
}
|
|
return $errorReturn;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
private function maUrl($path)
|
|
{
|
|
return $this->base_url . $this->tokenService->getMa() . '/' . $path;
|
|
}
|
|
|
|
public function fetchUserByIdOrName($data)
|
|
{
|
|
$searchQuery = rawurlencode($data);
|
|
return $this->apiGet(
|
|
'kunden/_search?q=' . $searchQuery,
|
|
'fetch_user_id_name'
|
|
);
|
|
}
|
|
|
|
public function fetchUserDetail($id, $endPoints)
|
|
{
|
|
return $this->apiGet(
|
|
'kunden/' . $id . '/' . $endPoints,
|
|
'user_end_points'
|
|
);
|
|
}
|
|
|
|
public function fetchUserByEmail($email)
|
|
{
|
|
$response = $this->apiPost(
|
|
'kunden/_search',
|
|
'fetch_user_email',
|
|
['json' => ['mail' => $email]]
|
|
);
|
|
|
|
if (!empty($response)) {
|
|
return $response;
|
|
}
|
|
|
|
return $this->apiGet(
|
|
'kunden/_search',
|
|
'fetch_user_email_fallback',
|
|
['query' => ['mail' => $email]]
|
|
);
|
|
}
|
|
|
|
public function getContracts($customerId)
|
|
{
|
|
return $this->apiGet(
|
|
'kunden/' . $customerId . '/vertraege',
|
|
'get_contracts',
|
|
[],
|
|
['error' => 'redirect', 'url' => $this->tokenService->getAuthUrl()]
|
|
);
|
|
}
|
|
|
|
public function getContactEndPoints($end_points)
|
|
{
|
|
return $this->apiGet(
|
|
$end_points,
|
|
'contracts_end_points',
|
|
[],
|
|
[],
|
|
true
|
|
);
|
|
}
|
|
|
|
public function archiveConversation($data)
|
|
{
|
|
try {
|
|
$tokenError = $this->checkTokenError();
|
|
if ($tokenError) {
|
|
return $tokenError;
|
|
}
|
|
$this->ameiseLogStatus && \Helper::log('conversation_archive', 'Archive conversation request called.');
|
|
$headers = [
|
|
'X-Dio-Betreff' => $data['subject'],
|
|
'x-dio-metadaten' => json_encode($data['x-dio-metadaten']),
|
|
'X-Dio-Typ' => $data['type'],
|
|
'Content-Type' => $data['Content-Type'] ?? 'text/plain; charset="utf-8"',
|
|
'X-Dio-Zuordnungen' => json_encode($data['X-Dio-Zuordnungen']),
|
|
'X-Dio-Datum' => $data['X-Dio-Datum'],
|
|
'Authorization' => 'Bearer ' . $this->getAccessToken(),
|
|
];
|
|
$response = $this->client->request('POST', $this->maUrl('archiveintraege'), [
|
|
'headers' => $headers,
|
|
'body' => $data['body'],
|
|
]);
|
|
$this->ameiseLogStatus && \Helper::log('conversation_archive', 'Response status: ' . $response->getStatusCode());
|
|
if ($response->getStatusCode() === 200) {
|
|
return $response->getBody();
|
|
} elseif ($response->getStatusCode() === 401) {
|
|
$this->tokenService->disconnectAmeise();
|
|
} else {
|
|
$errorResponse = json_decode($response->getBody(), true);
|
|
$this->ameiseLogStatus && \Helper::log('conversation_archive', 'Request failed with status code: ' . $response->getStatusCode());
|
|
$this->ameiseLogStatus && \Helper::log(
|
|
'conversation_archive',
|
|
'Error response: ' . json_encode($this->sanitizeLogData($errorResponse))
|
|
);
|
|
}
|
|
} catch (Exception $e) {
|
|
$body = $e->hasResponse() ? (string) $e->getResponse()->getBody() : '';
|
|
$this->ameiseLogStatus && \Helper::log('conversation_archive', 'Error body: ' . $this->sanitizeLogText($body));
|
|
$this->ameiseLogStatus && \Helper::logException($e, 'conversation_archive');
|
|
if ($e->getCode() === 401) {
|
|
$this->tokenService->disconnectAmeise();
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private function sanitizeLogData($data)
|
|
{
|
|
if (is_array($data)) {
|
|
$sanitized = [];
|
|
foreach ($data as $key => $value) {
|
|
if (is_string($key) && $this->isSensitiveKey($key)) {
|
|
$sanitized[$key] = $this->valueFingerprint($value);
|
|
continue;
|
|
}
|
|
$sanitized[$key] = $this->sanitizeLogData($value);
|
|
}
|
|
return $sanitized;
|
|
}
|
|
|
|
if (is_object($data)) {
|
|
return $this->sanitizeLogData((array) $data);
|
|
}
|
|
|
|
if (is_string($data)) {
|
|
return $this->sanitizeLogText($data);
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
private function sanitizeLogText(string $text): string
|
|
{
|
|
$pattern = '/(Bearer\s+)([A-Za-z0-9\-\._~\+\/]+=*)/i';
|
|
return preg_replace_callback($pattern, function (array $matches) {
|
|
return $matches[1] . $this->valueFingerprint($matches[2]);
|
|
}, $text) ?? $text;
|
|
}
|
|
|
|
private function isSensitiveKey(string $key): bool
|
|
{
|
|
$normalized = strtolower($key);
|
|
return in_array($normalized, ['access_token', 'refresh_token', 'id_token', 'authorization', 'token'], true);
|
|
}
|
|
|
|
private function valueFingerprint($value): string
|
|
{
|
|
if (!is_string($value) || $value === '') {
|
|
return '[redacted]';
|
|
}
|
|
|
|
return '[fingerprint:sha256:' . substr(hash('sha256', $value), 0, 12) . ']';
|
|
}
|
|
}
|