Skip to content

tgram-analytics/server

Repository files navigation

tgram-analytics · server

Self-hosted, privacy-first analytics controlled entirely through a Telegram bot. No dashboard. No third parties. Just Telegram.

CI License: MIT Python 3.12+


Quick start

1 — Prerequisites

  • Docker & Docker Compose v2
  • A Telegram bot token from @BotFather
  • Your Telegram chat ID (message @userinfobot to find it)

2 — Configure

git clone https://github.com/tgram-analytics/server.git
cd server
cp .env.example .env
# Edit .env and fill in TELEGRAM_BOT_TOKEN, ADMIN_CHAT_ID, and SECRET_KEY

Generate a SECRET_KEY:

python -c "import secrets; print(secrets.token_hex(32))"

3 — Run

docker compose up

The server starts on http://localhost:8000. Verify it's running:

curl http://localhost:8000/health
# {"status":"ok"}

4 — Add your first project

Open Telegram and message your bot:

/add myapp.com

The bot replies with your API key (proj_xxxx) and a ready-to-use JS snippet.


Usage

Track events (REST API)

curl -X POST https://your-server.com/api/v1/track \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "proj_xxxxxxxxxxxx",
    "event": "purchase",
    "session_id": "uuid-here",
    "properties": {"amount": 49, "plan": "pro"}
  }'

JavaScript SDK

<script src="https://your-server.com/sdk/tga.min.js"></script>
<script>
  TGA.init('proj_xxxxxxxxxxxx', { serverUrl: 'https://your-server.com' });
  TGA.track('purchase', { amount: 49 });
</script>

Flutter SDK

await TgAnalytics.init(
  apiKey: 'proj_xxxxxxxxxxxx',
  serverUrl: 'https://your-server.com',
);
await TgAnalytics.track('purchase', properties: {'amount': 49});

Bot commands

Command Description
/start Greet the bot and see available commands
/add <name> Create a new project and get its API key
/projects List all projects
/report <event> Get a chart for an event (with period/granularity controls)
/settings Configure retention and domain allowlist
/help Show this command reference

Development

Setup

python -m venv .venv
source .venv/bin/activate
make install
cp .env.example .env   # edit values

Run locally (with Docker DB)

make dev-db          # start postgres + quickchart in Docker
make migrate         # apply migrations
uvicorn app.main:app --reload

Tests

make test            # run all tests
make test-cov        # with coverage report

Code quality

make lint            # ruff linter
make typecheck       # mypy
make check           # both

Database migrations

# Create a new migration
make migration MSG="add users table"

# Apply migrations
make migrate

# Roll back one step
make downgrade

Architecture

app/
├── api/          REST endpoints (track, pageview, projects)
├── bot/          Telegram bot handlers and conversation state
├── core/         Config, database engine, security utilities
├── models/       SQLAlchemy ORM models
├── schemas/      Pydantic request/response schemas
└── services/     Analytics, charts, scheduler, alerts

See PROJECT.md for full architecture documentation.


Deployment

VPS (Docker Compose)

cp .env.example .env
# Fill in all values, especially WEBHOOK_BASE_URL=https://your-domain.com
docker compose up -d

Point your reverse proxy (Nginx/Caddy) at port 8000.

Railway

Deploy on Railway

Add the environment variables from .env.example in the Railway dashboard.


Contributing

Contributions are welcome. Please open an issue before submitting a pull request for anything beyond a typo or small bug fix, so we can discuss the approach first.

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/my-feature
  3. Write tests alongside your code
  4. Ensure make check and make test pass
  5. Open a pull request

Please follow the existing code style (ruff-enforced) and keep PRs focused.


Disclaimer

This project is an independent open-source project, not affiliated with or endorsed by Telegram Messenger LLP or its parent company in any way. "Telegram" is a trademark of Telegram Messenger LLP.

License

MIT — see the file for details.

Releases

No releases published

Packages

 
 
 

Contributors

Languages