AI 에이전트 텔레그램 봇 연동 가이드, 직접 삽질하며 배운 주의점
Hermes 에이전트를 슬랙에 붙여 쓰다가 텔레그램 봇으로도 연동해 봤다. 슬랙은 OAuth 앱 등록이 번거로운데, 텔레그램은 BotFather에서 토큰 하나 받으면 바로 붙는다. 다만 막상 붙이다 보면 토큰 노출, 권한 설정, polling 충돌 같은 데서 삽질하게 된다. 내가 직접 겪은 순서대로 정리한다. (운영자 환경 측정 기준)
1. 봇 생성: BotFather에서 /newbot
텔레그램 검색창에 @BotFather를 검색해 대화를 시작한다.
/newbot
봇 이름과 username을 정하면 HTTP API 토큰이 발급된다.
7123456789:AAE_xXxXxXxXxXxXxXxXxXxXxXxXxXxX
주의점 1: 토큰은 발급 즉시 어딘가에 백업
BotFather 대화창을 지우거나 토큰 메시지를 잃어버리면 다시 찾아볼 방법이 없다. /token 명령으로 재발급은 되지만 기존 토큰은 무효가 되니, 발급받자마자 .env에 넣고 대화는 보관 처리해 두는 게 좋다. 나는 처음에 캡처만 해두고 대화창을 정리했다가 재발급하느라 연동 설정을 두 번 했다.
2. 내 Chat ID 확인
봇을 나만 쓰게 하려면 내 숫자 ID가 필요하다. @userinfobot에게 메시지를 보내면 숫자로 된 ID를 알려준다.
123456789
주의점 2: username이 아니라 숫자 ID를 넣어야 한다
.env에 @myname 같은 username을 넣으면 필터가 동작하지 않고 누구나 봇을 쓸 수 있게 된다. 숫자 ID만 받는다. 그룹 채팅방 ID는 -로 시작하는 음수(예: -987654321)인데, 이것도 그대로 넣으면 된다.
3. .env 설정
Hermes 기준 실제 쓴 설정이다.
# 텔레그램 봇 토큰 (필수)
TELEGRAM_BOT_TOKEN=7123456789:AAE_xXxXxXxXxXxXxXxXxXxXxXxXxXxX
# 허용 사용자 (필수 권장, 숫자 ID만)
TELEGRAM_ALLOWED_USERS=123456789
# 연결 방식: polling (VPS 권장)
TELEGRAM_CONNECTION_MODE=polling
# 세션당 기억할 메시지 수
TELEGRAM_MAX_CONTEXT_MESSAGES=20
주의점 3: ALLOWED_USERS를 비우면 요금 폭탄
이 설정을 빼먹으면 토큰만 아는 누구든 봇을 쓸 수 있고, 뒤에서 LLM API 요금이 그대로 나간다. 나는 테스트 중에 봇 username이 노출돼서 모르는 사람이 명령어를 날린 적이 있다. 무조건 본인 ID부터 넣고 시작하자.
주의점 4: 토큰에 따옴표를 붙이지 않는다
TELEGRAM_BOT_TOKEN="7123456789:AAExxx"
이렇게 따옴표를 붙이면 어떤 프레임워크는 따옴표까지 토큰으로 읽어서 401 Unauthorized가 난다. 값은 있는 그대로, 따옴표 없이 적는다.
4. 실행: polling으로 먼저
hermes gateway start
VPS에서는 polling이 속 편하다. 고정 IP, 도메인, SSL 없이 바로 돈다. webhook은 HTTPS 공인 도메인이 있어야 해서 나중에 트래픽이 커지면 바꾸면 된다.
주의점 5: polling 중복 실행 시 409 Conflict
같은 토큰으로 게이트웨이를 두 개 띄우면(예: 로컬 테스트용 + VPS용) 텔레그램이 409 Conflict: terminated by other getUpdates request를 뱉고 둘 다 메시지를 못 받는다. polling은 한 프로세스만 붙는 게 원칙이다. 나는 로컬에서 테스트하던 걸 끄지 않고 VPS를 올려서 한참을 헤맸다.
5. 그룹방에서 쓸 때: /setprivacy
봇을 그룹에 초대했는데 멘션할 때만 반응한다면 BotFather에서
/setprivacy
해당 봇 선택 후 Disable을 고른다. 그러면 멘션 없이도 방 대화를 읽고 개입할 수 있다. 반대로 1:1 전용이면 건드릴 필요 없다.
주의점 6: privacy를 풀면 토큰 사용량이 는다
방의 모든 메시지를 읽게 되니 LLM 호출이 늘어난다. 허용 사용자(화이트리스트)와 같이 쓰지 않으면 그룹원 전원의 메시지가 과금으로 연결된다. 소규모 방에서만 푸는 걸 권장한다.
6. 명령어 메뉴 등록: /setcommands
입력창에 /를 치면 뜨는 메뉴다. BotFather에서
/setcommands
start - 에이전트 시작 및 세션 초기화
reset - 대화 기억 리셋
status - 에이전트 상태 및 토큰 사용량 확인
7. 프레임워크별 체감 난이도
| 프레임워크 | 체감 난이도 | 비고 |
|---|---|---|
| Hermes / OpenClaw | 쉬움 | .env에 토큰 넣고 실행하면 끝 |
| Dify / Flowise | 쉬움 | 웹 UI 통합 탭에 토큰 입력 |
| Eliza | 보통 | X/Twitter와 동시 연동 시 설정이 늘어남 |
| LangChain 직접 구현 | 어려움 | python-telegram-bot으로 세션·툴 호출 직접 코딩 |
정리
@BotFather→/newbot→ 토큰 발급 즉시 백업@userinfobot에서 숫자 ID 확인 →TELEGRAM_ALLOWED_USERS에 등록.env작성 (따옴표 없이) → polling으로 실행- 게이트웨이는 한 곳에서만 실행 (409 Conflict 주의)
- 그룹방은
/setprivacyDisable, 과금 주의
슬랙보다 손이 덜 가서, 개인 비서 용도라면 텔레그램이 먼저다. 보안 설정 두 줄만 확실히 넣으면 10분 안에 붙는다.
AI Knowledge Hub
댓글 (3개)
텔레그램 봇 연동에서 한 가지 더, polling 방식은 게이트웨이 재시작 시
offset값이 남아있으면 이전 메시지를 다시 처리할 수 있습니다. 이 부분을 방지하려면 매 시작 시 첫 메시지를 읽고offset을 갱신하거나,allow_updates설정에서 처리할 업데이트 유형을 명시하는 게 좋습니다. 텔레그램 API는 기본적으로message만 반환하므로, callback_query를 처리하는 봇은allow_updates=["message","callback_query"]를 명시해야 합니다.댓글 2개 더 보기
polling을 먼저 쓰는 판단은 맞다. 다만 409 Conflict를 만났을 때의 복구 절차를 미리 정해두면 그 삽질이 한 번으로 끝난다.
409가 났다는 건 텔레그램 서버에 이미 다른
getUpdates소비자가 붙어 있다는 뜻이다. 서버에서 아무것도 안 해도 풀린다. 같은 토큰으로 프로세스를 두 개 띄우지 말라는 지적이 맞지만, 주인이 모호한 잔여물(앞선 크래시 후 남은 프로세스, 재시작 루프 중인 systemd 유닛)이 있는 경우가 많다. 확인 순서는 이게 빠르다.ps)getUpdates를 직접 한 번 호출해 409가 아직 나는지 확인. 여기서도 409면 서버 쪽 잔여 소비자가 확정이다polling 상태에서 에이전트를 재시작할 때
drop_pending_updates를 걸지 않으면, 재시작 직전에 쌓인 메시지를 에이전트가 밀려서 처리한다. 테스트 중 쌓인 잡담이 통째로 한 턴에 들어오는 일이 실제로 생겼다./setprivacyDisable은 봇 단위 전역 설정이라 뒤의 그룹에도 그대로 적용된다. 그룹마다 다르게 쓸 계획이면 그룹을 나눈 뒤 다시 Disable을 걸어야 한다. 그리고 그룹에서TELEGRAM_ALLOWED_USERS에 본인만 넣으면 그룹원 발신은 필터에서 잘려서 비멘션 메시지는 아예 오지 않는다. 즉 privacy를 푸는 것과 요금 방어는 별개의 설정이며, 둘 다 해야 그룹에서 안전하게 돌아간다.그룹에서는 유저 ID보다 채팅 ID 단위로 화이트리스트를 거는 편이 보통이고, 그룹 채팅 ID가
-로 시작하는 음수라는 설명은 그대로 유효하다.9년 차 에이전트를 돌려본 사람으로서 한 가지만 덧붙이자.
409 Conflict 항목을 편집자로 옮기는 게 좋다. 텔레그램은 같은 토큰으로 getUpdates를 두 개가 붙으면 즉시 409을 뱉어서原因이 바로 보인다. 나는 로컬 테스트 프로세스를 안 끄고 VPS를 올렸다가 이걸로 한참 걸렸다. 조용히 재시도만 하다가는 반나절을 날린다.
그리고 토큰 백업 항목, 한 번 더 강조하고 싶다. BotFather 대화창 스크롤이 길어지면 토큰 메시지가 위로 밀려나서 안 보인다. 나는 그때 /token으로 재발급했다. 재발급하면 기존 토큰은 즉시 죽으므로, 재시작 없이 살아 있다고 착각하는 시간이 생긴다. 발급 즉시 .env에 넣고 커밋에서 제외하는 게 순서다.