콘텐츠로 이동

Telegram (Bot API) 설정 가이드

봇을 연동할 때 토큰 설정이나 권한 문제로 시간을 허비하면 정말 답답하죠. 특히 그룹 메시지가 읽히지 않거나 페어링 과정에서 막히는 상황은 개발자를 지치게 만듭니다. 복잡한 절차 없이 Telegram 봇을 바로 실무에 투입할 수 있도록 핵심 설정 위주로 정리했습니다.

  • Telegram 계정 및 @BotFather를 통한 봇 생성
  • openclaw CLI
  • 유효한 Bot API 토큰

5분 안에 봇을 활성화하는 최소 경로입니다.

Telegram에서 @BotFather를 검색하세요 (핸들이 정확히 @BotFather인지 확인해야 합니다).

/newbot 명령어를 실행하고 안내에 따라 봇을 만든 뒤, 발급된 토큰을 안전하게 복사해 두세요.

설정 파일에 다음 내용을 추가하세요. dmPolicy는 기본적으로 pairing을 사용합니다.

{
channels: {
telegram: {
enabled: true,
botToken: "123:abc",
dmPolicy: "pairing",
groups: { "*": { requireMention: true } },
},
},
}

환경 변수를 사용하려면 TELEGRAM_BOT_TOKEN=... 형식을 사용하세요 (기본 계정에만 적용됩니다).

터미널에서 Gateway를 실행하고 페어링 코드를 승인하세요.

Terminal window
openclaw gateway
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>

참고로 페어링 코드는 1시간 후에 만료되니 주의하세요.

봇을 원하는 그룹에 추가한 뒤, 액세스 모델에 맞춰 channels.telegram.groups와 groupPolicy를 설정하세요.

설정 중 발생할 수 있는 일반적인 문제와 해결 방법입니다.

Privacy mode 및 그룹 메시지 가시성

섹션 제목: “Privacy mode 및 그룹 메시지 가시성”

Telegram 봇은 기본적으로 Privacy Mode가 활성화되어 있어 그룹 메시지 수신이 제한됩니다. 봇이 모든 메시지를 수신해야 한다면 다음 방법 중 하나를 선택하세요.

  • /setprivacy 명령어로 Privacy Mode를 비활성화합니다.
  • 봇을 그룹 관리자(Admin)로 지정합니다.

주의: Privacy Mode 설정을 변경했다면, 변경 사항이 적용되도록 각 그룹에서 봇을 삭제했다가 다시 추가해야 합니다.

관리자 상태는 Telegram 그룹 설정에서 직접 관리합니다. 관리자 권한을 가진 봇은 모든 그룹 메시지를 수신할 수 있어, 상시 작동해야 하는 그룹 봇을 운영할 때 유용합니다.

  • /setjoingroups: 봇의 그룹 추가 허용 여부를 설정합니다.
  • /setprivacy: 그룹 내 메시지 가시성 동작을 제어합니다.

AI Setup Assistant

텔레그램 봇을 배포하고 나면 예상치 못한 메시지가 쏟아지거나, 모르는 그룹에 봇이 초대되어 당황스러운 상황이 생기곤 해요. 내 봇이 아무하고나 대화하게 둘 순 없겠죠? 봇의 보안을 지키면서 원하는 사용자만 소통할 수 있도록 정교하게 제어하는 방법을 정리해 드릴게요.

시작하기 전에 다음 사항들이 준비되었는지 확인해 주세요.

  • Telegram bot token
  • openclaw CLI 설치 및 실행 환경
  • 설정 파일에 접근 가능한 권한

봇의 접근 권한을 설정하는 가장 빠른 방법은 channels.telegram.dmPolicy를 수정하는 거예요.

channels.telegram.dmPolicy는 1대1 메시지 접근을 제어해요. 다음 4가지 옵션 중 하나를 선택할 수 있어요.

  • pairing: 기본값으로 설정되어 있어요.
  • allowlist: 허용된 사용자만 대화할 수 있어요.
  • open: 누구나 대화할 수 있어요 (allowFrom에 "*" 포함 필요).
  • disabled: DM 기능을 완전히 꺼요.

