Référence technique du Happy Milo Radar : pages, authentification et API. Écrite pour être utile à la fois à un humain technique, à un script (scraping/ingestion) et à un agent IA qui doit interagir avec cet outil par HTTP.
Pages
Pages HTML rendues côté serveur, aucune authentification requise pour les consulter.
/
Public
Le radar : calendrier des événements confirmed par mois, filtrable par tag
via ?tag=<event_type>. Bouton "+ Ajouter un événement".
/events/:id
Public
Page de modération d'un événement ("Happy Event Moderate") : connexion au bot Twitch,
chat en direct filtré par commande, configuration et suivi live du Happy Wall lié.
noindex. Les actions de cette page nécessitent le mot de passe de
modération (voir Authentification).
/leads
Public
File d'attente des événements pending créés par l'API d'ingestion.
Confirmer (→ devient un événement public + page de modération) ou rejeter (→ supprimé).
noindex, pas de lien visible depuis l'accueil.
/partial?tag=<event_type>
Public
Fragment HTML du calendrier (bandeau de tags + grille), utilisé par le JS de l'accueil pour rafraîchir la vue sans recharger la page. Pas destiné à être consommé en dehors du radar lui-même.
Authentification
Deux secrets distincts, chacun avec sa propre portée. Aucun des deux n'est jamais exposé côté client au-delà de ce que l'utilisateur saisit lui-même.
X-Radar-Password
Header HTTP requis sur les actions de la page de modération d'un événement (connecter
le bot, envoyer un message, configurer le Happy Wall, supprimer un message...). Sans ce
header (ou avec une mauvaise valeur), ces routes répondent 401. Se
récupère via le bandeau "Lecture seule" en haut de /events/:id, qui
l'échange contre une confirmation via POST /api/unlock et le garde en
localStorage côté navigateur.
curl -X POST https://twitch.happy-milo.com/api/events/42/bot/say \
-H "Content-Type: application/json" \
-H "X-Radar-Password: <mot-de-passe>" \
-d '{"message":"Coucou le chat !"}'
X-Radar-Api-Key
Header HTTP requis uniquement sur POST /api/ingest/events (voir
API d'ingestion). Totalement indépendante du mot de passe de
modération se révoque/régénère sans rien casser côté humains.
Tout le reste (consulter les pages, ajouter un événement manuellement, confirmer/rejeter un lead) ne demande aucune authentification.
API de lecture
Aucune authentification. Utile pour un agent qui veut d'abord vérifier l'état existant avant d'agir.
/api/channels/search?q=<texte>
Public
Recherche parmi les chaînes déjà en base (nom ou login Twitch). Retourne [] si q est vide.
/api/event-types
Public
Liste des types d'événements utilisés par au moins un événement confirmed (ce sont les tags affichés sur le radar).
/api/events/:id/bot/status
Public
Réponse : { ok, connected } le bot est-il actuellement joint au chat de la chaîne de cet événement.
/api/events/:id/bot/stream
Public
Flux text/event-stream (SSE) des messages de chat contenant la commande
configurée pour cet événement. Envoie d'abord le buffer récent, puis les nouveaux
messages en direct. Événement nommé delete quand un message est retiré.
/api/events/:id/wall-config
Public
Réponse : { ok, config } configuration du Happy Wall lié à cet événement (null si non configuré).
/api/events/:id/wall-messages
Public
Proxy en lecture vers l'API publique de happy-milo-core : messages
réellement présents sur le Happy Wall lié. Réponse :
{ ok, configured, messages }.
API des événements
Aucune authentification. Gère le cycle de vie d'un événement (ajout manuel, confirmation/rejet d'un lead).
/api/events
Public
Ajoute un événement directement en statut confirmed (visible immédiatement
sur le radar public) équivalent du formulaire "+ Ajouter un événement".
curl -X POST https://twitch.happy-milo.com/api/events \
-H "Content-Type: application/json" \
-d '{
"twitchLogin": "aurorexpress",
"eventType": "Anniversaire de Chaîne Twitch",
"eventDate": "2027-05-03",
"confirmationUrl": "https://twitch.tv/aurorexpress"
}'
twitchLogin (ou channelId pour une chaîne déjà en base),
eventType, eventDate (YYYY-MM-DD) et
confirmationUrl sont obligatoires.
/api/events/:id/confirm
Public
Passe un événement pending en confirmed. Utilisé par /leads et par le bandeau de la page de modération.
/api/events/:id/reject
Public
Supprime définitivement un événement (et sa config Happy Wall si elle existe). Utilisé par /leads.
API d'ingestion (leads)
Pensée pour un script ou un agent qui explore le web à la recherche de chaînes Twitch
ayant un moment à venir, sans passer par l'UI. Nécessite X-Radar-Api-Key.
/api/ingest/events
Clé API
Crée l'événement en statut pending invisible sur le radar public tant
qu'un modérateur ne l'a pas confirmé depuis /leads. La chaîne est créée
automatiquement via l'API Twitch si elle n'existe pas déjà en base. Rappeler avec les
mêmes twitchLogin + eventType + eventDate ne
recrée rien ("duplicate": true) sûr à répéter chaque jour.
curl -X POST https://twitch.happy-milo.com/api/ingest/events \
-H "Content-Type: application/json" \
-H "X-Radar-Api-Key: <cle>" \
-d '{
"twitchLogin": "aurorexpress",
"eventType": "Anniversaire de Chaîne Twitch",
"eventDate": "2027-05-03",
"sourceUrl": "https://twitch.tv/aurorexpress"
}'
sourceUrl : lien qui justifie la date trouvée (tweet, page "About" Twitch,
article...) devient le lien de preuve une fois l'événement confirmé. Réponse :
{ ok, duplicate, eventId, status }.
API de modération
Toutes ces routes nécessitent le header X-Radar-Password (voir
Authentification) sans lui, réponse 401. Ce sont les
actions de la page /events/:id.
/api/events/:id/bot/connect
Mot de passe
Connecte le bot au chat Twitch de la chaîne de cet événement.
/api/events/:id/bot/disconnect
Mot de passe
Déconnecte le bot de ce chat.
/api/events/:id/bot/say
Mot de passe
Corps : { "message": "..." }. Envoie un message dans le chat en tant que bot (le bot doit être connecté).
/api/events/:id/bot/messages/:messageId/delete
Mot de passe
Retire un message du buffer de chat affiché (local à cette page, ne touche pas Twitch).
/api/events/:id/command-trigger
Mot de passe
Corps : { "command_trigger": "!happy_wall" } (vide = revient au défaut global). Définit la commande chat qui déclenche le relai vers le Happy Wall pour cet événement.
/api/events/:id/thanks-message
Mot de passe
Corps : { "thanks_message": "..." }. Réponse envoyée dans le chat ("@pseudo <message>") après un relai réussi.
/api/events/:id/wall-config
Mot de passe
Corps : happy_wall_url, wall_title,
wall_description, image_url,
background_desktop_url, background_mobile_url,
reveal_at, music, effect. Écrase la config
existante (formulaire complet, pas un patch partiel). Si happy_wall_url
est fourni, son slug est résolu et vérifié en direct auprès de
happy-milo-core.
/api/events/:id/wall-messages
Mot de passe
Corps : { "pseudo": "...", "content": "..." }. Ajoute un message réel sur le Happy Wall lié (nécessite qu'il soit configuré).
/api/events/:id/wall-messages/:messageId/delete
Mot de passe
Supprime réellement un message du Happy Wall. Ne fonctionne que si son
browserSignature correspond à celui du radar (donc pour les messages
ajoutés depuis cet outil) voir les limitations du README.
robots.txt / sitemap.xml
/robots.txt
Public
Autorise le crawl de /, bloque /partial et /api/. Les pages internes (/events/:id, /leads, /help) restent crawlables mais portent noindex en meta.
/sitemap.xml
Public
Liste uniquement / les pages noindex n'y figurent pas volontairement.