Go to file
alisaza a541075765
Some checks failed
CI / Typecheck and test (push) Failing after 1m36s
Deploy / Typecheck and test (push) Failing after 35s
Deploy / Deploy to VPS (push) Has been skipped
Add Gitea Actions CI/CD and production deploy scripts.
Wire typecheck/test on PR/push and SSH deploy to the foreign VPS on main.
2026-09-13 14:39:59 +03:30
.gitea/workflows Add Gitea Actions CI/CD and production deploy scripts. 2026-09-13 14:39:59 +03:30
deploy Add Gitea Actions CI/CD and production deploy scripts. 2026-09-13 14:39:59 +03:30
scripts Add Gitea Actions CI/CD and production deploy scripts. 2026-09-13 14:39:59 +03:30
src Add initial Telegram relay service for Iran→foreign delivery. 2026-09-13 13:38:36 +03:30
.env.example Add initial Telegram relay service for Iran→foreign delivery. 2026-09-13 13:38:36 +03:30
.gitignore Add initial Telegram relay service for Iran→foreign delivery. 2026-09-13 13:38:36 +03:30
docker-compose.yml Add initial Telegram relay service for Iran→foreign delivery. 2026-09-13 13:38:36 +03:30
Dockerfile Add initial Telegram relay service for Iran→foreign delivery. 2026-09-13 13:38:36 +03:30
package-lock.json Add initial Telegram relay service for Iran→foreign delivery. 2026-09-13 13:38:36 +03:30
package.json Add initial Telegram relay service for Iran→foreign delivery. 2026-09-13 13:38:36 +03:30
README.md Add Gitea Actions CI/CD and production deploy scripts. 2026-09-13 14:39:59 +03:30
tsconfig.json Add initial Telegram relay service for Iran→foreign delivery. 2026-09-13 13:38:36 +03:30

Ghabilee Telegram Relay

Thin HTTP service that lives on a foreign VPS and forwards ops alerts to Telegram Bot API. The Iran-hosted Nest backend calls this relay instead of api.telegram.org directly (which is often unreachable from inside Iran).

Repo: https://git.ghabilee.ir/AliSaZa/telegrambot.git

Why

  • Core product (Jibit, Kavenegar, Postgres) stays in Iran.
  • Only Telegram delivery needs outbound access to api.telegram.org.
  • Failures here must not break user flows (backend already treats most alerts as best-effort).

API

GET /health

Liveness for Docker/load balancers. No auth.

POST /v1/send

Auth header (required):

X-Ghabilee-Telegram-Relay-Secret: <RELAY_SECRET>

Body (JSON):

Field Type Required Notes
text string yes 14096 chars (Telegram limit)
chatId string no Override default chat from env
messageThreadId number | null no Forum topic; null = no topic; omit = env default
disableWebPagePreview boolean no Default true

Success:

{ "ok": true, "messageId": 123 }

Errors: 401 unauthorized, 400 validation, 502 Telegram API failure.

Example

curl -sS -X POST "https://relay.example.com/v1/send" \
  -H "Content-Type: application/json" \
  -H "X-Ghabilee-Telegram-Relay-Secret: $RELAY_SECRET" \
  -d '{"text":"hello from relay","messageThreadId":8}'

Local run

cp .env.example .env
# fill TELEGRAM_BOT_TOKEN, chat ids, RELAY_SECRET (≥32 chars)

npm install
npm run dev

Tests / typecheck:

npm test
npm run typecheck

Docker

cp .env.example .env
docker compose up -d --build

CI/CD (Gitea Actions)

On push to main:

  1. .gitea/workflows/ci.yml — typecheck + tests
  2. .gitea/workflows/deploy.yml — rsync to VPS + scripts/deploy-on-vps.sh

Repo Actions secrets (Settings → Actions → Secrets):

Secret Value
DEPLOY_SSH_KEY private key that can SSH as root on the VPS
VPS_HOST 65.108.18.151 (public IP; job runs in Docker)
VPS_USER root

Production app dir: /opt/ghabilee-telegram-relay
Nginx host: telegram-relay.ghabilee.ir (add DNS A record, then certbot --nginx -d telegram-relay.ghabilee.ir)

Gitea git SSH uses port 222: ssh://git@git.ghabilee.ir:222/AliSaZa/telegrambot.git

Env

See .env.example. Production needs:

  • RELAY_SECRET (≥32)
  • TELEGRAM_BOT_TOKEN
  • TELEGRAM_GROUP_CHAT_ID (preferred) or TELEGRAM_CHAT_ID
  • optional TELEGRAM_GROUP_THREAD_ID (ops forum topic)

Backend integration (next step)

In ghabilee-backend OpsAlertsService.sendTelegram, when TELEGRAM_RELAY_URL is set, POST to {TELEGRAM_RELAY_URL}/v1/send with the shared secret instead of calling Telegram directly. Keep a direct-Telegram fallback for local/dev if useful.

Security notes

  • Do not put the secret in query strings (access logs).
  • Expose only HTTPS on the foreign VPS (Caddy/Nginx + Lets Encrypt).
  • Firewall: ideally allow only the Iran VPS egress IP to hit /v1/send.