Files
Mainframe-API/src/Service/DiscordApiService.php

184 lines
8.1 KiB
PHP

<?php
namespace App\Service;
use DateTime;
use DateInterval;
use App\Entity\User;
use App\Exception\DiscordApiException;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class DiscordApiService
{
private $client;
private $clientId;
private $clientSecret;
private $clientToken;
private $redirectUri;
private $baseUrl;
public function __construct(HttpClientInterface $client)
{
$this->client = $client;
$this->clientId = $_ENV['DISCORD_CLIENT_ID'];
$this->clientSecret = $_ENV['DISCORD_CLIENT_SECRET'];
$this->clientToken = $_ENV['DISCORD_CLIENT_TOKEN'];
$this->redirectUri = $_ENV['DISCORD_BACKEND_REDIRECT_URI'];
$this->baseUrl = $_ENV['DISCORD_API_BASE_URL'];
}
public function exchangeCodeForToken(string $code): array
{
try {
$response = $this->client->request('POST', $this->baseUrl . '/oauth2/token', [
'body' => [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => $this->redirectUri,
],
]);
return $response->toArray();
} catch (ClientExceptionInterface | ServerExceptionInterface | RedirectionExceptionInterface | TransportExceptionInterface $e) {
throw new DiscordApiException($e->getCode(), 'Erreur lors de la requête à l\'API Discord: ' . $e->getMessage(), $e);
}
}
public function refreshToken(string $refreshToken): array
{
try {
$response = $this->client->request('POST', $this->baseUrl . '/oauth2/token', [
'body' => [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
'redirect_uri' => $this->redirectUri,
],
]);
return $response->toArray();
} catch (ClientExceptionInterface | ServerExceptionInterface | RedirectionExceptionInterface | TransportExceptionInterface $e) {
throw new DiscordApiException($e->getCode(), 'Erreur lors de la requête à l\'API Discord: ' . $e->getMessage(), $e);
}
}
public function getUserToken(SessionInterface $session, EntityManagerInterface $entityManager): ?User
{
// Vérifier si une session est en cours
if (!$session->has('user_id')) throw new DiscordApiException(Response::HTTP_UNAUTHORIZED, 'Non authentifié');
$user = $entityManager->getRepository(User::class)->find($session->get('user_id'));
if (!$user) throw new DiscordApiException(Response::HTTP_NOT_FOUND, 'Utilisateur non trouvé');
// Vérifier si l'utilisateur a un token d'accès et qu'il n'est pas expiré
if (!$user->getAccessToken() || $user->getTokenExpiresAt() < new DateTime()) {
if ($user->getRefreshToken()) {
// Rafraîchir le token d'accès
$tokenData = $this->refreshToken($user->getRefreshToken());
$user->setAccessToken($tokenData['access_token']);
$user->setRefreshToken($tokenData['refresh_token']);
$user->setTokenExpiresAt((new DateTime())->add(new DateInterval('PT' . $tokenData['expires_in'] . 'S')));
} throw new DiscordApiException(Response::HTTP_UNAUTHORIZED, "Token d'accès expiré et/ou token de refresh invalide");
}
return $user;
}
public function getBotsData(): array
{
$output = array();
$botsId = [$_ENV['DISCORD_BOT_TAMISEUR_ID'], $_ENV['DISCORD_BOT_GROOVE_ID'], $_ENV['DISCORD_BOT_FUNKY_ID'], $_ENV['DISCORD_BOT_JUJUL_ID'], $_ENV['DISCORD_BOT_CHANTIER_ID']];
foreach($botsId as $botId)
{
try {
$response = $this->client->request('GET', $this->baseUrl . '/users/' . $botId, [
'headers' => [
'Authorization' => 'Bot ' . $this->clientToken,
],
]);
array_push($output, $response->toArray());
} catch (ClientExceptionInterface | ServerExceptionInterface | RedirectionExceptionInterface | TransportExceptionInterface $e) {
throw new DiscordApiException($e->getCode(), 'Erreur lors de la requête à l\'API Discord: ' . $e->getMessage(), $e);
}
}
return $output;
/*
try {
$response = $this->client->request('GET', $this->baseUrl . '/users/' . '223831938346123275', [
'headers' => [
//'Authorization' => 'Bearer ' . $accessToken,
'Authorization' => 'Bot ' . $this->clientToken,
],
]);
return $response->toArray();
} catch (ClientExceptionInterface | ServerExceptionInterface | RedirectionExceptionInterface | TransportExceptionInterface $e) {
throw new DiscordApiException($e->getCode(), 'Erreur lors de la requête à l\'API Discord: ' . $e->getMessage(), $e);
}
*/
}
public function getCurrentUserData(string $accessToken): array
{
try {
$response = $this->client->request('GET', $this->baseUrl . '/users/@me', [
'headers' => [
'Authorization' => 'Bearer ' . $accessToken,
],
]);
return $response->toArray();
} catch (ClientExceptionInterface | ServerExceptionInterface | RedirectionExceptionInterface | TransportExceptionInterface $e) {
throw new DiscordApiException($e->getCode(), 'Erreur lors de la requête à l\'API Discord: ' . $e->getMessage(), $e);
}
}
public function getCurrentUserGuildsData(string $accessToken): array
{
try {
$response = $this->client->request('GET', $this->baseUrl . '/users/@me/guilds', [
'headers' => [
'Authorization' => 'Bearer ' . $accessToken,
],
]);
return $response->toArray();
} catch (ClientExceptionInterface | ServerExceptionInterface | RedirectionExceptionInterface | TransportExceptionInterface $e) {
throw new DiscordApiException($e->getCode(), 'Erreur lors de la requête à l\'API Discord: ' . $e->getMessage(), $e);
}
}
public function getUserData(string $userId): array
{
try {
$response = $this->client->request('GET', $this->baseUrl . '/users/' . $userId, [
'headers' => [
'Authorization' => 'Bot ' . $this->clientToken,
],
]);
return $response->toArray();
} catch (ClientExceptionInterface | ServerExceptionInterface | RedirectionExceptionInterface | TransportExceptionInterface $e) {
throw new DiscordApiException($e->getCode(), 'Erreur lors de la requête à l\'API Discord: ' . $e->getMessage(), $e);
}
}
public function getGuildData(string $guildId, string $accessToken): array
{
try {
$response = $this->client->request('GET', $this->baseUrl . '/guilds/' . $guildId, [
'headers' => [
'Authorization' => 'Bearer ' . $accessToken,
],
]);
return $response->toArray();
} catch (ClientExceptionInterface | ServerExceptionInterface | RedirectionExceptionInterface | TransportExceptionInterface $e) {
throw new DiscordApiException($e->getCode(), 'Erreur lors de la requête à l\'API Discord: ' . $e->getMessage(), $e);
}
}
}