## (FS-33) CU-03-005: Integración técnica con BigBlueButton

**Fecha:** 05 de marzo de 2026  
**Caso de uso:** CU-03-005 – Instructor programa sesión en vivo  
**Ámbito:** Integración técnica con BigBlueButton (BBB) para sesiones en vivo

---

## 🎯 Objetivo del documento

Este documento complementa la especificación funcional de la sesión en vivo (`(FS-33) CU-03-005: Instructor Programa Sesión en Vivo`) y se enfoca en:

- **Qué se agregó/modificó en el código** para integrar BigBlueButton.
- **Cómo es el flujo de trabajo técnico** desde que el instructor programa la sesión hasta que entra a la sala BBB.
- **Qué variables nuevas deben configurarse en `.env`** y cómo se conectan con `config/bigbluebutton.php`.
- **Cómo se usa la API oficial de BBB** y el paquete `joisarjignesh/bigbluebutton` como referencia.

---

## 🧩 Archivos agregados y modificados

- **Agregado – Servicio BBB**
  - `app/Services/BigBlueButtonService.php`
  - **Por qué:** Encapsula todas las llamadas HTTP a la API de BigBlueButton (`create`, `join`, `isMeetingRunning`, `end`), generando el `checksum` tal como indica la documentación oficial de BBB (`callName + queryString + sharedSecret` usando `sha1`), basado en:
    - Configuración local `config/bigbluebutton.php`.
    - Variables de entorno `BBB_URL` y `BBB_SECRET`.

