Aller au contenu

« Documentation de l'API Jeuxvideo.com » : différence entre les versions

correction d'informations devenues erronées
(Bannière info (lien vers fonctionnement du site))
(correction d'informations devenues erronées)
 
(4 versions intermédiaires par 2 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
{{Bannière Info|Contenu=Cette page documente l'API v4 de jeuxvideo.com. Le fonctionnement du site est quant à lui détaillé sur [[Fonctionnement technique de Jeuxvideo.com]].}}
{{Bannière Info|Contenu=Cette page documente l'API v4 de jeuxvideo.com. Le fonctionnement du site est quant à lui détaillé sur [[Fonctionnement technique de Jeuxvideo.com]].}}


L''''API de [[jeuxvideo.com]]''', utilisée à l'origine par les applications mobiles de jeuxvideo.com, permet de développer plus facilement des applications, sites Web, et autres scripts en rapport avec jeuxvideo.com.
L''''API de [[jeuxvideo.com]]''', conçue par les développeurs du site pour l'application mobile, permet de programmatiser l'envoi de requêtes à JVC.
Étant à l'origine réservée à un usage privé, on ne dispose pas de sa documentation officielle. Toutefois, il est possible de détailler son fonctionnement grâce à un travail de rétro-ingéniérie.


Actuellement, deux API sont utilisées : l'api ''v4'' et l'api ''jvc.gg'' :
En juin 2025, l'API est hébergée sur le sous-domaine ''api'', et est à sa quatrième version (''v4'').
* L'API ''v4'' est hébergée sur le sous-domaine ''api'', et est actuellement à sa quatrième version (''v4''). Elle est utilisée par l'application mobile JVC. Cette API est privée et ne peut être documentée que par rétro-ingénierie de l'application mobile.
* L'API ''jvc.gg'', d'importance moindre, est hébergée à ''api.jvc.gg''. C'est une API utilisée par les pages Phoenix du site qui sert notamment à la recherche des jeux.


Les anciennes versions sont toujours exploitables avec les ''tokens'' qui leur sont propres{{Commentaire|Autre=potentiellement obsolète}}, mais certains ''endpoints'' renvoient des erreurs HTTP 403.
L'ancienne API ''jvc.gg'' était hébergée à ''api.jvc.gg'' jusqu'à son abandon en février 2025. Elle était utilisée par les pages Phoenix du site, notamment pour la recherche des jeux. Sa documentation (non-officielle) est toujours consultable sur cet article.


Les anciennes versions sont toujours exploitables avec les ''tokens'' qui leur sont propres{{Commentaire|Autre=très probablement obsolète}}, mais certains ''endpoints'' renvoient des erreurs HTTP 403.
<div id="jvclient"></div>
=JVClient=
=JVClient=
[[File:icon-512x512.png|vignette|256px|Le logo de JVClient : « Le pouvoir par les données ».]]
[[File:icon-512x512.png|vignette|256px|Le logo de JVClient : « Le pouvoir par les données ».]]
Ligne 852 : Ligne 854 :
En second lieu, vous ne devrez pas seulement envoyer aux serveurs le contenu de votre message (et le titre du topic si besoin) : la requête ''POST'' devra aussi contenir des paires clés-valeurs générées par le site lui-même et qui agissent comme une sorte de protection. Celles-ci sont : ''fs_session'', ''fs_timestamp'', ''fs_version'', ''form_alias_rang'' ainsi qu'un ''hash''.
En second lieu, vous ne devrez pas seulement envoyer aux serveurs le contenu de votre message (et le titre du topic si besoin) : la requête ''POST'' devra aussi contenir des paires clés-valeurs générées par le site lui-même et qui agissent comme une sorte de protection. Celles-ci sont : ''fs_session'', ''fs_timestamp'', ''fs_version'', ''form_alias_rang'' ainsi qu'un ''hash''.


Heureusement, ces valeurs sont directement disponibles depuis des ''inputs'' cachées dans le code HTML des pages de forums/topics et situées dans la ''div'' nommée ''js-form-session-data''.
'''Depuis mai 2025''', suite à une mise à jour de JVC, les informations ''"fs_" '', sont offusqués dans une chaîne en base 64.


Si l'on veut envoyer un message sur un topic (ou un forum), il faudra d'abord envoyer une requête ''GET'' à l'URL associée et récupérer ces valeurs chiffrées avant d'envoyer une requête ''POST'' avec le contenu du message en plus de ces dernières.
Les fs_ sont récupérables via la balise script : ''window.jvc.forumsAppPayload''


=== Script Python ===
<script>window.jvc=window.jvc||{};window.jvc.forumsAppPayload=[CHAINE_A_RECUPERER]</script>
La classe Python suivante permet d'interagir avec les forums de cette manière. Il vous suffit d'entrer la valeur de votre cookie ''coniunctio'' et d'appeler les fonctions souhaitées avec le contenu des messages ou topics.


Bien que cette méthode permette d'outrepasser les captchas, il se peut que vous soyez bloqué par le site en envoyant un trop grand nombre de requêtes dans un trop court laps de temps.
Pour récupérer les valeurs dans la chaîne :
const forumsAppPayload = [...document.scripts].map(s => s.textContent.match(/forumsAppPayload\s*=\s*["']([^"']+)["']/)).filter(Boolean)[0][1];
const decoded = JSON.parse(atob(forumsAppPayload));


<pre>
Auparavant, ces valeurs étaient disponibles depuis des ''inputs'' cachées dans le code HTML des pages de forums/topics et situées dans la ''div'' nommée ''js-form-session-data''.
import requests, json
from requests import Response
from bs4 import BeautifulSoup


DIV_CLASS = 'js-form-session-data'
Si l'on veut envoyer un message sur un topic (ou un forum), il faudra d'abord envoyer une requête ''GET'' à l'URL associée et récupérer ces valeurs chiffrées avant d'envoyer une requête ''POST'' à l'URL avec le contenu du message en plus de ces dernières.


class ForumClient:
'''Pour poster un message''', la requête POST devra être faite à <code>https://www.jeuxvideo.com/forums/message/add</code> avec le ''header'' <code>Content-Type</code> valant <code>multipart/form-data</code> et les données suivantes en ''body'' :
    def __init__(self, coniuntio: str):
<pre>
        self._cookies = {'coniunctio':coniuntio}
text : le contenu du message
topicId : ID du topic cible
topicTitle : titre du topic (si c'est une création du topic)
forumId : ID du forum cible
group : mettre à 1
messageId : undefined
toutes les clé/valeurs qui commencent par fs_ (à trouver selon la méthode donnée précédemment) + ajax_hash
</pre>


    def _scrape_input_tokens(self, res: Response) -> dict:
'''Pour poster un topic''', la requête POST devra être faite à <code>https://www.jeuxvideo.com/forums/topic/add</code> avec le ''header'' <code>Content-Type</code> valant <code>multipart/form-data</code> et les données suivantes en ''body'' :
        soup = BeautifulSoup(res.text, 'html.parser')
<pre>
        form = soup.find('div', {'class':DIV_CLASS})
text : le contenu du message
        jsi = form.findChildren("input")
topicId : mettre à 0
       
topicTitle : titre du topic (si c'est une création du topic)
        tokens = {
forumId : ID du forum cible
            "fs_session":jsi[0].attrs["value"],
group : mettre à 1
            "fs_timestamp":jsi[1].attrs["value"],
messageId : undefined
            "fs_version":jsi[2].attrs["value"],
toutes les clé/valeurs qui commencent par fs_ (à trouver selon la méthode donnée précédemment) + ajax_hash
            jsi[3].attrs["name"]:jsi[3].attrs["value"],
submitSurvey : true pour ajouter un sondage, false sinon
            "form_alias_rang":"1",
answerSurvey : titre du sondage s'il y en a un
            "g-recaptcha-response":""
responsesSurvey[] : une réponse au sondage
        }
</pre>
       
        return tokens


    def _get_forum_URL(self, forum_id) -> str:
'''Note''' : À date, ces informations sont uniquement offusquées dans la partie forum. Les messages privés conservent les informations en clair dans le HTML comme mentionné plus haut.
        return requests.get(f'https://www.jeuxvideo.com/forums/0-{forum_id}-0-1-0-1-0-a.htm').url
 
    def _get_topic_URL(self, topic_id) -> str:
        return requests.get(f'https://www.jeuxvideo.com/forums/42-1-{topic_id}-1-0-1-0-a.htm').url
 
    def post_message(self, topic_id: int, message: str) -> Response:
        """
        topic_id, int : ID du topic
        message, str : votre message
 
        renvoie un objet Response
        """
        topic_URL = self._get_topic_URL(topic_id)
        res = requests.get(topic_URL, cookies=self._cookies)
 
        data = self._scrape_input_tokens(res)
        data['message_topic'] = message
 
        res = requests.post(topic_URL, data=data, cookies=self._cookies)
 
        return res
 
    def post_topic(self, forum_id: int, titre: str, message: str, sondage: dict = None) -> Response:
        """
        forum_id, int : ID du forum
        titre, str : titre du topic
        message, str : corps du topic
 
        [sondage], dict : dictionnaire de la forme {
            "question_sondage" : "Question ?",
            "reponse_sondage[]" : ["reponse 1", "reponse 2"]
        }
        """
        forum_URL = self._get_forum_URL(forum_id)
        res = requests.get(forum_URL, cookies=self._cookies)
        data = self._scrape_input_tokens(res)
 
        data['titre_topic'] = titre
        data['message_topic'] = message
        if sondage:
            data |= sondage
            data['submit_sondage'] = '1'
 
        res = requests.post(forum_URL, data=data, cookies=self._cookies)
 
        return res
 
if __name__ == '__main__':
    client = ForumClient("votre coniunctio ici")
    # Exemples d'utilisation
    # Pour poster un message
    client.post_message(74204156, "Je poste depuis Python :)")
    # Pour poster un topic
    client.post_topic(51, 'Je poste depuis Python', 'Et toi ? :)')
</pre>


== Limitations ==
== Limitations ==
Kheys
423

modifications