Skip to main content

Lightweight analytics library for Telegram bots built with aiogram 3

Project description

Anystat

PyPI Python 3.12+ License: MIT CI

English | Русский

Lightweight, privacy-first analytics for Telegram bots built with aiogram 3.

Add two lines of code and see how people actually use your bot: /start sources and deep links, command usage, button clicks, blocks and unblocks — all in your Anystat dashboard.

anystat = Anystat(api_key="YOUR_API_KEY")
setup_anystat(dp, anystat)

Why Anystat

  • Two-line integration. One middleware, zero changes to your handlers.
  • Privacy by default. Message text is not collected unless you explicitly opt in. No user profile data is collected.
  • Nothing hidden. Turn on debug=True and the SDK logs every event it captures, every payload it sends, and everything it skips — verify it yourself.
  • Fire and forget. Events are batched, retried with backoff, and never block your handlers. If analytics fails, your bot keeps working.
  • Fully typed. Ships with py.typed — autocomplete and type checking out of the box.

Installation

pip install anystat

or with uv:

uv add anystat

Requires Python 3.12+ and aiogram 3.

Quickstart

import asyncio
from aiogram import Bot, Dispatcher
from anystat import Anystat, setup_anystat


async def main():
    bot = Bot(token="YOUR_BOT_TOKEN")
    dp = Dispatcher()

    anystat = Anystat(api_key="YOUR_ANYSTAT_API_KEY")   # 1
    setup_anystat(dp, anystat)                          # 2
    dp.shutdown.register(anystat.close)  # flush pending events on shutdown

    # ... register your handlers as usual ...

    await dp.start_polling(bot)


asyncio.run(main())

That's it. Auto-tracking starts immediately — no changes to your handlers required.

You can also provide the API key via the ANYSTAT_API_KEY environment variable and create the client with just Anystat().

What gets tracked

Event Default What it gives you
/start command ✅ on New users and deep-link parameters (t.me/yourbot?start=campaign_x) — track where users come from
Other commands ✅ on Which commands people actually use
Callback queries ✅ on Inline button clicks
Bot blocked / unblocked ✅ on Churn: when users block or return to your bot
Text messages off Full message text — opt-in only, see below

Every event includes the user ID, a timestamp, and how long your handler took to process the update (in ms).

What is NOT collected

  • Message text — unless you explicitly set track_messages=True.
  • User profile data (username, name, language) — profile collection is disabled in this version.
  • Anything else. Don't take our word for it — run with debug=True and watch every byte that leaves your bot.

Custom events

Track anything that matters to your bot with track():

from aiogram import types
from aiogram.filters import Command


@dp.message(Command("buy"))
async def buy_handler(message: types.Message):
    # ... your logic ...
    await anystat.track(
        "purchase",
        user_id=message.from_user.id,
        amount=99,
        currency="USD",
    )

The first argument is the event name, the second is the user ID (or None for system events). Any extra keyword arguments become event properties — pass anything JSON-serializable.

Configuration

Pass options directly:

anystat = Anystat(
    api_key="YOUR_API_KEY",
    track_messages=True,
    debug=True,
)

or group them in a config object:

from anystat import Anystat, AnystatConfig

config = AnystatConfig(track_messages=True, debug=True)
anystat = Anystat(api_key="YOUR_API_KEY", config=config)

Options passed directly to Anystat(...) override the config.

Option Default Description
debug False Log everything the SDK collects and sends (see below)
track_start True Auto-track the /start command and its deep-link parameter
track_command True Auto-track all other commands
track_callback_query True Auto-track inline button clicks
track_messages False Auto-track incoming text messages, including their text

Debug mode: see exactly what leaves your bot

Trust, but verify. With debug=True the SDK logs every event it captures, every event it skips (and why), and the exact payload of every request:

[anystat] endpoint: https://api.anystat.me | api key: any_…7f2c
[anystat] auto-tracking: /start=on commands=on callbacks=on messages=off
[anystat] message text is NOT collected (track_messages=off)
[anystat] capture start_command via AnystatMiddleware:
{
  "event_type": "start_command",
  "user_id": 12345,
  "received_at": 1767225600,
  "duration": 12,
  "message_id": 42,
  "start_param": "campaign_x"
}
[anystat] skip message from user=12345 (track_messages=off, text not collected)
[anystat] → POST /v1/collect/events (2 events)
[anystat] ← 200 in 143 ms

Debug output goes through the standard logging module under the "anystat" logger. If you've already configured logging in your app, Anystat respects your handlers and formatting; otherwise it sets up a minimal [anystat] console handler for you.

Reliability

Analytics should never be the reason your bot breaks:

  • Batching. Events are buffered in memory and sent in batches (up to 30 events or every 60 seconds), not one HTTP request per update.
  • Retries. Network errors and retryable status codes (429, 5xx, …) are retried with exponential backoff and jitter.
  • Non-blocking. Tracking runs after your handler finishes, so it never delays replies to users.
  • Fail-safe. If the Anystat API is unreachable after retries, events are dropped with a warning in the logs — your bot keeps running.

Call await anystat.close() on shutdown (or register it as shown in the quickstart) to flush any buffered events before the process exits.

Requirements

  • Python 3.12+
  • aiogram >= 3.28

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

anystat-0.1.0.tar.gz (10.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

anystat-0.1.0-py3-none-any.whl (15.3 kB view details)

Uploaded Python 3

File details

Details for the file anystat-0.1.0.tar.gz.

File metadata

  • Download URL: anystat-0.1.0.tar.gz
  • Upload date:
  • Size: 10.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for anystat-0.1.0.tar.gz
Algorithm Hash digest
SHA256 28d374490aa35d1cba656d026d1cb49cf15626ce818918191703a2b769dc75e8
MD5 88640fae45f5904b59efe009519fd0b0
BLAKE2b-256 bf1bf822b1fb0d7d4bc8216616a8ed02db9b7ac69ad18550e1442bb8bc1dc628

See more details on using hashes here.

File details

Details for the file anystat-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: anystat-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for anystat-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1e0fa7ed8f32af3cf98df7791a58bb6a09cf2fcf542ac29be9232e3eee46d988
MD5 ed40c059fcd1eec00e47827ae4a584fc
BLAKE2b-256 506c98c7e1da0f7953cf7ab5fe9084ae1f6bff4117942e8aa70e4b26a9ab2578

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page