backend: Exposes captions config via internal API

Adds an internal API endpoint to retrieve the captions configuration,
allowing the frontend to determine whether captions are enabled.
The configuration is read from the MEET_CAPTIONS_ENABLED environment variable.
This commit is contained in:
CSantosM 2026-01-28 15:21:00 +01:00
parent 30bd4b5a41
commit 43f7ff5001
9 changed files with 82 additions and 2 deletions

View File

@ -0,0 +1,5 @@
description: Successfully retrieved captions config
content:
application/json:
schema:
$ref: '../../schemas/internal/global-captions-config.yaml'

View File

@ -0,0 +1,8 @@
type: object
properties:
enabled:
type: boolean
description: Indicates whether captions are enabled in the system
example: true
required:
- enabled

View File

@ -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}:

View File

@ -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'

View File

@ -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');
}
};

View File

@ -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() {

View File

@ -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);

View File

@ -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']();

View File

@ -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 });
});
});
});