Projet

Général

Profil

Development #66156

connecteur Big Blue Button

Ajouté par Benjamin Dauvergne il y a presque 2 ans. Mis à jour il y a presque 2 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Version cible:
-
Début:
13 juin 2022
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

Je vais commencer par pomper un truc qui existe déjà (https://github.com/Execut3/django-bigbluebutton/blob/master/django_bigbluebutton/bbb.py) puis je vais itérer, l'idée étant d'avoir un modèle pour identifier le point de RdV d'un meetin entre un ou plusieurs personnes (un peu ce que fait Greenlight), la conf réelle étant créée au dernier moment.

class Meeting(Model):
    guid = UUID(unique=True)
    idempotent_id = Text(unique=True)
    data = JSON()
...
meeting.data['bbb_create'] <- retour de l'API BBB /create/
API:
  • POST /meeting/?idempotent-id=xyz
    {
      'id': 'abcd1234ffff000000000000000000',
      'idempotent_id': 'xyz',
      'url': '/bbb/slug/meeting/abcd1234ffff000000000000000000/'
      'user_url': '/bbb/slug/meeting/abcd1234ffff000000000000000000/join/user/?key=xyz',
      'agent_url': '/bbb/slug/meeting/abcd1234ffff000000000000000000/join/user/?key=abc'
    }
  • GET /meeting/abcd1234ffff000000000000000000/
    {
      'id': 'abcd1234ffff000000000000000000',
      'idempotent_id': 'xyz',
      'url': '/bbb/slug/meeting/abcd1234ffff000000000000000000/',
      'user_url': '/bbb/slug/meeting/abcd1234ffff000000000000000000/join/user/?key=xyz',
      'agent_url': '/bbb/slug/meeting/abcd1234ffff000000000000000000/join/user/?key=abc'
    }

Fichiers

Révisions associées

Révision ebc6ed23 (diff)
Ajouté par Benjamin Dauvergne il y a presque 2 ans

add connector for BigBlueButton (#66156)

Historique

#1

Mis à jour par Benjamin Dauvergne il y a presque 2 ans

  • Description mis à jour (diff)
#2

Mis à jour par Benjamin Dauvergne il y a presque 2 ans

  • Description mis à jour (diff)
#3

Mis à jour par Benjamin Dauvergne il y a presque 2 ans

#4

Mis à jour par Benjamin Dauvergne il y a presque 2 ans

Rien de transcendant, le workflow doit faire un POST sur /bbb/slug/meeting/ avec comme payload :

{
   "name": "Nom de la conf",
   "idempotent_id": "identifiant du formulaire",
   "create_parameters": { // toute sorte de flag que BBB accepte mais le plus courant dans un premier temps, logoutURL, l'URL où revenir quand la conf ferme
       "logoutURL": "https://wcs/form/1234/" 
   }
}

Ça retourne ça :
{
   "err" : 0,
   "data" : {
      "created" : "2022-01-01T12:00:00Z",
      "updated" : "2022-01-01T12:00:00Z",
      "guid" : "1999",
      "idempotent_id" : "10",
      "is_running_url" : "http://testserver/bbb/test/meeting/1999/",
      "join_agent_url" : "http://testserver/bbb/test/meeting/1999/join/agent/2b2111/",
      "join_user_url" : "http://testserver/bbb/test/meeting/1999/join/user/fb918f/",
      "name" : "RDV",
      "running" : false,
      "last_time_running" : null,
      "url" : "http://testserver/bbb/test/meeting/1999/",
      "bbb_meeting_info" : {
         "create_time" : 1234,
         "logout_url" : "https://portal/" 
      }
   }
}  

Les deux URLs de join sont à utiliser pour envoyer soit l'agent (modérateur) soit l'usager vers la conférence (via un lien, une iframe, une popup, comme vous voulez).
"is_running_url" est appelable en Ajax/CORS pour détecter si la conférence est démarrée (

$.ajax({ url: "{{ visio_response_data_is_running_url }}", success: function(data) { if (data.data) { $('#join-button').show(); } }});
).

#5

Mis à jour par Frédéric Péters il y a presque 2 ans

(ceci n'est pas une relecture)

passerelle/apps/bbb/templates/bbb/resource_detail.html

{% extends "passerelle/manage/service_view.html" %}
{% load i18n passerelle %}

C'est un reste de fichier qui contenait quelque chose à un moment et qui pourrait être supprimé ?

#6

Mis à jour par Benjamin Dauvergne il y a presque 2 ans

Frédéric Péters a écrit :

C'est un reste de fichier qui contenait quelque chose à un moment et qui pourrait être supprimé ?

Je pensais que j'en aurai besoin et puis non; c'est supprimé dans la branche.

#7

Mis à jour par Benjamin Dauvergne il y a presque 2 ans

  • Statut changé de Solution proposée à En cours

Des besoin supplémentaires sont apparus en discutant avec Anaïs.

#9

Mis à jour par Benjamin Dauvergne il y a presque 2 ans

  • Statut changé de En cours à Solution proposée

Branche à jour.

PS: j'ai rajouté les fonctionnalités suivantes :
  • possibilité de définir des paramètres pour l'appel join au moment de la création (champs "join_user_parameters/join_agent_parameters")
  • possibilité de définir le paramètre "fullName" pour les appels joins au moment de la création et si absent à la création et lors de l'appel à /join/user/ ou /join/agent/ par défaut ça pose "Usager" et "Agent" (pour éviter d'être bloqué le paramètre étant obligatoire pour BBB)
  • champ libre "metadata" pour rendre l'objet autonome, par exemple pour avoir une page dans combo (/rdv-visio/{guid}/) qui donnerait une page d'accueil pour une vision, rappellerait l'heure du RdV et n'afficherait le bouton pour rejoindre la conf qu'au bon moment (il y a un besoin que ces visioconf soit accessibles sans utilisateur connecté), le plus simple c'est d'attaché toutes ces informations à l'objet représentant le rdv directement, l'uuid suffit à rendre ça suffisamment "privé" (on aurait pu se baser sur un rdv chrono pour y stocker des trucs, mais on a pas d'uuid)
#10

Mis à jour par Thomas Noël il y a presque 2 ans

  • Le payload n'est pas un dictonnaire à plat, il ne peut pas être géré par w.c.s., il le sera pas un autre truc ?
  • sur meetings_endpoint avec update=1 on peut quand même avoir création (update_or_create), si c'est bien ce qui est voulu, modifier la doc de update "Update existing meeting" → "Update meeting if exists, or create a new one". Ou alors tenter un update et APIError en cas de pépin... ça aurait ma préférence dans une première version, sauf si à l'usage tu sais déjà que le update=1 pourrait être lancé sur un meeting inexistant...
  • de l'autre côté, en cas de update=0, si ça existe déjà on ne va rien laisser paraître et juste renvoyer l'existant. Là aussi je préférerais être sans magie, create et APIError si ça rate.
  • les get_object_or_404, ils ne vont pas lancer du APIError comme il faut, avec err:1 et tout ça. Ca serait mieux, quand même.
  • les codes de Meeting.url et Meeting.is_running_url sont identiques, il manque sans doute le 'is-running/' final dans le rest du second
  • sur les tests, en regardant la couverture, je dirais qu'il manque des appels à BBB.is_meeting_running, BBB.Meeting.update, BBB.Meeting.update_is_running ainsi que quelques cas non passants si tu veux passer à 100%
Plus divers petites choses :
  • Copyright (C) 2019, mais achète toi une DeLorean quoi :)
  • typo dans le help_text de l'attribut shared_secret : Shared ecret → Shared secret
  • agent_full_name = models.TextField(_('User full name'), null=True) → c'est 'Agent full name'
  • join_agent_parameters = JSONField('Join user parameters', null=True) → c'est 'Join agent parameters'
  • pour check_status tu peux ne pas avoir de try/except, n'importe quelle exception roule
