API ドキュメント
概要
BotBell API を使えば、プログラムやスクリプトから Apple デバイスにプッシュ通知を送信し、返信を受け取ることができます。SDK は不要——シンプルな HTTP リクエストだけで利用できます。
Base URL: https://api.botbell.app仕組み
- BotBell アプリで Bot を作成し、プッシュ URL をコピーします
- 任意の言語やツールからプッシュ URL に JSON メッセージを POST します
- すべてのデバイスで即座にプッシュ通知を受け取ります
- オプションとして、返信コールバック URL またはポーリング API であなたの返信を受け取れます
レスポンス形式
すべての API レスポンスは同じ JSON エンベロープを使用します。code が 0 の場合は成功、それ以外の場合はエラーを示します。
// Success
{
"code": 0,
"message": "success",
"data": { ... }
}
// Error
{
"code": 40001,
"message": "Invalid bot token"
}メッセージをプッシュ
Bot から BotBell アプリに通知を送信します。Bot のプッシュ URL には認証トークンが含まれているため、そのまま POST するだけで送信できます。
エンドポイント
POST https://api.botbell.app/v1/push/<your_bot_token>Authorization ヘッダーは不要です。URL 内のトークンが認証情報となります。
POST /v1/messages/push に X-Bot-Token: <token> ヘッダーを付けて使用することもできます。
リクエストボディ(JSON)
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
message | string | はい | メッセージ本文(最大 4,096 文字) |
title | string | いいえ | メッセージの上に表示されるタイトル(最大 256 文字) |
url | string | いいえ | 通知に添付されるタップ可能なリンク |
imageUrl | string | いいえ | 通知に表示する画像の URL |
リクエスト例
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"
}'レスポンス
{
"code": 0,
"message": "success",
"data": {
"message_id": "msg_abc123",
"delivered": true,
"timestamp": 1709827200
}
}| フィールド | 説明 |
|---|---|
message_id | このメッセージの一意な ID |
delivered | APNs へのプッシュ通知送信が成功した場合は true、登録済みデバイスがない場合は false |
timestamp | メッセージが作成された Unix タイムスタンプ(秒) |
今すぐ試す
Bot Token を貼り付けて、デバイスにリアルなプッシュ通知を送信しましょう。
返信の受信
アプリで Bot に返信すると、BotBell はその返信を自動的にサーバーに転送できます。これはオプションです——Bot が双方向の会話を処理する場合にのみ必要です。
返信コールバック URL の設定
BotBell アプリで Bot の設定に移動し、返信コールバック URL(例:https://your-server.com/botbell/reply)を入力してください。BotBell はあなたの返信をリアルタイムでこの URL に POST します。
コールバックペイロード
あなたが返信すると、BotBell は以下の形式で返信コールバック URL に POST リクエストを送信します:
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
}署名検証
各コールバックには HMAC-SHA256 署名が含まれており、BotBell からのリクエストであることを検証できます。署名キーは Bot 設定に表示される Webhook Secret です。
signature = HMAC-SHA256(
key: <your_webhook_secret>,
message: "<timestamp>.<raw_request_body>"
)署名を検証するには:
- X-Webhook-Timestamp ヘッダーと X-Webhook-Signature ヘッダーを取得します
- タイムスタンプが現在時刻から 5 分以内であることを確認します(リプレイ攻撃を防止するため)
- Webhook Secret をキーとして、文字列 "<timestamp>.<raw_body>" の HMAC-SHA256 を計算します
- 計算した値を "sha256=" プレフィックスの後の署名と比較します
サーバーのレスポンス
受信確認として任意の HTTP 2xx ステータスコードを返してください。2xx 以外のレスポンスやタイムアウト(5 秒)は失敗として扱われ、返信はポーリングキューに 24 時間保存され、後で取得できます。
返信のポーリング
コールバックを受信するための公開サーバーがない場合、代わりに返信をポーリングで取得できます。返信コールバック URL が一時的にダウンしている場合のフォールバックとしても便利です。
エンドポイント
GET https://api.botbell.app/v1/messages/poll
Headers:
X-Bot-Token: <your_bot_token>クエリパラメータ
| フィールド | 型 | デフォルト | 説明 |
|---|---|---|---|
since | integer | - | この Unix タイムスタンプ以降のメッセージのみを返します |
limit | integer | 20 | 返すメッセージ数(最大 100) |
レスポンス
{
"code": 0,
"message": "success",
"data": {
"messages": [
{
"message_id": "msg_xyz789",
"content": "Got it, thanks!",
"timestamp": 1709827300
}
],
"has_more": false
}
}注意: ポーリングされたメッセージは既読としてマークされ、再度返されることはありません。ポーリングされなかったメッセージは 24 時間後に期限切れになります。
エラーコード
| コード | HTTP ステータス | 説明 |
|---|---|---|
| 40001 | 401 | Bot トークンが無効または欠落しています |
| 40010 | 400 | リクエストの検証に失敗しました(例:message フィールドの欠落、ボディが大きすぎる) |
| 40029 | 429 | レート制限を超過しました——1 分あたりのリクエスト数が多すぎます |
| 40030 | 429 | 月間メッセージクォータを使い果たしました |
| 40031 | 403 | プランの Bot 数上限に達しました |
| 50000 | 500 | 内部サーバーエラー |
レート制限とクォータ
| 制限 | 値 |
|---|---|
| プッシュレート(Bot ごと) | 60 |
| メッセージ本文(文字数) | 4,096 |
| タイトル(文字数) | 256 |
| 月間無料枠 | Bot あたり 300 メッセージ |
| ポーリングメッセージの保持期間 | 24h |
| 返信コールバック URL のタイムアウト | 5s |
レート制限のステータスはレスポンスヘッダーで返されます:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1709827260コード例
メッセージの送信
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);返信署名の検証
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),
);
}