feat: mid-flow audio — transcribed text goes to NormalBot, not NLU

When a user sends audio while in an active flow (__cap, __foreach,
collecting, __api_vars), the Whisper transcription is passed directly
to NormalBot as the step answer instead of going through NLU routing.

Bot still shows '🎤 Escuché: _texto_' confirmation before processing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-05 21:38:25 -05:00
co-authored by Claude Sonnet 4.6
parent 1114c52df4
commit d0c1b1d3be
+16 -2
View File
@@ -125,13 +125,20 @@ class BotRouter
if ($text !== null && trim($text) !== '') {
self::log("NLU media [{$inputType}]: texto extraído → \"{$text}\"");
// Confirmar al usuario lo que entendió
$prefix = $inputType === 'audio' ? '🎤 Transcripción' : '🖼️ Imagen analizada';
$prefix = $inputType === 'audio' ? '🎤 Escuché' : '🖼️ Imagen analizada';
WhatsAppSender::sendText(
$context['from'],
"{$prefix}: _{$text}_",
$context['phone_number_id'] ?? ''
);
// Si el usuario está en medio de un flujo activo, el texto va directo
// a NormalBot como respuesta al paso actual — no al NLU
if (self::hasActiveFlow((int)$company['id'], $context['from'])) {
self::log("NLU media: flujo activo detectado → NormalBot recibe \"{$text}\"");
return self::runNormalBot($company, $context, $text, 'text', false);
}
return self::runNluOnText($company, $context, $text, $config);
}
}
@@ -155,6 +162,13 @@ class BotRouter
return self::categoryMenuFallback($company, $context, $config);
}
private static function hasActiveFlow(int $companyId, string $phone): bool
{
$botCtx = ConversationContext::getOrCreate($companyId, $phone, 'normal');
$meta = ConversationContext::getMetadata((int)$botCtx['id']);
return !empty($meta['__cap']) || !empty($meta['__foreach']) || !empty($meta['collecting']) || !empty($meta['__api_vars']);
}
private static function runNluOnText(array $company, array $context, string $input, array $config): ?array
{
$result = AiBot::routeOrChat($company, $context, $input);