Shared Inbox de WhatsApp para nueva PlataformaMás
1msg official logo

Confirmar cancelación de reserva con WhatsApp API

El escenario envía al cliente una plantilla de WhatsApp personalizada cuando se cancela una reserva.

Descripción del caso de uso

El escenario envía al cliente una plantilla de WhatsApp personalizada cuando se cancela una reserva. El mensaje incluye el nombre del cliente, nombre del servicio, fecha original y hora. Un botón URL estático permite reservar de nuevo.

Ejemplo de plantilla

Hola, {{1}}! Tu cita de {{2}} del {{3}} a las {{4}} fue cancelada.

Reservar de nuevo
  • {{1}}
    nombre del cliente
  • {{2}}
    servicio o tipo de reserva
  • {{3}}
    fecha de reserva cancelada
  • {{4}}
    hora de reserva cancelada
  • “Reservar de nuevo”
    botón — fijo en la plantilla de Meta
WhatsApp Business API for booking cancellation confirmation

Cuándo usarlo

Usa este escenario cuando un cliente o el personal cancela una cita y el negocio necesita que sepa que el turno quedó cerrado de verdad — no con la duda de si la reserva sigue activa. Encaja en salones y clínicas que manejan citas por servicio, restaurantes que cierran el ciclo al cancelar una mesa, e integradores que conectan webhooks de cancelación a confirmaciones en WhatsApp.

Menos llamadas de "¿sigue mi cita?"
Cuatro variables del cuerpo llevan el nombre del cliente, el servicio y la fecha y hora canceladas en WhatsApp, así queda claro qué turno se eliminó sin llamar a soporte.
Menos confusión tras una cancelación
La plantilla aprobada llega al cliente aunque no haya chat abierto, porque el sistema de agenda la envía con el evento de cancelación en lugar de depender de un correo que quizá nunca abra.
Camino más rápido para reservar de nuevo
El botón URL estático Reservar de nuevo está fijado en la plantilla de Meta y abre el flujo de reserva directamente desde el mensaje de confirmación.
Cero avisos manuales de cancelación
El sistema de agenda captura el evento de cancelación, arma la plantilla con las cuatro variables del cuerpo y registra la entrega para seguimiento en agenda o CRM — nadie retipea los datos.

Flujo de trabajo

  1. El cliente actúa

    El cliente o el personal completa una cancelación y el sistema dispara un evento.

    acción del usuario

  2. Capturar evento

    El sistema obtiene el teléfono del cliente y los campos de cancelación.

    phone: "+…"

  3. Construir y enviar

    Se construye un mensaje de plantilla personalizado con cuatro variables en el cuerpo y un botón URL estático.

    POST /sendTemplate

  4. Entregado

    El cliente recibe la confirmación de cancelación en WhatsApp.

    entregado

  5. Estado registrado

    Se registra el resultado de entrega para seguimiento en agenda o CRM.

    status: "read"

WhatsApp Business API for booking cancellation confirmation

Implementación técnica

Requisitos previos

  1. Clave API de 1MSG · Cómo obtener la clave API
  2. Cuenta de WhatsApp Business · Cómo conectar WABA
  3. Plantilla de WhatsApp · Cómo aprobar una plantilla WABA
  4. Opt-in del cliente · Cómo gestionar el consentimiento

Ejemplos de código

#!/usr/bin/env bash
set -euo pipefail

# === Configuration (replace "___" placeholders) ===

API_BASE_URL="https://api.1msg.io"        # production 1MSG API base URL
CHANNEL_ID="___"                           # channel ID from 1MSG dashboard
API_TOKEN="___"                            # channel JWT token (Bearer)

TEMPLATE_NAME="___"                        # approved template name
TEMPLATE_NAMESPACE="___"                   # template namespace (required — send fails without it)
TEMPLATE_LANGUAGE="___"                    # template language code, e.g. "en"



# === Test data ===
TEST_PHONE="___"                 # client phone in international format
TEST_CUSTOMERNAME="___"         # {{1}} customer name
TEST_SERVICE="___"         # {{2}} service name
TEST_BOOKINGDATE="___"         # {{3}} booking date
TEST_BOOKINGTIME="___"         # {{4}} booking time

PHONE_NORM="$(printf '%s' "$TEST_PHONE" | tr -cd '0-9')"