사용자를 특정하려면 channels.telegram.allowFrom에 숫자 ID나 username을 넣으면 돼요. telegram:이나 tg: 접두사를 붙여도 시스템이 알아서 처리해 주니 편해요.

설정에 사용할 내 ID를 찾는 방법은 4가지가 있어요. 가장 안전한 방법부터 시도해 보세요.

  • 가장 안전한 방법: 봇에게 DM을 보낸 뒤, 터미널에서 openclaw logs --follow를 실행하세요. 로그에 찍히는 from.id를 읽으면 돼요.
  • 공식 API 활용: curl "https://api.telegram.org/bot<bot_token>/getUpdates" 명령어를 사용하세요.
  • 외부 봇 활용: @userinfobot이나 @getidsbot을 사용하면 ID를 바로 알려줘요.
  • 그룹 메시지 활용: 그룹 메시지를 위 외부 봇들에게 전달해도 ID를 확인할 수 있어요.

그룹 설정은 두 가지 독립적인 컨트롤로 나뉘어 있어 아주 유연해요.

  • 그룹 허용 여부 (channels.telegram.groups):
    • 설정이 없으면 모든 그룹을 허용해요.
    • 특정 ID나 "*"를 설정하면 해당 리스트가 허용 목록(allowlist)으로 작동해요.
  • 그룹 내 발신자 제한 (channels.telegram.groupPolicy):
    • open, allowlist (기본값), disabled 중 선택하세요.

그룹 전용 발신자 필터링에는 groupAllowFrom을 사용해요. 이 값이 없으면 allowFrom 설정을 대신 사용하게 돼요.

특정 그룹의 모든 멤버를 허용하고 싶다면 아래 예시처럼 설정해 보세요.

{
channels: {
telegram: {
groups: {
"-1001234567890": {
groupPolicy: "open",
requireMention: false,
},
},
},
},
}

기본적으로 그룹 내에서는 봇을 멘션해야 답장을 받을 수 있어요. 멘션으로 인식되는 경우는 다음과 같아요.

  • 기본적인 @botusername 호출
  • agents.list[].groupChat.mentionPatterns에 정의된 패턴
  • messages.groupChat.mentionPatterns에 정의된 패턴

대화 중에 /activation always나 /activation mention 명령어로 활성화 상태를 바꿀 수 있지만, 이건 세션 동안만 유지돼요. 설정을 영구적으로 적용하려면 config 파일을 수정해야 해요.

{
channels: {
telegram: {
groups: {
"*": { requireMention: false },
},
},
},
}

설정 과정에서 문제가 생기면 다음 내용을 확인해 보세요.

  • 그룹 ID를 모르겠어요: 봇에게 그룹 메시지를 보내고 openclaw logs --follow에서 chat.id를 확인하거나, Bot API의 getUpdates를 조회해 보세요. 외부 봇인 @userinfobot에 그룹 메시지를 전달하는 방법도 있어요.
  • 명령어가 저장이 안 돼요: /activation 명령어는 현재 세션의 상태만 바꿔요. 봇을 재시작해도 유지되게 하려면 반드시 위에서 설명한 JSON5 설정 파일에 requireMention 옵션을 추가해야 해요.

설정하다가 막히는 부분이 있다면 AI Setup Assistant에게 물어보시면 바로 도움을 드릴 거예요.

