#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Mattermost Incoming Webhook 알림 송신 유틸리티 스크립트. 3인 연구팀의 협업 환경 및 빌드/테스트/실험 결과 전송용으로 사용됩니다. """ import os import sys import json import argparse import urllib.request from urllib.error import URLError, HTTPError def load_env(env_path=".env"): """.env 파일에서 환경 변수를 로드합니다.""" if os.path.exists(env_path): with open(env_path, "r", encoding="utf-8") as f: for line in f: line = line.strip() if not line or line.startswith("#"): continue if "=" in line: key, value = line.split("=", 1) os.environ[key.strip()] = value.strip().strip('"').strip("'") def send_mattermost_message(webhook_url, text, username=None, icon_emoji=None, attachments=None): """ Mattermost Webhook으로 POST 요청을 보냅니다. """ payload = { "text": text } if username: payload["username"] = username if icon_emoji: payload["icon_emoji"] = icon_emoji if attachments: payload["attachments"] = attachments data = json.dumps(payload).encode("utf-8") req = urllib.request.Request( webhook_url, data=data, headers={"Content-Type": "application/json"} ) try: with urllib.request.urlopen(req) as response: if response.status in [200, 201]: return True, "SUCCESS" else: return False, f"Unexpected response status: {response.status}" except HTTPError as e: return False, f"HTTP Error {e.code}: {e.reason}" except URLError as e: return False, f"URL Error: {e.reason}" except Exception as e: return False, f"General Error: {str(e)}" def main(): parser = argparse.ArgumentParser(description="Mattermost webhook notification CLI utility.") parser.add_argument("--message", "-m", required=True, help="송신할 메시지 본문 (Markdown 포맷 지원)") parser.add_argument("--title", "-t", help="메시지 첨부 카드 제목") parser.add_argument("--level", "-l", choices=["info", "warning", "error", "success"], default="info", help="알림 레벨") parser.add_argument("--author", "-a", default="Multi-Agent-Backplane", help="송신자 이름") parser.add_argument("--env", default=".env", help="환경 변수 파일 경로") args = parser.parse_args() # 환경 변수 로드 load_env(args.env) webhook_url = os.environ.get("MATTERMOST_WEBHOOK_URL") if not webhook_url: print("[ERROR] MATTERMOST_WEBHOOK_URL 환경변수가 설정되지 않았습니다.", file=sys.stderr) print("💡 로컬의 .env 파일에 'MATTERMOST_WEBHOOK_URL=웹훅주소' 형태로 추가하거나 셸 환경변수를 설정하십시오.", file=sys.stderr) sys.exit(1) # 알림 레벨별 색상 및 이모지 설정 colors = { "info": "#2196F3", # Blue "warning": "#FF9800", # Orange "error": "#F44336", # Red "success": "#4CAF50" # Green } emojis = { "info": ":information_source:", "warning": ":warning:", "error": ":x:", "success": ":white_check_mark:" } color = colors.get(args.level) emoji = emojis.get(args.level) username = f"{args.author} {emoji}" attachments = None if args.title: attachments = [{ "fallback": f"[{args.level.upper()}] {args.title}", "color": color, "title": args.title, "text": args.message, "fields": [ { "short": True, "title": "Notification Level", "value": args.level.upper() }, { "short": True, "title": "Trigger Entity", "value": args.author } ] }] text = "" # attachments가 있으면 본문 텍스트는 비우거나 제목으로 대체 else: text = f"{args.message}" success, msg = send_mattermost_message( webhook_url=webhook_url, text=text, username=username, attachments=attachments ) if success: print("[SUCCESS] Mattermost 알림 전송 완료.") else: print(f"[ERROR] Mattermost 알림 전송 실패: {msg}", file=sys.stderr) sys.exit(2) if __name__ == "__main__": main()