En discutant avec des collègues, on s'est dit que ça pourrait être pas mal de publier du contenu pour aider les speakers de notre groupe à se rappeler les CFPs auxquels postuler avant qu'ils ferment, voir même découvrir des nouvelles conférences ! Ce qui nous a semblé le plus efficace c'est de publier ça chaque semaine dans un espace Google Chat. J'ai pris le point de réaliser ce bot.

Problème : je n'ai jamais écrit de bot… 😅 je n'ai jamais utilisé l'API Google Chat… 🤔 je ne connais pas de technique magique pour récupérer le listing des conférences qui existent et leurs CFPs… 😵

Premier problème : lister les CFPs en cours…

Bon sur ce point j'avais en fait dès le début ma petite idée, car il se trouve que je connais une certaine toulousaine du nom Aurélie Vache et que je sais qu'elle a un projet qui tourne très bien avec une super communauté qui s'appelle : Developer Conference Agenda !

J'ai suivi le projet depuis le début, et je sais que derrière le site, ce n'est "que" des fichiers markdown (c'est un peu plus compliqué que ça en vrai), mais heureusement pour moi, il y a aussi une version structurée en JSON des évènements et des CFPs ! 🤩

Pour la logique c'est simple : un HTTP GET pour récupérer le fichier JSON avec la liste des événements. Je veux faire ça avec Node.JS et TypeScript donc le fetch est natif, manipuler des JSON est très facile avec ce langage, donc pas de souci !

À partir de ça, il n'y a qu'un pas pour passer du listing des conférences à un message texte !

## ⏳ CFPs qui ferment cette semaine

- Capitole Du Libre - Toulouse (France) (le 16/11/2024) *jusqu'à dimanche*
- JakartaOne Livestream 2024 - Online (le 03/12/2024) *jusqu'à dimanche*
- GroupBy 2024 - Online (le 29/10/2024) *jusqu'à mardi*

## 📢 CFPs ouvert

- Conf42 Incident Management 2024 - Online (le 17/10/2024)
- CapSec 2024 - Online (le 17/10/2024)
- Conf42 JavaScript 2024 - Online (le 31/10/2024)
- Codeurs en Seine - Rouen (France) (le 21/11/2024)
- HashiTalks: India - Online (le 21/11/2024)
- Conf24 Prompt Engineering - Online (le 14/11/2024)
- SnowCamp 2025 - Grenoble (France) (le 22/01/2025)
- Conf42 Prompt Engineering 2024 - Online (le 21/11/2024)
- DevOps D-Day #9 - Marseille (France) (le 30/01/2025)
- Touraine Tech - Tours (France) (le 06/02/2025)
- NAVIGATE 2025 - Online (le 18/03/2025)
- Generation AI - Paris (France) (le 03/12/2024)
- APIdays Paris - Paris (France) (le 03/12/2024)
- Conf42.com DevSecOps 2024 - Online (le 05/12/2024)
- GraphQL Day Europe - Paris (France) (le 05/12/2024)
- Conf42.com Internet of Things (IoT) 2024 - Online (le 19/12/2024)
- HashiTalks: América Latina - Online (le 16/01/2025)
- HashiTalks: Israel - Online (le 23/01/2025)
- Conf42.com DevOps 2025 - Online (le 23/01/2025)
- Conf42.com Chaos Engineering 2025 - Online (le 13/02/2025)
- Conf42.com Python 2025 - Online (le 27/02/2025)
- Conf42.com Cloud Native 2025 - Online (le 20/03/2025)
- Conf42.com Large Language Models (LLMs) 2025 - Online (le 10/04/2025)

## 🎙️ Conférences qui ont lieux cette semaine

- eBPF Summit - Online (le 11/09/2024)
- Litmus Chaos Con - Online (le 12/09/2024)
- HashiTalks: France - Online (le 12/09/2024)

_-- 🤖 The Speaker Bot ❤️_

Second problème : générer un message chaque semaine…

J'ai donc un script qui génère un message, mais je l'exécute à la main sur ma machine. Je pourrais le lancer tous les lundis matin et copier-coller le message, mais je suis bien trop feignant pour faire ça !

Donc comment je lance mon script tous les matins ? Ma première idée a été une Cloud Function, et clairement je suis certain que c'est une méthode qui fonctionne. Mais j'ai trouvé encore plus simple : un job de CI. Mon projet est sous Gitlab, donc j'ai juste à créer un fichier .gitlab-ci.yml et un peu de boilerplate, je lance dedans ma commande et c'est parti j'ai un pipeline qui fait que j'attends !

default:
  image: node:latest
  before_script:
    - npm ci --cache .npm --prefer-offline
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - .npm/

stages:
  - send-message

send-message:
  stage: send-message
  script:
    - npm run start

Il ne reste qu'à le programmer tous les lundis, en allant dans "Build schedules" et en se laissant guider !

Et voilà ! On peut même déclencher à la main le schedule.

Troisième problème : publier le message…

J'avoue c'était le point qui m'inquiétait le plus et celui qui m'amusait le moins (donc je l'ai gardé pour la fin 😅).

Finalement : c'est tellement simple que c'en est effrayant !

Sauf si c'est désactivé par votre administrateur : dans la configuration de vos espaces Google Chat vous avez une partie Application et Webhook. Dans la partie Webhook vous pouvez générer une URL de Webhook.

Une fois que vous avez votre URL, vous pouvez faire un HTTP POST dessus avec le bon body. Pas besoin de token, de projet GCP, d'authentification. Tout est déjà dans l'URL et vous pouvez appeler cette URL depuis n'importe où à priori.

const CHAT_HOOK_URL = "https://chat.googleapis.com/v1/spaces/...";

export async function sendMessage(text: string): Promise<void> {
	await fetch(CHAT_HOOK_URL, {
		method: "POST",
		headers: { "Content-Type": "application/json; charset=UTF-8" },
		body: JSON.stringify({ text }),
	});
}

Après un essai rapide, je me rends compte que tout n'est pas bien pris en compte niveau formatage Markdown… 😅

Message du bot sans formatage…

En fait seul un sous-ensemble du formatage Markdown est supporté. Seule la partie inline est supportée à priori. Donc j'ai modifié tous les titres pour passer sur du simple gras et tout est ok ! 🤓

Bonus : avoir une vraie CI !

Comme je n'ai pas envie que tout soit cassé à chaque développement ou de devoir faire de la non régression à la main, j'ai tout fait en TDD. Mais j'ai bien envie que tout s'exécute dans la CI.

J'ai donc amélioré l'exécution de ma pipeline pour jouer les tests quand on pousse un nouveau commit. J'ai aussi ajouté un dry mode de sorte à pouvoir exécuter le script sans avoir à publier un message dans un canal Google Chat.

Je vous donne mon pipeline final pour vous donner une idée :

default:
  image: node:latest
  before_script:
    - npm ci --cache .npm --prefer-offline
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - .npm/

stages:
  - test
  - send-message

test:
  stage: test
  script:
    - npm run test
  rules:
    - if: $DRY == "true"

send-message:
  stage: send-message
  script:
    - npm run start

Conclusion

Ça fait déjà 3 semaines que le bot tourne et tout fonctionne parfaitement bien ! La solution que j'ai mis en place est complètement gratuite, super simple et super efficace ! Je ne pensais pas que ce serait aussi simple de monter un bot du genre, publier sur Google Chat c'est super simple donc aucune raison de se priver si on peut créer nos propres outils ! 🤖

Sources :

Crédit photo : https://pixabay.com/photos/robot-light-shadow-thinking-7387740/