---
title: "Telegram Runtime Behavior 이해하기"
description: "Gateway 프로세스에서 Telegram 통합이 실제로 어떻게 작동하는지, 라우팅과 세션 격리 방식을 알아봅니다."
---
텔레그램 봇을 개발하다 보면 메시지가 엉뚱한 곳으로 전달되거나 세션이 꼬여서 당황스러운 적이 있으셨을 거예요. 특히 그룹 채팅이나 포럼의 복잡한 스레드 구조를 다룰 때는 더욱 그렇죠.
이 글에서는 Telegram 통합 환경에서 런타임이 어떻게 동작하는지, 그리고 메시지 라우팅과 세션 관리가 어떤 원칙으로 이루어지는지 명확하게 설명해 드릴게요.
## 필요한 것
시작하기 전에 소스 문서에서 언급된 다음 구성 요소들을 확인해 주세요.
* Gateway 프로세스
* Telegram Bot API
* grammY runner
* `agents.defaults.maxConcurrent` 설정
## 빠른 시작
Telegram 통합의 핵심 동작을 5분 안에 파악할 수 있는 4단계 가이드입니다.
1. **프로세스 소유권 확인**: Telegram은 기본적으로 Gateway 프로세스에 의해 소유되고 관리됩니다.
2. **결정론적 라우팅**: 별도의 채널 선택 과정 없이, Telegram으로 들어온 메시지는 다시 Telegram으로 응답이 나가는 결정론적(deterministic) 구조를 따릅니다.
3. **데이터 정규화**: 인바운드 메시지는 reply metadata와 media placeholders를 포함한 공통 채널 envelope로 자동 변환됩니다.
4. **동시성 설정**: `agents.defaults.maxConcurrent`를 사용하여 전체 runner sink의 동시 실행 수를 조절하세요.
## Runtime behavior 상세
Telegram의 런타임 동작은 예측 가능성과 격리를 최우선으로 설계되었습니다.
### 라우팅 및 메시지 처리
Telegram 인바운드 메시지는 시스템 내에서 정규화된 과정을 거칩니다. 모델이 직접 채널을 선택하는 것이 아니라, 들어온 통로를 따라 그대로 응답이 돌아가는 구조예요. 이 과정에서 메시지는 reply metadata와 미디어 위치를 나타내는 placeholders를 포함한 표준화된 형태로 처리됩니다.
### 세션 및 스레드 격리
다양한 대화 환경을 지원하기 위해 다음과 같은 격리 전략을 사용합니다.
* **그룹 세션**: 각 그룹은 Group ID를 기준으로 엄격하게 격리됩니다.
* **포럼 토픽**: 포럼 내의 토픽은 `:topic:<threadId>`를 식별자에 추가하여 각 토픽이 서로 간섭하지 않도록 관리합니다.
* **DM 및 스레드**: DM 메시지에 `message_thread_id`가 포함된 경우, OpenClaw는 thread-aware session keys를 사용하여 라우팅하며 응답 시에도 thread ID를 그대로 유지합니다.
### 폴링 및 성능 제어
Long polling 방식은 grammY runner를 사용하여 처리됩니다. 채팅 및 스레드별로 시퀀싱(sequencing)이 이루어지며, 전체적인 시스템 부하를 관리하기 위해 `agents.defaults.maxConcurrent` 설정을 따릅니다.
## 문제 해결
개발 중에 겪을 수 있는 일반적인 상황과 소스 문서에 기반한 해결책입니다.
* **읽음 확인(Read-receipt) 기능이 작동하지 않나요?**
* Telegram Bot API 자체에서 읽음 확인 기능을 지원하지 않습니다. 따라서 `sendReadReceipts` 옵션은 적용되지 않으니 참고해 주세요.
---
궁금한 점이 더 있거나 설정 중에 막히는 부분이 있다면 [AI Setup Assistant](/docs/)에게 언제든 물어보세요!
## 다음 단계
* [Gateway 설정 가이드](/docs/gateway/configuration-reference)
* [세션 관리 심화](/docs/session-management)

텔레그램 봇을 개발하다 보면 사용자에게 실시간으로 응답이 생성되고 있다는 느낌을 주는 게 얼마나 중요한지 깨닫게 돼요. 답변이 올 때까지 멍하니 빈 화면만 보고 있으면 사용자는 봇이 고장 났다고 생각하기 쉽거든요.

이런 문제를 해결하고 더 똑똑한 봇을 만들기 위해 OpenClaw가 제공하는 다양한 Telegram 전용 기능들을 하나씩 살펴볼게요. 복잡한 설정 없이도 봇의 완성도를 높일 수 있는 팁들이 가득해요.