#11

Mis à jour par Frédéric Péters il y a presque 2 ans

Le payload n'est pas un dictonnaire à plat, il ne peut pas être géré par w.c.s., il le sera pas un autre truc ?

il y a unflatten: True pour ça.

#12

Mis à jour par Thomas Noël il y a presque 2 ans

Frédéric Péters a écrit :

Le payload n'est pas un dictonnaire à plat, il ne peut pas être géré par w.c.s., il le sera pas un autre truc ?

il y a unflatten: True pour ça.

Oups, effectivement, je l'ai eu raté.

#13

Mis à jour par Benjamin Dauvergne il y a presque 2 ans

Thomas Noël a écrit :

  • sur meetings_endpoint avec update=1 on peut quand même avoir création (update_or_create), si c'est bien ce qui est voulu, modifier la doc de update "Update existing meeting" → "Update meeting if exists, or create a new one". Ou alors tenter un update et APIError en cas de pépin... ça aurait ma préférence dans une première version, sauf si à l'usage tu sais déjà que le update=1 pourrait être lancé sur un meeting inexistant...
  • de l'autre côté, en cas de update=0, si ça existe déjà on ne va rien laisser paraître et juste renvoyer l'existant. Là aussi je préférerais être sans magie, create et APIError si ça rate.

Clairement l'API sur ces points n'est pas claire pour tout le monde, j'ai préféré virer le update, de toute façon je ne suis pas certain que coté BBB si une conférence est déjà créée on puisse la modifier et de toute façon ce sont des objets jetables, si besoin d'avoir une nouvelle conférence il faudra en créer une nouvelle (et donc changer le idempotent_id). L'important ici c'est justement qu'en cas de création ça réussit toujours pourvu que le paramétrage n'ait pas changé, ça réplique le fonctionnement de BBB sur ce point, donc non pas de APIError, ça casse totalement l'idée que l'appel soit idempotent et ne nécessite pas de gestion d'erreur (si err=1, c'est une erreur irrécupérable on s'arrête), uniquement une boucle si on a une erreur réseau ou HTTP.

  • les get_object_or_404, ils ne vont pas lancer du APIError comme il faut, avec err:1 et tout ça. Ca serait mieux, quand même.

