virtual-insanity
← 리포트 목록

Gmail 뉴스레터 이중 발송 차단

2026-04-24 gmail [gmail, telegram, alert-center, cron, hermes-migration]

Gmail 뉴스레터 이중 발송 차단

결론

알림센터 중복 원인은 ~/.openclaw/cron/jobs.json의 OpenClaw 잡이 아니라, 사용자 crontab에 남아 있던 OpenClaw legacy 직접 실행 라인이었다.

  • Hermes: ocAQ-AQ004-gmail-newsletter-command active 유지
  • OpenClaw jobs.json: gmail-newsletter-collector disabled 상태 재확인 + nextRun 제거 보강
  • OpenClaw crontab legacy: 0 7 * * * ... gmail_newsletter_collector.py 주석 처리 완료
  • 내일 확인용 모니터: 2026-04-25 07:08 crontab 등록 완료

Before

Hermes

  • 파일: /Users/ron/.hermes/cron/jobs.json
  • 잡: ocAQ-AQ004-gmail-newsletter-command
  • 상태: enabled=true, state=scheduled
  • 스케줄: 47 6 * * * Asia/Seoul
  • 명령: bash PYTHONPATH=/Users/ron/.hermes/workspace/scripts/shared:/Users/ron/.hermes/workspace/scripts/pipeline bash /Users/ron/.hermes/workspace/scripts/pipeline/gmail_newsletter_collector_dual.sh --days 2
  • Hermes CLI 확인: text ocAQ-AQ004-gmail-newsletter-command [active] Name: gmail-newsletter-collector Schedule: 47 6 * * *

OpenClaw jobs.json

  • 파일: /Users/ron/.openclaw/cron/jobs.json
  • 잡: gmail-newsletter-collector
  • 조사 시점 상태: 이미 enabled=false였으나 legacy metadata에 nextRunAtMs가 남아 있던 이력이 있었음.
  • 보강 후: enabled=false, state.status=disabled, state.nextRunAtMs=null

실제 중복 발송 원인: 사용자 crontab

crontab -l에서 아래 legacy 라인이 활성 상태였다.

0 7 * * * cd /Users/ron/.openclaw/workspace/scripts/pipeline && PYTHONUNBUFFERED=1 /usr/bin/python3 gmail_newsletter_collector.py >> /Users/ron/.openclaw/workspace/logs/gmail_newsletter.log 2>&1

이 라인이 07:00에 OpenClaw 구버전 스크립트를 실행했고, Hermes 06:47 실행 결과와 같은 뉴스레터를 알림센터 report 토픽으로 다시 보냈다.

실행 내용

1) 백업

  • OpenClaw jobs.json 백업: /Users/ron/.openclaw/cron/jobs.json.bak-gmail-dual-send-fix-20260424T105202
  • crontab 백업: /Users/ron/knowledge-agent/600-data/crontab.bak-disable-openclaw-gmail-20260424T121404

2) OpenClaw jobs.json 비활성 상태 보강

적용 내용:

{
  "id": "gmail-newsletter-collector",
  "enabled": false,
  "state": {
    "status": "disabled",
    "nextRunAtMs": null,
    "disabledAt": "2026-04-24T10:52:02+09:00",
    "disabledReason": "2026-04-24 gmail dual-send fix: Hermes is canonical; OpenClaw legacy newsletter collector disabled without deletion."
  }
}

3) crontab legacy 라인 비활성화

삭제하지 않고 주석 처리했다.

# DISABLED 2026-04-24 gmail dual-send fix: OpenClaw legacy collector; Hermes ocAQ-AQ004 remains active
# original: 0 7 * * * cd /Users/ron/.openclaw/workspace/scripts/pipeline && PYTHONUNBUFFERED=1 /usr/bin/python3 gmail_newsletter_collector.py >> /Users/ron/.openclaw/workspace/logs/gmail_newsletter.log 2>&1

검증:

active_openclaw_gmail_lines 0

4) 내일 아침 확인용 모니터 설정

LaunchAgent bootstrap이 환경상 Bootstrap failed: 5로 실패해, 실제 동작 가능한 user crontab으로 모니터를 등록했다.

  • 모니터 스크립트: /Users/ron/knowledge-agent/600-data/gmail_dual_send_monitor_260425.py
  • 실행 시각: 2026-04-25 07:08 KST
  • 출력: /Users/ron/knowledge-agent/600-data/260425_gmail_dual_send_monitor.json /Users/ron/knowledge-agent/400-reports/260425_gmail_dual_send_monitor.md

등록 라인:

8 7 25 4 * /usr/bin/python3 /Users/ron/knowledge-agent/600-data/gmail_dual_send_monitor_260425.py >> /Users/ron/knowledge-agent/600-data/260425_gmail_dual_send_monitor.cron.out 2>> /Users/ron/knowledge-agent/600-data/260425_gmail_dual_send_monitor.cron.err # gmail-dual-send-monitor-260425

모니터 판정 기준:

  • OpenClaw sector_trace.log2026-04-25.*gmail_newsletter_collector가 있으면 FAIL_OPENCLAW_LEGACY_SENT
  • OpenClaw hit 없고 Hermes hit 있으면 PASS_HERMES_ONLY
  • 둘 다 없으면 WARN_NO_GMAIL_SEND_FOUND

After

항목 상태
Hermes gmail-newsletter-collector active 유지
OpenClaw jobs.json gmail-newsletter-collector disabled / nextRun 제거
OpenClaw crontab gmail_newsletter_collector.py 주석 처리, active 0건
내일 검증 모니터 2026-04-25 07:08 등록

복구 방법

OpenClaw legacy crontab 복구

필요 시 아래 원본 라인의 주석을 해제한다.

0 7 * * * cd /Users/ron/.openclaw/workspace/scripts/pipeline && PYTHONUNBUFFERED=1 /usr/bin/python3 gmail_newsletter_collector.py >> /Users/ron/.openclaw/workspace/logs/gmail_newsletter.log 2>&1

또는 백업 복구:

crontab /Users/ron/knowledge-agent/600-data/crontab.bak-disable-openclaw-gmail-20260424T121404

OpenClaw jobs.json 복구

cp /Users/ron/.openclaw/cron/jobs.json.bak-gmail-dual-send-fix-20260424T105202 /Users/ron/.openclaw/cron/jobs.json

검증 명령

python3 -m json.tool /Users/ron/.openclaw/cron/jobs.json >/dev/null
crontab -l | grep gmail_newsletter_collector.py
cd /Users/ron/.hermes/hermes-agent && venv/bin/python -m hermes_cli.main cron list | rg -i 'gmail-newsletter|ocAQ-AQ004'
python3 -m py_compile /Users/ron/knowledge-agent/600-data/gmail_dual_send_monitor_260425.py

자체평가

  • 정확성: 4.5/5 — jobs.json만이 아니라 실제 crontab 원인까지 차단.
  • 완성도: 4.3/5 — 내일 검증 모니터까지 등록.
  • 검증: 4.2/5 — JSON/py_compile/crontab/Hermes active 확인 완료.
  • 최소 변경: 4.5/5 — Hermes collector는 미변경, OpenClaw legacy 실행만 주석 처리.

종합: 4.4/5

Remaining Risks

  • OpenClaw에는 Gmail 외에도 legacy crontab 작업이 여럿 남아 있다. 이번 범위는 Gmail 뉴스레터 중복 차단으로 제한했다.
  • LaunchAgent 방식 모니터는 bootstrap 실패로 사용하지 않았고, crontab 방식으로 대체했다.