Skip to content

Commit 5421cb0

Browse files
committed
feat: demo app
1 parent 262973c commit 5421cb0

3 files changed

Lines changed: 142 additions & 1 deletion

File tree

‎Dockerfile‎

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,31 @@
1-
FROM nginx
1+
# Use the official Python base image
2+
FROM python:3.12-slim
3+
4+
# Set environment variables
5+
ENV PYTHONDONTWRITEBYTECODE=1
6+
ENV PYTHONUNBUFFERED=1
7+
8+
# Set work directory
9+
WORKDIR /app
10+
11+
# Install system dependencies
12+
RUN apt-get update && \
13+
apt-get install -y --no-install-recommends \
14+
build-essential \
15+
&& rm -rf /var/lib/apt/lists/*
16+
17+
# Copy requirements file
18+
COPY requirements.txt .
19+
20+
# Install Python dependencies
21+
RUN pip install --upgrade pip && \
22+
pip install --no-cache-dir -r requirements.txt
23+
24+
# Copy project files
25+
COPY . .
26+
27+
# Expose port (change if your app uses a different port)
28+
EXPOSE 8010
29+
30+
# Default command (change as needed)
31+
CMD ["python", "app.py"]

‎app.py‎

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import os
2+
import io
3+
import json
4+
import html
5+
import requests
6+
from flask import Flask, request, Response
7+
8+
TELEGRAM_CHAT_ID = -4947069491
9+
TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN")
10+
if not TOKEN:
11+
raise RuntimeError("Set TELEGRAM_BOT_TOKEN env var")
12+
TG_BASE = f"https://api.telegram.org/bot{TOKEN}"
13+
14+
app = Flask(__name__)
15+
16+
def _chunk(s: str, n: int = 3900):
17+
for i in range(0, len(s), n):
18+
yield s[i:i+n]
19+
20+
def send_text(text: str):
21+
for part in _chunk(text):
22+
r = requests.post(
23+
f"{TG_BASE}/sendMessage",
24+
data={
25+
"chat_id": TELEGRAM_CHAT_ID,
26+
"text": f"<pre>{html.escape(part)}</pre>",
27+
"parse_mode": "HTML",
28+
"disable_web_page_preview": True,
29+
},
30+
timeout=15,
31+
)
32+
r.raise_for_status()
33+
34+
def send_document(fileobj, filename: str, caption: str = None, mime: str = None):
35+
data = {"chat_id": TELEGRAM_CHAT_ID}
36+
if caption:
37+
data["caption"] = caption[:1024]
38+
files = {"document": (filename, fileobj, mime or "application/octet-stream")}
39+
r = requests.post(f"{TG_BASE}/sendDocument", data=data, files=files, timeout=120)
40+
r.raise_for_status()
41+
42+
@app.get("/")
43+
def root_ok():
44+
return Response("ok", mimetype="text/plain")
45+
46+
@app.post("/post")
47+
def post_handler():
48+
try:
49+
lines = []
50+
ctype = request.content_type or "-"
51+
lines.append(f"POST /post")
52+
lines.append(f"Content-Type: {ctype}")
53+
54+
if request.args:
55+
lines.append("Query:")
56+
lines.append(json.dumps(request.args.to_dict(flat=False), ensure_ascii=False, indent=2))
57+
58+
files_sent = 0
59+
body_summary = ""
60+
61+
if request.is_json:
62+
data = request.get_json(silent=True)
63+
if data is None:
64+
body_summary = (request.get_data(as_text=True) or "").strip()
65+
else:
66+
body_summary = json.dumps(data, ensure_ascii=False, indent=2)
67+
68+
elif request.mimetype == "application/x-www-form-urlencoded":
69+
form = request.form.to_dict(flat=False)
70+
body_summary = json.dumps(form, ensure_ascii=False, indent=2)
71+
72+
elif request.mimetype and request.mimetype.startswith("multipart/"):
73+
form = request.form.to_dict(flat=False)
74+
if form:
75+
body_summary = json.dumps(form, ensure_ascii=False, indent=2)
76+
for key in request.files:
77+
for storage in request.files.getlist(key):
78+
f = storage.stream
79+
f.seek(0)
80+
caption = f"{storage.filename or key} ({storage.content_type or 'application/octet-stream'})"
81+
send_document(f, storage.filename or key, caption=caption, mime=storage.content_type)
82+
files_sent += 1
83+
84+
else:
85+
raw = request.get_data()
86+
try:
87+
txt = raw.decode("utf-8")
88+
if len(txt) > 4000:
89+
body_summary = txt[:4000] + "\n...[truncated]"
90+
send_document(io.BytesIO(raw), "payload.txt", caption="Raw payload")
91+
else:
92+
body_summary = txt
93+
except UnicodeDecodeError:
94+
send_document(io.BytesIO(raw), "payload.bin", caption="Binary payload")
95+
body_summary = "(binary payload sent as document)"
96+
97+
if body_summary:
98+
lines.append("Body:")
99+
lines.append(body_summary)
100+
101+
send_text("\n\n".join(lines))
102+
return Response("ok", mimetype="text/plain", status=200)
103+
104+
except requests.HTTPError:
105+
return Response("ok", mimetype="text/plain", status=502)
106+
except Exception:
107+
return Response("ok", mimetype="text/plain", status=500)
108+
109+
if __name__ == "__main__":
110+
app.run(host="0.0.0.0", port=8080)

‎requirements.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
flask==3.1.2

0 commit comments

Comments
 (0)