- **Agregado – Configuración dedicada de BBB**
  - `config/bigbluebutton.php`
  - **Por qué:** Se publicó el archivo de configuración del paquete [`joisarjignesh/bigbluebutton`](https://github.com/joisarjignesh/bigbluebutton), y se adaptó para leer:
    - `BBB_SECURITY_SALT` desde `env('BBB_SECRET')`.
    - `BBB_SERVER_BASE_URL` desde `env('BBB_URL')`.
  - También se documentan opciones del endpoint `create` que son compatibles con la API oficial de BBB (`record`, `duration`, `maxParticipants`, `guestPolicy`, `disabledFeatures`, etc.), alineadas con la referencia de API de BBB: [API Reference – create](https://docs.bigbluebutton.org/development/api/#create).

- **Modificado – Componente Livewire de creación**
  - `app/Livewire/Instructor/LiveSessions/Create.php`
  - **Cambios clave:**
    - Antes de guardar la sesión:
      - Verifica que el tenant esté inicializado.
      - Verifica que exista la tabla `live_sessions`.
      - Verifica **conflictos de horario**.
      - **Verifica conectividad con BBB** usando `BigBlueButtonService::isConnected()`.
    - Al guardar:
      - Crea el registro en `live_sessions` (las credenciales BBB se generan automáticamente en el modelo).
      - Llama a `BigBlueButtonService::createMeeting()` para crear la reunión en BBB con:
        - `name`, `meetingID`, `attendeePW`, `moderatorPW`
        - `welcome`, `record`, `duration`, `maxParticipants`
      - Si BBB falla, **la sesión se guarda igual**, pero se registra el error mediante `InstructorPanelLogger`.

- **Modificado – Modelo de dominio de sesiones**
  - `app/Models/LiveSession.php`
  - **Cambios clave:**
    - Evento `creating` en el `boot()`:
      - Genera automáticamente:
        - `bbb_meeting_id = 'bbb-' . Str::random(20)`
        - `bbb_moderator_password = Str::random(12)`
        - `bbb_attendee_password = Str::random(12)`
    - Exposición de helpers de estado (`isScheduled`, `isLive`, `isCompleted`, `isCancelled`) y atributos derivados (`available_spots`, `type_label`, `status_label`) para la UI.

- **Modificado – Rutas de tenant para unirse a la sesión**
  - `routes/tenant.php`
  - **Nueva ruta para instructores:**
    - `GET /instructor/live-sessions/{liveSession}/join`
    - **Lógica:**
      - Verifica que el usuario autenticado sea el `instructor_id` de la sesión.
      - Verifica que el `status` de la sesión sea `scheduled` o `live`.
      - Usa `BigBlueButtonService::joinMeeting()` para construir la URL de unión a BBB, siempre como **MODERATOR** para el instructor.
      - Redirige con `redirect()->away($joinUrl)`.

- **Modificado – Vista de listado de sesiones en vivo**
  - `resources/views/livewire/instructor/live-sessions/index.blade.php`
  - **Cambio relevante (validado por tests):**
    - Botón "Unirse" apunta a `route('instructor.live-sessions.join', $session)` y se abre en nueva pestaña (`target="_blank"`), de manera que:
      - El panel del instructor permanece abierto.
      - La sala de BBB se abre en otra pestaña.

- **Agregado – Tests de integración LiveSession + BBB**
  - `tests/Feature/InstructorLiveSessionJoinTest.php`
  - **Qué verifican:**
    - El instructor es redirigido a la URL de unión de BBB usando `BigBlueButtonService::joinMeeting`.
    - Un usuario que no es el instructor recibe `403 Forbidden`.
    - La vista index muestra el botón de unión con `target="_blank"` y la URL correcta de la ruta `instructor.live-sessions.join`.
    - No se permite unirse cuando la sesión **no** está en estado `scheduled` o `live`.

---

## 🔐 Variables de entorno y configuración BBB

### 1. Variables en `.env`

En el archivo `.env` se deben definir las credenciales del servidor BigBlueButton:

```env
# BigBlueButton Configuration
BBB_URL=https://tu-servidor-bbb.com/bigbluebutton
BBB_SECRET=TU_SECRET_BBB_AQUI
```

- **`BBB_URL`**
  - Debe apuntar a la **URL base** del servidor BBB, normalmente terminando en `/bigbluebutton` (sin `/api` extra).
  - Ejemplo válido: `https://bbb1-statg.futurum.pe/bigbluebutton`
  - Coincide con la recomendación de la documentación oficial de BBB: el endpoint de API suele ser `https://servidor.com/bigbluebutton/api`.

- **`BBB_SECRET`**
  - Es el `securitySalt`/`sharedSecret` configurado en el servidor BBB.
  - Se puede obtener en el servidor con:
    - `bbb-conf --secret`
  - Es usado para generar el `checksum` con `sha1(callName + queryString + sharedSecret)` como indica la documentación: [API Security Model](https://docs.bigbluebutton.org/development/api/#api-security-model).

> **Importante:** Nunca exponer `BBB_SECRET` ni valores reales de `.env` en la interfaz de usuario o en logs accesibles públicamente.

### 2. Configuración Laravel `config/bigbluebutton.php`

El archivo `config/bigbluebutton.php` mapea las variables de entorno a la configuración interna del paquete:

- **Clave principal:**
  - `BBB_SECURITY_SALT` → `env('BBB_SECRET', '')`
  - `BBB_SERVER_BASE_URL` → `env('BBB_URL', '')`
- **Algoritmo de hash:**
  - `hash_algorithm` = `'sha1'` (compatible con la implementación de `BigBlueButtonService::generateChecksum`).
- **Sección `create`:**
  - Incluye valores por defecto para:
    - `passwordLength`, `welcomeMessage`, `maxParticipants`, `record`, `duration`, `guestPolicy`, `disabledFeatures`, etc.
  - Estos parámetros siguen la especificación de `/create` documentada en: [API Reference – create](https://docs.bigbluebutton.org/development/api/#create).

El servicio `BigBlueButtonService` **no** usa directamente la facade del paquete, pero se apoya en esta configuración para leer la URL base y el secret de BBB.

---

## 🔄 Flujo de trabajo técnico

### 1. Programar sesión en vivo (instructor)

1. El instructor accede a:
   - Ruta: `/instructor/live-sessions`
   - Componente: `App\Livewire\Instructor\LiveSessions\Index`
2. Hace clic en **"Programar Nueva Sesión"**:
   - Ruta: `/instructor/live-sessions/create`
   - Componente: `App\Livewire\Instructor\LiveSessions\Create`
3. Completa el formulario:
   - Título, descripción, curso opcional.
   - Fecha, hora, duración.
   - Tipo de sesión (`one_to_one` o `group`).
   - Cupos (`max_participants`) y lista de espera.
   - Opciones de grabación (`record_session`) y recordatorios.
4. Al hacer clic en **"Programar Sesión"**:
   - Se ejecuta `Create::save()`:
     - Valida reglas de negocio y conflicto de horario.
     - Verifica que exista la tabla `live_sessions`.
     - Verifica la configuración y **conectividad con BBB**:
       - Instancia `BigBlueButtonService`.
       - Llama a `isConnected()`.
       - Si falla, muestra error: _"No se puede conectar con BigBlueButton. Verifica la configuración."_ y no crea la sesión.

### 2. Creación de la sesión y reunión en BBB

Si todo es válido:

1. Se abre una transacción con `DB::beginTransaction()`.
2. Se crea el registro en `live_sessions`:
   - El `boot()` del modelo `LiveSession` genera:
     - `bbb_meeting_id`
     - `bbb_moderator_password`
     - `bbb_attendee_password`
3. Se confirma la transacción (`DB::commit()`).
4. Después, se intenta crear la reunión en BBB:
   - Se instancia de nuevo `BigBlueButtonService`.
   - Se llama a `createMeeting([...])` con parámetros alineados a la doc oficial:
     - `name` → Nombre de la sesión.
     - `meetingID` → `bbb_meeting_id`.
     - `attendeePW` / `moderatorPW`.
     - `welcome` → mensaje de bienvenida.
     - `record` → según `record_session`.
     - `duration` → `duration_minutes`.
     - `maxParticipants` → `max_participants`.
   - Internamente:
     - Construye el `queryString`.
     - Calcula `checksum = sha1('create' . queryString . secret)`.
     - Llama a `GET {BBB_URL}/api/create?...&checksum=...`.
   - Si BBB responde `returncode != SUCCESS` o hay error de red:
     - Se lanza excepción capturada en `Create::save()`, se loguea el error, pero **no** se hace rollback de la sesión ya creada.

### 3. Unirse a la sesión (instructor)

Cuando llega la hora de la sesión:

1. Desde el listado `/instructor/live-sessions`, el instructor ve un botón **"Unirse"**:
   - URL: `route('instructor.live-sessions.join', $session)`
   - Target: `_blank` (abre BBB en nueva pestaña).
2. La ruta `instructor.live-sessions.join` ejecuta un closure en `routes/tenant.php`:
   - Verifica que el usuario autenticado sea el `instructor_id` de la sesión.
   - Verifica que el `status` de la sesión sea `scheduled` o `live`.
   - Instancia `BigBlueButtonService`.
   - Llama a `joinMeeting($meetingID, $fullName, $moderatorPW, 'MODERATOR')`.
   - Recibe una URL construida según la doc oficial:
     - `GET {BBB_URL}/api/join?meetingID=...&fullName=...&password=...&role=MODERATOR&checksum=...`
   - Redirige con `redirect()->away($joinUrl)`.

> Este flujo respeta el modelo recomendado por BBB: las llamadas API (`create`, `join`, `isMeetingRunning`, `end`) se hacen **desde el servidor**, nunca desde el navegador, y usan el `checksum` basado en el secret compartido.

---

## 🧪 Tests relacionados

Archivo: `tests/Feature/InstructorLiveSessionJoinTest.php`

- **`redirects instructor to the BBB join url`**
  - Mockea `BigBlueButtonService` y verifica que:
    - Se llame a `joinMeeting('bbb-test', $user->name, 'modpw', 'MODERATOR')`.
    - La respuesta redirige a la URL generada.

- **`forbids non-instructor from joining the session`**
  - Verifica que otro usuario (no instructor de la sesión) reciba `403 Forbidden`.

- **`renders join button with target blank in index view`**
  - Valida que la vista index incluya:
    - `target="_blank"`.
    - La ruta `instructor.live-sessions.join` para la sesión.

- **`does not allow joining when status is not scheduled or live`**
  - Verifica que sesiones con estado `completed` no permitan el join (403).

Estos tests aseguran que:

- La integración con BBB se usa solo en los escenarios permitidos.
- El instructor siempre entra como moderador.
- La UI refleja correctamente el flujo de unión a la sala BBB.

---

## 📚 Referencias externas

- **Paquete Laravel BBB:**
  - [`joisarjignesh/bigbluebutton` – GitHub](https://github.com/joisarjignesh/bigbluebutton)  
    Usado como referencia para:
    - Estructura de configuración (`config/bigbluebutton.php`).
    - Opciones de `create`, `join`, `getRecordings`, etc.

- **Documentación oficial BigBlueButton:**
  - [API Reference – create](https://docs.bigbluebutton.org/development/api/#create)  
    Usada para:
    - Parámetros soportados (`name`, `meetingID`, `attendeePW`, `moderatorPW`, `record`, `duration`, `maxParticipants`, `guestPolicy`, etc.).
    - Modelo de seguridad (uso de `checksum` con `sha1` y `sharedSecret`).
    - Flujo recomendado de creación y unión a reuniones.

---

## ✅ Resumen

- Se integró BigBlueButton en el flujo de sesiones en vivo mediante:
  - Servicio dedicado `BigBlueButtonService`.
  - Configuración centralizada en `config/bigbluebutton.php` + `.env`.
  - Generación automática de credenciales BBB en el modelo `LiveSession`.
  - Ruta protegida para que el instructor se una como moderador.
  - Tests de feature que validan el flujo de unión y las restricciones de acceso.
- La implementación sigue las recomendaciones oficiales de BBB y se apoya en la configuración del paquete `joisarjignesh/bigbluebutton` para mantener consistencia y extensibilidad futura.

