v2.3.3: fix Discord webhook always failing (Cloudflare blocks Python UA)
Cloudflare protects Discord webhook endpoints and rejects requests
with the default Python urllib User-Agent ('Python-urllib/3.x') with
HTTP 403 + 'error code 1010'. Add a browser-like User-Agent header
to the request.
The onboarding wizard's 'Send Test Message' button (and clock-in/out
push messages) now succeed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
86cf438785
commit
d3a4efc173
10
CHANGELOG.md
10
CHANGELOG.md
@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||||
|
|
||||||
|
## [2.3.3] — 2026-04-30
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- **Discord 웹훅 항상 실패하던 문제** (Cloudflare error 1010 / 403 Forbidden)
|
||||||
|
- 원인: Python 기본 User-Agent(`Python-urllib/3.x`)를 Discord/Cloudflare가
|
||||||
|
봇으로 인식해 차단
|
||||||
|
- 수정: `utils/discord_webhook.py`에 브라우저 UA 헤더 추가
|
||||||
|
(`Mozilla/5.0 (Windows NT 10.0; Win64; x64) ClockOutCalculator/2.3`)
|
||||||
|
- 이제 온보딩 위저드의 "테스트 메시지 보내기" + 출퇴근/휴식 push 모두 정상 동작
|
||||||
|
|
||||||
## [2.3.2] — 2026-04-30
|
## [2.3.2] — 2026-04-30
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@ -4,4 +4,4 @@
|
|||||||
릴리스 시 이 값을 올린 후 git tag → push.
|
릴리스 시 이 값을 올린 후 git tag → push.
|
||||||
CHANGELOG.md의 최상단 항목과 일치시킬 것.
|
CHANGELOG.md의 최상단 항목과 일치시킬 것.
|
||||||
"""
|
"""
|
||||||
__version__ = '2.3.2'
|
__version__ = '2.3.3'
|
||||||
|
|||||||
@ -10,6 +10,10 @@ import urllib.error
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Optional, List
|
from typing import Optional, List
|
||||||
|
|
||||||
|
# Discord/Cloudflare는 Python 기본 UA(Python-urllib/3.x)를 봇으로 차단(error 1010).
|
||||||
|
# 일반 브라우저 UA로 위장해야 통과.
|
||||||
|
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ClockOutCalculator/2.3'
|
||||||
|
|
||||||
# Discord embed 색상 (decimal)
|
# Discord embed 색상 (decimal)
|
||||||
COLOR_GREEN = 0x57F287
|
COLOR_GREEN = 0x57F287
|
||||||
COLOR_BLUE = 0x5865F2
|
COLOR_BLUE = 0x5865F2
|
||||||
@ -49,7 +53,10 @@ def send(webhook_url: str, title: str, description: str,
|
|||||||
data = json.dumps(payload, ensure_ascii=False).encode('utf-8')
|
data = json.dumps(payload, ensure_ascii=False).encode('utf-8')
|
||||||
req = urllib.request.Request(
|
req = urllib.request.Request(
|
||||||
webhook_url, data=data,
|
webhook_url, data=data,
|
||||||
headers={'Content-Type': 'application/json; charset=utf-8'},
|
headers={
|
||||||
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
|
'User-Agent': USER_AGENT,
|
||||||
|
},
|
||||||
method='POST',
|
method='POST',
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user