Skip to content

Commit 834ebec

Browse files
[ADD] Первая реализация бота на вайбах (#1)
1 parent 8d7bf90 commit 834ebec

File tree

5 files changed

+146
-0
lines changed

5 files changed

+146
-0
lines changed

.dockerignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.env
2+
*.pyc
3+
*.pyo
4+
*.pyd
5+
__pycache__
6+
*.sqlite
7+
*.db

Dockerfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
FROM python:3.9-slim
2+
3+
WORKDIR /app
4+
5+
COPY /src .
6+
RUN pip install -r requirements.txt
7+
8+
EXPOSE 8844
9+
10+
CMD ["gunicorn", "--bind", "0.0.0.0:8844", "bot:app"]

src/.env.sample

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
PORT=8844
2+
ALERT_CHAT_ID=
3+
TELEGRAM_BOT_TOKEN=
4+
DEBUG_MODE=0

src/bot.py

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import logging
2+
import os
3+
4+
import requests
5+
from dotenv import load_dotenv
6+
from flask import Flask, request
7+
8+
# Load environment variables
9+
load_dotenv()
10+
11+
TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
12+
ALERT_CHAT_ID = os.getenv("ALERT_CHAT_ID")
13+
DEBUG_MODE = int(os.getenv("DEBUG_MODE", "0"))
14+
15+
# Configure logging
16+
if DEBUG_MODE:
17+
logging.basicConfig(
18+
level=logging.DEBUG, format="%(asctime)s [%(levelname)s] %(message)s"
19+
)
20+
logging.debug("Debug mode enabled")
21+
else:
22+
logging.basicConfig(
23+
level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s"
24+
)
25+
26+
app = Flask(__name__)
27+
28+
29+
def escape_markdown_v2(text):
30+
"""Escapes characters for Telegram MarkdownV2."""
31+
escape_chars = r"_*[]()~`>#+-=|{}.!"
32+
return "".join(f"\\{char}" if char in escape_chars else char for char in str(text))
33+
34+
35+
@app.route("/", methods=["POST", "GET"])
36+
def glitchtip_webhook():
37+
if request.method == "GET":
38+
logging.debug("Received GET request at root '/'")
39+
return "OK", 200
40+
41+
logging.debug("Received POST request at root '/'")
42+
payload = request.json
43+
44+
if payload and payload.get("alias") == "GlitchTip":
45+
try:
46+
attachments = payload.get("attachments", [])
47+
messages = []
48+
49+
# Iterate through all attachments and build a list of formatted messages
50+
for att in attachments:
51+
title = att.get("title", "No title")
52+
link = att.get("title_link", "")
53+
fields = att.get("fields", [])
54+
55+
project = ""
56+
environment = ""
57+
release = ""
58+
59+
for field in fields:
60+
field_title = field.get("title")
61+
field_value = field.get("value")
62+
63+
if field_title == "Project":
64+
project = field_value
65+
elif field_title == "Environment":
66+
environment = field_value
67+
elif field_title == "Release":
68+
release = field_value
69+
70+
# Escape values for MarkdownV2
71+
title = escape_markdown_v2(title)
72+
project = escape_markdown_v2(project)
73+
environment = escape_markdown_v2(environment)
74+
release = escape_markdown_v2(release)
75+
link = escape_markdown_v2(link)
76+
77+
# Format the message for a single issue using MarkdownV2
78+
issue_message = (
79+
f"*Title*: {title}\n"
80+
f"*Project*: {project}\n"
81+
f"*Environment*: {environment}\n"
82+
f"*Release*: {release}\n"
83+
f"*Link*: {link}"
84+
)
85+
messages.append(issue_message)
86+
87+
if messages:
88+
# Combine all formatted issues into a single message
89+
separator = "\n\n*New GlitchTip Event*\n\n"
90+
combined_message = "*New GlitchTip Event*\n\n" + separator.join(
91+
messages
92+
)
93+
send_telegram_message(
94+
ALERT_CHAT_ID, combined_message, parse_mode="MarkdownV2"
95+
)
96+
except Exception as e:
97+
logging.exception(f"Error processing GlitchTip payload: {e}")
98+
else:
99+
logging.warning("Received POST with empty or invalid payload")
100+
101+
return "OK", 200
102+
103+
104+
def send_telegram_message(chat_id, text, parse_mode=None):
105+
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
106+
data = {"chat_id": chat_id, "text": text}
107+
if parse_mode:
108+
data["parse_mode"] = parse_mode
109+
110+
logging.debug(f"Sending message to Telegram: {data}")
111+
try:
112+
r = requests.post(url, json=data, timeout=60)
113+
logging.debug(f"Telegram response: {r.status_code} {r.text}")
114+
except Exception as e:
115+
logging.exception(f"Error sending message to Telegram: {e}")
116+
117+
118+
if __name__ == "__main__":
119+
port = 8844
120+
logging.info(f"Starting server on port {port} (debug={DEBUG_MODE})")
121+
app.run(host="0.0.0.0", port=port)

src/requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Flask==3.0.3
2+
python-dotenv==1.0.1
3+
requests==2.31.0
4+
gunicorn==20.1.0

0 commit comments

Comments
 (0)