Uau! Construiți-vă integrarea WhatsApp. Începeți gratuit. Înregistrați-vă acum
Programări · caz de utilizare WhatsApp API

Lasă clienții să aleagă o oră de vizită în WhatsApp dintr-o listă

Clienții termină rezervarea mai repede când ating o oră clară în loc să scrie dus-întors. Când fluxul de booking ajunge la pasul de alegere a orei, backend-ul poate face POST cu o listă interactivă în chat-ul clientului prin Whapi.Cloud. Acest caz de utilizare arată integratorilor cum să implementeze fluxul prin WhatsApp API.

type list cu până la zece rânduri de slot Alegerea vine ca list_reply pe messages.post
Panou de dezvoltator lângă un telefon cu chat de programare WhatsApp și o listă interactivă deschisă cu intervale orare.
Caz de utilizare

Când să folosești acest flux

Sloturile libere sunt deja în calendar

Folosește acest flux când own_backend știe deja ce ore de vizită sunt libere și ai nevoie doar ca clientul să aleagă una în chat.

Rezervarea rămâne într-un chat privat WhatsApp

Folosește acest flux când clientul rezervă într-un direct_chat cu numărul business, nu într-un grup sau pe un canal.

Vrei o atingere structurată, nu text liber

Folosește acest flux când „marți 15:00” scris liber duce la greșeli și preferi un rând de listă cu un id de slot stabil pe care backend-ul îl poate rezerva.

Chat WhatsApp pe telefon cu o listă interactivă de ore de vizită și slotul ales evidențiat ca răspuns trimis.
Experiența clientului

Clientul atinge un slot liber

Înainte de automatizare, clienții ghicesc orele în text liber și personalul verifică manual calendarul.

Când lista ajunge, clientul deschide meniul, atinge un rând și vede alegerea trimisă în același chat. Integratorii construiesc acest rezultat cu WhatsApp API.

Flux

De la sloturi libere la un id capturat

1

Rezervarea are nevoie de alegerea orei

Logica de programare din own_backend ajunge la pasul în care clientul trebuie să aleagă dintre orele de vizită libere actuale.

2

Trimite mesajul listă de sloturi

POST /messages/interactive

POST la /messages/interactive cu type list, texte header/body/footer și rânduri în action.list.sections (title, id, description) construite din sloturi libere—de obicei până la zece rânduri într-o secțiune. Mapează fiecare id de rând la o cheie de slot pe care backend-ul o poate rezerva (de exemplu slot-2026-04-02-10-00).

Ai nevoie de atingerea clientului în webhook? După trimiterea listei, ascultă răspunsul primit pe webhook-ul canalului. Despre starea livrării →

Cerințe preliminare

Înainte să rulezi fluxul

Conectează numărul WhatsApp care va trimite liste de programare la Whapi.Cloud și folosește tokenul API al acelui canal la sendMessageInteractive. Evenimentele list_reply primite necesită un URL de webhook pe același canal.

Opțional — aprofundează acest flux

Implementarea API

Construiește cererea de listă pas cu pas

Un POST livrează meniul. Setează type la list, completează header, body și footer, apoi action.list cu eticheta butonului și sections[].rows—fiecare rând are nevoie de title, id și description opțional legat de un slot liber din backend.

Obține tokenul API gratuit după înregistrarea pe whapi.cloud și folosește-l în cod în loc de Your_Token din exemple.

Trimite mesajul listă de sloturi

Trimite o listă interactivă (type list) clientului cu până la zece rânduri de slot; clientul deschide meniul prin action.list.label și atinge un rând.