Ah je croyais... en fait si on a status_code=404 mais on a bien un contenu json produit via jsonresponse dans les cas ObjectDoesNotExist et Http404.

  • les codes de Meeting.url et Meeting.is_running_url sont identiques, il manque sans doute le 'is-running/' final dans le rest du second

Bien vu.

  • sur les tests, en regardant la couverture, je dirais qu'il manque des appels à BBB.is_meeting_running, BBB.Meeting.update, BBB.Meeting.update_is_running ainsi que quelques cas non passants si tu veux passer à 100%

J'ai ajouté du code pour la couverture.

Plus divers petites choses :
  • Copyright (C) 2019, mais achète toi une DeLorean quoi :)
  • typo dans le help_text de l'attribut shared_secret : Shared ecret → Shared secret
  • agent_full_name = models.TextField(_('User full name'), null=True) → c'est 'Agent full name'
  • join_agent_parameters = JSONField('Join user parameters', null=True) → c'est 'Join agent parameters'
  • pour check_status tu peux ne pas avoir de try/except, n'importe quelle exception roule

Tout corrigé, branche à jour.

#14

Mis à jour par Thomas Noël il y a presque 2 ans

Benjamin Dauvergne a écrit :

...

Parfait, sans le update c'est plus clair, on verra si le besoin se fait sentir, j'en doute.

Il reste ces petits points qui ne sont pas dans la branche :

  • typo dans le help_text de l'attribut shared_secret : Shared ecret → Shared secret
  • agent_full_name = models.TextField(_('User full name'), null=True) → c'est 'Agent full name'
  • join_agent_parameters = JSONField('Join user parameters', null=True) → c'est 'Join agent parameters'
  • pour check_status tu peux ne pas avoir de try/except, n'importe quelle exception roule

et juste au cas où : attention les migrations vont devoir aussi bouger un peu sur les help_text et autres

#15

Mis à jour par Benjamin Dauvergne il y a presque 2 ans

Thomas Noël a écrit :

Benjamin Dauvergne a écrit :

...

Parfait, sans le update c'est plus clair, on verra si le besoin se fait sentir, j'en doute.

Il reste ces petits points qui ne sont pas dans la branche :

Déso, pas re-re-poussé.

et juste au cas où : attention les migrations vont devoir aussi bouger un peu sur les help_text et autres

Yep c'est poussé aussi.

#16

Mis à jour par Thomas Noël il y a presque 2 ans

  • Statut changé de Solution proposée à Solution validée

... squash and push !

#17

Mis à jour par Benjamin Dauvergne il y a presque 2 ans

  • Statut changé de Solution validée à Résolu (à déployer)
commit ebc6ed23435628f1285a20bdf6cc7bf9eb9aa815
Author: Benjamin Dauvergne <bdauvergne@entrouvert.com>
Date:   Tue Jun 14 15:46:11 2022 +0200

    add connector for BigBlueButton (#66156)
#18

Mis à jour par Transition automatique il y a presque 2 ans

  • Statut changé de Résolu (à déployer) à Solution déployée
#19

Mis à jour par Transition automatique il y a plus d'un an

Automatic expiration

Formats disponibles : Atom PDF