Documentation de l'API
Présentation
L'API BotBell permet à vos programmes et scripts d'envoyer des notifications push vers vos appareils Apple et de recevoir des réponses. Aucun SDK nécessaire — de simples requêtes HTTP suffisent.
Base URL: https://api.botbell.appComment ça Marche
- Créez un bot dans l'app BotBell et copiez son URL de push
- Envoyez un message JSON via POST à l'URL de push depuis n'importe quel langage ou outil
- Recevez une notification push instantanée sur tous vos appareils
- Optionnellement, recevez vos réponses via le callback d'URL de réponse ou l'API de sondage
Format de Réponse
Toutes les réponses de l'API utilisent la même enveloppe JSON. Un code de 0 signifie succès ; tout autre code indique une erreur.
// Success
{
"code": 0,
"message": "success",
"data": { ... }
}
// Error
{
"code": 40001,
"message": "Invalid bot token"
}Envoyer un Message
Envoyez une notification depuis votre bot vers l'app BotBell. L'URL de push de votre bot contient déjà le token d'authentification — il suffit de faire un POST.
Point d'accès
POST https://api.botbell.app/v1/push/<your_bot_token>Aucun en-tête Authorization nécessaire. Le token dans l'URL sert d'authentification.
Vous pouvez aussi utiliser POST /v1/messages/push avec l'en-tête X-Bot-Token: <token>.
Corps de la Requête (JSON)
| Champ | Type | Requis | Description |
|---|---|---|---|
message | string | Oui | Le texte du message (max 4 096 caractères) |
title | string | Non | Titre affiché au-dessus du message (max 256 caractères) |
url | string | Non | Un lien cliquable attaché à la notification |
imageUrl | string | Non | URL d'une image à afficher dans la notification |
Exemple de Requête
curl -X POST https://api.botbell.app/v1/push/bt_your_token \
-H "Content-Type: application/json" \
-d '{
"message": "Server CPU is at 95%!",
"title": "Alert",
"url": "https://grafana.example.com/dashboard"
}'Réponse
{
"code": 0,
"message": "success",
"data": {
"message_id": "msg_abc123",
"delivered": true,
"timestamp": 1709827200
}
}| Champ | Description |
|---|---|
message_id | Identifiant unique de ce message |
delivered | true si la notification push a été envoyée à APNs avec succès ; false si aucun appareil n'est enregistré |
timestamp | Horodatage Unix (secondes) de la création du message |
Essayer maintenant
Collez votre token de bot et envoyez une vraie notification push à votre appareil.
Recevoir des Réponses
Lorsque vous répondez à un bot dans l'app, BotBell peut transmettre votre réponse à votre serveur automatiquement. C'est optionnel — vous n'en avez besoin que si votre bot gère des conversations bidirectionnelles.
Configurer une URL de Réponse
Dans l'app BotBell, allez dans les paramètres de votre bot et entrez une URL de réponse (ex. https://your-server.com/botbell/reply). BotBell enverra vos réponses à cette URL au fur et à mesure.
Payload du Callback
Lorsque vous répondez, BotBell envoie une requête POST à votre URL de réponse avec le format suivant :
POST https://your-server.com/botbell/reply
Headers:
Content-Type: application/json
X-Webhook-Signature: sha256=abc123...
X-Webhook-Timestamp: 1709827300
Body:
{
"event": "user_reply",
"bot_id": "bot_abc123",
"message_id": "msg_xyz789",
"content": "Got it, thanks!",
"timestamp": 1709827300
}Vérification de la Signature
Chaque callback inclut une signature HMAC-SHA256 pour que vous puissiez vérifier qu'il provient de BotBell. La clé de signature est le Secret Webhook affiché dans les paramètres de votre bot.
signature = HMAC-SHA256(
key: <your_webhook_secret>,
message: "<timestamp>.<raw_request_body>"
)Pour vérifier la signature :
- Extrayez les en-têtes X-Webhook-Timestamp et X-Webhook-Signature
- Vérifiez que l'horodatage est dans les 5 minutes de l'heure actuelle (pour prévenir les attaques par rejeu)
- Calculez le HMAC-SHA256 sur la chaîne "<timestamp>.<raw_body>" en utilisant votre Secret Webhook comme clé
- Comparez la valeur calculée avec la signature après le préfixe "sha256="
Réponse de Votre Serveur
Retournez n'importe quel code de statut HTTP 2xx pour accuser réception. Les réponses non-2xx ou les délais d'attente dépassés (5 secondes) sont considérés comme des échecs — la réponse sera stockée dans la file de sondage pendant 24 heures pour que vous puissiez la récupérer plus tard.
Sonder les Réponses
Si vous n'avez pas de serveur public pour recevoir les callbacks, vous pouvez sonder les réponses à la place. C'est aussi utile comme solution de repli lorsque votre URL de réponse est temporairement indisponible.
Point d'accès
GET https://api.botbell.app/v1/messages/poll
Headers:
X-Bot-Token: <your_bot_token>Paramètres de Requête
| Champ | Type | Par défaut | Description |
|---|---|---|---|
since | integer | - | Ne retourner que les messages après cet horodatage Unix |
limit | integer | 20 | Nombre de messages à retourner (max 100) |
Réponse
{
"code": 0,
"message": "success",
"data": {
"messages": [
{
"message_id": "msg_xyz789",
"content": "Got it, thanks!",
"timestamp": 1709827300
}
],
"has_more": false
}
}Note : Les messages sondés sont marqués comme lus et ne seront plus retournés. Les messages non sondés expirent après 24 heures.
Codes d'Erreur
| Code | Statut HTTP | Description |
|---|---|---|
| 40001 | 401 | Token de bot invalide ou manquant |
| 40010 | 400 | Validation de la requête échouée (ex. champ message manquant, corps trop volumineux) |
| 40029 | 429 | Limite de débit dépassée — trop de requêtes par minute |
| 40030 | 429 | Quota mensuel de messages épuisé |
| 40031 | 403 | Limite de bots atteinte pour votre forfait |
| 50000 | 500 | Erreur interne du serveur |
Limites de Débit et Quotas
| Limite | Valeur |
|---|---|
| Débit de push (par bot) | 60 |
| Corps du message (caractères) | 4,096 |
| Titre (caractères) | 256 |
| Quota mensuel gratuit | 300 messages / bot |
| Rétention des messages sondés | 24h |
| Délai d'attente de l'URL de réponse | 5s |
Le statut de la limite de débit est retourné dans les en-têtes de réponse :
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1709827260Exemples de Code
Envoi de Messages
curl -X POST https://api.botbell.app/v1/push/bt_your_token \
-H "Content-Type: application/json" \
-d '{"message":"Server CPU at 95%","title":"Alert"}'import requests
resp = requests.post(
"https://api.botbell.app/v1/push/bt_your_token",
json={
"message": "Build #42 succeeded",
"title": "CI/CD",
"url": "https://ci.example.com/builds/42",
},
)
print(resp.json()) # {"code": 0, "data": {"message_id": "...", ...}}const resp = await fetch("https://api.botbell.app/v1/push/bt_your_token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
message: "New order received!",
title: "E-Commerce",
}),
});
const data = await resp.json();
console.log(data);package main
import (
"bytes"
"encoding/json"
"net/http"
)
func main() {
body, _ := json.Marshal(map[string]string{
"message": "Disk usage above 90%",
"title": "Alert",
})
http.Post(
"https://api.botbell.app/v1/push/bt_your_token",
"application/json",
bytes.NewReader(body),
)
}<?php
$ch = curl_init('https://api.botbell.app/v1/push/bt_your_token');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'message' => 'Payment received: $49.99',
'title' => 'Stripe',
]),
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
curl_close($ch);Vérification des Signatures de Réponse
import hmac, hashlib
def verify_signature(payload: bytes, timestamp: str, signature: str, secret: str) -> bool:
message = f"{timestamp}.{payload.decode()}"
expected = hmac.new(secret.encode(), message.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)const crypto = require("crypto");
function verifySignature(payload, timestamp, signature, secret) {
const message = `${timestamp}.${payload}`;
const expected = crypto.createHmac("sha256", secret).update(message).digest("hex");
return crypto.timingSafeEqual(
Buffer.from(`sha256=${expected}`),
Buffer.from(signature),
);
}