mirror of
https://github.com/artemium428/428th-website-2026.git
synced 2026-09-15 17:06:20 +00:00
Wire the anonymous form to a VPS Python endpoint that notifies Telegram, persists submissions locally, and stops faking success on failure. Co-authored-by: Cursor <cursoragent@cursor.com>
109 lines
2.8 KiB
Markdown
109 lines
2.8 KiB
Markdown
# Contact API → Telegram
|
|
|
|
Small Python 3 (stdlib only) service that accepts `POST /api/contact` and forwards the message to Telegram.
|
|
|
|
## Setup (once)
|
|
|
|
1. Create a bot with [@BotFather](https://t.me/BotFather) → copy the token.
|
|
2. Open a chat with the bot and press **Start**.
|
|
3. Get your numeric chat id (`@userinfobot`, or call `getUpdates` after messaging the bot).
|
|
4. On the VPS:
|
|
|
|
```bash
|
|
cd /path/to/site/api
|
|
cp .env.example .env
|
|
# edit .env — set TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID
|
|
```
|
|
|
|
## Local smoke test
|
|
|
|
```bash
|
|
cd api
|
|
cp .env.example .env # fill tokens
|
|
python3 contact_server.py
|
|
```
|
|
|
|
```bash
|
|
curl -sS -X POST http://127.0.0.1:8787/api/contact \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"name":"Test","contact":"@you","message":"hello"}'
|
|
```
|
|
|
|
Health check: `GET /api/health` → `{"ok":true,"configured":true}`.
|
|
|
|
## systemd
|
|
|
|
`/etc/systemd/system/428th-contact.service`:
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=428th contact form → Telegram
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
WorkingDirectory=/var/www/428th.com/api
|
|
EnvironmentFile=/var/www/428th.com/api/.env
|
|
ExecStart=/usr/bin/python3 /var/www/428th.com/api/contact_server.py
|
|
Restart=always
|
|
RestartSec=3
|
|
User=www-data
|
|
Group=www-data
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
```
|
|
|
|
```bash
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now 428th-contact
|
|
sudo systemctl status 428th-contact
|
|
```
|
|
|
|
Adjust `WorkingDirectory`, `EnvironmentFile`, `User`, and paths to match your VPS layout.
|
|
|
|
## nginx
|
|
|
|
Inside the HTTPS server block for `428th.com`:
|
|
|
|
```nginx
|
|
location /api/contact {
|
|
proxy_pass http://127.0.0.1:8787/api/contact;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
client_max_body_size 16k;
|
|
}
|
|
|
|
# optional
|
|
location /api/health {
|
|
proxy_pass http://127.0.0.1:8787/api/health;
|
|
proxy_set_header Host $host;
|
|
}
|
|
```
|
|
|
|
Then:
|
|
|
|
```bash
|
|
sudo nginx -t && sudo systemctl reload nginx
|
|
```
|
|
|
|
Deploy updated static files (`common.js`, built HTML) as usual so the form shows real errors and includes the honeypot field.
|
|
|
|
## Message backup
|
|
|
|
Every valid submission is appended to `messages.jsonl` (override with `MESSAGES_FILE` in `.env`), one JSON object per line:
|
|
|
|
```json
|
|
{"ts":"2026-07-26T16:40:00Z","name":"…","contact":"…","message":"…","ip":"1.2.3.4","telegram_ok":true,"telegram_error":null}
|
|
```
|
|
|
|
Backup is written even if Telegram fails (`telegram_ok: false`), so you still have the text on disk. Honeypot hits are not stored. Keep this file private (same permissions as `.env`); it is gitignored.
|
|
|
|
## Behaviour notes
|
|
|
|
- Honeypot field `website`: if filled, returns `200` without notifying Telegram or writing a backup.
|
|
- In-memory rate limit: 5 POSTs per IP per 60 seconds → `429`.
|
|
- Field limits: name/contact ≤ 200 chars, message ≤ 4000.
|