for pair in "CHANNEL_ID=$CHANNEL_ID" "API_TOKEN=$API_TOKEN" \
            "TEMPLATE_NAME=$TEMPLATE_NAME" "TEMPLATE_NAMESPACE=$TEMPLATE_NAMESPACE" \
            "TEMPLATE_LANGUAGE=$TEMPLATE_LANGUAGE" "TEST_PHONE=$TEST_PHONE" \
            "TEST_CUSTOMERNAME=$TEST_CUSTOMERNAME" \
            "TEST_SERVICE=$TEST_SERVICE" \
            "TEST_BOOKINGDATE=$TEST_BOOKINGDATE" \
            "TEST_BOOKINGTIME=$TEST_BOOKINGTIME"; do
    val="${pair#*=}"
    if [ -z "$val" ] || [ "$val" = "___" ]; then
        echo "Missing configuration value: ${pair%%=*}" >&2
        exit 1
    fi
done

if [ -z "$PHONE_NORM" ]; then
    echo "Error: phone number has no digits after normalization" >&2
    exit 1
fi

URL="${API_BASE_URL%/}/${CHANNEL_ID}/sendTemplate"

# params carries body ONLY. Button text is fixed in the Meta template — no button param.

# {{1}} customer name → ${TEST_CUSTOMERNAME}
# {{2}} service name → ${TEST_SERVICE}
# {{3}} booking date → ${TEST_BOOKINGDATE}
# {{4}} booking time → ${TEST_BOOKINGTIME}
read -r -d '' PAYLOAD <<JSON || true
{
  "phone": "${PHONE_NORM}",
  "template": "${TEMPLATE_NAME}",
  "namespace": "${TEMPLATE_NAMESPACE}",
  "language": { "policy": "deterministic", "code": "${TEMPLATE_LANGUAGE}" },
  "params": [
    {
      "type": "body",
      "parameters": [
        { "type": "text", "text": "${TEST_CUSTOMERNAME}" },
        { "type": "text", "text": "${TEST_SERVICE}" },
        { "type": "text", "text": "${TEST_BOOKINGDATE}" },
        { "type": "text", "text": "${TEST_BOOKINGTIME}" }
      ]
    }

  ]
}
JSON

RESPONSE="$(curl -s -w '\n%{http_code}' -X POST "$URL" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${API_TOKEN}" \
    -d "$PAYLOAD")"

HTTP_CODE="$(printf '%s' "$RESPONSE" | tail -n1)"
BODY="$(printf '%s' "$RESPONSE" | sed '$d')"

case "$BODY" in
    *'"sent":true'*) ok=1 ;;
    *) ok=0 ;;
esac

if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ] && [ "$ok" -eq 1 ]; then
    echo "Message sent to client."
    echo "API response: $BODY"
else
    echo "Send failed. HTTP status: $HTTP_CODE" >&2
    echo "$BODY" >&2
    exit 1
fi

Respuesta y estado de entrega

HTTP 2xx y JSON "sent": true significan que 1MSG aceptó el mensaje para envío — no que ya llegó al teléfono del cliente. Guarda el campo id (tipo wamid.…) para correlacionar los callbacks de entrega.

200 OKRespuesta
{
  "sent": true,
  "message": "Sent to [email protected]",
  "description": "Message has been sent to the provider",
  "id": "wamid.HBgLMzgwNjM5..."
}
  • sent

    Aceptado para envío — aún no en el teléfono del cliente

  • id

    Guárdalo; los callbacks de entrega y hookInfo se basan en él

Estados de entrega y webhooks →

Errores frecuentes

EstadoRespuesta de la APICausaSolución
200Message was not sent: template is not definedFalta namespace, template o language en el cuerpo de la petición.Envía los tres. Toma namespace y el nombre exacto de la plantilla de GET /templates; language es un objeto: {"policy": "deterministic", "code": "es_MX"}.
200template name (…) does not exist in <language>La plantilla está aprobada en otro idioma que el solicitado.Usa el código de idioma exacto con el que se aprobó la plantilla (por ejemplo, es_MX no es lo mismo que es). Revísalo en GET /templates.
200Message was not sent: provide chatId, phone, bsuid, or usernameNingún destinatario que el canal pudiera resolver.Envía un solo destinatario: phone (código de país y número, solo dígitos), chatId (por ejemplo [email protected]) o bsuid.

Todos los códigos de error →

Preguntas comunes

Relacionado

Desarrolla para WhatsApp en horas
sin complicaciones de infraestructura