브리핑 파일은 잘 만들어졌는데 텔레그램에는 아무것도 안 오면, 사람은 보통 “cron이 안 돌았나?”부터 의심한다. 그런데 OpenClaw에서는 이 문제가 생각보다 자주 실행 성공과 전달 실패 또는 전달 비활성화가 섞여서 보인다. 즉, 생성은 끝났는데 채널 전달만 빠진 경우가 많다.
이럴 때 가장 중요한 건 질문 순서를 바꾸는 것이다. “왜 안 왔지?”보다 먼저 **“job은 성공했는가, delivery는 켜져 있었는가, target은 맞았는가”**를 따로 본다. 이 세 가지를 분리하면 생각보다 빨리 풀린다.
안내: 이 문서는 생성형 AI를 활용해 작성되었습니다.
flowchart LR A[cron 실행] --> B{run status ok?} B -- 아니오 --> C[실행 로그부터 확인] B -- 예 --> D{delivery.mode 설정됨?} D -- none --> E[외부 메시지 안 오는 것이 정상] D -- announce/webhook --> F{channel/to/accountId 정상?} F -- 아니오 --> G[전달 설정 수정] F -- 예 --> H{채널 연결/권한 정상?} H -- 아니오 --> I[텔레그램 인증/권한 점검] H -- 예 --> J[중복방지 또는 후속 전달 잡 확인]
30초 핵심 요약
cron runs가ok라도,delivery.mode=none이면 텔레그램 메시지는 오지 않는다.- 브리핑 파일 생성과 텔레그램 전달은 같은 문제처럼 보여도 실제로는 별도 단계일 수 있다.
- 가장 빠른 순서는
runs → list → channels status → logs다. - 생성 cron과 전달 cron을 분리했다면, 어느 잡이 전달 책임을 갖는지부터 확인해야 한다.
칠판 치트시트
run status가 먼저다delivery.mode가none인지 본다channel / to / accountId가 맞는지 본다- 텔레그램 채널 연결 상태를 확인한다
- 생성용 잡과 전달용 잡을 분리했다면 둘 다 점검한다
먼저 이 구조부터 이해하면 덜 헷갈린다
OpenClaw cron 문서 기준으로, isolated job은 무엇을 실행할지와 어디로 보낼지가 분리되어 있다. 그래서 job이 잘 돌았다는 사실과 텔레그램에 메시지가 도착했다는 사실은 같은 뜻이 아니다.
문서에서도 delivery는 announce, webhook, none으로 나뉜다. 여기서 none은 에러가 아니라 외부 전달을 하지 않겠다는 설정이다. 그래서 작업이 내부적으로 성공했는데도 사용자 입장에서는 “아무것도 안 왔다”고 느낄 수 있다.
이 차이를 모르면, 실제로는 전달 설정 문제인데 계속 스케줄만 다시 만들게 된다.
공식 참고:
- OpenClaw cron docs: https://docs.openclaw.ai/automation/cron-jobs
- Automation troubleshooting: https://docs.openclaw.ai/automation/troubleshooting
왜 자주 생기나
1) run은 성공했지만 delivery가 none이다
가장 흔한 패턴이다. 특히 브리핑 생성과 전달을 분리해서 운영할 때 잘 생긴다.
예를 들어 아침 06:30 job은 파일 생성만 담당하고, 06:35 job이 저장된 파일을 읽어 텔레그램 전달만 담당하도록 나누면, 06:30 job에 delivery.mode=none이 들어가는 것이 맞다. 이때 06:30 job만 보고 “왜 텔레그램이 안 왔지?”라고 보면 원인을 잘못 짚게 된다.
즉, 이 경우에는 장애가 아니라 역할 분리 설계일 수 있다.
미니 사례:
- before: 생성 cron 하나가 파일 생성과 전달을 동시에 맡음
- after: 생성 cron은
delivery.mode=none, 전달 보장 cron이 5분 뒤 저장 파일 기준으로 전송 - 포인트: 생성 잡 성공만으로는 사용자 메시지 도착을 보장하지 않는다
2) delivery는 켜졌지만 target 정보가 비어 있거나 틀렸다
문서 기준으로 isolated job에서 외부 전달을 하려면 delivery.channel, delivery.to, 필요 시 accountId가 맞아야 한다. 이 값이 비어 있거나 잘못되면 실행은 끝나도 실제 메시지는 나가지 않을 수 있다.
초보 운영자가 자주 놓치는 부분은 여기다.
channel은telegram인데to가 옛 채팅방 ID거나- 멀티 계정 환경에서
accountId가 다른 봇 계정을 가리키는 경우
이때 겉으로는 “cron이 조용하다”로 보이지만, 실제로는 전달 대상이 잘못된 문제다.
3) 채널 연결이나 권한이 흔들렸다
delivery 설정이 맞아도 텔레그램 채널 쪽 인증/권한이 흔들리면 메시지가 막힌다. Automation troubleshooting 문서도 이 구간에서 channels status --probe와 로그 확인을 먼저 권한다.
대표적으로 이런 경우가 있다.
- 봇 토큰은 살아 있는데 채널 권한이 바뀜
- 그룹/토픽 대상이 바뀌어 예전
to가 더 이상 유효하지 않음 - 채널 연결은 살아 있지만 특정 대상 전송만 실패함
이 문제는 스케줄을 다시 만든다고 해결되지 않는다. 전송 경로 자체를 다시 확인해야 한다.
4) 생성 잡과 전달 잡을 분리해 놓고, 전달 잡 점검을 빼먹는다
운영이 조금 고도화되면 이 구조가 자주 나온다.
- 첫 번째 cron이 리서치/파일 저장
- 두 번째 cron이 저장 결과를 읽어 전달 보장
이 방식은 안정적이다. 중간에 첫 번째 job이 성공했는데 채널 전송만 빠져도, 두 번째 job이 다시 메워 줄 수 있기 때문이다. 하지만 단점도 있다. 어느 job이 사용자 전달 책임을 지는지 잊으면, 문제를 엉뚱한 곳에서 찾게 된다.
그래서 job 이름에도 역할을 드러내는 편이 좋다. 예를 들어:
경제 브리핑 생성 (06:30)경제 브리핑 전달 보장 (06:35)
이렇게 나누면 운영자가 로그를 볼 때도 훨씬 덜 헷갈린다.
5분 복구 순서
이 문제는 아래 순서가 가장 빠르다.
1) 최근 run 상태를 먼저 본다
openclaw cron runs --id <jobId> --limit 20여기서 제일 먼저 볼 것은 세 가지다.
- 최근 실행이 실제로 있었는가
- 상태가
ok인가 - 실패라면 실행 단계에서 멈췄는가, 전달 단계에서 멈췄는가
만약 여기서 ok가 찍혔다면, 다음 질문은 바로 “전달이 켜져 있었나?”로 넘어가면 된다.
2) job 정의에서 delivery 설정을 본다
openclaw cron list이 단계에서는 아래를 같이 본다.
delivery.modedelivery.channeldelivery.to- 필요 시
accountId
여기서 delivery.mode=none이면, 텔레그램 미수신은 이상 현상이 아니라 설정대로 동작한 것이다.
반대로 announce인데도 안 왔다면, target 또는 채널 상태를 의심하면 된다.
3) 텔레그램 채널 상태를 본다
openclaw channels status --probe
openclaw logs --follow좋은 상태는 단순하다.
- Telegram transport가 connected/ready
- 관련 계정이 정상
- 반복적인
unauthorized,Forbidden,missing_scope성격의 오류가 없음
여기서 에러가 보이면 cron보다 채널 복구가 우선이다.
4) 생성용 job인지 전달용 job인지 역할을 나눠서 본다
실무에서는 이 단계가 특히 중요하다.
- 생성용 job이면: 파일이 실제로 생겼는지 본다
- 전달용 job이면: 생성된 파일을 읽어 메시지로 보냈는지 본다
예를 들어 브리핑 파일이 아래에 존재한다면,
- Quartz 저장본 존재
- archive 저장본 존재
생성 단계는 끝난 것이다. 그다음은 전달 단계만 보면 된다. 이렇게 보면 문제 범위가 절반으로 줄어든다.
현장 미니 사례 2개
사례 A) 파일은 생겼는데 텔레그램이 비었다
- 상황: 아침 브리핑 문서는 저장됐는데, 사용자는 브리핑을 못 받음
- 실제 원인: 생성 cron은 성공했고 저장도 끝났지만, 최종 전달 단계가 누락됨
- 해결: 생성 job은
delivery.mode=none으로 분리하고, 5분 뒤 저장 파일 기반 전달 보장 cron을 별도로 추가 - 포인트: 생성 성공과 전달 성공을 같은 것으로 보면 안 된다
사례 B) run status는 ok인데 여전히 조용했다
- 상황:
cron runs상 최근 실행은 성공으로 보임 - 실제 원인:
delivery.channel/to또는 계정 연결 상태 문제로 외부 메시지가 빠짐 - 해결:
cron list로 delivery target을 다시 보고,channels status --probe로 Telegram 연결 상태 확인 - 포인트: run 성공은 내부 실행 성공일 뿐, 외부 도착 보장은 아니다
재발 방지 원칙
1) 생성과 전달은 로그 이름부터 분리한다
잡 이름만 봐도 역할이 보이게 만든다. 그래야 아침에 문제가 생겨도 어느 단계가 비었는지 바로 찾을 수 있다.
2) 브리핑류는 전달 보장용 2단계 구조가 안전하다
외부 소스가 많고 요약 길이도 긴 작업은, 생성과 전달을 분리하는 편이 운영 복원력이 좋다. 생성이 끝났다면 저장 파일 기준으로 한 번 더 전달할 수 있기 때문이다.
3) run ok를 “사용자 수신 완료”로 해석하지 않는다
운영 기준에서는 이 둘을 따로 본다.
run ok= job 내부 단계가 끝남user received= 실제 채널 도착 확인
이렇게 구분하면 원인 파악 속도가 훨씬 빨라진다.
복구 확인 체크리스트
-
cron runs --id <jobId>에서 최근 run 상태를 확인했다 -
cron list에서delivery.mode / channel / to를 확인했다 -
channels status --probe에서 Telegram 연결 상태를 확인했다 - 생성용 job과 전달용 job 중 어디가 책임 단계인지 구분했다
- 저장 파일이 있으면 생성 성공, 없으면 실행 실패로 분리해 해석했다
한 줄 결론
cron은 잘 돌았는데 텔레그램만 조용할 때는, 스케줄보다 먼저 delivery 설정과 전달 책임 job을 봐야 한다.
runs → list → channels status → logs 순서로 보면, “안 돌았다”와 “돌았지만 안 보냈다”를 훨씬 빨리 분리할 수 있다.
다음 읽기
- 06. Cron Job
- 30. 텔레그램 완전설정 운영가이드
- 37. Scheduled reminder 떴는데 액션이 안 이어질 때
- 42. cron 시간을 바꿨는데 예전 시각에 계속 돌 때
- 🚀 OpenClaw 인덱스
내부링크 보강 (10개)
- 25. 크론 서브에이전트 분산운영
- 29. 텔레그램 권한변화 버전비교
- 31. Quota 리셋 안 됨 해결
- 32. HEARTBEAT_OK 반복응답 해결
- 33. gateway 무응답 PM2·systemd 충돌 해결
- 35. 예약 리마인더 중복발송 해결
- 36. Quota 리셋 알림 뒤 quota exceeded 해결
- 38. 14시 할일이 자동 실행 안 될 때
- remote unauthorized 해결
- 🚀 OpenClaw 허브
다음 추천 읽기: 30. 텔레그램 완전설정 운영가이드