# 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.