fix: resolveMenu usa menus fusionados de per_type + bugs de $endpoint y tipo de retorno
- resolveMenu ahora recibe los menus ya fusionados (global + per_type) para que flujos que referencian menús de otro per_type se resuelvan correctamente - handleFlow y processInteractive propagan el array de menus fusionados - Corrige variable indefinida $endpoint → $endpointKey en 3 logs de executeApiReport - buildMenuResponse cambia tipo de retorno a ?array para evitar TypeError en PHP 8 - BD: flow global show_main_menu apunta a menú show_main_menu (completo) en lugar de show_menu_cat2 (solo existía en per_type[2]), fix para usuarios permission_type=3 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
932a7a78a7
commit
e4841e2741
+20
-17
@@ -21,7 +21,7 @@ class NormalBot
|
|||||||
$normalized = self::normalize($input);
|
$normalized = self::normalize($input);
|
||||||
|
|
||||||
if ($currentNode !== null && isset($flows[$currentNode])) {
|
if ($currentNode !== null && isset($flows[$currentNode])) {
|
||||||
return self::handleFlow($flows[$currentNode], $context, $company, $ctxId);
|
return self::handleFlow($flows[$currentNode], $context, $company, $ctxId, $menus);
|
||||||
}
|
}
|
||||||
|
|
||||||
$matchedCommand = null;
|
$matchedCommand = null;
|
||||||
@@ -36,7 +36,7 @@ class NormalBot
|
|||||||
ConversationContext::updateNode($ctxId, $matchedCommand);
|
ConversationContext::updateNode($ctxId, $matchedCommand);
|
||||||
|
|
||||||
if (isset($flows[$matchedCommand])) {
|
if (isset($flows[$matchedCommand])) {
|
||||||
return self::handleFlow($flows[$matchedCommand], $context, $company, $ctxId);
|
return self::handleFlow($flows[$matchedCommand], $context, $company, $ctxId, $menus);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($menus[$matchedCommand])) {
|
if (isset($menus[$matchedCommand])) {
|
||||||
@@ -51,7 +51,7 @@ class NormalBot
|
|||||||
$greetingFlowId = $perType['greeting_flow'] ?? 'greeting';
|
$greetingFlowId = $perType['greeting_flow'] ?? 'greeting';
|
||||||
if (isset($flows[$greetingFlowId])) {
|
if (isset($flows[$greetingFlowId])) {
|
||||||
ConversationContext::updateNode($ctxId, $greetingFlowId);
|
ConversationContext::updateNode($ctxId, $greetingFlowId);
|
||||||
return self::handleFlow($flows[$greetingFlowId], $context, $company, $ctxId);
|
return self::handleFlow($flows[$greetingFlowId], $context, $company, $ctxId, $menus);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = self::sendText($greeting, $context['from'], $company);
|
$response = self::sendText($greeting, $context['from'], $company);
|
||||||
@@ -62,7 +62,7 @@ class NormalBot
|
|||||||
$fallbackFlowId = $perType['fallback_flow'] ?? $config['fallback_flow'] ?? null;
|
$fallbackFlowId = $perType['fallback_flow'] ?? $config['fallback_flow'] ?? null;
|
||||||
if ($fallbackFlowId !== null && isset($flows[$fallbackFlowId])) {
|
if ($fallbackFlowId !== null && isset($flows[$fallbackFlowId])) {
|
||||||
ConversationContext::updateNode($ctxId, $fallbackFlowId);
|
ConversationContext::updateNode($ctxId, $fallbackFlowId);
|
||||||
return self::handleFlow($flows[$fallbackFlowId], $context, $company, $ctxId);
|
return self::handleFlow($flows[$fallbackFlowId], $context, $company, $ctxId, $menus);
|
||||||
}
|
}
|
||||||
|
|
||||||
$fallback = $perType['fallback'] ?? $config['fallback'] ?? null;
|
$fallback = $perType['fallback'] ?? $config['fallback'] ?? null;
|
||||||
@@ -74,24 +74,26 @@ class NormalBot
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function resolveMenu($menuRef, array $company): array
|
private static function resolveMenu($menuRef, array $company, array $allMenus = []): array
|
||||||
{
|
{
|
||||||
if (is_string($menuRef)) {
|
if (is_string($menuRef)) {
|
||||||
|
if (isset($allMenus[$menuRef])) {
|
||||||
|
return $allMenus[$menuRef];
|
||||||
|
}
|
||||||
$config = self::getConfig($company);
|
$config = self::getConfig($company);
|
||||||
$menus = $config['menus'] ?? [];
|
return ($config['menus'] ?? [])[$menuRef] ?? [];
|
||||||
return $menus[$menuRef] ?? [];
|
|
||||||
}
|
}
|
||||||
return is_array($menuRef) ? $menuRef : [];
|
return is_array($menuRef) ? $menuRef : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function handleFlow(array $flow, array $context, array $company, int $ctxId): ?array
|
private static function handleFlow(array $flow, array $context, array $company, int $ctxId, array $menus = []): ?array
|
||||||
{
|
{
|
||||||
$type = $flow['type'] ?? 'text';
|
$type = $flow['type'] ?? 'text';
|
||||||
|
|
||||||
return match ($type) {
|
return match ($type) {
|
||||||
'text' => self::sendText($flow['message'] ?? '', $context['from'], $company),
|
'text' => self::sendText($flow['message'] ?? '', $context['from'], $company),
|
||||||
'image' => self::sendImage($flow['media_id'] ?? '', $flow['caption'] ?? null, $context['from'], $company),
|
'image' => self::sendImage($flow['media_id'] ?? '', $flow['caption'] ?? null, $context['from'], $company),
|
||||||
'menu' => self::buildMenuResponse(self::resolveMenu($flow['menu'] ?? [], $company), $context['from'], $company),
|
'menu' => self::buildMenuResponse(self::resolveMenu($flow['menu'] ?? [], $company, $menus), $context['from'], $company),
|
||||||
'function' => self::executeFunction($flow['function'] ?? '', $flow['params'] ?? [], $context, $company, $ctxId),
|
'function' => self::executeFunction($flow['function'] ?? '', $flow['params'] ?? [], $context, $company, $ctxId),
|
||||||
default => null,
|
default => null,
|
||||||
};
|
};
|
||||||
@@ -167,12 +169,12 @@ class NormalBot
|
|||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
|
||||||
if ($error) {
|
if ($error) {
|
||||||
self::log("API report error [{$endpoint}]: {$error}");
|
self::log("API report error [{$endpointKey}]: {$error}");
|
||||||
return self::sendText('Error al obtener el reporte. Intenta de nuevo.', $context['from'], $company);
|
return self::sendText('Error al obtener el reporte. Intenta de nuevo.', $context['from'], $company);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($httpCode >= 400) {
|
if ($httpCode >= 400) {
|
||||||
self::log("API report HTTP {$httpCode} [{$endpoint}]: " . mb_substr($content, 0, 200));
|
self::log("API report HTTP {$httpCode} [{$endpointKey}]: " . mb_substr($content, 0, 200));
|
||||||
return self::sendText('Error al obtener el reporte. Intenta de nuevo.', $context['from'], $company);
|
return self::sendText('Error al obtener el reporte. Intenta de nuevo.', $context['from'], $company);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +207,7 @@ class NormalBot
|
|||||||
$upload = WhatsAppSender::uploadMedia($tmpFile, $mime, $phoneNumberId);
|
$upload = WhatsAppSender::uploadMedia($tmpFile, $mime, $phoneNumberId);
|
||||||
|
|
||||||
if (!$upload['success'] || !$upload['media_id']) {
|
if (!$upload['success'] || !$upload['media_id']) {
|
||||||
self::log("API report upload failed [{$endpoint}]: " . ($upload['error'] ?? 'unknown'));
|
self::log("API report upload failed [{$endpointKey}]: " . ($upload['error'] ?? 'unknown'));
|
||||||
return self::sendText('Error al enviar el reporte. Intenta de nuevo.', $context['from'], $company);
|
return self::sendText('Error al enviar el reporte. Intenta de nuevo.', $context['from'], $company);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +221,7 @@ class NormalBot
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function buildMenuResponse(array $menu, string $to, array $company): array
|
private static function buildMenuResponse(array $menu, string $to, array $company): ?array
|
||||||
{
|
{
|
||||||
$menuType = $menu['type'] ?? 'list';
|
$menuType = $menu['type'] ?? 'list';
|
||||||
|
|
||||||
@@ -283,7 +285,7 @@ class NormalBot
|
|||||||
return self::enqueueInteractive($to, $interactive, $company);
|
return self::enqueueInteractive($to, $interactive, $company);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null; // tipo de menú desconocido
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function sendText(string $text, string $to, array $company): array
|
private static function sendText(string $text, string $to, array $company): array
|
||||||
@@ -339,19 +341,20 @@ class NormalBot
|
|||||||
$permType = (string)($company['_permission_type'] ?? 1);
|
$permType = (string)($company['_permission_type'] ?? 1);
|
||||||
$perType = $config['per_type'][$permType] ?? [];
|
$perType = $config['per_type'][$permType] ?? [];
|
||||||
$flows = array_merge($config['flows'] ?? [], $perType['flows'] ?? []);
|
$flows = array_merge($config['flows'] ?? [], $perType['flows'] ?? []);
|
||||||
|
$menus = array_merge($config['menus'] ?? [], $perType['menus'] ?? []);
|
||||||
|
|
||||||
$botCtx = ConversationContext::getOrCreate((int)$company['id'], $context['from'], 'normal');
|
$botCtx = ConversationContext::getOrCreate((int)$company['id'], $context['from'], 'normal');
|
||||||
$ctxId = (int)$botCtx['id'];
|
$ctxId = (int)$botCtx['id'];
|
||||||
|
|
||||||
foreach ($flows as $flowId => $flow) {
|
foreach ($flows as $flowId => $flow) {
|
||||||
if (($flow['type'] ?? '') === 'menu') {
|
if (($flow['type'] ?? '') === 'menu') {
|
||||||
$menu = self::resolveMenu($flow['menu'] ?? [], $company);
|
$menu = self::resolveMenu($flow['menu'] ?? [], $company, $menus);
|
||||||
foreach ($menu['sections'] ?? [] as $section) {
|
foreach ($menu['sections'] ?? [] as $section) {
|
||||||
foreach ($section['rows'] ?? [] as $row) {
|
foreach ($section['rows'] ?? [] as $row) {
|
||||||
if (($row['id'] ?? '') === $input) {
|
if (($row['id'] ?? '') === $input) {
|
||||||
ConversationContext::updateNode($ctxId, $row['id']);
|
ConversationContext::updateNode($ctxId, $row['id']);
|
||||||
if (isset($flows[$row['id']])) {
|
if (isset($flows[$row['id']])) {
|
||||||
return self::handleFlow($flows[$row['id']], $context, $company, $ctxId);
|
return self::handleFlow($flows[$row['id']], $context, $company, $ctxId, $menus);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -361,7 +364,7 @@ class NormalBot
|
|||||||
if (($btn['id'] ?? '') === $input) {
|
if (($btn['id'] ?? '') === $input) {
|
||||||
ConversationContext::updateNode($ctxId, $btn['id']);
|
ConversationContext::updateNode($ctxId, $btn['id']);
|
||||||
if (isset($flows[$btn['id']])) {
|
if (isset($flows[$btn['id']])) {
|
||||||
return self::handleFlow($flows[$btn['id']], $context, $company, $ctxId);
|
return self::handleFlow($flows[$btn['id']], $context, $company, $ctxId, $menus);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user