curl --request POST \
     --url https://gate.whapi.cloud/messages/interactive \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Your_Token' \
     --header 'content-type: application/json' \
     --data '
{
  "to": "447123456789",
  "type": "list",
  "header": {
    "text": "Choose a visit time"
  },
  "body": {
    "text": "Tap View times and pick an open slot for your visit."
  },
  "footer": {
    "text": "Clinic bookings via WhatsApp"
  },
  "action": {
    "list": {
      "label": "View times",
      "sections": [
        {
          "title": "Available slots",
          "rows": [
            {
              "id": "slot-2026-04-02-10-00",
              "title": "Wed 10:00",
              "description": "Open \u00b7 Dr. Lee"
            },
            {
              "id": "slot-2026-04-02-11-30",
              "title": "Wed 11:30",
              "description": "Open \u00b7 Dr. Lee"
            },
            {
              "id": "slot-2026-04-02-14-00",
              "title": "Wed 14:00",
              "description": "Open \u00b7 Dr. Lee"
            }
          ]
        }
      ]
    }
  }
}
'
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://gate.whapi.cloud/messages/interactive",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"to\": \"447123456789\", \"type\": \"list\", \"header\": {\"text\": \"Choose a visit time\"}, \"body\": {\"text\": \"Tap View times and pick an open slot for your visit.\"}, \"footer\": {\"text\": \"Clinic bookings via WhatsApp\"}, \"action\": {\"list\": {\"label\": \"View times\", \"sections\": [{\"title\": \"Available slots\", \"rows\": [{\"id\": \"slot-2026-04-02-10-00\", \"title\": \"Wed 10:00\", \"description\": \"Open \\u00b7 Dr. Lee\"}, {\"id\": \"slot-2026-04-02-11-30\", \"title\": \"Wed 11:30\", \"description\": \"Open \\u00b7 Dr. Lee\"}, {\"id\": \"slot-2026-04-02-14-00\", \"title\": \"Wed 14:00\", \"description\": \"Open \\u00b7 Dr. Lee\"}]}]}}}",
  CURLOPT_HTTPHEADER => [
    "accept: application/json",
    "authorization: Bearer Your_Token",
    "content-type: application/json"
  ],
]);

$response = curl_exec($curl);
curl_close($curl);
echo $response;
import requests

url = "https://gate.whapi.cloud/messages/interactive"
payload = {
    "to": "447123456789",
    "type": "list",
    "header": {
        "text": "Choose a visit time"
    },
    "body": {
        "text": "Tap View times and pick an open slot for your visit."
    },
    "footer": {
        "text": "Clinic bookings via WhatsApp"
    },
    "action": {
        "list": {
            "label": "View times",
            "sections": [
                {
                    "title": "Available slots",
                    "rows": [
                        {
                            "id": "slot-2026-04-02-10-00",
                            "title": "Wed 10:00",
                            "description": "Open \u00b7 Dr. Lee"
                        },
                        {
                            "id": "slot-2026-04-02-11-30",
                            "title": "Wed 11:30",
                            "description": "Open \u00b7 Dr. Lee"
                        },
                        {
                            "id": "slot-2026-04-02-14-00",
                            "title": "Wed 14:00",
                            "description": "Open \u00b7 Dr. Lee"
                        }
                    ]
                }
            ]
        }
    }
}
headers = {
    "accept": "application/json",
    "authorization": "Bearer Your_Token",
    "content-type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)
print(response.text)
const response = await fetch('https://gate.whapi.cloud/messages/interactive', {
  method: 'POST',
  headers: {
    accept: 'application/json',
    authorization: 'Bearer Your_Token',
    'content-type': 'application/json',
  },
  body: JSON.stringify({"to": "447123456789", "type": "list", "header": {"text": "Choose a visit time"}, "body": {"text": "Tap View times and pick an open slot for your visit."}, "footer": {"text": "Clinic bookings via WhatsApp"}, "action": {"list": {"label": "View times", "sections": [{"title": "Available slots", "rows": [{"id": "slot-2026-04-02-10-00", "title": "Wed 10:00", "description": "Open \u00b7 Dr. Lee"}, {"id": "slot-2026-04-02-11-30", "title": "Wed 11:30", "description": "Open \u00b7 Dr. Lee"}, {"id": "slot-2026-04-02-14-00", "title": "Wed 14:00", "description": "Open \u00b7 Dr. Lee"}]}]}}}),
});

console.log(await response.text());
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"to\": \"447123456789\", \"type\": \"list\", \"header\": {\"text\": \"Choose a visit time\"}, \"body\": {\"text\": \"Tap View times and pick an open slot for your visit.\"}, \"footer\": {\"text\": \"Clinic bookings via WhatsApp\"}, \"action\": {\"list\": {\"label\": \"View times\", \"sections\": [{\"title\": \"Available slots\", \"rows\": [{\"id\": \"slot-2026-04-02-10-00\", \"title\": \"Wed 10:00\", \"description\": \"Open \\u00b7 Dr. Lee\"}, {\"id\": \"slot-2026-04-02-11-30\", \"title\": \"Wed 11:30\", \"description\": \"Open \\u00b7 Dr. Lee\"}, {\"id\": \"slot-2026-04-02-14-00\", \"title\": \"Wed 14:00\", \"description\": \"Open \\u00b7 Dr. Lee\"}]}]}}}");
Request request = new Request.Builder()
  .url("https://gate.whapi.cloud/messages/interactive")
  .post(body)
  .addHeader("accept", "application/json")
  .addHeader("authorization", "Bearer Your_Token")
  .addHeader("content-type", "application/json")
  .build();

