184 lines
8.1 KiB
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);
|
|
}
|
|
}
|
|
} |