시작하기 전에 소스 문서에서 언급된 몇 가지 요구 사항을 확인해 주세요.

  • 봇 설정에서 getMe().has_topics_enabled가 활성화되어야 함 (Topic 사용 시)
  • Telegram Private Chat (Draft Streaming 기능 사용 시)
  • 아웃바운드 DNS/HTTPS가 api.telegram.org에 접속 가능한 환경

5분 만에 핵심 기능을 설정하고 시작하는 방법이에요.

  1. 커맨드 메뉴 등록: commands.native: "auto" 설정을 확인하세요. OpenClaw가 시작될 때 자동으로 Telegram 메뉴에 커맨드를 등록해요.
  2. 스트리밍 활성화: channels.telegram.streamMode를 "partial"(기본값)로 두면 사용자가 입력 중인 상태를 실시간으로 볼 수 있어요.
  3. 커스텀 커맨드 추가: 아래 JSON 설정을 config 파일에 추가해서 나만의 메뉴를 만들어 보세요.
{
channels: {
telegram: {
customCommands: [
{ command: "backup", description: "Git backup" },
{ command: "generate", description: "Create an image" },
],
},
},
}

OpenClaw가 지원하는 Telegram의 강력한 기능들을 상세히 설명해 드릴게요.

OpenClaw는 Telegram의 초안 버블(sendMessageDraft)을 사용해 답변의 일부를 실시간으로 스트리밍할 수 있어요.

요구 사항:

  • channels.telegram.streamMode가 "off"가 아님 (기본값: "partial")
  • 1:1 개인 채팅(Private chat)
  • 인바운드 업데이트에 message_thread_id 포함
  • 봇 토픽이 활성화됨

모드 종류:

  • off: 스트리밍 미사용
  • partial: 텍스트 일부를 자주 업데이트
  • block: channels.telegram.draftChunk 설정을 사용해 덩어리 단위로 업데이트

block 모드에서의 기본값은 minChars: 200, maxChars: 800, breakPreference: "paragraph"예요. 만약 초안 업데이트 대신 실제 메시지를 일찍 보내고 싶다면 channels.telegram.blockStreaming: true를 사용하면 돼요.

OpenClaw는 아웃바운드 텍스트에 parse_mode: "HTML"을 사용해요.

  • Markdown 스타일의 텍스트를 Telegram에 안전한 HTML로 렌더링해요.
  • 모델이 생성한 원시 HTML은 이스케이프 처리해서 파싱 오류를 방지해요.
  • 만약 HTML 파싱이 실패하면, 자동으로 일반 텍스트(Plain text)로 재시도해요.

링크 미리보기는 기본적으로 켜져 있지만, channels.telegram.linkPreview: false로 끌 수 있어요.

OpenClaw는 시작 시 setMyCommands를 통해 메뉴를 등록해요.

  • 커맨드 이름은 자동으로 소문자로 변환되고 앞에 붙은 /는 제거돼요.
  • a-z, 0-9, _ 문자를 사용할 수 있고 길이는 1~32자여야 해요.
  • 커스텀 커맨드는 메뉴에만 나타날 뿐, 동작을 자동으로 구현해 주지는 않아요. 별도의 플러그인이나 스킬 설정이 필요해요.

인라인 키보드 버튼을 사용할 범위를 설정할 수 있어요.

{
channels: {
telegram: {
capabilities: {
inlineButtons: "allowlist", // off, dm, group, all, allowlist 중 선택
},
},
},
}

에이전트가 버튼이 포함된 메시지를 보내는 예시예요. 사용자가 버튼을 클릭하면 callback_data: <값> 형태의 텍스트가 에이전트에게 전달돼요.

{
action: "send",
channel: "telegram",
to: "123456789",
message: "Choose an option:",
buttons: [
[
{ text: "Yes", callback_data: "yes" },
{ text: "No", callback_data: "no" },
],
[{ text: "Cancel", callback_data: "cancel" }],
],
}

메시지 액션 (에이전트 및 자동화용)

섹션 제목: “메시지 액션 (에이전트 및 자동화용)”

에이전트는 다음과 같은 도구들을 사용할 수 있어요.

  • sendMessage: 텍스트, 미디어, 답장, 스레드 지정 가능
  • react: 이모지 반응 남기기
  • deleteMessage: 메시지 삭제
  • editMessage: 보낸 메시지 수정

