ボット開発
Bot API リファレンス
Pabal の HTTP Bot API が受け付けるメソッド、やり取りするオブジェクト、エラーを漏れなくまとめました。Telegram Bot API と互換性があります。
Pabal の HTTP Bot API は、Telegram Bot API と同じアドレス形式・リクエスト・レスポンス・エラーを使います。このドキュメントには、Pabal が実際に受け付けるものだけを記載しています。ここにないメソッドは 404 Not Found: method not found を返します。はじめての方は、ボット作成チュートリアルから読んでください。
リクエストの送信
https://pabal.me/bot<トークン>/<メソッド>
- HTTP メソッド:
GETとPOSTのどちらも使えます。 - パラメーターを送る 4 つの方法 — クエリ文字列(
?chat_id=1&text=hi)、application/x-www-form-urlencoded、application/json、ファイルをアップロードするときのmultipart/form-data。組み合わせて使ってもかまいません。 - オブジェクト型のパラメーター(
reply_markup、commands、allowed_updates)は、JSON 本文ではオブジェクト・配列のまま、フォーム・クエリでは JSON 文字列として入れます。 - メソッド名は大文字と小文字を区別しません(
sendMessage=sendmessage)。 - 本文のサイズは 12MB までです(超えると
413)。 - ファイルのダウンロードは、別のアドレス
https://pabal.me/file/bot<トークン>/<file_path>です(getFile)。
レスポンスとエラー
レスポンスは常に JSON です。成功なら HTTP 200 と result、失敗ならその HTTP ステータスと同じ error_code と、人が読むための description が返ります。
{"ok": true, "result": { … }}{"ok": false, "error_code": 400, "description": "Bad Request: chat not found"}| error_code | 発生する場面 | description の例 |
|---|---|---|
400 | パラメーターが正しくない | Bad Request: chat not found、Bad Request: message text is empty、Bad Request: message is not modified: …、Bad Request: message to edit not found、Bad Request: wrong file identifier/HTTP URL specified、Bad Request: query is too old and response timeout expired or query ID is invalid |
401 | トークンが正しくない | Unauthorized |
403 | 送信する権限がない | Forbidden: bot can't initiate conversation with a user、Forbidden: bot is not a member of the group chat |
404 | 存在しないメソッド・ファイル | Not Found: method not found |
409 | Webhook の設定中に getUpdates を呼んだ | Conflict: can't use getUpdates method while webhook is active; use deleteWebhook to delete the webhook first |
413 | 本文が 12MB を超えた | Request Entity Too Large |
500 | サーバー内部エラー | Internal Server Error |
Pabal はまだリクエスト全体のレート制限を設けていませんが、音声のメソッドには 1 時間あたりの上限があり、429 Too Many Requests: retry after N が返ります(音声通話)。429 を受け取ったら parameters.retry_after 秒待ってから再送するように実装しておいてください。
アップデートの受信
2 つの方法のどちらかを使います。同時には使えません。
getUpdates
POST/bot<トークン>/getUpdates
待機中のアップデートを取得します(ロングポーリング)。Webhook が設定されていると 409。
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
offset | Integer | 任意 | この番号以上のアップデートのみ。これより小さいものは「受信済み」として消えます。最後に処理した update_id + 1 を指定してください。 |
limit | Integer | 任意 | 1〜100、既定 100 |
timeout | Integer | 任意 | 待つ秒数、0〜50、既定 0。25〜30 をおすすめします。 |
allowed_updates | Array of String | 任意 | 受け取る種類(Update)。空なら既定の種類(message、edited_message、callback_query)すべて。音声の種類は名前を書いた場合にだけ届きます。渡したリストはボットの設定として残り、次の呼び出しと Webhook にも使われます(渡さなければ前の値のまま) |
戻り値:Array of Update
setWebhook
POST/bot<トークン>/setWebhook
アップデートを HTTPS アドレスで受け取ります。詳しい説明は Webhook のドキュメントにあります。
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
url | String | はい | https:// のグローバルアドレス。空文字列なら Webhook を削除 |
secret_token | String | 任意 | 1〜256 文字、A-Z a-z 0-9 _ -。リクエストヘッダー X-Telegram-Bot-Api-Secret-Token で送る |
allowed_updates | Array of String | 任意 | message、edited_message、callback_query から選択。空ならこの 3 つすべて。音声の種類(voice_call、voice_call_tool_query、voice_call_transcript)は名前を書いた場合にだけ届きます。渡さなければ前の値のまま |
drop_pending_updates | Boolean | 任意 | 待機中のアップデートを破棄 |
max_connections | Integer | 任意 | 1〜100、既定 40。保持するだけで、配信はボットごとに一度に 1 つずつ |
certificate | InputFile | 不可 | 400 — 公的な証明書を使ってください |
ip_address | String | 無視 |
戻り値:True
deleteWebhook
POST/bot<トークン>/deleteWebhook
Webhook を削除して getUpdates に戻ります。Webhook がなくても成功します。
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
drop_pending_updates | Boolean | 任意 | 待機中のアップデートを破棄 |
戻り値:True
getWebhookInfo
GET/bot<トークン>/getWebhookInfo
Webhook の状態。パラメーターなし。Webhook がなければ url は空文字列です。
戻り値:WebhookInfo
メソッド
| メソッド | 内容 |
|---|---|
getMe | ボット自身の情報 |
sendMessage | テキストの送信(ボタンを含む) |
sendPhoto | 写真の送信 |
sendDocument | ファイルの送信 |
sendLocation | 位置情報の送信(ライブ位置情報を含む) |
sendVenue | 場所の送信(名前と住所の付いた位置情報) |
sendContact | 連絡先カードの送信 |
editMessageLiveLocation · stopMessageLiveLocation | ライブ位置情報の移動・停止 |
editMessageText | 送信したメッセージのテキスト・ボタンの編集 |
editMessageCaption | 写真のキャプションの編集 |
editMessageReplyMarkup | ボタンのみの編集 |
deleteMessage | メッセージの削除 |
answerCallbackQuery | ボタンの押下への応答 |
sendChatAction | 「入力中」の表示(受け付けるだけ) |
getChat | チャットの情報 |
getFile | 受け取った写真のダウンロードパス |
setMyCommands · getMyCommands · deleteMyCommands | コマンドメニュー |
logOut · close | 互換性のため(何もしない) |
getUpdates · setWebhook · deleteWebhook · getWebhookInfo | アップデートの受信(上記) |
setVoiceCallSettings · getVoiceCallSettings · endVoiceCall · sendVoiceCallContext · getVoiceCallUsage · startVoiceCall · answerVoiceCallToolQuery · setVoiceCallApiKey · setVoiceCallMcpServer … | 音声ボット(下の音声通話) |
chat_id に指定できるもの
1 対 1 の会話なら人の ID(正の数)、基本グループならグループ ID(負の数)、または人のユーザー名("@hana_lee")。いずれもアップデートの chat.id でわかります。チャンネル・スーパーグループの ID(-100…)はまだありません(400 chat not found)。
getMe
GET/bot<トークン>/getMe
トークンが正しいかを確認するときに使います。パラメーターなし。
戻り値:User — ボットの場合は、can_join_groups(true)、can_read_all_group_messages(true)、supports_inline_queries(false)、can_connect_to_business(false)、has_main_web_app(false)が追加されます。
sendMessage
POST/bot<トークン>/sendMessage
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
chat_id | Integer または String | はい | 送信先のチャット(上のボックスを参照) |
text | String | はい | 1〜4,096 文字。文字どおりに送ります |
reply_markup | InlineKeyboardMarkup · ReplyKeyboardMarkup · ReplyKeyboardRemove · ForceReply | 任意 | ボタン |
disable_notification | Boolean | 任意 | 通知音なしで送信 |
parse_mode、entities、reply_parameters、link_preview_options … | 無視 | 受け取りますが使いません。書式は適用されません |
戻り値:送信した Message
人に送るには、その人が先にボットに話しかけている必要があります(403 Forbidden: bot can't initiate conversation with a user)。グループに送るには、ボットがそのグループのメンバーである必要があります。
sendPhoto
POST/bot<トークン>/sendPhoto
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
chat_id | Integer または String | はい | 送信先のチャット |
photo | InputFile または String | はい | multipart/form-data でアップロードしたファイル(10MB まで、JPEG・PNG・GIF)、または以前に受け取った写真の file_id。URL はまだ使えない |
caption | String | 任意 | 0〜1,024 文字 |
reply_markup | sendMessage と同じ | 任意 | |
disable_notification | Boolean | 任意 |
戻り値:送信した Message(photo に新しい file_id)
sendDocument
POST/bot<トークン>/sendDocument
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
chat_id | Integer または String | はい | 送信先のチャット |
document | InputFile または String | はい | multipart/form-data でアップロードしたファイル(形式の制限なし、20MB まで)、または以前に受け取ったファイルの file_id。URL はまだ使えない |
filename | String | 任意 | 受け取る側に表示される名前。指定しなければ、アップロードしたファイルの名前を使います |
caption | String | 任意 | 0〜1,024 文字 |
reply_markup | sendMessage と同じ | 任意 | |
disable_notification | Boolean | 任意 | |
thumbnail、disable_content_type_detection | 無視 | 受け取りますが使いません |
戻り値:送信した Message(document に新しい file_id)
形式(mime_type)は、ファイル名の拡張子から決めます。アプリから送るファイルは 2GB までですが、ボットが HTTP でアップロード・ダウンロードできるのは、Telegram と同じく 20MB までです。
sendLocation
POST/bot<トークン>/sendLocation
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
chat_id | Integer または String | はい | 送信先のチャット |
latitude、longitude | Float | はい | 緯度(−90〜90)と経度(−180〜180)。範囲外なら 400 Bad Request: GEO_POINT_INVALID |
horizontal_accuracy | Float | 任意 | 誤差の半径(メートル、0〜1,500)。四捨五入して整数で保存します |
live_period | Integer | 任意 | 指定するとライブ位置情報になります:60〜86,400 秒、または停止するまでなら 2147483647(0x7FFFFFFF)。それ以外の値は 400 Bad Request: wrong live_period |
heading | Integer | 任意 | ライブ位置情報の進行方向、1〜360 度 |
proximity_alert_radius | Integer | 任意 | ライブ位置情報の接近通知の半径(メートル)。保存して表示しますが、通知はまだ送りません |
reply_markup | sendMessage と同じ | 任意 | |
disable_notification | Boolean | 任意 |
戻り値:送信した Message(location に Location)
sendVenue
POST/bot<トークン>/sendVenue
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
chat_id | Integer または String | はい | 送信先のチャット |
latitude、longitude | Float | はい | 場所の位置(sendLocation と同じ) |
title | String | はい | 場所の名前 |
address | String | はい | 住所 |
foursquare_id、foursquare_type | String | 任意 | Foursquare の場所 ID と種類。受け取ったまま伝えます |
google_place_id、google_place_type | String | 任意 | Google の場所 ID と種類。foursquare_id がないときだけ使います |
reply_markup | sendMessage と同じ | 任意 | |
disable_notification | Boolean | 任意 |
戻り値:送信した Message(venue に Venue、location にも同じ位置)
title または address がなければ 400 Bad Request: title and address are required になります。
sendContact
POST/bot<トークン>/sendContact
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
chat_id | Integer または String | はい | 送信先のチャット |
phone_number | String | はい | 電話番号。書かれたとおりに伝えます |
first_name | String | はい | 名 |
last_name | String | 任意 | 姓 |
vcard | String | 任意 | vCard 形式の追加情報、64KB まで |
reply_markup | sendMessage と同じ | 任意 | |
disable_notification | Boolean | 任意 |
戻り値:送信した Message(contact に Contact)
ボットが送った連絡先カードには user_id が付きません。番号が Pabal のアカウントのものでも同じです — ボットには連絡先がなく、付けてしまうと番号ごとにカードを 1 枚ずつ送って、その番号が誰のものかを調べられるからです。phone_number または first_name がなければ 400 Bad Request: phone_number and first_name are required になります。
editMessageLiveLocation
POST/bot<トークン>/editMessageLiveLocation
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
chat_id | Integer または String | はい | メッセージのあるチャット |
message_id | Integer | はい | 移動するライブ位置情報(ボットが送ったもの) |
latitude、longitude | Float | はい | 新しい位置 |
horizontal_accuracy | Float | 任意 | 誤差の半径(メートル、0〜1,500) |
heading | Integer | 任意 | 進行方向、1〜360 度 |
proximity_alert_radius | Integer | 任意 | 接近通知の半径(メートル)。0 ならオフ |
live_period | Integer | 任意 | 新しい共有期間:メッセージを送った時刻から数えた秒数。今の期間より 1 日を超えて延ばすことはできず、2147483647 なら停止するまで |
reply_markup | InlineKeyboardMarkup | 任意 | 新しいボタン |
inline_message_id | String | 不可 | インラインモードがないため 400 |
戻り値:編集後の Message
すでに終わったライブ位置情報 — 停止したもの、または期間が切れたもの — は、移動することも、期間を延ばして復活させることもできません(400 Bad Request: message can't be edited)。ライブ位置情報でないメッセージも同じです。
最後に反映された移動から 10 秒たっていない移動や、10m も動いていない移動は、サーバーが保存せずに見送ります。停止と、期間・通知半径の変更は常に反映されます。見送った場合に返される Message は最後に反映された位置を示すので、数秒ごとに送っても問題ありません。
stopMessageLiveLocation
POST/bot<トークン>/stopMessageLiveLocation
パラメーターは chat_id、message_id、reply_markup(任意)。ライブ位置情報を最後の位置で止めます。共有期間が実際に経過した時間に縮まるので、すべてのアプリが終了した位置情報として表示します。すでに停止または終了していれば 400 Bad Request: message is not modified: … になります。戻り値:編集後の Message。
editMessageText
POST/bot<トークン>/editMessageText
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
chat_id | Integer または String | はい | メッセージのあるチャット |
message_id | Integer | はい | 編集するメッセージ(ボットが送ったもの) |
text | String | はい | 新しいテキスト、1〜4,096 文字 |
reply_markup | InlineKeyboardMarkup | 任意 | 新しいボタン。省略するとボタンが消えます(Telegram と同じ) |
inline_message_id | String | 不可 | インラインモードがないため 400 |
戻り値:編集後の Message。アプリにはすぐ反映され、人が編集したメッセージはボットに edited_message として届きます。
テキストとボタンが以前とまったく同じなら 400 Bad Request: message is not modified: …、他人のメッセージを編集しようとすると 400 Bad Request: message can't be edited になります。
editMessageCaption
POST/bot<トークン>/editMessageCaption
パラメーターは chat_id、message_id、caption(0〜1,024 文字、省略するとキャプションを削除)、reply_markup。戻り値:編集後の Message。
editMessageReplyMarkup
POST/bot<トークン>/editMessageReplyMarkup
テキストはそのままで、ボタンだけを変更します。パラメーターは chat_id、message_id、reply_markup(省略するとボタンを削除)。戻り値:編集後の Message。
deleteMessage
POST/bot<トークン>/deleteMessage
パラメーターは chat_id、message_id。メッセージを会話の双方から削除します。存在しないメッセージなら 400 Bad Request: message to delete not found。戻り値:True。
answerCallbackQuery
POST/bot<トークン>/answerCallbackQuery
人が押したボタン(CallbackQuery)に応答します。10 秒以内に、1 回だけ応答できます。
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
callback_query_id | String | はい | アップデートの callback_query.id |
text | String | 任意 | 画面上部に一瞬表示される文言 |
show_alert | Boolean | 任意 | true なら、OK ボタン付きのダイアログで表示 |
url | String | 任意 | アプリが開くアドレス |
cache_time | Integer | 任意 | アプリがこの応答を記憶する秒数 |
戻り値:True。遅すぎた場合やすでに応答済みの場合は 400 Bad Request: query is too old and response timeout expired or query ID is invalid。
sendChatAction
POST/bot<トークン>/sendChatAction
互換性のために受け付けて True を返しますが、まだアプリに「入力中…」は表示しません。
getChat
GET/bot<トークン>/getChat?chat_id=…
パラメーターは chat_id(数値)。人ならその人、グループならボットがメンバーであるグループのみ。戻り値:Chat。存在しないか閲覧できない場合は 400 Bad Request: chat not found。
getFile
GET/bot<トークン>/getFile?file_id=…
受け取った写真の file_id から、ダウンロード用のパスを取得します。戻り値:File。その後、次のアドレスからダウンロードします。
https://pabal.me/file/bot<トークン>/<file_path>
file_id は、その写真を取得する権利でもあります。無効な値なら 400 Bad Request: wrong file identifier/HTTP URL specified。
setMyCommands
POST/bot<トークン>/setMyCommands
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
commands | Array of BotCommand | はい | 最大 100 個 |
language_code | String | 任意 | 言語別の一覧として保存。アプリには現在、言語コードなしの既定の一覧だけが表示されます |
scope | BotCommandScope | 無視 |
戻り値:True。ルールに合わなければ何も保存せず 400 Bad Request: BOT_COMMAND_INVALID(コマンド)、BOT_COMMAND_DESCRIPTION_INVALID(説明が空か 256 文字超)、BOT_COMMANDS_TOO_MUCH(100 個超)。
getMyCommands
GET/bot<トークン>/getMyCommands
パラメーターは language_code(任意)。戻り値:Array of BotCommand。
deleteMyCommands
POST/bot<トークン>/deleteMyCommands
パラメーターは language_code(任意)。その一覧を空にします。戻り値:True。
logOut · close
Telegram では、ローカルの Bot API サーバーへ移行するときに使うメソッドです。Pabal には移行先がないため、受け付けて True を返すだけです。トークンを無効にするには、BotFather の /revoke を使ってください。
オブジェクト
フィールドの横の 任意 は、含まれない場合があることを示します。ここにない Telegram のほかのフィールドを、Pabal は送りません。
Update
1 件の新着。update_id と、下のうち1 つが含まれます。
| フィールド | 型 | 説明 |
|---|---|---|
update_id | Integer | 1 ずつ増える番号。getUpdates の offset に使います |
message 任意 | Message | ボットに届いた新しいメッセージ(1 対 1 の会話、またはボットがメンバーであるグループのすべてのメッセージ) |
edited_message 任意 | Message | 編集されたメッセージ |
callback_query 任意 | CallbackQuery | インラインボタンの押下 |
voice_call 任意 | VoiceCall | 音声ボットにかかってきた通話とボットがかけた電話の開始・終了(名前で求めた場合にだけ届く) |
voice_call_tool_query 任意 | VoiceCallToolQuery | 通話中にモデルが呼んだボットのツール(名前で求めた場合にだけ届く) |
voice_call_transcript 任意 | VoiceCallTranscript | 通話中の文字起こしの 1 発話(名前で求めた場合にだけ届く) |
User
| フィールド | 型 | 説明 |
|---|---|---|
id | Integer | ユーザー ID(このサーバー内でのみ意味を持つ) |
is_bot | Boolean | ボットなら true |
first_name | String | 名前。削除されたアカウントなら Deleted Account |
last_name 任意 | String | 姓 |
username 任意 | String | ユーザー名(@ なし) |
Chat
| フィールド | 型 | 説明 |
|---|---|---|
id | Integer | 人ならその人の ID(正の数)、基本グループなら負の数 |
type | String | private または group |
title 任意 | String | グループ名(group) |
first_name、last_name、username 任意 | String | 相手の名前・ユーザー名(private) |
Message
| フィールド | 型 | 説明 |
|---|---|---|
message_id | Integer | この会話の中でのメッセージ番号 |
from 任意 | User | 送信者 |
chat | Chat | メッセージのある会話 |
date | Integer | 送信時刻(Unix 秒) |
edit_date 任意 | Integer | 最後に編集した時刻 |
text 任意 | String | テキスト(写真・ファイル・位置情報・場所・連絡先のメッセージでなければ常にある) |
entities 任意 | Array of MessageEntity | テキスト中のコマンド・メンション・URL・ハッシュタグ |
photo 任意 | Array of PhotoSize | 写真(Pabal では原本 1 つ) |
document 任意 | Document | ファイル |
location 任意 | Location | 位置情報またはライブ位置情報。場所のメッセージにもその位置が一緒に入ります |
venue 任意 | Venue | 場所 |
contact 任意 | Contact | 連絡先カード |
caption 任意 | String | 写真のキャプション |
caption_entities 任意 | Array of MessageEntity | キャプション中のコマンド・メンション・URL・ハッシュタグ |
reply_markup 任意 | InlineKeyboardMarkup | メッセージに付いたインラインボタン |
MessageEntity
| フィールド | 型 | 説明 |
|---|---|---|
type | String | bot_command、mention、url、hashtag |
offset | Integer | 開始位置(UTF-16 コード単位) |
length | Integer | 長さ(UTF-16 コード単位) |
サーバーがテキストから自動的に見つけて付けます。太字・斜体のような書式のエンティティはまだありません。
PhotoSize
| フィールド | 型 | 説明 |
|---|---|---|
file_id | String | ダウンロード(getFile)と再送信(sendPhoto)に使う ID |
file_unique_id | String | 同じ写真なら、ボットが違っても同じ値。ダウンロードには使えない |
width、height | Integer | ピクセル単位のサイズ |
file_size | Integer | バイト数 |
Document
| フィールド | 型 | 説明 |
|---|---|---|
file_id | String | ダウンロード(getFile)と再送信(sendDocument)に使う ID |
file_unique_id | String | 同じファイルなら、ボットが違っても同じ値。ダウンロードには使えない |
file_name | String | 送信側が付けた名前 |
mime_type | String | 送信側が申告した形式 |
file_size | Integer | バイト数 |
Location
| フィールド | 型 | 説明 |
|---|---|---|
latitude、longitude | Float | 緯度と経度 |
horizontal_accuracy 任意 | Float | 誤差の半径(メートル) |
live_period 任意 | Integer | ライブ位置情報の共有期間:メッセージを送った時刻から数えた秒数。停止すると実際に経過した時間に縮まります |
heading 任意 | Integer | 進行方向、1〜360 度 |
proximity_alert_radius 任意 | Integer | 接近通知の半径(メートル) |
人が共有するライブ位置情報は、サーバーが移動を反映するたびに edited_message としてもう一度届きます。
Venue
| フィールド | 型 | 説明 |
|---|---|---|
location | Location | 場所の位置 |
title | String | 場所の名前 |
address | String | 住所 |
foursquare_id、foursquare_type 任意 | String | Foursquare の場所 ID と種類 |
google_place_id、google_place_type 任意 | String | Google の場所 ID と種類 |
Contact
| フィールド | 型 | 説明 |
|---|---|---|
phone_number | String | 送った人が書いたままの番号 |
first_name | String | 名 |
last_name 任意 | String | 姓 |
user_id 任意 | Integer | その番号の Pabal アカウント。送った人が自分の連絡先に保存している相手か、本人であるときだけ付きます |
vcard 任意 | String | vCard 形式の追加情報 |
File
| フィールド | 型 | 説明 |
|---|---|---|
file_id、file_unique_id | String | PhotoSize と同じ |
file_size | Integer | バイト数 |
file_path | String | photos/<file_id>.jpg または documents/<file_id> の形式。/file/bot<トークン>/ の後ろに付けてダウンロードします |
CallbackQuery
| フィールド | 型 | 説明 |
|---|---|---|
id | String | answerCallbackQuery に渡す ID |
from | User | ボタンを押した人 |
message 任意 | Message | ボタンが付いたメッセージ |
chat_instance | String | その会話を表す値 |
data 任意 | String | ボタンの callback_data |
InlineKeyboardMarkup
inline_keyboard:Array of Array of InlineKeyboardButton — 外側の配列が行、内側の配列が 1 行分のボタンです。1 つのメッセージに最大 100 行・100 個。
InlineKeyboardButton
| フィールド | 型 | 説明 |
|---|---|---|
text | String | ボタンの文字 |
callback_data いずれか一方 | String | 押すとボットに送られる値、1〜64 バイト |
url いずれか一方 | String | 押すと開くアドレス |
switch_inline_query、web_app、login_url、pay のようなほかの種類はまだありません(400)。
ReplyKeyboardMarkup
| フィールド | 型 | 説明 |
|---|---|---|
keyboard | Array of Array of KeyboardButton | 入力欄の下のボタンパネル |
resize_keyboard、one_time_keyboard、is_persistent、selective 任意 | Boolean | サイズ調整 · 一度使うと非表示 · 常に表示 · 特定の人にのみ表示 |
input_field_placeholder 任意 | String | 入力欄のプレースホルダー |
KeyboardButton
文字列 1 つ、または text と任意のフィールド request_contact(自分の連絡先を送る)・request_location(現在地を送る、Boolean)を持つオブジェクト。
ReplyKeyboardRemove
{"remove_keyboard": true} — ボタンパネルを隠します。selective は任意。
ForceReply
{"force_reply": true} — アプリが、このメッセージへの返信状態で入力欄を開きます。selective、input_field_placeholder は任意。
BotCommand
| フィールド | 型 | 説明 |
|---|---|---|
command | String | 英小文字・数字・アンダースコアの 1〜32 文字(/ なし) |
description | String | 1〜256 文字 |
WebhookInfo
| フィールド | 型 | 説明 |
|---|---|---|
url | String | Webhook のアドレス。なければ空文字列 |
has_custom_certificate | Boolean | 常に false |
pending_update_count | Integer | 配信を待っているアップデートの数 |
ip_address 任意 | String | 最後に送信した IP |
last_error_date 任意 | Integer | 最後の失敗時刻(Unix 秒) |
last_error_message 任意 | String | 最後の失敗理由(一覧) |
max_connections 任意 | Integer | setWebhook で指定した値 |
allowed_updates 任意 | Array of String | setWebhook で指定した値 |
音声通話
Pabal にだけあるメソッドです。音声ボットは、アプリから人が電話をかけると AI 音声モデルが応答するボットで、これらのメソッドでそのモデルの設定を決め、通話を扱います。何が有効になっている必要があるか、有効にする方法と例は、音声ボットの案内にあります。メソッドは音声が無効なサーバーにもあって設定を読めますが、音声が無効か、運営者がまだ許可していないボットは、無効にする操作と削除以外に設定を変えられません(403 VOICE_NOT_AVAILABLE)。
setVoiceCallSettings
POST/bot<トークン>/setVoiceCallSettings
ボットの音声の設定を変えます。送った項目だけが変わり、全体を検査してから一度に書き込むか、すべてを拒否します。ボットごとに 1 時間 30 回(@BotFather と合わせて)。
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
enabled | Boolean | 任意 | オンにするのは @BotFather で音声ボットのルールに同意したあとだけ(403 VOICE_RULES_NOT_ACCEPTED)。オフはいつでも |
instructions | String | 任意 | モデルの指示文、8,192 バイトまで。"" は削除(有効なマネージドモードのボットでは不可) |
greeting | String | 任意 | 最初のあいさつ、512 バイトまで。"" ならモデルにまかせる |
voice | String | 任意 | 声の id、既定は kore(一覧) |
language | String | 任意 | ko-KR(既定) · en-US · ja-JP · cmn-CN · fr-FR · es-US · id-ID · vi-VN · ar-EG(一覧)。大文字・小文字は区別せず、zh-CN は cmn-CN として保存します。韓国語・英語以外のボットは、運営者が指示文・あいさつを読んで許可したあとで電話を受けます |
max_call_duration | Integer | 任意 | 秒、60 〜 limits.max_call_duration |
max_concurrent_calls | Integer | 任意 | 1 〜 limits.max_concurrent_calls |
tools | Array of VoiceCallTool | 任意 | 通話中にモデルが呼ぶボットのツール:{"name", "description", "parameters"?, "timeout_ms"?}。ルールはツールを決める。フォームでは JSON 文字列 |
transcript | Boolean | 任意 | 文字起こしのスイッチ。オンにできるのはボットオーナー規約に同意したあとだけ |
mode | String | 任意 | managed(Pabal の AI モデル)または stream(ストリームモード) |
stream_url、stream_secret | String | 任意 | mode=stream と一緒に。シークレットはリクエスト本文でのみ |
戻り値:True
getVoiceCallSettings
GET/bot<トークン>/getVoiceCallSettings
パラメーターなし。現在の設定と、ボットがいま電話を受けられるか(available、unavailable_reason)、サーバーの上限、声と言語の一覧、ツール問い合わせ・文字起こしの届け先、自前のキー・ストリームモード・MCP サーバーの状態。キーとシークレットは表示されず、フィンガープリントだけが表示されます。フィールドは音声ボット — 現在の設定を見るにあります。
戻り値:VoiceCallSettings(オブジェクト)
endVoiceCall
POST/bot<トークン>/endVoiceCall
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
voice_call_id | String | はい | voice_call.id |
farewell | Boolean | 任意 | 既定 true: モデルが短く別れのあいさつをして切る(10 秒以内に切れなければサーバーが終わらせる)。false ならすぐに |
戻り値:True。このボットの進行中の通話でなければ 400 VOICE_CALL_NOT_FOUND。
sendVoiceCallContext
POST/bot<トークン>/sendVoiceCallContext
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
voice_call_id | String | はい | つながっている通話 |
text | String | はい | モデルに渡すボットのオーナーのメモ。2,000 文字・6,144 バイトまで、内容のルールで検査 |
respond | Boolean | 任意 | 既定 false。true ならモデルがすぐに反応 |
戻り値:True。つながる前は VOICE_CALL_NOT_ACTIVE、ストリーム通話は VOICE_CONTEXT_NOT_SUPPORTED、長すぎれば VOICE_CONTEXT_TOO_LONG、通話ごとに 1 分に 10 件を超えると 429。
getVoiceCallUsage
GET/bot<トークン>/getVoiceCallUsage
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
period | String | 任意 | today(既定)または month |
month | String | 任意 | YYYY-MM、period=month と一緒にだけ |
戻り値:period、from_date、to_date、calls、seconds、missed、refused(busy・budget・unavailable)、platform_seconds、own_key_seconds、remaining_seconds_today(bot・owner)、発信を有効にしたことのあるボットなら outbound(today・limits)— 日付の区切りはサーバーのタイムゾーン
startVoiceCall
POST/bot<トークン>/startVoiceCall
ボットが人に電話をかけます。ボットオーナーが @BotFather で有効にし、運営者が審査したボットが、そのボットに電話を許可した人にだけかけられます。答えと判定は音声ボット — かけるにあります。
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
user_id | Integer | はい | かける相手 |
purpose | String | はい | reminder、wake_up、delivery、appointment のうちボットが選んだもの |
context | String | はい | モデルにだけ渡す説明、1,000 文字・3,072 バイトまで、内容のルールを検査 |
max_duration | Integer | 任意 | 出たあとの最大の秒数、30–300(ボットの上限まで)。既定 180 |
ring_timeout | Integer | 任意 | 鳴らす秒数、30–45。既定 40 |
戻り値:{"voice_call_id": "…"} — 受け付けたという意味だけで、鳴ったか・出たかは voice_call アップデートで届きます。拒否は 403 VOICE_OUTBOUND_OFF: <理由>、403 USER_UNAVAILABLE(いつも同じ本文)、429、503 VOICE_UNAVAILABLE。Webhook の応答からは呼べません。
answerVoiceCallToolQuery
POST/bot<トークン>/answerVoiceCallToolQuery
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
tool_query_id | String | はい | VoiceCallToolQuery の id |
result | String · Object · Array | いずれか一方 | ツールの結果、16,384 バイトまで |
error | String | いずれか一方 | ボットの失敗の文言、512 バイトまで |
戻り値:True。最初の答えが最後です。遅れると 400 TOOL_QUERY_EXPIRED: answered|timeout|cancelled|call_ended|unreachable、知らない id は TOOL_QUERY_ID_INVALID、答えが拒否されると TOOL_RESULT_EMPTY・TOOL_RESULT_INVALID・TOOL_RESULT_TOO_LONG・TOOL_ERROR_TOO_LONG・TOOL_RESULT_REFUSED: <コード>。Webhook のツール問い合わせの POST には、レスポンス本文でも答えられます。
setVoiceCallApiKey · deleteVoiceCallApiKey
POST/bot<トークン>/setVoiceCallApiKey
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
provider | String | はい | google(Vertex AI のサービス アカウントの JSON キー)または openai(sk-…) |
api_key | String | はい | キー。リクエスト本文でのみ(クエリなら 400)、8KiB まで |
戻り値:True — ゲートウェイのテストセッションを通ったあとでだけ保管します。API_KEY_INVALID、API_KEY_NO_REALTIME_ACCESS、503 API_KEY_CHECK_UNAVAILABLE(保管しない)、403 VOICE_OWN_KEY_NOT_AVAILABLE(このサーバーは自前のキーを受け付けない)。deleteVoiceCallApiKey はパラメーターなしで、いつでも True。どちらのメソッドも bots.sendCustomRequest では呼べず、setVoiceCallApiKey は Webhook のレスポンスでも呼べません。詳しくは自前のモデルキー。
MCP サーバーのメソッド
| メソッド | パラメーター | 戻り値 |
|---|---|---|
setVoiceCallMcpServer | label、url、auth(オブジェクト)、任意で audience、allowed_tools、requested_level、timeout_ms、tools(分類の上書き)、declaration、auto_repin | 登録の結果(status、job_id)。送り先が変わると 400 MCP_CHANGE_NEEDS_CONFIRMATION のあと @BotFather で確認 |
refreshVoiceCallMcpServer | label | 再検査(refreshing: true、job_id) |
deleteVoiceCallMcpServer | label | True — MCP が無効でもできる |
getVoiceCallMcpBinding | なし | iss、sub(bot:<id>)、issuer_document、jwks_uri、audiences |
createVoiceCallMcpClientKey | label | 公開の jwk、thumbprint(秘密鍵は Pabal の外に出ない) |
auth とシークレットはリクエスト本文でのみ送ります。MCP が無効なサーバーでは 403 VOICE_NOT_AVAILABLE: MCP tools are not available on this server。詳しくは音声ボット — MCP サーバー。
音声のアップデートを受け取るには
voice_call、voice_call_tool_query、voice_call_transcript は名前で求めた場合にだけ届きます — getUpdates か setWebhook の allowed_updates に書いてください。空のリストでは届かず、求める前に起きたものはためられません。ツール問い合わせは、Webhook があれば別に送る POST で、直近 15 秒以内に getUpdates を呼んでいれば次の getUpdates の先頭に届きます。
VoiceCall
| フィールド | 型 | 説明 |
|---|---|---|
id | String | 通話 id(符号なし 10 進数) |
direction | String | incoming(ボットへの電話)または outgoing(ボットがかけた電話)。いつもある |
event | String | started、ended、missed、refused。ボットがかけた電話は started、ended、not_answered、failed |
from 任意 | User | ボットへの電話だけ — 発信者:id、is_bot、first_name、last_name、language_code。ユーザー名と電話番号はない |
to 任意 | Object | ボットがかけた電話だけ — {"id": …}、着信者の ID 1 つ |
purpose 任意 | String | ボットがかけた電話だけ — 依頼の目的 |
date | Integer | 起きた時刻(Unix 秒)。started は、アプリの通話なら鍵交換が終わったとき、Apple Watch の通話ならウォッチの音声がつながったとき。ended は、文字起こしを待つサーバーや会話を残す機能が有効なサーバーでは最大 10 秒遅れて届きます。ボットがかけた電話では、サーバーの設定にかかわらず、出た通話の ended がゲートウェイの使用量を待つため最大 10 秒遅れて届きます |
max_duration 任意 | Integer | この通話の最大の長さ(秒)— started, ended |
start_date、duration 任意 | Integer | つながった時刻と、つながっていた秒数(サーバーの時計)— ended |
end_reason 任意 | String | caller(ボットがかけた電話は callee)、bot、max_length、failed、operator、suspended — ended, missed |
refused_reason 任意 | String | busy、budget、unavailable — refused |
transcript 任意 | Object | {"turns": [{"role", "text", "offset_ms"}], "truncated"} — ended、文字起こしが有効だったとき。ボットがかけた電話にはない |
VoiceCall には、発信者が会話を残すことを選んだかどうかを知らせるフィールドはありません。意図したものです — その文章は発信者自身のもので、ボットには送られません。そのため、会話を残す機能が有効なサーバーでは、ストリームモード以外のすべての通話の ended が同じだけ待ち、通話記録の次のメッセージ番号も、すべての通話で記録より 31 以上大きくなります(番号をあらかじめ確保するため)。
VoiceCallToolQuery
| フィールド | 型 | 説明 |
|---|---|---|
id | String | answerVoiceCallToolQuery に渡す id |
voice_call_id | String | 通話 id |
from | User | 発信者(VoiceCall と同じフィールド) |
name | String | ツールの名前 |
arguments | String | 引数、JSON オブジェクトのテキスト(サーバーが検査済み) |
budget_ms | Integer | 受け取った時点から、答えがサーバーに届くべき期限までのミリ秒 |
VoiceCallTranscript
| フィールド | 型 | 説明 |
|---|---|---|
voice_call_id | String | 通話 id |
seq | Integer | 発話の番号 |
role | String | caller または bot |
text | String | AI が書き取った文章。カード番号・住民登録番号を含むと数字を * に |
is_final | Boolean | 常に true |
offset_ms、date | Integer | 通話の音声が始まったときからのミリ秒、時刻 |
HTTP Bot API でだけ届きます。通話全体は、終わった voice_call の transcript にあります。
ストリームモード(mode=stream)
ストリームモードでは、通話の音声が Pabal の AI モデルの代わりにボットのオーナーのサーバーに送られます。setVoiceCallSettings に mode=stream、stream_url=wss://…、stream_secret=…(32〜128 文字の表示可能な ASCII、リクエスト本文でのみ)を送ると、Pabal のゲートウェイがそのアドレスに 1 回接続してみて(プローブ)、成功すれば有効になります。ボットオーナー規約と、ストリーム用の確認画面を含むアプリのビルドが必要です。設定・プローブの結果・例は音声ボット — ストリームモードにあります。
- 接続:TLS 1.2 以上、URL の名前に合う公的な証明書、サブプロトコル
pabal.voice.v1、圧縮なし、1 メッセージ 64KiB・テキスト 4KiB まで、リダイレクトなし。 - 署名:
X-Pabal-Voice-Signature: t=…,nonce=…,call=…,v1=HMAC-SHA256(stream_secret, "pabal-voice-stream/1\n<t>\n<nonce>\n<call>\n<host>\n<path?query>")。hostは自分が伝えた URL のホスト。300 秒・nonce は 1 回だけ・バイトどうしの比較・start.call_idがcallと同じかを確認(詳しく)。 - 音声:テキストメッセージは JSON のイベント、バイナリは PCM16 リトルエンディアン・モノラル・24 kHz。発信者の音声は 20 ms(960 バイト)単位。
- Pabal → ボット:
start(1 回) ·live(AI の案内が終わった) · 音声 ·mark·cleared·buffer_full·stop(→ 1000 で閉じる)。 - ボット → Pabal:
ready(startのあと 3 秒以内、いちばん最初に) · 音声(liveのあと) ·clear·mark·hangup。
メッセージ 1 つずつの形は、音声ボット — 仕様の表にあります。
音声のメソッドのエラー
音声のメソッドのエラーコードと意味は、音声ボット — エラーにまとめてあります。403 は Forbidden: <コード>: <説明> の形で(VOICE_RULES_NOT_ACCEPTED、VOICE_NOT_AVAILABLE、VOICE_SUSPENDED、VOICE_OWNER_TERMS_NOT_ACCEPTED、VOICE_OWN_KEY_NOT_AVAILABLE、VOICE_STREAM_NOT_AVAILABLE、VOICE_OUTBOUND_OFF)、USER_UNAVAILABLE だけは説明なしでいつも Forbidden: USER_UNAVAILABLE です。1 時間の上限を超えると 429 と retry_after です。
Telegram Bot API との違い
- アップデートの種類:
message、edited_message、callback_queryと、Pabal にだけある音声ボットの種類(voice_call、voice_call_tool_query、voice_call_transcript)のみ届きます。チャンネルの投稿、インラインクエリ、決済、投票、メンバーの変更(my_chat_member)などはありません。 - 書式:
parse_mode・entitiesを無視し、文字どおりに送ります。コマンド・メンション・URL・ハッシュタグだけが自動的に表示されます。 - チャットの種類:1 対 1 と基本グループのみ。チャンネル・スーパーグループ・フォーラムのトピックはありません。
- メディア:写真、ファイル(
sendDocument)、位置情報・ライブ位置情報・場所・連絡先のみ。動画・音声として再生されるメッセージ、ステッカー、アルバム(sendMediaGroup)、投票、URL を指定しての送信はありません。HTTP でのアップロード・ダウンロードは 20MB までです。 - 位置情報:ライブ位置情報の接近通知(
proximity_alert_radius)は保存するだけで送りません。10 秒・10m 以内の移動は反映せずに見送り、ボットが送った連絡先カードにはuser_idが付きません。 - グループ内のボット:プライバシーモードがないため、グループのすべてのメッセージを受け取ります。
- キュー:未取得のアップデートはボットごとに直近 1,000 件までメモリに保持し、サーバーの再起動時に消えます(Telegram は 24 時間保持)。
- Webhook:一度に 1 つずつ順番に送り(
max_connectionsは保持のみ)、自己署名証明書は受け付けず、ポートの制限はありません。 - ID:ユーザー・メッセージ・ファイルの ID は、このサーバーの中でのみ意味を持ちます。チャンネル・スーパーグループがないため、
-100…形式の ID もありません。 - 存在しないメソッド:上の一覧にないもの(
forwardMessage、copyMessage、sendVideo、sendPoll、getChatMember、banChatMember、answerInlineQuery…)は404 Not Found: method not found。