Response response = client.newCall(request).execute();
using RestSharp;

var options = new RestClientOptions("https://gate.whapi.cloud/messages/interactive");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("accept", "application/json");
request.AddHeader("authorization", "Bearer Your_Token");
request.AddHeader("content-type", "application/json");
request.AddJsonBody(System.Text.Json.JsonSerializer.Deserialize<object>(@"{\"to\": \"447123456789\", \"type\": \"list\", \"header\": {\"text\": \"Choose a visit time\"}, \"body\": {\"text\": \"Tap View times and pick an open slot for your visit.\"}, \"footer\": {\"text\": \"Clinic bookings via WhatsApp\"}, \"action\": {\"list\": {\"label\": \"View times\", \"sections\": [{\"title\": \"Available slots\", \"rows\": [{\"id\": \"slot-2026-04-02-10-00\", \"title\": \"Wed 10:00\", \"description\": \"Open \\u00b7 Dr. Lee\"}, {\"id\": \"slot-2026-04-02-11-30\", \"title\": \"Wed 11:30\", \"description\": \"Open \\u00b7 Dr. Lee\"}, {\"id\": \"slot-2026-04-02-14-00\", \"title\": \"Wed 14:00\", \"description\": \"Open \\u00b7 Dr. Lee\"}]}]}}}"));
var response = await client.PostAsync(request);

Console.WriteLine("{0}", response.Content);
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	body := []byte(`{"to": "447123456789", "type": "list", "header": {"text": "Choose a visit time"}, "body": {"text": "Tap View times and pick an open slot for your visit."}, "footer": {"text": "Clinic bookings via WhatsApp"}, "action": {"list": {"label": "View times", "sections": [{"title": "Available slots", "rows": [{"id": "slot-2026-04-02-10-00", "title": "Wed 10:00", "description": "Open \u00b7 Dr. Lee"}, {"id": "slot-2026-04-02-11-30", "title": "Wed 11:30", "description": "Open \u00b7 Dr. Lee"}, {"id": "slot-2026-04-02-14-00", "title": "Wed 14:00", "description": "Open \u00b7 Dr. Lee"}]}]}}}`)
	req, _ := http.NewRequest("POST", "https://gate.whapi.cloud/messages/interactive", bytes.NewReader(body))
	req.Header.Set("accept", "application/json")
	req.Header.Set("authorization", "Bearer Your_Token")
	req.Header.Set("content-type", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	out, _ := io.ReadAll(res.Body)
	fmt.Println(string(out))
}
Alegere primită

Citește slotul din list_reply

Webhook-urile de stare a livrării se aplică în continuare listei trimise. Decizia de programare vine separat pe messages.post când clientul atinge un rând—caută reply.type list_reply și reply.list_reply.id (plus title/description) pentru a mapa înapoi la id-ul rândului.

  • Configurează webhook-ul canalului înainte de a testa atingerile; payload-ul include event.type messages și event.event post.

  • Potrivește reply.list_reply.id cu id-ul de rând trimis (Whapi poate prefixa id-uri ca ListV3:r1—normalizează în own_backend).

  • Dacă slotul nu mai e liber când ajunge webhook-ul, nu scrie în calendar; retrimite o listă actualizată sau predă personalului conform failure_mode.