각 액션은 channels.telegram.actions 설정을 통해 개별적으로 허용하거나 제한할 수 있어요.

Telegram 포럼(Supergroup) 기능을 완벽하게 지원해요.

  • 토픽 세션 키는 :topic:<threadId> 형식을 사용해요.
  • 일반 토픽(threadId=1)의 경우 메시지를 보낼 때 message_thread_id를 생략해서 오류를 방지해요.
  • 토픽 설정은 그룹 설정을 상속받지만, requireMention이나 systemPrompt 등을 개별적으로 덮어쓸 수 있어요.
  • 오디오: 기본은 파일 형태지만, 답변에 [[audio_as_voice]] 태그를 넣으면 음성 메시지(Voice note)로 전송돼요.
  • 비디오: 일반 비디오 파일과 비디오 노트(둥근 화면)를 구분해요. 비디오 노트는 캡션을 지원하지 않아서 텍스트가 별도로 전송돼요.
  • 스티커: 정지된 WEBP 스티커는 다운로드해서 처리하지만, 애니메이션(TGS)이나 비디오(WEBM) 스티커는 건너뛰어요. 스티커 정보는 ~/.openclaw/telegram/sticker-cache.json에 캐싱되어 재사용돼요.

기본적으로는 Long polling을 사용하지만, Webhook으로 전환할 수 있어요.

{
channels: {
telegram: {
webhookUrl: "https://your-public-domain.com/telegram-webhook",
webhookSecret: "your-secret-key",
},
},
}

로컬 리스너는 기본적으로 0.0.0.0:8787에서 대기해요. 공용 엔드포인트가 다르다면 리버스 프록시를 앞에 두고 webhookUrl을 설정해 주세요.

문제가 발생했을 때 확인해 볼 내용이에요.

  • setMyCommands failed 오류: 주로 봇 서버에서 api.telegram.org로의 아웃바운드 DNS 요청이나 HTTPS 접속이 차단되었을 때 발생해요. 네트워크 환경을 확인해 보세요.
  • 스티커 처리 안 됨: 애니메이션 TGS나 비디오 WEBM 형식은 현재 지원하지 않으니 참고해 주세요.
  • 반응(Reaction) 알림 문제: Telegram은 반응 업데이트 시 스레드 ID를 제공하지 않아요. 포럼 그룹의 경우 특정 토픽이 아닌 일반(General) 토픽 세션으로 라우팅될 수 있어요.

더 궁금한 점이 있거나 설정 중에 막히는 부분이 있다면 AI Setup Assistant에게 바로 물어보세요!

What’s Next:

봇을 다 만들고 설레는 마음으로 테스트를 시작했는데, 아무런 반응이 없으면 정말 답답하죠. 설정 파일은 완벽해 보이는데 왜 메시지를 무시하는지, 왜 특정 그룹에서만 대답이 없는지 고민하며 시간을 허비하게 됩니다.

이 가이드는 Telegram 봇을 운영하며 마주칠 수 있는 일반적인 문제들을 정리했습니다. 설정을 하나씩 점검하며 문제를 해결해 보세요.

  • openclaw CLI 도구
  • Telegram 봇 관리 권한 (BotFather 접근)
  • Node.js v22 이상 (특정 네트워크 이슈 확인 시 필요)
  • api.telegram.org에 접근 가능한 네트워크 환경

문제를 빠르게 진단하려면 다음 3단계를 먼저 확인하세요.

  1. 로그 확인: openclaw logs --follow 명령어로 봇이 메시지를 건너뛰는 이유를 실시간으로 확인하세요.
  2. 개인정보 설정: BotFather에서 /setprivacy를 Disable로 설정하여 봇이 모든 메시지를 볼 수 있게 하세요.
  3. 세션 테스트: 대화창에서 /activation always를 입력하여 즉시 활성화 상태를 테스트하세요.

봇이 맨션(@) 없는 그룹 메시지에 응답하지 않아요

