diff --git a/meet-ce/backend/openapi/components/responses/internal/success-get-captions-config.yaml b/meet-ce/backend/openapi/components/responses/internal/success-get-captions-config.yaml new file mode 100644 index 00000000..1d156c57 --- /dev/null +++ b/meet-ce/backend/openapi/components/responses/internal/success-get-captions-config.yaml @@ -0,0 +1,5 @@ +description: Successfully retrieved captions config +content: + application/json: + schema: + $ref: '../../schemas/internal/global-captions-config.yaml' diff --git a/meet-ce/backend/openapi/components/schemas/internal/global-captions-config.yaml b/meet-ce/backend/openapi/components/schemas/internal/global-captions-config.yaml new file mode 100644 index 00000000..e544a4fb --- /dev/null +++ b/meet-ce/backend/openapi/components/schemas/internal/global-captions-config.yaml @@ -0,0 +1,8 @@ +type: object +properties: + enabled: + type: boolean + description: Indicates whether captions are enabled in the system + example: true +required: + - enabled diff --git a/meet-ce/backend/openapi/openvidu-meet-internal-api.yaml b/meet-ce/backend/openapi/openvidu-meet-internal-api.yaml index b5b1b995..96f13ffa 100644 --- a/meet-ce/backend/openapi/openvidu-meet-internal-api.yaml +++ b/meet-ce/backend/openapi/openvidu-meet-internal-api.yaml @@ -32,6 +32,8 @@ paths: $ref: './paths/internal/meet-global-config.yaml#/~1config~1security' /config/rooms/appearance: $ref: './paths/internal/meet-global-config.yaml#/~1config~1rooms~1appearance' + /config/captions: + $ref: './paths/internal/meet-global-config.yaml#/~1config~1captions' /rooms/{roomId}/token: $ref: './paths/internal/rooms.yaml#/~1rooms~1{roomId}~1token' /meetings/{roomId}: diff --git a/meet-ce/backend/openapi/paths/internal/meet-global-config.yaml b/meet-ce/backend/openapi/paths/internal/meet-global-config.yaml index 2b409ca2..9c2496f1 100644 --- a/meet-ce/backend/openapi/paths/internal/meet-global-config.yaml +++ b/meet-ce/backend/openapi/paths/internal/meet-global-config.yaml @@ -139,3 +139,20 @@ $ref: '../../components/responses/validation-error.yaml' '500': $ref: '../../components/responses/internal-server-error.yaml' + +/config/captions: + get: + operationId: getCaptionsConfig + summary: Get captions config + description: > + Retrieves the captions configuration from the environment variable MEET_CAPTIONS_ENABLED. + This endpoint returns whether captions are enabled in the system. + tags: + - Internal API - Global Config + responses: + '200': + $ref: '../../components/responses/internal/success-get-captions-config.yaml' + '401': + $ref: '../../components/responses/unauthorized-error.yaml' + '500': + $ref: '../../components/responses/internal-server-error.yaml' diff --git a/meet-ce/backend/src/controllers/global-config.controller.ts b/meet-ce/backend/src/controllers/global-config.controller.ts index 53920b73..5874b4cb 100644 --- a/meet-ce/backend/src/controllers/global-config.controller.ts +++ b/meet-ce/backend/src/controllers/global-config.controller.ts @@ -1,6 +1,7 @@ import { MeetAppearanceConfig, SecurityConfig, WebhookConfig } from '@openvidu-meet/typings'; import { Request, Response } from 'express'; import { container } from '../config/dependency-injector.config.js'; +import { MEET_ENV } from '../environment.js'; import { handleError } from '../models/error.model.js'; import { GlobalConfigService } from '../services/global-config.service.js'; import { LoggerService } from '../services/logger.service.js'; @@ -108,3 +109,16 @@ export const getRoomsAppearanceConfig = async (_req: Request, res: Response) => handleError(res, error, 'getting rooms appearance config'); } }; + +export const getCaptionsConfig = async (_req: Request, res: Response) => { + const logger = container.get(LoggerService); + + logger.verbose('Getting captions config'); + + try { + const captionsEnabled = MEET_ENV.CAPTIONS_ENABLED === 'true'; + return res.status(200).json({ enabled: captionsEnabled }); + } catch (error) { + handleError(res, error, 'getting captions config'); + } +}; diff --git a/meet-ce/backend/src/environment.ts b/meet-ce/backend/src/environment.ts index 43fcd499..8a2e2d2d 100644 --- a/meet-ce/backend/src/environment.ts +++ b/meet-ce/backend/src/environment.ts @@ -79,13 +79,14 @@ export const MEET_ENV = { REDIS_SENTINEL_PASSWORD: process.env.MEET_REDIS_SENTINEL_PASSWORD ?? '', REDIS_SENTINEL_MASTER_NAME: process.env.MEET_REDIS_SENTINEL_MASTER_NAME ?? 'openvidu', + // Live Captions configuration + CAPTIONS_ENABLED: process.env.MEET_CAPTIONS_ENABLED || 'false', + // Deployment configuration MODULES_FILE: process.env.MODULES_FILE || undefined, MODULE_NAME: process.env.MODULE_NAME || 'openviduMeet', ENABLED_MODULES: process.env.ENABLED_MODULES ?? '', - // Agent Speech Processing configuration - CAPTIONS_ENABLED: process.env.MEET_CAPTIONS || 'true', }; export function checkModuleEnabled() { diff --git a/meet-ce/backend/src/routes/global-config.routes.ts b/meet-ce/backend/src/routes/global-config.routes.ts index edc50cff..1ba95d8a 100644 --- a/meet-ce/backend/src/routes/global-config.routes.ts +++ b/meet-ce/backend/src/routes/global-config.routes.ts @@ -41,3 +41,6 @@ configRouter.put( globalConfigCtrl.updateRoomsAppearanceConfig ); configRouter.get('/rooms/appearance', withAuth(allowAnonymous), globalConfigCtrl.getRoomsAppearanceConfig); + +// Captions config +configRouter.get('/captions', withAuth(allowAnonymous), globalConfigCtrl.getCaptionsConfig); diff --git a/meet-ce/backend/tests/helpers/request-helpers.ts b/meet-ce/backend/tests/helpers/request-helpers.ts index 75ea3751..7c88047b 100644 --- a/meet-ce/backend/tests/helpers/request-helpers.ts +++ b/meet-ce/backend/tests/helpers/request-helpers.ts @@ -184,6 +184,13 @@ export const changeSecurityConfig = async (authMode: AuthMode) => { expect(response.status).toBe(200); }; +export const getCaptionsConfig = async () => { + checkAppIsRunning(); + + const response = await request(app).get(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/config/captions`).send(); + return response; +}; + export const restoreDefaultGlobalConfig = async () => { const configService = container.get(GlobalConfigService); const defaultGlobalConfig = configService['getDefaultConfig'](); diff --git a/meet-ce/backend/tests/integration/api/global-config/captions.test.ts b/meet-ce/backend/tests/integration/api/global-config/captions.test.ts new file mode 100644 index 00000000..ed19c6ef --- /dev/null +++ b/meet-ce/backend/tests/integration/api/global-config/captions.test.ts @@ -0,0 +1,23 @@ +import { beforeAll, describe, expect, it } from '@jest/globals'; +import { getCaptionsConfig, startTestServer } from '../../../helpers/request-helpers.js'; + +describe('Captions Config API Tests', () => { + beforeAll(async () => { + await startTestServer(); + }); + + describe('Get captions config', () => { + it('should return captions config when not authenticated', async () => { + const response = await getCaptionsConfig(); + expect(response.status).toBe(200); + expect(response.body).toHaveProperty('enabled'); + expect(typeof response.body.enabled).toBe('boolean'); + }); + + it('should return enabled true by default', async () => { + const response = await getCaptionsConfig(); + expect(response.status).toBe(200); + expect(response.body).toEqual({ enabled: true }); + }); + }); +});