OpenClaw를 텔레그램에 연결하기
— 폰에서 부르는 내 비서, 따라하기 편
지난 편에서 본인 ATOM에는 OpenClaw 에이전트가 살아있는 상태가 됐어요. 다만 게이트웨이가 127.0.0.1(= 본인 컴퓨터 안에서만)에 묶여 있어서, ATOM 앞에 앉아야만 비서를 부를 수 있었죠. 비서인데 사무실 책상에 묶여 있는 셈입니다.
바인딩을 열어서 외부 접속을 받을 수도 있어요. 그런데 10화에서 봤듯이 에이전트는 본인 파일을 읽고 명령을 실행할 수 있는 존재라, 그런 걸 네트워크에 노출하는 건 변호사 본능이 허락하지 않았습니다. 문은 닫아둔 채로, 폰에서 부를 방법이 필요했어요.
답이 텔레그램 봇입니다. 오늘은 그 연결 과정 전체를, 보시는 분이 그대로 따라할 수 있게 단계별로 적었어요. 준비물은 텔레그램 계정 하나면 됩니다.
시작 전에 30초 - 문을 안 열었는데 왜 되지?
따라하기 전에 원리 하나만 알고 가면 전체 그림이 잡혀요.
일반 웹서버 방식 (안 됨):
[폰] ---> [ATOM]
외부에서 집으로 들어오는 연결. 공유기와 방화벽이 막음.
텔레그램 봇 방식 (됨):
[ATOM] ---> [텔레그램 서버] "새 메시지 있나요?" (계속 물어봄)
[폰] ---> [텔레그램 서버] 메시지를 보냄
[ATOM] <--- [텔레그램 서버] "있어요, 이거요" (가져옴)
ATOM이 텔레그램 서버에 먼저, 계속, 나가서 확인합니다. 비유하면 사서함이에요. 사무실 주소는 아무에게도 안 알려주고 우체국에 사서함만 하나 두는 것. 폰은 사서함에 편지를 넣고, ATOM은 틈틈이 가서 확인합니다. 그래서 포트를 하나도 안 열고, IP를 어디에도 노출하지 않고도 폰과 대화가 돼요.
이제 만들러 갑시다.
1단계: BotFather에게 봇 만들어달라고 하기
텔레그램 봇은 텔레그램 앱 안에서 만듭니다. BotFather라는, 봇을 만들어주는 봇에게 말을 걸면 돼요. (이름이 대부 패러디인 건 텔레그램의 유머입니다.)
1-1. 텔레그램 검색창에 @BotFather 입력
⚠️ 사칭 주의.
BotFather2,botfather_official같은 유사품이 같이 뜹니다. 진짜는 파란색 인증 체크가 붙은@BotFather하나뿐이에요. 피싱 사이트가 은행 홈페이지 흉내 내는 거랑 같은 구도이니, 체크 마크부터 확인하세요.
1-2. 채팅창에 입력:
/newbot
텔레그램 봇들은 이렇게 /로 시작하는 단어를 명령으로 알아듣습니다. /newbot은 말 그대로 “새 봇 만들어줘”예요.
1-3. 봇의 표시 이름을 물어봅니다. 채팅 화면 상단에 보이는 이름이에요. 한글 가능, 마음대로 지으세요. (본인은 “gaga”라고 지었습니다.)
1-4. 봇의 username을 물어봅니다. 표시 이름과 달리 이건 전 세계에서 유일한 고유 주소 같은 거라, 규칙이 있어요.
| 규칙 | 예시 |
|---|---|
| 영문/숫자/언더바만 | hong_lawyer_bot ⭕ / 홍변호사봇 ❌ |
반드시 bot으로 끝나야 함 | my_atom_bot ⭕ / my_atom ❌ |
| 전 세계에서 유일해야 함 | 겹치면 다시 지으라고 함 |
1-5. 성공하면 BotFather가 축하 메시지와 함께 긴 문자열을 줍니다.
Use this token to access the HTTP API:
1234567890:AAHxxxxxxxxxxxxxxxxxxxxxxxx
이 숫자:영문자열이 토큰이에요. 메모장에 잠시 복사해두세요. 곧 씁니다.
🔑 토큰 = 봇의 인감도장. 이 문자열을 가진 사람은 누구든 이 봇 행세를 할 수 있습니다. 블로그, 스크린샷, GitHub 어디에도 올리면 안 돼요. 유출이 의심되면 BotFather에게
/revoke를 보내면 새 토큰으로 교체됩니다(인감 분실신고). 이 글에도 토큰은 끝까지 등장하지 않습니다.
2단계: 본인의 텔레그램 ID 알아내기
봇의 username은 공개 정보라서 누구든 검색해서 말을 걸 수 있어요. 아무나 말 걸 수 있는 비서는 비서가 아니라 안내데스크입니다. 그래서 “본인만 통과시키는 출입명부”를 만들 건데, 명부에 적을 본인 ID부터 알아냅니다.
2-1. 텔레그램 검색창에 @userinfobot 입력 (역시 파란 체크 확인)
2-2. Start 버튼을 누르거나 아무 말이나 보내면 이렇게 답이 옵니다.
Id: 123456789
First: 길동
Lang: ko
Id: 뒤의 9~10자리 숫자가 본인의 텔레그램 ID예요. 이것도 메모해두세요.
💡 이 숫자는 토큰과 달리 비밀번호가 아니라 회원번호 같은 거라, 알려져도 큰일은 안 납니다. 다만 굳이 공개할 필요도 없어요.
3단계: 설정 파일 찾고, 백업하기
이제 ATOM의 터미널로 갑니다.
먼저 우리가 손댈 파일이 뭔지부터 알고 가요. OpenClaw는 자기의 모든 설정 - 어떤 모델을 두뇌로 쓰는지, 게이트웨이가 어느 주소에서 돌아가는지, 어떤 채널로 대화를 받는지 - 을 파일 하나에 담아둡니다.
~/.openclaw/openclaw.json
경로를 풀어보면 이렇습니다.
| 부분 | 의미 |
|---|---|
~ | 본인의 홈 폴더 (/home/사용자이름의 줄임 표기) |
.openclaw | OpenClaw가 자기 살림을 보관하는 폴더. 점(.)으로 시작하는 폴더는 평소 파일 탐색기에 안 보이는 숨김 폴더예요 |
openclaw.json | 설정 본체. JSON이라는, 사람도 읽을 수 있는 텍스트 형식으로 적혀 있습니다 |
JSON은 중괄호 { }와 따옴표로 이루어진 설정 문서 형식이에요. 메모장으로 열리는 그냥 텍스트라서 우리가 직접 고칠 수 있는데, 대신 문법이 엄격합니다. 콤마 하나, 따옴표 하나가 빠지면 파일 전체가 무효가 돼요. 쉼표 하나로 해석이 뒤집히는 계약서라고 생각하면 긴장감이 적당합니다.
그래서 엄격한 문서에 손대기 전, 의식처럼 하는 일이 있어요. 백업.
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.backup-before-telegram
cp는 copy, 즉 복사 명령입니다. cp 원본 사본 순서로 적으면 원본은 그대로 두고 사본이 하나 생겨요. 사본 이름에 사연을 적어두는 게 포인트입니다. .bak 같은 무미건조한 이름 말고 “텔레그램 작업 전”이라고 박아두면, 한 달 뒤에 봐도 어느 시점으로 돌아가는 백업인지 한눈에 알아요. 계약서 버전 관리할 때 파일명에 날짜와 사유 적는 습관 그대로입니다.
잘 만들어졌는지 확인합니다.
ls -la ~/.openclaw/
ls는 list, 폴더 안의 목록을 보여주는 명령이에요. 뒤에 붙은 -la는 “자세히(l), 숨김 파일까지(a)” 보여달라는 옵션입니다. 목록에 openclaw.json과 방금 만든 openclaw.json.backup-before-telegram이 나란히 보이면 준비 끝. 이제 뭘 망가뜨려도 한 줄로 되돌릴 수 있는 상태입니다.
4단계: 설정 파일에 텔레그램 등록
핵심 단계입니다. 설정 파일을 열어요.
nano ~/.openclaw/openclaw.json
nano는 터미널 안에서 돌아가는 텍스트 에디터입니다. 메모장의 터미널 버전이라고 보면 돼요. 화면 맨 아래에 단축키가 늘 표시되는데, ^O 표기는 Ctrl+O라는 뜻입니다. 저장은 Ctrl+O 누르고 엔터, 종료는 Ctrl+X. 이 둘만 알면 됩니다.
파일을 열면 중괄호로 묶인 설정 덩어리들이 보일 거예요. 맨 위쪽의 "agents": { ... }, 덩어리가 끝나는 지점을 찾아서, 그 바로 다음 줄에 아래 블록을 통째로 추가합니다.
"channels": {
"telegram": {
"enabled": true,
"botToken": "1단계에서_받은_토큰",
"dmPolicy": "allowlist",
"allowFrom": ["2단계에서_받은_본인_ID"]
}
},
channels는 이름 그대로 “OpenClaw가 대화를 주고받는 통로들”을 등록하는 자리예요. 거기에 telegram이라는 통로를 새로 뚫는 겁니다. 각 줄의 의미는 이렇습니다.
| 줄 | 의미 |
|---|---|
enabled: true | 이 통로를 켠다 |
botToken | 1단계의 인감도장. 콜론 포함 전체를 따옴표 안에 |
dmPolicy: "allowlist" | 출입 방식: 명부에 등록된 사람만 통과 |
allowFrom | 그 명부. 2단계에서 받은 본인 ID를 따옴표로 감싸서 |
💡 dmPolicy의 다른 선택지:
open(아무나 말 걸 수 있음 - 절대 비추천),pairing(처음 말 건 사람을 건건이 승인 - 안전하지만 번거로움). 혼자 쓸 거면allowlist가 가장 깔끔합니다. 누가 봇 username을 알아내서 말을 걸어도, 명부에 없으면 메시지 자체가 버려져요.
다 넣었으면 Ctrl+O → 엔터로 저장하고, Ctrl+X로 나옵니다.
5단계: 문법 검증
재시작하기 전에, 아까 말한 그 엄격한 JSON 문법이 멀쩡한지 기계로 확인합니다. 여기서 쓰는 도구가 jq예요.
jq는 JSON 전용 검사기 겸 돋보기입니다. JSON 파일을 읽어서 문법이 맞으면 보기 좋게 정리해 출력해주고, 깨져 있으면 몇 번째 줄이 이상한지 알려줘요. 날인 전 최종 검토를 맡기는 셈입니다.
jq . ~/.openclaw/openclaw.json
jq 뒤의 점(.)은 “파일 전체를 보여달라”는 뜻이에요. 결과는 둘 중 하나입니다.
- 정리된 JSON이 쫙 출력되면 → 문법 통과
parse error: ...가 뜨면 → 콤마나 따옴표 어딘가가 깨진 것. 에러에 적힌 줄 번호 근처를 다시 보세요
점 자리에 경로를 적으면 특정 부분만 골라볼 수도 있어요. 방금 우리가 추가한 부분만 확인해봅니다.
jq '.channels.telegram' ~/.openclaw/openclaw.json
“channels 안의 telegram을 보여달라”는 뜻입니다. 4단계에서 넣은 네 줄이 그대로 출력되면 성공.
💡
jq: command not found라고 나오면 아직 설치가 안 된 거예요.sudo apt install jq한 줄로 설치됩니다.
🛟 만약 망가뜨렸다면, 3단계의 백업이 비상구입니다.
cp ~/.openclaw/openclaw.json.backup-before-telegram ~/.openclaw/openclaw.json아까와 같은 복사 명령인데 방향만 반대예요. 사본을 원본 자리에 덮어써서, 작업 전 상태로 완전 복귀합니다. 백업이 있으니 마음 편히 실험하세요.
6단계: 재시작하고 로그 확인
새 설정을 게이트웨이가 읽게 합니다. 설정 파일은 시작할 때 한 번 읽기 때문에, 고친 내용을 반영하려면 재시작이 필요해요.
systemctl --user restart openclaw-gateway
12화에서 만난 그 관리인, systemd에게 내리는 명령입니다. systemctl이 관리인을 부르는 창구이고, --user는 “(시스템 전체가 아니라) 내 사용자 서비스 중에서”, restart openclaw-gateway는 “openclaw-gateway를 껐다 켜줘”라는 뜻이에요.
잘 켜졌는지 봅니다.
systemctl --user status openclaw-gateway
status는 “지금 상태 보고해줘”입니다. Active: active (running) 초록 글씨가 보이면 정상. 보고 화면에서 나올 땐 q를 누릅니다.
켜진 것과 텔레그램에 연결된 건 별개라서, 한 가지 더 확인합니다. 이번엔 일지를 펼쳐요.
journalctl --user -u openclaw-gateway -n 50 --no-pager
journalctl은 systemd가 적어두는 업무 일지(로그)를 열람하는 명령입니다. 옵션을 풀어보면,
| 부분 | 의미 |
|---|---|
--user | 내 사용자 서비스의 일지 중에서 |
-u openclaw-gateway | 이 서비스 것만 (u = unit) |
-n 50 | 최근 50줄만 |
--no-pager | 페이지 넘김 없이 한 번에 출력 |
출력된 일지에서 이 줄을 찾으세요.
[telegram] [default] starting provider (@본인봇이름_bot)
이 한 줄의 의미: “사서함 확인 업무 개시.” 이 순간부터 ATOM은 텔레그램 서버에 쉬지 않고 묻고 있습니다. “새 메시지 있나요?”
7단계: 첫 메시지
폰에서 텔레그램을 엽니다.
- 검색창에 본인 봇 username 입력 (
@..._bot) - 하단의 파란
START버튼 누르기 - 아무 말이나 보내기 - 본인의 첫 마디는 이거였습니다:
안녕 넌 누구야?
잠시 후 답이 도착합니다.
Hello! I’m Nemotron, your AI assistant. How can I help you today? 🤖
💡 첫 답장은 느립니다. 5분 넘게 안 쓰면 모델이 메모리에서 내려가 있어서, 첫 호출 때 다시 올라오는 시간이 필요해요. 두 번째 메시지부터는 빨라집니다.

