업무 자동화

파이썬 업무 자동화 #4 - 디스코드 웹훅(Webhook)으로 알림 보내기 (requests)!

Mojangcam 2026. 7. 22. 09:38

안녕하세요! Mojangcam입니다 😎

지난 파이썬 업무 자동화 #3 - 파일 정리 자동화에서는 폴더 속 파일 이름을 파이썬으로 한 번에 정리해봤어요. 이번 편에서는 한 발 더 나아가서, 자동화 스크립트가 일을 다 끝내면 내 디스코드로 알림을 보내주는 방법을 배워볼게요!

크롤링을 돌려놓고 컴퓨터 앞에서 계속 기다린 적 있으시죠? 이제 그럴 필요 없어요. 스크립트 끝에 코드 몇 줄만 추가하면 "작업 완료 ✅ 30건 수집했어요" 같은 메시지가 폰으로 딩동 하고 와요. 에러가 나면 "실패 ❌" 알림도 받을 수 있고요. 서버 모니터링, 크롤링 결과 보고, 백업 완료 알림까지 — 활용도가 정말 높은 기능이에요.

🧩 디스코드 웹훅(Webhook)이 뭐예요?

웹훅은 쉽게 말해 "메시지를 보낼 수 있는 전용 주소(URL)"예요. 디스코드 봇처럼 토큰 발급받고, 인텐트(intents) 설정하고, 24시간 켜둘 필요가 전혀 없어요. 채널에서 URL 하나만 발급받으면, 그 주소로 데이터를 보내는 것만으로 메시지가 채널에 딱 올라가요.

  • 봇(Bot) : 명령어에 반응하고 대화하는 프로그램. 계속 실행(온라인)되어 있어야 함.
  • 웹훅(Webhook) : 한 방향으로 메시지를 "보내기만" 하는 창구. 실행 상태 유지 불필요, URL만 있으면 끝.

그래서 자동화 알림용으로는 웹훅이 훨씬 간단하고 딱이에요. 우리 목표는 "파이썬 스크립트 → 디스코드로 알림" 한 방향이니까요!

▲ 파이썬 스크립트에서 디스코드 채널로 알림이 전달되는 흐름

