텔레그램 API 사용

알파카파카·2026년 9월 7일
post-thumbnail

서버 오류, 프로세스 결과, 서버 스케줄 작업 그리고 이벤트 기반 알림을 받을 때

문자나 알림톡으로 받으면 간편하겠지만 구축이나 계약 등 사전 작업이 많고
어플을 만들어서 알람을 보내기엔 번거로울 때..!

전부 해봤는데 무료로 가장 간단하고 다양하게 구현할 수 있는 수단이 바로 텔레그램 API 를 사용하는 것 같아서 구현 방법을 순서대로 작성해보았다

1. 봇 생성 및 API 토큰 발급

  1. 텔레그램 검색창에서 공식 인증 마크가 있는 @BotFather를 찾아 대화를 시작
  2. /newbot 명령어를 전송
  3. 안내에 따라 봇 정보를 입력
    Name : 봇의 표시 이름 ( 자유롭게 입력 가능 )
    Username : 봇의 고유 식별자 ( 전 세계 유일해야 하며, 반드시 끝이 bot 또는 _bot으로 끝나야 함 )
  4. ( 중요 ) 생성이 완료되면 발급되는 HTTP API 토큰( 1234567890:ABCdef... 이런 구조의 긴 문자열임 )을 복사

2. 그룹 채팅방 생성 및 봇 초대

봇을 사용하여 원하는 그룹방에 메시지를 보내려면 그 방의 고유 식별자인 Chat ID가 필요

  1. 알림을 수신할 새 그룹 채팅방 생성
  2. 그룹 설정의 멤버 추가 메뉴로 이동
  3. 봇의 Username( @아이디 )을 검색해 그룹 멤버로 초대
  4. 그룹방에 일반 텍스트 대신 /test나 /start 등 슬래시(/)로 시작하는 명령어를 입력해 전송
    ( 참고 - 원래는 아무 채팅이나 입력해도 되었다고 하는데 요즘은 봇들이 그룹 개인정보 보호 모드라는 것이 켜져 있어, 그룹방 내 일반 텍스트는 봇의 이벤트 큐에 수신되지 않음 )
  5. 브라우저 주소창에 아래 URL을 입력해 접속
https://api.telegram.org/bot<API_TOKEN>/getUpdates

JSON 응답의 message.chat.id 항목이 바로 우리가 찾던 그룹방의 고유 ID

{
  "ok": true,
  "result": [
    {
      "message": {
        "chat": {
          "id": -1001234567890,
          "title": "알림방"
        }
      }
    }
  ]
}

** 주의: 그룹 및 슈퍼그룹의 Chat ID는 음수(- 또는 -100)로 시작하는데 마이너스 기호(-)를 빠뜨리면 전송 에러가 발생하니깐 부호까지 모두 입력하기

3. 봇 알람의 가독성을 높이고 싶다?

1) HTML 서식 적용

서식 유형HTML 태그 문법
굵게<b>내용</b>
기울임<i>내용</i>
인라인 코드<code>코드</code>
코드 블록<pre>코드 블록</pre>
링크<a href="URL">링크명</a>
스포일러<span class="tg-spoiler">내용</span>

2) 미디어 및 대용량 로그 전송

  • 차트 이미지 전송 (sendPhoto): CPU 점유율 그래프나 모니터링 스크린샷 전송에 적합
  • 원본 파일 전송 (sendDocument): 압축 없는 원본 로그 파일(.log), CSV, JSON 파일을 그대로 공유할 때 사용
  • 두 엔드포인트 모두 caption 파라미터를 통해 본문 설명과 HTML 서식을 함께 전송 가능

4. 파이썬(Python) 예제 코드

import os
import requests

BOT_TOKEN = "1234567890:ABCdefGHIjklMNOpqrsTUVwxyz123456"
CHAT_ID = "-1001234567890"  # 음수 부호 포함

class TelegramBot:
    def __init__(self, token, chat_id):
        self.base_url = f"https://api.telegram.org/bot{token}"
        self.chat_id = chat_id

    def send_message(self, text):
        """HTML 서식 텍스트 메시지 전송"""
        url = f"{self.base_url}/sendMessage"
        payload = {
            "chat_id": self.chat_id,
            "text": text,
            "parse_mode": "HTML"
        }
        return requests.post(url, data=payload).json()

    def send_photo(self, photo_path, caption=""):
        """모니터링 차트/스크린샷 이미지 전송"""
        url = f"{self.base_url}/sendPhoto"
        data = {"chat_id": self.chat_id, "caption": caption, "parse_mode": "HTML"}
        with open(photo_path, "rb") as photo:
            return requests.post(url, data=data, files={"photo": photo}).json()

    def send_document(self, doc_path, caption=""):
        """로그 파일/에러 덤프 문서 전송"""
        url = f"{self.base_url}/sendDocument"
        data = {"chat_id": self.chat_id, "caption": caption, "parse_mode": "HTML"}
        with open(doc_path, "rb") as doc:
            return requests.post(url, data=data, files={"document": doc}).json()


if __name__ == "__main__":
    bot = TelegramBot(BOT_TOKEN, CHAT_ID)

    # 1. 서식 텍스트 알림 전송
    alert_text = (
        "<b>[ERROR] 배치 작업 오류 발생</b>\n"
        "<b>발생 일시 : </b> <i>2026-09-07 22:30:00</i>\n"
        "<b>오류 코드 : </b> <code>DB_CONN_TIMEOUT</code>\n\n"
        "<b>상세 내용 : </b>\n"
        "<pre>Timeout connecting to master-db:5432</pre>\n"
        "<a href=\"https://example.com/monitoring\">모니터링 대시보드 바로가기</a>"
    )
    bot.send_message(alert_text)

    # 2. 결과 차트 이미지 전송
    # bot.send_photo("resource_usage.png", caption="<b>📈 일일 자원 사용률 그래프</b>")

    # 3. 상세 로그 원본 파일 전송
    # bot.send_document("error.log", caption="<b>📄 상세 스택 트레이스 로그</b>")

5. 삽질 체크리스트

□ 봇 식별자( Username )의 끝자리가 bot 또는 _bot으로 끝나는가?
□ 그룹 채팅방에 생성한 봇을 멤버로 초대했는가?
□ getUpdates 확인 전 그룹방에 /test 등 슬래시( / ) 명령어를 입력했는가?
□ 그룹 Chat ID 앞의 마이너스( - 또는 -100 ) 기호를 빠뜨리지 않았는가?
□ HTML 서식 사용 시 줄바꿈을 <br> 대신 \n으로 작성했는가?
profile
타닥,,, 타다닥,,,,,,,

0개의 댓글