[Tuto] Scruter le prochain rdv Doctolib disponible

Bonjour,
Je vous propose ci-dessous de détailler comment obtenir via le plugin script la date et l’heure du prochain rendez-vous disponible sur l’agenda Doctolib chez un praticien.
On commence très logiquement par la fin :slight_smile: en vous montrant le résultat :

Prérequis: connaître le « slug-name » du praticien c’est à dire l’alias qui apparaît dans l’URL Doctolib de son profil. Par exemple pour ce praticien choisi au hasard en naviguant sur le site « https://www.doctolib.fr/gastro-enterologue/bordeaux/alain-castinel?pid=practice-194708 » son slug-name sera « alain-castinel ».
Il faut ensuite ouvrir l’URL « https://www.doctolib.fr/online_booking/api/slot_selection_funnel/v1/info.json?profile_slug=XXXXX » en remplaçant évidemment les XXX par le slug-name identifié précédemment. On tombe alors sur une page au format json que je vous conseille de traiter via un décodeur json pour pouvoir récupérer trois items numériques :

  • visit_motive_ids qui correspond au type de consultation que vous souhaitez
  • agenda_ids : le numéro de l’agenda du praticien (il peut aussi y en avoir plusieurs en les groupant avec des tirets
  • practice_ids : item lié à l’agenda ci-dessus.

On peut alors tester ces IDs en les utilisant dans l’URL suivant : https://www.doctolib.fr/availabilities.json?visit_motive_ids=xxxxx&agenda_ids=yyyyyy&practice_ids=zzzzzz&telehealth=false&limit=2&start_date=2025-05-27 qui doit alors afficher un json de ce type :

On y retrouve le nombre de créneau dispo sur les 2 prochains jours, les horaires des creneaux en question si il y en a, et la date et heure du prochain créneau dispo si il n’y en a pas dans les 2 jours. J’ai donc créé un code python pour extraire le premier créneau dispo (j’ai essayé plusieurs manières dont un script json mais ça ne fonctionne pas, voir ce post).

Voici donc le script en question, il appelle en argument les trois ids récupérés précédemment, et retourne le prochain créneau dispo au format dd/mm/yy HH:mm.

#!/usr/bin/python3

import requests
import json
from datetime import datetime
import sys

def format_slot(slot):
    """Formate un créneau horaire en chaîne lisible."""
    if slot:
        try:
            slot_datetime = datetime.strptime(slot, "%Y-%m-%dT%H:%M:%S.%f%z")
            return slot_datetime.strftime("%d/%m/%Y %H:%M")
        except ValueError:
            print("Format de date/time invalide !")
            return None
    else:
        print("Aucun créneau disponible.")
        return None

def get_next_slot(visit_motive_ids, agenda_ids, practice_ids):
    base_url = "https://www.doctolib.fr/availabilities.json"
    start_date = datetime.now().strftime('%Y-%m-%d')
    url = (f"{base_url}?visit_motive_ids={visit_motive_ids}"
           f"&agenda_ids={agenda_ids}&practice_ids={practice_ids}"
           f"&telehealth=false&limit=2&start_date={start_date}")
    
    headers = {
        'User-Agent': 'Mozilla/5.0'
    }
    
    response = requests.get(url, headers=headers)
    
    if response.status_code == 200:
        data = response.json()

        # Si total est nul → aucun créneau du tout
        if data.get('total', 0) == 0:
            next_slot= data.get('next_slot')
            return format_slot(next_slot)

        # Cherche le premier créneau non vide dans availabilities
        for day in data.get('availabilities', []):
            slots = day.get('slots', [])
            if slots:
                # retourne le premier créneau formaté
                return format_slot(slots[0])

        # Aucun slot trouvé malgré total > 0
        return "aucun creneau"
    else:
        print(f"Erreur lors de la requête : {response.status_code}")
        return None

if __name__ == "__main__":
    if len(sys.argv) != 4:
        print("Usage: python script.py <visit_motive_ids> <agenda_ids> <practice_ids>")
        sys.exit(1)

    visit_motive_ids = sys.argv[1]
    agenda_ids = sys.argv[2]
    practice_ids = sys.argv[3]

    slot_result = get_next_slot(visit_motive_ids, agenda_ids, practice_ids)
    if slot_result:
        print(slot_result)

Il reste donc à appeler ce script dans le plugin avec les trois id en argument, comme sur le premier screenshot de ce post, avec un rafraichissement auto de votre choix.
Évidemment, ce script seul n’est pas forcément suffisant, mais on peut ensuite imaginer des scénarios qui compare ce prochain créneau avec une date de votre choix pour vous alerter si un créneau plus proche se débloque !

PS: merci à @vicnet pour l’idée et avoir fourni l’URL utile via ce post.

11 « J'aime »

Edit du jour : en fait si il y a un slot disponible dans les 15 jours prochains, l’item « next_slot » n’apparait pas dans le json donc mon code ne marche plus :clown_face:. Je dois l’améliorer pour récupérer soit le slot dispo dans la liste, soit le next_slot !

Edit su jour : script modifié pour récupérer soit le le next_slot soit le premier créneau listé.
J’ai aussi modifié l’URL pour n’afficher que 2 jours au lieu de 15, ça ne me servait pas.