섹션 제목: “봇이 맨션(@) 없는 그룹 메시지에 응답하지 않아요”
  • requireMention=false로 설정했다면, Telegram의 privacy mode가 모든 메시지를 볼 수 있도록 허용해야 합니다.
    • BotFather 접속: /setprivacy -> Disable 선택
    • 설정 변경 후, 그룹에서 봇을 제거했다가 다시 추가하세요.
  • openclaw channels status 명령어를 실행하면, 설정상 맨션 없는 메시지를 받아야 하는데 권한이 부족한 경우 경고를 표시해 줍니다.
  • openclaw channels status --probe를 사용하면 특정 숫자 ID 형식의 그룹 권한을 명시적으로 체크할 수 있습니다. (와일드카드 "*" 설정은 멤버십 조사가 불가능합니다.)
  • 빠른 세션 테스트를 위해 /activation always 명령어를 사용해 보세요.

봇이 그룹 메시지를 전혀 읽지 못해요

섹션 제목: “봇이 그룹 메시지를 전혀 읽지 못해요”
  • channels.telegram.groups 설정이 존재한다면, 해당 그룹이 목록에 명시되어 있거나 "*"가 포함되어야 합니다.
  • 봇이 해당 그룹의 멤버로 정상적으로 추가되어 있는지 확인하세요.
  • 로그를 확인하세요: openclaw logs --follow 명령어를 통해 메시지를 스킵하는 구체적인 이유를 볼 수 있습니다.

명령어가 부분적으로 작동하거나 아예 작동하지 않아요

섹션 제목: “명령어가 부분적으로 작동하거나 아예 작동하지 않아요”
  • 보낸 사람의 ID가 인증되었는지 확인하세요 (Pairing 또는 allowFrom 설정).
  • 그룹 정책이 open으로 설정되어 있더라도 명령어 권한 부여는 별도로 적용됩니다.
  • setMyCommands failed 에러가 발생한다면 보통 api.telegram.org에 대한 DNS 또는 HTTPS 연결 문제입니다.

폴링(Polling) 또는 네트워크 불안정 문제

섹션 제목: “폴링(Polling) 또는 네트워크 불안정 문제”
  • Node 22 버전 이상에서 커스텀 fetch나 proxy를 사용할 때, AbortSignal 타입이 일치하지 않으면 즉각적인 중단(abort) 동작이 발생할 수 있습니다.
  • 일부 호스트는 api.telegram.org를 IPv6로 먼저 해석합니다. IPv6 출구(egress)가 제대로 작동하지 않으면 Telegram API 연결이 간헐적으로 실패할 수 있습니다.
  • 다음 명령어로 DNS 응답을 확인해 보세요:
Terminal window
dig +short api.telegram.org A
dig +short api.telegram.org AAAA

도움이 더 필요하다면 Channel troubleshooting 문서를 참고하세요.

주요 참고 문서:

설정 시 주의 깊게 살펴봐야 할 필드들입니다:

  • 시작 및 인증: enabled, botToken, tokenFile, accounts.*
  • 액세스 제어: dmPolicy, allowFrom, groupPolicy, groupAllowFrom, groups, groups.*.topics.*
  • 명령어 및 메뉴: commands.native, customCommands
  • 스레드 및 답장: replyToMode
  • 스트리밍: streamMode, draftChunk, blockStreaming
  • 포맷 및 전송: textChunkLimit, chunkMode, linkPreview, responsePrefix
  • 미디어 및 네트워크: mediaMaxMb, timeoutSeconds, retry, network.autoSelectFamily, proxy
  • Webhook: webhookUrl, webhookSecret, webhookPath
  • 기능 및 권한: capabilities.inlineButtons, actions.sendMessage|editMessage|deleteMessage|reactions|sticker
  • 리액션: reactionNotifications, reactionLevel
  • 기록 저장: configWrites, historyLimit, dmHistoryLimit, dms.*.historyLimit

설정 과정에서 막히는 부분이 있다면 AI Setup Assistant에게 질문해 보세요!

OpenClaw

OpenClaw Expert

아직 막혀 있나요?

이 문서에서 답을 못 찾았다면 OpenClaw Expert에게 바로 물어보세요.