Implementación
Crear una instancia de AudioRecognition
Cree un SORIAudioRecognizer con las credenciales de su aplicación SORI. No escriba credenciales reales directamente en código fuente público. Cárguelas mediante la configuración de la versión, un almacenamiento seguro o un proceso de compilación específico del entorno.
El siguiente ejemplo utiliza valores de --dart-define para evitar que el código fuente contenga datos confidenciales:
import 'package:sorisdk_flutter/sorisdk_flutter.dart';
const applicationId = String.fromEnvironment('SORI_APP_ID');
const secretKey = String.fromEnvironment('SORI_SECRET_KEY');
final recognizer = SORIAudioRecognizer(
applicationId: applicationId,
secretKey: secretKey,
);
await recognizer.configure();Ejecute la aplicación con los valores proporcionados por su entorno local o de CI:
flutter run \
--dart-define=SORI_APP_ID=your-application-id \
--dart-define=SORI_SECRET_KEY=your-secret-keyWARNING
app_id y secret_key autentican su aplicación ante el servidor de la API de SORI. No incluya valores reales en commits de repositorios, aplicaciones de ejemplo, incidencias, capturas de pantalla ni documentación pública.
Reconocedor Web
Las compilaciones para navegadores no deben contener el secret_key de larga duración de SORI. Después de preparar el bridge Web durante la instalación, cree el reconocedor con un endpoint de clave efímera en el servidor de su aplicación:
final recognizer = SORIAudioRecognizer.web(
applicationId: applicationId,
webAuth: SORIWebAuthOptions.ephemeralKeyEndpoint(
Uri.parse('/api/sori/ephemeral-key'),
requestCredentials: SORIWebRequestCredentials.sameOrigin,
),
);
await recognizer.configure();Proteja el endpoint con los mismos controles de sesión, origen, CSRF y limitación de frecuencia que utiliza para las demás API de su aplicación. El secret_key de larga duración permanece en el servidor, mientras que applicationId se compila en la aplicación del navegador y no es secreto. El endpoint solo devuelve al navegador la clave efímera de corta duración. Consulte Clave efímera.
Escuchar eventos de reconocimiento
Suscríbase a recognizer.events antes de iniciar el reconocimiento. Según el evento de la plataforma nativa, la información de la campaña estará disponible en event.campaign o en el payload del evento.
import 'dart:async';
import 'package:sorisdk_flutter/sorisdk_flutter.dart';
late final SORIAudioRecognizer recognizer;
StreamSubscription<SORIRecognitionEvent>? subscription;
subscription = recognizer.events.listen((event) {
if (event.type == SORIRecognitionEventType.stateChanged) {
final state = event.payload['state'];
// Update your UI for STARTING, STARTED, or stopped states.
}
final campaign = event.campaign;
if (campaign != null) {
// Render campaign.name, campaign.imageUrl, and campaign.actionUrl.
final marker = campaign.trait?.marker;
if (marker != null) {
// Optionally use the Audio Marker code attached to this campaign.
}
}
if (event.type == SORIRecognitionEventType.audioMarkerChanged) {
final marker = event.audioMarker;
// Update marker-specific UI or state.
}
if (event.type == SORIRecognitionEventType.error ||
event.type == SORIRecognitionEventType.networkError) {
// Show event.message in your app's error UI.
}
});Conciliar el segmento de actividad actual
Los eventos de campaña y reconocimiento exponen un event.activityId opcional, mientras que una campaña puede exponer event.campaign?.materialId y event.campaign?.trait?.marker. Muestre inmediatamente el primer evento de campaña y mantenga un segmento actual explícito en el estado de la aplicación.
- Un evento posterior con el mismo
event.activityIdno vacío solo puede refinar la fila actual. No busque filas anteriores ni derive la identidad de actividad de los ID de campaña o material. - Los servidores anteriores pueden devolver un ID de actividad null. Un fallback mediante material solo es seguro cuando la fila actual tiene el mismo
event.campaign?.materialIdno vacío. - Conserve la hora, la posición y los demás metadatos de UI de la primera observación de la fila actual. Los reporters nativos y Web anclan sus metadatos de transporte a la primera observación; la aplicación no debe sustituirlos por la hora del callback de refinamiento.
- Conserve el primer marker y los campos de campaña refinados cuando un evento posterior no tenga marker o incluya datos de campaña menos completos.
- Un evento
campaignFoundorecognitionResultde otro material, o una parada explícita del reconocimiento, cierra el segmento. Ignore los refinamientos retrasados de una actividad anterior después de ese punto.audioMarkerChangedno cierra el segmento. SORIRecognitionEventType.audioMarkerChangedsigue siendo un estado de marker observable de forma independiente. Por sí solo no crea ni refina una fila de campaña.
A(activity-1) -> A'(activity-1, marker) -> A(activity-1, marker miss) es una sola fila que conserva el marker. A(activity-1) -> B(activity-2) -> delayed A'(activity-1) mantiene B como actual y no modifica la A histórica.
Cancele la suscripción cuando se descarte el ámbito del widget o de la aplicación:
await subscription?.cancel();Iniciar y detener el reconocimiento
Llame a startRecognition() después de configurar el reconocedor y cuando la interfaz de usuario esté lista para recibir eventos.
await recognizer.startRecognition(
notification: const SORIAndroidNotificationOptions(
title: 'SORI recognition',
body: 'Listening for SORI audio signals',
),
);La opción notification se utiliza para las notificaciones del servicio en primer plano de Android. En iOS y Web se ignora. En Web, llame a startRecognition() desde una acción del usuario para que el navegador pueda solicitar permiso para usar el micrófono.
Para detener el reconocimiento:
await recognizer.stopRecognition();También puede consultar el estado actual de la grabadora:
final isRunning = await recognizer.isRecorderRunning();Activar el reconocimiento de Audio Marker
El reconocimiento de Audio Marker está desactivado de forma predeterminada. Actívelo solo si su configuración de SORI Console utiliza Audio Markers.
await recognizer.configure(
config: const SORIRecognitionConfig(audiomarker: true),
);Cuando está activado, los cambios de estado exclusivos del marcador se emiten como SORIRecognitionEventType.audioMarkerChanged y el marcador más reciente puede leerse en event.audioMarker. Si se encuentra una campaña con un marcador, este también está disponible en event.campaign?.trait?.marker.
Gestionar las acciones de campaña
Cuando una campaña tenga una URL de acción, decida en su aplicación si debe abrirse. Después de que la aplicación acepte la URL, llame a handleActionUrl() para informar de la interacción y gestionarla mediante el SDK.
final actionUrl = campaign.actionUrl;
if (actionUrl != null && actionUrl.isNotEmpty) {
await recognizer.handleActionUrl(actionUrl);
}Actualizar la base de datos de reconocimiento
El SDK puede solicitar al reconocedor nativo que actualice su base de datos de reconocimiento local.
Actualmente, updateDatabase() no es compatible con Web.
final result = await recognizer.updateDatabase();
if (!result.success) {
// Inspect result.errorMessage and show a retry option if needed.
}