Aide pour concevoir un plugin d'intégration personnalisé

Bonjour à tous ! Je mène des recherches sur différentes plateformes de forums afin de créer une communauté pour les programmeurs compétitifs brésiliens (CP), mais il semble que je l’ai trouvée !

Une fonctionnalité que j’aimerais intégrer à ce forum est une liaison avec Codeforces, une plateforme en ligne qui accueille des compétitions et des discussions sur le CP. Sur Codeforces, les participants disposent d’un rating (notation) qui évolue en fonction de leurs performances lors des compétitions classées. J’aimerais permettre à mes utilisateurs d’afficher leur notation, gagnée de haute lutte, sur leur profil du forum.

La première chose que ce plugin, que je souhaite développer, devra faire, c’est permettre à l’utilisateur de saisir son identifiant (handle) Codeforces, puis de vérifier de manière à authentifier que cet identifiant appartient bien à l’utilisateur du forum. Pour ce faire, j’envisage d’utiliser le plugin Custom Wizard pour demander leur identifiant, puis d’envoyer une chaîne aléatoire via l’API Codeforces Talks que l’utilisateur devra renvoyer correctement. Si tout est en ordre, je stockerai leur identifiant dans un champ utilisateur personnalisé. Cela vous semble-t-il correct ? Feriez-vous cela différemment ?

Maintenant, je connais mes utilisateurs [futurs], après tout, je suis moi-même un CPer ! Ils apprécieraient d’afficher leur notation grâce à la couleur de leur identifiant sur le forum. Autrement dit, si vous avez une notation supérieure à 1400, votre identifiant est de couleur cyan ; si elle est supérieure à 1600, il est bleu, et ainsi de suite.

Mes recherches rapides sur la personnalisation des couleurs des identifiants sur Discourse m’ont conduit à la solution suivante. Je devrais créer un groupe d’utilisateurs pour chaque tranche de notation, puis assigner dynamiquement mes utilisateurs au groupe approprié. (Existe-t-il une méthode meilleure ou plus simple ?)

Ainsi, lorsque l’utilisateur lie initialement son compte Codeforces à son profil, je pourrais récupérer sa notation et lui assigner le groupe correspondant (specialist, expert, candidate master, …, international grandmaster). Cependant, la notation peut changer rapidement et j’aimerais mettre à jour automatiquement le groupe de l’utilisateur lorsque sa notation évolue.

J’ai alors envisagé plusieurs façons de réaliser cela et j’aimerais avoir des suggestions sur celle à suivre, et, si possible, quelques conseils sur les spécificités de Discourse :

  • Exécuter un Job régulièrement qui met à jour la notation et le groupe de chaque utilisateur (un grand nombre de requêtes externes vers l’API de Codeforces).
  • Exécuter un Job régulièrement qui traite les compétitions au fur et à mesure qu’elles se déroulent. Puisque les notations ne peuvent changer que pendant une compétition, si les notations des utilisateurs sont initialement cohérentes, en traitant les changements de notation au moment où ils surviennent, je peux mettre à jour uniquement les notations modifiées et maintenir la cohérence avec une seule requête externe vers l’API.
  • Créer un résolveur de notation et de groupe personnalisé. Je devrais alors stocker la dernière récupération de notation et, lors de la prochaine requête GET rating/groups, si la notation est obsolète, je contacterais l’API Codeforces pour mettre à jour la notation et le groupe de l’utilisateur. C’est ma solution préférée car elle semble simple et garantira une cohérence éventuelle. Cependant, je ne suis pas certain de la manière de l’implémenter ni des conséquences du retrait et de l’ajout dynamique d’un groupe à un utilisateur. Ou même si cela est possible du tout sous forme de plugin.

Eh bien, je m’excuse pour ce mur de texte ! Je serais ravi d’avoir tout type de retour sur tout cela. Merci de votre attention.

Une fois que vous avez leur identifiant Codeforces dans un user_custom_field, il devrait être assez facile de mettre à jour toutes les données que vous souhaitez depuis leur profil (attribuer des groupes, insérer n’importe quelles données de profil de Codeforces dans les champs personnalisés de l’utilisateur, etc.) lors de leur connexion.

Quelque chose comme :

after_initialize do
  DiscourseEvent.on(:user_logged_in) do |user|
    # Récupérer les données depuis Codeforces
      if codeforce_rating > 1400
          group = Group.find_by(name: group_1400)
          if group
            gu = GroupUser.find_by(group_id: group.id, user_id: user.id)
            GroupUser.create(group_id: group.id, user_id: user.id) unless gu
          end
        end
      end

  end

end

Cette méthode est vraiment simple et vous ne mettrez à jour les données que pour les personnes qui sont réellement actives dans la communauté.

C’est magnifique ! Je suis ravi d’avoir posé des questions avant de mettre quoi que ce soit en place.

Merci beaucoup !

Si tous vos utilisateurs sont des utilisateurs de Codeforces, je mettrais en place une authentification unique (SSO), où Codeforces agit comme fournisseur d’authentification. De cette façon, aucune étape d’authentification supplémentaire n’est nécessaire et vos utilisateurs bénéficieront d’un flux d’inscription et d’authentification amélioré. Vous pourrez même synchroniser les groupes de cette manière !

Je le ferais à la source, c’est-à-dire là où Codeforces sait que la cote a changé, en faisant en sorte qu’il effectue un appel API vers Discourse pour mettre à jour la cote (ou toute autre propriété utilisateur influencée par cette cote). Ainsi, tout sera toujours à jour. Lorsque vous devez synchroniser des éléments, le sondage (polling) entraîne toujours des problèmes d’une manière ou d’une autre, alors évitez-le lorsque vous le pouvez et privilégiez une approche basée sur les événements.

J’ai supposé qu’il n’était pas possible d’utiliser Codeforces comme maître SSO. Si c’est le cas, vous voulez absolument le faire de cette manière !

L’hypothèse de @pfaffman selon laquelle il n’était pas possible d’utiliser Codeforces comme fournisseur d’authentification était correcte. Codeforces est essentiellement maintenu par une seule personne, et je doute qu’il implémente quoi que ce soit pour un projet qui en est encore au stade de la planification ou du financement.

Je suis d’accord pour dire que le sondage (polling) est sous-optimal ! C’est pourquoi la solution proposée consistant à interroger le système lors de la connexion de l’utilisateur semble être un bon compromis entre [l’intérêt de l’utilisateur pour] la cohérence et le fait de ne pas solliciter excessivement les serveurs de Codeforces, ce qui pourrait attirer l’attention et entraîner un éventuel blocage.

Si notre cas spécifique pour la communauté brésilienne est un succès et que d’autres communautés tentent de faire de même, peut-être que Mike (la seule personne responsable de Codeforces) implémentera quelque chose de similaire.

Néanmoins, merci beaucoup pour vos suggestions ! Je les garderai à l’esprit lors de ma prochaine rencontre avec Mike en juin de l’année prochaine, où je pourrai essayer de le convaincre de nous aider et, éventuellement, d’optimiser la solution que notre forum utilisera à ce moment-là.