|
| 1 | +# Typebot: Selección numérica de opciones |
| 2 | + |
| 3 | +## Problema |
| 4 | + |
| 5 | +Cuando Typebot enviaba opciones (choice input) al usuario vía WhatsApp, se mostraban con un emoji ▶️ como prefijo: |
| 6 | + |
| 7 | +``` |
| 8 | +▶️ Inmobiliario |
| 9 | +▶️ Automotor |
| 10 | +▶️ IIBB |
| 11 | +▶️ Atencion Personalizada |
| 12 | +``` |
| 13 | + |
| 14 | +Esto generaba dos problemas: |
| 15 | +1. **UX confusa**: el usuario no sabía cómo responder |
| 16 | +2. **Respuesta exacta requerida**: el usuario debía escribir el texto completo de la opción (ej: "Atencion Personalizada") para que Typebot lo reconociera. Cualquier diferencia (mayúsculas, tildes, espacios) rompía el flujo. |
| 17 | + |
| 18 | +## Solución |
| 19 | + |
| 20 | +Se reemplazó el formato con **lista numerada en negrita** y se agregó **resolución de respuestas numéricas**: |
| 21 | + |
| 22 | +``` |
| 23 | +*1.* Inmobiliario |
| 24 | +*2.* Automotor |
| 25 | +*3.* IIBB |
| 26 | +*4.* Atencion Personalizada |
| 27 | +``` |
| 28 | + |
| 29 | +Ahora el usuario puede responder de dos formas: |
| 30 | +- **Con el número**: escribir `3` selecciona "IIBB" |
| 31 | +- **Con el texto**: escribir `IIBB` sigue funcionando como antes |
| 32 | + |
| 33 | +## Implementación técnica |
| 34 | + |
| 35 | +### Archivo modificado |
| 36 | +`src/api/integrations/chatbot/typebot/services/typebot.service.ts` |
| 37 | + |
| 38 | +### Cambios realizados |
| 39 | + |
| 40 | +#### 1. Formato de opciones (método `processMessages`) |
| 41 | +```typescript |
| 42 | +// Antes |
| 43 | +for (const item of items) { |
| 44 | + formattedText += `▶️ ${item.content}\n`; |
| 45 | +} |
| 46 | + |
| 47 | +// Después |
| 48 | +const choiceMap: Record<string, string> = {}; |
| 49 | +for (let i = 0; i < items.length; i++) { |
| 50 | + formattedText += `*${i + 1}.* ${items[i].content}\n`; |
| 51 | + choiceMap[String(i + 1)] = items[i].content; |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +#### 2. Persistencia del mapeo en sesión |
| 56 | +Al mostrar las opciones, se guarda el mapeo número→texto en el campo `parameters` de la sesión (`IntegrationSession`): |
| 57 | + |
| 58 | +```typescript |
| 59 | +const updatedParams: any = { |
| 60 | + ...currentParams, |
| 61 | + lastChoiceMap: { "1": "Inmobiliario", "2": "Automotor", ... }, |
| 62 | +}; |
| 63 | +await prismaRepository.integrationSession.update({ |
| 64 | + where: { id: session.id }, |
| 65 | + data: { awaitUser: true, parameters: updatedParams }, |
| 66 | +}); |
| 67 | +``` |
| 68 | + |
| 69 | +#### 3. Resolución de respuesta numérica (método `processTypebot`) |
| 70 | +Cuando el usuario responde, se lee el `lastChoiceMap` de la sesión y se traduce el número al texto de la opción antes de enviarlo a la API de Typebot: |
| 71 | + |
| 72 | +```typescript |
| 73 | +const freshSession = await this.prismaRepository.integrationSession.findUnique({ |
| 74 | + where: { id: session.id }, |
| 75 | +}); |
| 76 | +const sessionParams = (freshSession?.parameters as Record<string, any>) || {}; |
| 77 | +if (sessionParams.lastChoiceMap && sessionParams.lastChoiceMap[content.trim()]) { |
| 78 | + resolvedContent = sessionParams.lastChoiceMap[content.trim()]; |
| 79 | + // Se limpia el choiceMap después de usarlo |
| 80 | +} |
| 81 | +``` |
| 82 | + |
| 83 | +### Flujo completo |
| 84 | + |
| 85 | +``` |
| 86 | +1. Typebot envía choice input con items ["Inmobiliario", "Automotor", "IIBB", "Atencion Personalizada"] |
| 87 | +2. Evolution API formatea como "*1.* Inmobiliario\n*2.* Automotor\n..." |
| 88 | +3. Se guarda choiceMap: {"1":"Inmobiliario", "2":"Automotor", "3":"IIBB", "4":"Atencion Personalizada"} |
| 89 | +4. Usuario responde "3" |
| 90 | +5. Evolution API lee choiceMap de la sesión, traduce "3" → "IIBB" |
| 91 | +6. Se envía "IIBB" a la API de Typebot (continueChat) |
| 92 | +7. Se limpia el choiceMap de la sesión |
| 93 | +8. Typebot continúa el flujo normalmente |
| 94 | +``` |
| 95 | + |
| 96 | +## Compatibilidad |
| 97 | + |
| 98 | +- **Sin breaking changes**: los usuarios que escriban el texto completo de la opción siguen funcionando igual |
| 99 | +- **No requiere migración de DB**: usa el campo JSON `parameters` existente en `IntegrationSession` |
| 100 | +- **No requiere cambios en Typebot**: la traducción ocurre antes de enviar a la API de Typebot |
0 commit comments