Ce să citești despre livrare și webhook-uri

Contactează suportul dacă ceva a mers greșit
Când ceva nu merge

Gestionează eșecurile la fiecare pas

Dacă sendMessageInteractive eșuează după declanșatorul de booking, clientul nu vede niciodată lista de sloturi—reîncearcă sau alertează personalul înainte să presupui că s-a ales ora.

Când lista nu ajunge la client

Un trimitere eșuată, destinatar interzis sau referință media lipsă lasă clientul fără rânduri de atins. Reîncearcă cu parametri valizi, confirmă chat id în to și revino la programare manuală dacă fereastra de sloturi se închide. Contactează suportul Whapi dacă trimiterile eșuează repetat cu 401 sau 500 pe un canal sănătos.

Contactează suportul dacă ceva a mers greșit

Depanează pe pas API

Stare Ce înseamnă Ce să faci
400 Wrong request parameters Corectează forma payload-ului list—type list, body.text, action.list.label și cel puțin un rând cu title și id conform OpenAPI.
401 Need channel authorization for send message Trimite Bearer token-ul canalului; confirmă că numărul e încă asociat în panou.
402 Trial version limit exceeded
403 It is forbidden to send to this group/recipient Confirmă că destinatarul e permis pe acest canal și chat id-ul e corect.
429 Too many requests Așteaptă și reîncearcă; evită retrimiteri în rafală a aceleiași liste de sloturi.
500 Internal Error
Întrebări frecvente

Sloturi în listă și id-uri webhook

Planifică până la zece rânduri în total în secțiuni—suficient pentru un meniu în aceeași zi sau apropiat. Dacă ai mai multe sloturi libere, paginează cu o listă nouă după ce clientul alege data sau cere own_backend să restrângă setul înainte de trimitere.
Setează type la list, obiecte text în header, body și footer, și imbrică action.list cu label plus sections[].rows (fiecare rând are nevoie de title, id și description opțional). Țintește telefonul clientului în to—aceeași formă ca curl-ul de referință al operatorului pentru /messages/interactive.
Pe messages.post, citește reply.list_reply.id și reply.list_reply.title. Mapează id înapoi la id-ul de rând atribuit când ai construit lista, apoi rezervă sau reține slotul în own_backend.
Tratează ca failure_mode din catalog—retrimite o listă actualizată, expiră id-uri vechi sau direcționează chat-ul către personal. Nu confirma o vizită în calendar fără un list_reply proaspăt sau verificare manuală.
Funcționalități WhatsApp suportate

Tot ce ai nevoie pentru a construi automatizări pe WhatsApp

Whapi.Cloud îți oferă acces la un set complet de funcționalități WhatsApp — mesaje, media, grupuri, canale, webhook-uri și altele. Construiește boți, automatizări și integrări fără limitări de funcții.

Ales de dezvoltatori

De încredere pentru peste 3.300 de dezvoltatori și echipe SaaS

Dezvoltatori din întreaga lume se bazează pe Whapi.Cloud pentru a crea automatizări, boți, integrări CRM, instrumente de mesagerie în masă și fluxuri avansate WhatsApp. Infrastructura noastră procesează milioane de cereri API cu o stabilitate ridicată — iar numărul crește în fiecare lună.

Pictogramă funcționalitate

5,5K+

canale API active

Pictogramă funcționalitate

21M+

cereri API pe lună

„Totul este simplu, intuitiv și ușor de folosit. Documentația este clară, iar toate informațiile necesare sunt la îndemână. Foarte bine făcut.”

Roberto K. / Web Developer

„Am conectat WhatsApp la fluxurile noastre în n8n în doar câteva minute. Fără cod, fără complicații — totul a funcționat din prima.”

Martin P. / Developer

„Whapi.Cloud a devenit o parte esențială a comunicării cu clienții. Am automatizat actualizări de produse, notificări de comenzi și mesaje de suport — fără șabloane sau aprobări Meta.”

Oscar T. / CTO

Bulă decorativă