결론부터
- 1받는 길은 둘 — 내가 묻는 롱 폴링, 텔레그램이 오는 웹훅. 한 번에 하나만.
- 2폴링은 offset 을 올려야 같은 업데이트가 다시 안 온다.
- 3웹훅은 HTTPS·지정 포트·비밀 토큰 — 바꿀 땐 deleteWebhook 먼저.
업데이트란
사용자가 봇에게 메시지를 보내거나 버튼을 누르면, 텔레그램 서버에 그 일이 업데이트(update) 한 건으로 쌓입니다. 봇 프로그램은 이 업데이트를 받아야 답할 수 있습니다. 받는 방법은 두 가지이고, 한 번에 하나만 쓸 수 있습니다.
| 방법 | 움직임 · 필요한 것 | 맞는 경우 |
|---|---|---|
| 롱 폴링(getUpdates) | 내 프로그램이 텔레그램에 묻는다 · 인터넷만 되면 내 PC 도 가능 | 처음 만들 때, 공개 서버가 없을 때 |
| 웹훅(setWebhook) | 텔레그램이 내 서버로 보내 준다 · 밖에서 열리는 HTTPS 주소 | 서버가 있고, 봇이 늘 켜져 있어야 할 때 |
받아 가지 않은 업데이트는 서버에 쌓여 있다가 24시간이 지나면 사라집니다. 봇이 하루 넘게 꺼져 있으면 그사이 메시지는 받을 수 없습니다.
롱 폴링 — getUpdates
내 프로그램이 getUpdates 를 부르고, 새 업데이트가 올 때까지 연결을 열어 둔 채 기다립니다. timeout 에 기다릴 초를 주는 것이 '롱' 폴링입니다. timeout 을 0 으로 두면 곧바로 빈손으로 돌아오기를 되풀이하게 되는데, 공식 문서는 이 방식을 시험용으로만 권합니다.
curl "https://api.telegram.org/bot123456:ABC-EXAMPLE/getUpdates?timeout=30&offset=101"
- 업데이트마다
update_id번호가 붙어 있습니다. - 처리한 마지막 번호보다 1 큰 수를 offset 으로 주면, 그보다 앞의 업데이트는 '받았다'로 확인되어 다시 오지 않습니다.
- offset 을 올리지 않으면 같은 업데이트가 계속 다시 옵니다 — 같은 메시지에 두 번 답하는 흔한 원인입니다.
웹훅 — setWebhook
내 서버 주소를 텔레그램에 한 번 알려 두면, 업데이트가 생길 때마다 텔레그램이 그 주소로 HTTPS 요청을 보냅니다.
curl https://api.telegram.org/bot123456:ABC-EXAMPLE/setWebhook \
-d url=https://example.com/tg-hook \
-d secret_token=임의의-긴-문자열
| 조건 | 내용 |
|---|---|
| 주소 | HTTPS 만. 포트는 443 · 80 · 88 · 8443 중 하나 |
| 인증서 | 정식 인증서가 기본, 직접 만든(자체 서명) 인증서도 올려서 쓸 수 있다 |
| 진짜 텔레그램인지 확인 | secret_token 을 주면 요청 머리에 X-Telegram-Bot-Api-Secret-Token 으로 함께 온다 — 값이 다르면 버린다 |
| 실패했을 때 | 내 서버가 성공 응답을 주지 않으면 텔레그램이 다시 보낸다 — 처리 뒤 빨리 200 을 돌려준다 |
| 동시 연결 | max_connections 로 정한다(기본 40, 1~100) |
지금 상태는 getWebhookInfo 로 봅니다. 등록된 주소, 쌓여 있는 업데이트 수, 마지막 오류가 나옵니다.
둘 사이를 오갈 때
- 웹훅이 걸려 있으면 getUpdates 는 동작하지 않습니다. 폴링으로 돌아가려면 먼저
deleteWebhook을 부릅니다. - 바꾸는 동안 쌓인 옛 업데이트를 버리고 싶으면
drop_pending_updates를 true 로 줍니다. 남겨 두면 새 방식으로 그대로 받아 옵니다. - 필요한 종류만 받고 싶으면
allowed_updates로 고릅니다. 비워 두면 기본 종류가 오는데, 그룹 참가자 변화·반응 같은 일부 종류는 직접 적어야 옵니다.
고르는 기준
| 상황 | 권하는 쪽 |
|---|---|
| 처음 만들어 보는 중, 내 PC 에서 시험 | 롱 폴링 |
| 공개 HTTPS 서버가 없다(공유 호스팅 등) | 롱 폴링 — 예약 작업으로 주기적으로 부르기 |
| 답이 바로 나가야 하고 서버가 늘 켜져 있다 | 웹훅 |
| 요청이 많아 여러 서버로 나눠야 한다 | 웹훅 + max_connections |
요청 주소의 기본 모양과 응답 읽기는 봇 API 첫 요청에 있습니다.
자주 묻는 질문
롱 폴링과 웹훅을 같이 쓸 수 있나요?
없습니다. 웹훅이 걸려 있는 동안 getUpdates 는 동작하지 않습니다. 폴링으로 돌아가려면 deleteWebhook 을 먼저 부릅니다.
같은 메시지가 계속 다시 와요.
getUpdates 의 offset 을 처리한 마지막 update_id 보다 1 크게 주지 않아서입니다. offset 을 올리면 앞의 업데이트는 확인되어 다시 오지 않습니다.
봇이 꺼져 있던 동안의 메시지는 어떻게 되나요?
받지 않은 업데이트는 서버에 쌓여 있다가 24시간이 지나면 사라집니다.
웹훅은 어떤 포트를 쓸 수 있나요?
HTTPS 로 443, 80, 88, 8443 포트 중 하나를 씁니다.
참고한 공식 문서
한눈에 정리
- 1롱 폴링
getUpdates · offset 올리기.
- 2웹훅
HTTPS · secret_token.
- 3하나만
바꿀 땐 deleteWebhook.
최종 수정 2026-10-06