이 한 줄이 도착하기까지의 경로를 정리하면: 폰 → 텔레그램 사서함 → ATOM이 가져옴 → 출입명부에서 본인 ID 확인 → Nemotron이 답 생성 → 사서함 → 폰. 이 모든 과정에서 집 문은 한 번도 열리지 않았습니다. 지하철에서도, 법원 앞에서도, 이제 책상 위의 비서를 부를 수 있어요.
보너스: Bubbling…이 떠도 놀라지 마세요
답장을 기다리는 동안 “입력 중…” 자리에 이런 게 뜰 수 있습니다.
Bubbling…
오타도 고장도 아닙니다. OpenClaw는 봇이 생각 중일 때 띄우는 문구를 자기들만의 단어 풀에서 무작위로 골라 써요.
Thinking… Shelling… Scuttling… Clawing… Pinching… Molting… Bubbling… Cracking… Lobstering… Surfacing…
전부 바다·갑각류 테마입니다. 마스코트가 가재 🦞 인 걸 로딩 문구까지 밀고 나가는 거예요. 비서가 물속에서 보글보글 거품 내며 고민하는 그림. 위험 경고는 문서 첫 줄에 빨간 글씨로 박아두면서 로딩 문구엔 가재 말장난을 심는 사람들이 만든 도구입니다. 나쁘지 않은 조합이에요.
오늘의 정리
- ✅ 봇은 들어오는 연결이 아니라 나가는 연결 (롱폴링 = 사서함). 그래서 포트 안 열고, IP 노출 없이 폰 연결이 됩니다
- ✅ 순서: BotFather에서 봇 생성 → @userinfobot으로 본인 ID → 설정 파일 백업 → channels 블록 추가 → jq 검증 → 재시작 → 로그 확인 → 첫 메시지
- ✅ OpenClaw의 모든 설정은
~/.openclaw/openclaw.json한 파일에 있고, 고치기 전엔 백업이 먼저입니다 - ✅ 토큰 = 인감도장 (공개 금지, 유출 시
/revoke) - ✅
dmPolicy: "allowlist"+ 본인 ID 하나 = 출입명부. 이 한 줄이 이 집의 가장 중요한 잠금장치입니다 - ✅
jq= JSON 전용 검사기. 재시작 전에 문법부터 통과시키기 - ✅ 성공 신호는 로그의
starting provider (@본인봇)한 줄
첫 답장의 기쁨은 정확히 30초 갔습니다. 그 직후 노란 경고 삼각형이 떴거든요.
⚠️ Edit: in IDENTITY.md failed
그리고 두 번째 질문을 던지자, 비서는 혼자 뭔가를 정리하기 시작하더니 정리할수록 짐이 늘어나는 기이한 현상 끝에 스스로 대화를 리셋해버렸습니다. 다이어트를 했는데 몸무게가 늘어난 사건. 다음 편에서 그 부검 기록과 수술기를 공개합니다.
읽어주셔서 감사합니다.