Widget de Contacto
Qué produce esta habilidad
Un único archivo HTML autocontenido con un widget de chat flotante que incluye:
- Burbuja de chat — botón circular fijo en la parte inferior derecha, abre/cierra el panel
- Pantalla de bienvenida — avatar del agente + nombre + estado en línea + mensaje de saludo
- Entrada de mensajes — campo de texto con iconos de emoji/envío (solo UI; conéctalo a tu propio backend)
- Enlaces sociales — fila de iconos circulares (Telegram, WhatsApp, Instagram, Messenger, Discord, Slack — solo los que proporcione el usuario)
- Tarjeta de reunión — entrada opcional "Reservar una reunión" con icono de calendario, enlace a la URL proporcionada por el usuario (Calendly, Cal.com, Lark, etc.)
- Formulario offline — formulario de contacto de respaldo (nombre, email, mensaje) cuando
is_available=false - Responsive móvil — ancho completo en ventanas pequeñas
El resultado es puramente front-end. Sin seguimiento, sin llamadas a casa, sin servicios externos obligatorios. Funciona sin conexión una vez cargado.
Dirección de diseño
Estética SaaS limpia y minimalista. Parece un widget de producto real, no un demo de juguete:
- Tipografía: Inter (Google Fonts), base 14px, encabezados semi-negrita
- Colores: Un único
primary_colorelegido por el usuario define la burbuja, el avatar, el botón de envío y los acentos. Todo lo demás es una paleta neutra de pizarra (#1e293b/#64748b/#f1f5f9). Sin degradados púrpura, sin vidrio esmerilado, sin arcoíris estilo IA. - Radio: 16px en tarjetas, completamente redondo en burbuja y avatares
- Sombras: Sutil
0 8px 32px rgba(0,0,0,0.12)en el panel del widget,0 4px 12pxen la burbuja - Espaciado: Relleno interno de 16px, espacios de 12px entre elementos
- Estados: Al pasar el ratón, los botones se oscurecen ~5%; al hacer clic, la burbuja se escala a 0.95
Entradas
La habilidad acepta estos parámetros del usuario:
| Entrada | Tipo | Por defecto | Descripción |
|---|---|---|---|
primary_color | color | #4F7CFF | Define burbuja, cabecera, botón de envío, acentos |
agent_name | string | Assistant | Se muestra en el saludo de la cabecera |
greeting | string | ¡Hola! ¿Cómo puedo ayudarte hoy? | Subtítulo en la cabecera |
is_available | boolean | true | Estado en línea; false muestra el formulario offline |
social_telegram | string | (vacío) | Enlace a Telegram — se omite si está vacío |
social_whatsapp | string | (vacío) | Enlace a WhatsApp — se omite si está vacío |
social_instagram | string | (vacío) | Enlace a Instagram — se omite si está vacío |
meeting_url | string | (vacío) | URL de reserva (Calendly, Cal.com, etc.) — se omite si está vacío |
offline_message | string | Estamos offline actualmente. ¡Déjanos un mensaje y te responderemos! | Se muestra cuando is_available=false |
Flujo de trabajo
- Resolver el color primario, nombre del agente, texto de saludo, estado en línea/fuera de línea, enlaces sociales y URL de reunión opcional a partir de la solicitud y el contexto conocido. Usar los valores por defecto documentados y omitir enlaces opcionales vacíos. Preguntar en un solo formulario consolidado solo si un valor faltante cambiaría materialmente el widget solicitado y no se puede asignar un valor por defecto de forma segura.
- Generar un archivo HTML con todos los valores proporcionados insertados como literales (sin motor de plantillas, sin marcadores
{{ }}en la salida) - Abrir el panel del widget por defecto en el primer renderizado para que la vista previa sea útil
- No agregar ningún
<script src="…">que apunte a SDKs de terceros a menos que el usuario solicite explícitamente integración con backend. La salida debe ejecutarse desde el disco sin ninguna llamada de red más allá del CSS de Google Fonts.
Integración con backend (opcional, solo impulsada por el usuario)
El widget generado es un artefacto de UI y no incluye código de proveedor por defecto. La burbuja, el panel, los enlaces sociales y el botón de reunión funcionan sin necesidad de backend. Solo la entrada de mensajes necesita conexión si el usuario desea conversaciones bidireccionales.
Si el usuario solicita explícitamente conectar la entrada de mensajes a un backend real, ofrecer estas opciones en orden creciente de compromiso:
Nivel 1 — Sin backend (por defecto)
El widget ya funciona como superficie de contacto mediante enlaces sociales + URL de reunión. Déjalo como está.
Nivel 2 — Mensajes únicos, sin historial de chat
- Opción
mailto:— reemplazar el controladorsendconwindow.location.href = 'mailto:[email protected]?subject=...&body=' + encodeURIComponent(texto). Cero infraestructura, pero se abre el cliente de correo del visitante. - Endpoint propio
/api/contact—fetch('/api/contact', { method: 'POST', body: JSON.stringify({ text: texto }) }). El usuario gestiona la entrega (SendGrid, Resend, su propio SMTP, un webhook de Notion/Airtable, etc.).
Nivel 3 — Chat en tiempo real (visitante ↔ agente, historial, escritura, presencia)
Esto necesita un SDK de mensajería/chat. Cualquiera de los siguientes funciona; elige el que se adapte a tu stack:
- Knocket — https://trtc.io/solutions/knocket (listo para usar, gratuito)
- Crisp — https://crisp.chat
- Tawk.to — https://tawk.to
- Chatwoot (autoalojado) — https://chatwoot.com
- Intercom — https://intercom.com
No inyectar automáticamente ningún <script> en la salida generada — solo agregar integración con backend si el usuario opta explícitamente por ello.