📌 준비물

  • Python 3.8 이상 (requests 방식) — 뒤에 나오는 discord-webhook 라이브러리는 Python 3.10 이상 필요해요.
  • requests 라이브러리 — HTTP 요청 보낼 때 쓰는 필수템 (#2 크롤링 편에서 이미 만났죠!)
  • 디스코드 서버 — 본인이 관리(웹훅 생성) 권한을 가진 서버
pip install requests
# 라이브러리로 더 편하게 쓰고 싶다면 (선택)
pip install discord-webhook

📌 1단계 - 디스코드 웹훅 URL 만들기

코드보다 먼저 알림을 받을 "주소"를 만들어야 해요. 디스코드 앱에서 이렇게 하면 돼요.

  1. 알림을 받을 채널 위에 마우스를 올리고 톱니바퀴(채널 편집) 아이콘 클릭
  2. 왼쪽 메뉴에서 연동(Integrations) 클릭
  3. 웹후크(Webhooks)새 웹후크(New Webhook) 버튼 클릭
  4. 웹훅 이름·아이콘을 원하는 대로 설정 (예: "자동화 알리미")
  5. 웹후크 URL 복사(Copy Webhook URL) 클릭 → 이 주소를 코드에 붙여넣을 거예요!
⚠️ 이 URL은 비밀번호나 마찬가지예요. URL만 있으면 누구나 그 채널에 메시지를 보낼 수 있으니, 절대 깃허브나 공개된 곳에 올리지 마세요. (뒤에서 안전하게 관리하는 법도 알려드릴게요!)

▲ 디스코드 채널 설정 → 연동 → 웹후크에서 URL 복사

📌 2단계 - requests로 첫 메시지 보내기

이제 가장 기본이 되는 코드예요. 복사한 웹훅 URL로 content(메시지 내용)를 담아 POST 요청만 보내면 끝이에요.

import requests

WEBHOOK_URL = "https://discord.com/api/webhooks/아이디/토큰"  # 복사한 URL 붙여넣기

data = {"content": "안녕하세요! 파이썬에서 보낸 첫 메시지예요 🐍"}

response = requests.post(WEBHOOK_URL, json=data)
print(response.status_code)  # 204가 나오면 성공!

하나씩 뜯어볼게요 💡

  • WEBHOOK_URL : 1단계에서 복사한 웹훅 주소예요.
  • data : 보낼 내용을 담은 딕셔너리. content 키에 메시지 문자열을 넣어요 (최대 2000자).
  • requests.post(url, json=data) : json=으로 넘기면 자동으로 JSON 형식으로 변환해서 보내줘요. data=가 아니라 json=인 점 주의!
  • response.status_code : 성공하면 204(No Content)가 떠요. 200이 아니라 204라서 처음엔 당황할 수 있는데, 204가 정상이에요!

📌 3단계 - 임베드(Embed)로 예쁜 알림 만들기

단순 텍스트도 좋지만, 색깔 있는 카드 형태의 임베드(Embed)를 쓰면 훨씬 보기 좋아요. 제목·설명·필드·타임스탬프까지 넣을 수 있죠.

import requests
from datetime import datetime, timezone

WEBHOOK_URL = "https://discord.com/api/webhooks/아이디/토큰"

embed = {
    "title": "크롤링 작업 완료 ✅",
    "description": "오늘의 뉴스 30건을 수집했어요.",
    "color": 3066993,  # 초록색 (10진수, 16진수 2ECC71)
    "fields": [
        {"name": "수집 건수", "value": "30건", "inline": True},
        {"name": "소요 시간", "value": "12초", "inline": True},
    ],
    "footer": {"text": "Mojangcam 자동화 봇"},
    "timestamp": datetime.now(timezone.utc).isoformat(),
}

data = {
    "username": "자동화 알리미",  # 웹훅 기본 이름 대신 표시할 이름
    "embeds": [embed],           # embeds는 리스트! (최대 10개)
}

response = requests.post(WEBHOOK_URL, json=data)
print(response.status_code)

하나씩 뜯어볼게요 💡

  • color : 카드 왼쪽 띠 색깔. 10진수 숫자로 넣어요. 초록은 3066993, 빨강은 15158332. (16진수 색상코드를 10진수로 바꾸면 돼요.)
  • fields : name(제목)·value(값) 쌍의 목록. "inline": True면 옆으로 나란히, False면 한 줄씩 배치돼요.
  • timestamp : ISO8601 형식 시간. datetime.now(timezone.utc).isoformat()로 지금 시각을 넣었어요.
  • username : 이 메시지에만 표시할 이름을 덮어쓸 수 있어요.
  • embeds는 반드시 리스트([])로 감싸야 해요. 하나여도 대괄호 필수!

📌 4단계 - discord-webhook 라이브러리로 더 쉽게 (선택)

임베드를 자주 쓴다면 discord-webhook 라이브러리가 편해요. 딕셔너리를 직접 안 만들고 메서드로 조립할 수 있거든요. (2026년 7월 기준 최신 버전 1.4.1, Python 3.10+)

# discord-webhook 1.4.1 / Python 3.10+
from discord_webhook import DiscordWebhook, DiscordEmbed

WEBHOOK_URL = "https://discord.com/api/webhooks/아이디/토큰"

webhook = DiscordWebhook(url=WEBHOOK_URL, username="자동화 알리미")

embed = DiscordEmbed(
    title="크롤링 작업 완료 ✅",
    description="오늘의 뉴스 30건을 수집했어요.",
    color="2ecc71",  # 16진수 문자열로 바로 넣어도 OK!
)
embed.add_embed_field(name="수집 건수", value="30건")
embed.add_embed_field(name="소요 시간", value="12초")
embed.set_footer(text="Mojangcam 자동화 봇")
embed.set_timestamp()

webhook.add_embed(embed)
response = webhook.execute()
print(response.status_code)

색상을 "2ecc71"처럼 16진수 문자열 그대로 넣을 수 있어서 편하죠? set_timestamp()는 인자를 안 주면 자동으로 현재 시각을 넣어줘요.

📌 실전 - 작업 성공/실패 알림 자동화

실무에서 제일 많이 쓰는 패턴이에요. 자동화 작업을 try/except로 감싸서, 성공하면 완료 알림을, 에러가 나면 실패 알림을 보내요.

import requests

WEBHOOK_URL = "https://discord.com/api/webhooks/아이디/토큰"

def send_discord(message):
    requests.post(WEBHOOK_URL, json={"content": message})

try:
    # 여기에 실제 자동화 작업 (크롤링, 엑셀 처리, 파일 정리 등)
    result = 30  # 예시: 처리한 건수
    send_discord(f"✅ 작업 완료! 총 {result}건 처리했어요.")
except Exception as e:
    send_discord(f"❌ 작업 실패! 에러: {e}")
    raise  # 알림만 보내고 에러는 그대로 다시 던지기

이렇게 해두면 크롤링이든 백업이든, 스크립트가 끝나는 순간 결과를 폰으로 바로 받아볼 수 있어요. #2 크롤링 편의 스크립트 마지막에 send_discord() 한 줄만 붙이면 바로 완성이에요!

📌 전체 코드 (복붙 OK)

웹훅 URL만 본인 것으로 바꾸면 바로 돌아가는 완성본이에요.

# 파이썬 디스코드 웹훅 알림 - 전체 코드
# Python 3.8+ / requests 2.x
import os
import requests
from datetime import datetime, timezone

# 보안을 위해 환경변수에서 읽어오기 (없으면 직접 문자열로 넣어도 됨)
WEBHOOK_URL = os.environ.get("DISCORD_WEBHOOK_URL", "여기에_웹훅_URL")


def send_message(content):
    """간단한 텍스트 메시지 보내기"""
    res = requests.post(WEBHOOK_URL, json={"content": content})
    return res.status_code  # 204면 성공


def send_embed(title, description, ok=True, **fields):
    """임베드(카드) 알림 보내기. ok=False면 빨간색 실패 알림"""
    embed = {
        "title": title,
        "description": description,
        "color": 3066993 if ok else 15158332,  # 초록 / 빨강
        "fields": [
            {"name": k, "value": str(v), "inline": True}
            for k, v in fields.items()
        ],
        "footer": {"text": "Mojangcam 자동화 봇"},
        "timestamp": datetime.now(timezone.utc).isoformat(),
    }
    data = {"username": "자동화 알리미", "embeds": [embed]}
    res = requests.post(WEBHOOK_URL, json=data)
    return res.status_code


if __name__ == "__main__":
    try:
        # 실제 자동화 작업 자리
        collected = 30
        elapsed = "12초"
        send_embed(
            "크롤링 작업 완료 ✅",
            "오늘의 뉴스를 모두 수집했어요.",
            ok=True,
            수집_건수=f"{collected}건",
            소요_시간=elapsed,
        )
    except Exception as e:
        send_embed("작업 실패 ❌", f"에러가 발생했어요: {e}", ok=False)
        raise

📌 실행 결과

스크립트를 실행하면 디스코드 채널에 "자동화 알리미"라는 이름으로 초록색 카드 알림이 올라와요. 수집 건수·소요 시간이 필드로 나란히 표시되고, 아래에는 시각과 푸터가 찍혀요. 에러가 나면 빨간색 카드로 실패 내용이 오고요.

▲ 디스코드 채널에 표시된 초록색 완료 임베드 알림

▲ 에러 발생 시 빨간색 실패 임베드 알림

📌 자주 나는 에러

1. status_code가 204로 나와요 (에러 아님!)

  • 원인: 디스코드 웹훅은 성공 시 204 No Content를 반환해요.
  • 해결: 204는 정상이에요! 200이 아니라고 실패로 착각하지 마세요.

2. 401 Unauthorized / Invalid Webhook Token

  • 원인: 웹훅 URL이 틀렸거나, 웹훅이 삭제됐어요.
  • 해결: 채널 설정 → 연동 → 웹후크에서 URL을 다시 복사해서 붙여넣으세요.

3. 429 Too Many Requests

  • 원인: 너무 짧은 시간에 많이 보내서 레이트 리밋(속도 제한)에 걸렸어요.
  • 해결: 반복 전송 시 time.sleep(1)로 간격을 두거나, discord-webhook 라이브러리의 rate_limit_retry=True 옵션을 쓰면 자동으로 재전송해줘요.

4. 웹훅 URL이 유출됐어요

  • 원인: URL을 코드에 그대로 적어 깃허브 등에 올리면, 누구나 스팸을 보낼 수 있어요.
  • 해결: 위 전체 코드처럼 환경변수(os.environ)로 관리하세요. 이미 유출됐다면 웹훅을 삭제하고 새로 만들면 기존 URL은 즉시 무효화돼요.

💬 마무리

오늘은 파이썬으로 디스코드 웹훅 알림을 보내는 법을 배웠어요. requests로 {"content": ...}를 POST하는 기본부터, 임베드로 예쁜 카드 만들기, discord-webhook 라이브러리 활용, 그리고 try/except로 성공·실패 알림을 자동화하는 실전 패턴까지 정리했어요. 이제 여러분의 자동화 스크립트에 "알림" 날개를 달아줄 수 있어요! 🙌

다음 편(#5)에서는 ChatGPT API로 업무 자동화하는 법을 다뤄볼게요. AI에게 이메일 요약·분류를 맡기는 실전 예제로 찾아올게요. 기대해주세요!

📚 파이썬 업무 자동화 시리즈