Oui — dans les 24 h, un message interactif avec un bouton [Prolonger 1 h] ; hors des 24 h, un template à bouton de réponse rapide (approuvé par Meta). Dans les deux cas le clic revient dans button_id.
Astuce
Oui — dans les 24 h, un message interactif avec un bouton [Prolonger 1 h] ; hors des 24 h, un template à bouton de réponse rapide (approuvé par Meta). Dans les deux cas le clic revient dans button_id.
Un client a une session en cours (salle de jeu, location, parking, abonnement d'essai). Quand il reste 10 minutes, vous l'avertissez et lui proposez de prolonger d'un geste. S'il touche le bouton, votre serveur prolonge et confirme.
Deux cas, selon que le client vous a écrit il y a moins de 24 h ou non :
Oui, dans les deux cas, mais avec un outil différent. Le bouton-lien (ouvrir une page) n'existe pas en message libre ; pour un lien dans un bouton, voir Un lien unique par client dans un bouton.
Vous : Il vous reste 10 minutes de session.
[ Prolonger 1 h ] [ Terminer ]
Client : (touche « Prolonger 1 h »)
Webhook : message.inbound type=text text="Prolonger 1 h" button_id="session:extend:S789"
Vous : Session prolongée d'1 h, jusqu'à 21:40. Merci !
Dans les 24 h, message interactif :
curl
curl -X POST "https://wa-api.geskap.com/v1/messages/interactive" \
-H "Authorization: Bearer $GESKAP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+237690000001",
"body": "Il vous reste 10 minutes de session.",
"buttons": [
{ "id": "session:extend:S789", "title": "Prolonger 1 h" },
{ "id": "session:end:S789", "title": "Terminer" }
]
}'
Node.js
const res = await fetch("https://wa-api.geskap.com/v1/messages/interactive", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.GESKAP_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"to": "+237690000001",
"body": "Il vous reste 10 minutes de session.",
"buttons": [
{ "id": "session:extend:S789", "title": "Prolonger 1 h" },
{ "id": "session:end:S789", "title": "Terminer" }
]
}),
});
console.log(res.status, await res.json());
PHP
$ch = curl_init("https://wa-api.geskap.com/v1/messages/interactive");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("GESKAP_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"to" => "+237690000001",
"body" => "Il vous reste 10 minutes de session.",
"buttons" => [
["id" => "session:extend:S789", "title" => "Prolonger 1 h"],
["id" => "session:end:S789", "title" => "Terminer"],
],
]),
]);
$res = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $res;
Python
import os, requests
res = requests.request(
"POST",
"https://wa-api.geskap.com/v1/messages/interactive",
headers={"Authorization": f"Bearer {os.environ['GESKAP_API_KEY']}"},
json={
"to": "+237690000001",
"body": "Il vous reste 10 minutes de session.",
"buttons": [
{"id": "session:extend:S789", "title": "Prolonger 1 h"},
{"id": "session:end:S789", "title": "Terminer"},
],
},
timeout=15,
)
print(res.status_code, res.json())
Hors des 24 h, template à bouton de réponse rapide (créé et approuvé au préalable, voir Boutons de réponse rapide dans un template) :
curl
curl -X POST "https://wa-api.geskap.com/v1/messages" \
-H "Authorization: Bearer $GESKAP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+237690000001",
"template": {
"name": "alerte_session_fin",
"language": "fr",
"variables": ["10"]
}
}'
Node.js
const res = await fetch("https://wa-api.geskap.com/v1/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.GESKAP_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"to": "+237690000001",
"template": {
"name": "alerte_session_fin",
"language": "fr",
"variables": ["10"]
}
}),
});
console.log(res.status, await res.json());
PHP
$ch = curl_init("https://wa-api.geskap.com/v1/messages");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("GESKAP_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"to" => "+237690000001",
"template" => [
"name" => "alerte_session_fin",
"language" => "fr",
"variables" => ["10"],
],
]),
]);
$res = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $res;
Python
import os, requests
res = requests.request(
"POST",
"https://wa-api.geskap.com/v1/messages",
headers={"Authorization": f"Bearer {os.environ['GESKAP_API_KEY']}"},
json={
"to": "+237690000001",
"template": {
"name": "alerte_session_fin",
"language": "fr",
"variables": ["10"],
},
},
timeout=15,
)
print(res.status_code, res.json())
Choix du bon envoi côté serveur, puis réception du clic :
// Vous connaissez la date du dernier message reçu de ce client (webhook message.inbound)
const within24h = Date.now() - lastInboundAt < 24 * 3600 * 1000;
await (within24h ? sendInteractiveAlert(to, sessionId) : sendTemplateAlert(to, sessionId));
// Réception (voir « Savoir quel bouton… »)
if (data.button_id?.startsWith("session:extend:")) {
const sessionId = data.button_id.split(":")[2];
await db.extendSession(sessionId, { hours: 1 }); // relisez l'état : la session existe-t-elle encore ?
await sendText(data.from, "Session prolongée d'1 h.");
}
Le clic sur le bouton du template arrive de la même façon (button_id = le libellé du bouton) : voir Savoir quel bouton ou quelle ligne le client a touché. Ce clic est un message du client : il rouvre la fenêtre de 24 h, et votre confirmation peut partir en texte libre.
| Élément | Interactif (dans les 24 h) | Template (hors 24 h) |
|---|---|---|
| Nombre de boutons | 1 à 3 | 2 de réponse rapide au plus |
| Titre d'un bouton | 20 caractères | 25 caractères |
| Validation Meta | aucune | obligatoire avant l'envoi |
| Texte | 1 024 caractères | 1 024 caractères |
Attention
Piège : une alerte doit partir à la bonne minute : l'API n'a pas de minuteur. C'est votre planificateur qui déclenche l'envoi, et il doit décider interactif ou template selon la date du dernier message du client, sans quoi l'appel interactif échoue hors des 24 h.
Attention
Piège : un client peut toucher « Prolonger » après l'expiration de la session, ou deux fois. Au retour, relisez l'état chez vous (session expirée ? déjà prolongée ?) avant de prolonger, et ne prolongez qu'une fois par alerte. Si l'extension se paie, ne la confirmez qu'après l'encaissement : un clic n'est pas un paiement.
Preuve — vérifié dans le code de l'API : api_schemas.py, public_api.py, api_send.py, webhooks.py.