봇 개발
Bot API 레퍼런스
파발의 HTTP Bot API 가 받는 메서드와 주고받는 객체, 오류를 빠짐없이 정리했습니다. 텔레그램 Bot API 와 호환됩니다.
파발의 HTTP Bot API 는 텔레그램 Bot API 와 같은 주소 형식·요청·응답·오류를 씁니다. 이 문서는 파발이 실제로 받는 것만 적습니다. 여기 없는 메서드는 404 Not Found: method not found 를 돌려줍니다. 처음이라면 봇 만들기 튜토리얼부터 보세요.
요청 보내기
https://pabal.me/bot<토큰>/<메서드>
- HTTP 메서드:
GET과POST모두 됩니다. - 파라미터를 보내는 네 가지 방법 — 쿼리 문자열(
?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 | 웹훅이 있는데 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 |
파발은 아직 요청 속도 제한(429 Too Many Requests)을 두지 않지만, 앞으로 생길 수 있으니 429 를 받으면 parameters.retry_after 초만큼 기다렸다 다시 보내도록 짜 두세요.
업데이트 받기
두 방법 중 하나를 씁니다. 동시에 쓸 수는 없습니다.
getUpdates
POST/bot<토큰>/getUpdates
기다리는 업데이트를 가져옵니다(롱 폴링). 웹훅이 설정돼 있으면 409.
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
offset | Integer | 선택 | 이 번호 이상의 업데이트만. 이보다 작은 것은 "받았음"으로 지워집니다. 처리한 마지막 update_id + 1 을 주세요. |
limit | Integer | 선택 | 1~100, 기본 100 |
timeout | Integer | 선택 | 기다릴 초, 0~50, 기본 0. 25~30 을 권합니다. |
allowed_updates | Array of String | 무시 | 받지만 쓰지 않습니다. 종류를 거르려면 받은 뒤 거르세요. |
돌려주는 것: Array of Update
setWebhook
POST/bot<토큰>/setWebhook
업데이트를 HTTPS 주소로 받습니다. 자세한 설명은 웹훅 문서에 있습니다.
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
url | String | 예 | https:// 공인 주소. 빈 문자열이면 웹훅을 지움 |
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 중에서. 비우면 전부 |
drop_pending_updates | Boolean | 선택 | 기다리던 업데이트를 버림 |
max_connections | Integer | 선택 | 1~100, 기본 40. 보관만 하고, 전달은 봇마다 한 번에 하나씩 |
certificate | InputFile | 안 됨 | 400 — 공인 인증서를 쓰세요 |
ip_address | String | 무시 |
돌려주는 것: True
deleteWebhook
POST/bot<토큰>/deleteWebhook
웹훅을 지우고 getUpdates 로 돌아갑니다. 웹훅이 없어도 성공합니다.
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
drop_pending_updates | Boolean | 선택 | 기다리던 업데이트를 버림 |
돌려주는 것: True
getWebhookInfo
GET/bot<토큰>/getWebhookInfo
웹훅 상태. 파라미터 없음. 웹훅이 없으면 url 이 빈 문자열입니다.
돌려주는 것: WebhookInfo
메서드
| 메서드 | 하는 일 |
|---|---|
getMe | 봇 자신의 정보 |
sendMessage | 글 보내기 (버튼 포함) |
sendPhoto | 사진 보내기 |
editMessageText | 보낸 메시지의 글·버튼 고치기 |
editMessageCaption | 사진 설명 고치기 |
editMessageReplyMarkup | 버튼만 고치기 |
deleteMessage | 메시지 지우기 |
answerCallbackQuery | 버튼 누름에 답하기 |
sendChatAction | "입력 중" 표시 (받기만 함) |
getChat | 대화 정보 |
getFile | 받은 사진의 내려받기 경로 |
setMyCommands · getMyCommands · deleteMyCommands | 명령어 메뉴 |
logOut · close | 호환용 (아무 일도 하지 않음) |
getUpdates · setWebhook · deleteWebhook · getWebhookInfo | 업데이트 받기 (위) |
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)
editMessageText
POST/bot<토큰>/editMessageText
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
chat_id | Integer 또는 String | 예 | 메시지가 있는 대화 |
message_id | Integer | 예 | 고칠 메시지 (봇이 보낸 것) |
text | String | 예 | 새 글, 1~4,096자 |
reply_markup | InlineKeyboardMarkup | 선택 | 새 버튼. 빼면 버튼이 없어집니다(텔레그램과 같음) |
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초 안에, 한 번만 답할 수 있습니다.
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
callback_query_id | String | 예 | 업데이트의 callback_query.id |
text | String | 선택 | 화면 위에 잠깐 뜨는 문구 |
show_alert | Boolean | 선택 | true 면 확인 버튼이 있는 창으로 |
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.
getMyCommands
GET/bot<토큰>/getMyCommands
파라미터는 language_code(선택). 돌려주는 것: Array of BotCommand.
deleteMyCommands
POST/bot<토큰>/deleteMyCommands
파라미터는 language_code(선택). 그 목록을 비웁니다. 돌려주는 것: True.
logOut · close
텔레그램에서는 로컬 Bot API 서버로 옮길 때 쓰는 메서드입니다. 파발에는 옮길 곳이 없으므로 받기만 하고 True 를 돌려줍니다. 토큰을 무효로 하려면 BotFather 의 /revoke 를 쓰세요.
객체
필드 옆 선택 은 없을 수도 있다는 뜻입니다. 여기 없는 텔레그램의 다른 필드는 파발이 보내지 않습니다.
Update
새 소식 하나. update_id 와 아래 셋 중 하나가 들어 있습니다.
| 필드 | 타입 | 설명 |
|---|---|---|
update_id | Integer | 1씩 커지는 번호. getUpdates 의 offset 에 씁니다 |
message 선택 | Message | 봇에게 온 새 메시지 (1:1, 또는 봇이 멤버인 그룹의 모든 메시지) |
edited_message 선택 | Message | 고쳐진 메시지 |
callback_query 선택 | CallbackQuery | 인라인 버튼 누름 |
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 | 보낸 시각 (유닉스 초) |
edit_date 선택 | Integer | 마지막으로 고친 시각 |
text 선택 | String | 글 (사진 메시지가 아니면 늘 있음) |
entities 선택 | Array of MessageEntity | 글 속의 명령·멘션·URL·해시태그 |
photo 선택 | Array of PhotoSize | 사진 (파발은 원본 하나) |
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 | 바이트 |
File
| 필드 | 타입 | 설명 |
|---|---|---|
file_id, file_unique_id | String | PhotoSize 와 같음 |
file_size | Integer | 바이트 |
file_path | String | photos/<file_id>.jpg 꼴. /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 — 바깥 배열이 줄, 안쪽 배열이 한 줄의 버튼입니다. 한 메시지에 최대 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
문자열 하나, 또는 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 | 웹훅 주소, 없으면 빈 문자열 |
has_custom_certificate | Boolean | 늘 false |
pending_update_count | Integer | 전달을 기다리는 업데이트 수 |
ip_address 선택 | String | 마지막으로 보낸 IP |
last_error_date 선택 | Integer | 마지막 실패 시각 (유닉스 초) |
last_error_message 선택 | String | 마지막 실패 이유 (목록) |
max_connections 선택 | Integer | setWebhook 에 준 값 |
allowed_updates 선택 | Array of String | setWebhook 에 준 값 |
텔레그램 Bot API 와 다른 점
- 업데이트 종류:
message,edited_message,callback_query만 옵니다. 채널 글, 인라인 쿼리, 결제, 투표, 멤버 변경(my_chat_member) 등은 없습니다. - 서식:
parse_mode·entities를 무시하고 글자 그대로 보냅니다. 명령·멘션·URL·해시태그만 자동으로 표시됩니다. - 대화 종류: 1:1 과 기본 그룹만. 채널·슈퍼그룹·포럼 토픽은 없습니다.
- 미디어: 사진만. 문서·동영상·음성·스티커·앨범, URL 로 보내기는 없습니다.
- 그룹의 봇: 프라이버시 모드가 없어 그룹의 모든 메시지를 받습니다.
- 대기열: 가져가지 않은 업데이트는 봇마다 최근 1,000개까지 메모리에 두며, 서버 재시작 때 사라집니다(텔레그램은 24시간 보관).
- 웹훅: 한 번에 하나씩 순서대로 보내고(
max_connections는 보관만), 자체 서명 인증서를 받지 않으며, 포트 제한이 없습니다. - ID: 사용자·메시지·파일 ID 는 이 서버 안에서만 뜻이 있습니다. 채널·슈퍼그룹이 없어
-100…꼴의 ID 도 없습니다. - 없는 메서드: 위 목록에 없는 것(
forwardMessage,copyMessage,sendDocument,sendPoll,getChatMember,banChatMember,answerInlineQuery…)은404 Not Found: method not found.