Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

codex-resets

Telegram alerts for Codex subscription quota resets.

codex-resets is a self-hosted Python service that watches Codex subscription limits through the local app-server and sends a GIF to Telegram when an early reset is confirmed. It is Telegram-first by design: deploy it to a VPS, add the bot to a channel or group, and get notified when a quota unexpectedly refreshes.

Unofficial community project. It is not affiliated with OpenAI or Telegram.

Features

  • polls Codex subscription limits on a configurable interval;
  • distinguishes ordinary and manual resets from unexpected early resets;
  • requires two equivalent consecutive observations before sending an alert;
  • sends the alert animation through the Telegram Bot API;
  • stores baseline, candidate, and event state in SQLite to avoid duplicate alerts;
  • optionally accepts /status and /ignore-next-reset Telegram commands;
  • does not use the Platform Admin API, private HTTP endpoints, or OAuth tokens;
  • runs without third-party Python runtime dependencies.

How it works

Codex CLI app-server
        │  account/rateLimits/read
        ▼
Normalize only the required fields
        ▼
SQLite: baseline + candidate + events
        ▼
Reset classifier
        │  confirmed early reset
        ▼
Telegram Bot API → GIF in a channel / group

The service starts codex app-server --stdio as a user with an existing Codex login, reads account/rateLimits/read, and stores only normalized fields. The first poll establishes a baseline and never sends an alert.

When an alert is sent

An early reset is considered confirmed only when all of these conditions hold:

  1. the used percentage drops materially and the remaining percentage rises;
  2. the reset time moves forward;
  3. reset-credit information is available;
  4. two consecutive polls produce the same result.

Ordinary resets, manual resets, unknown states, and unstable candidates are discarded. Primary and secondary windows from one incident are grouped into one notification, and already-sent events are not repeated.

Quick start

Requirements

  • Python 3.11+;
  • Codex CLI with support for app-server --stdio and account/rateLimits/read;
  • an existing Codex login in CODEX_HOME for the user running the service;
  • a Telegram bot created through @BotFather, plus a channel or group where the bot can send animations.

Installation

git clone https://github.com/aachebotok/codex-resets.git
cd codex-resets

python3.11 -m venv .venv
. .venv/bin/activate
python -m pip install --no-deps -e .

cp .env.example .env.private
chmod 600 .env.private

Fill in .env.private. At minimum, set:

CODEX_HOME=/path/to/authenticated/codex-home
TELEGRAM_BOT_TOKEN=123456:replace-me
TELEGRAM_CHAT_ID=@your_channel_or_chat

The secret file is not loaded automatically. Export it before starting the monitor:

set -a
. ./.env.private
set +a

python -m quota_monitor --status
python -m quota_monitor --once

To run continuously:

quota-monitor

Useful commands:

quota-monitor --help
quota-monitor --status
quota-monitor --once
quota-monitor --ignore-next-reset
python -m unittest discover -s tests -v

--ignore-next-reset writes a durable one-shot marker and does not contact Codex. The marker is consumed only by the next material reset observation.

Telegram setup

  1. Create a bot through @BotFather.
  2. Add the bot to the target Telegram channel or group.
  3. Give it permission to send GIFs/animations.
  4. Set TELEGRAM_BOT_TOKEN and the real TELEGRAM_CHAT_ID.
  5. Run quota-monitor --once and check the logs.

TELEGRAM_CHAT_ID=@codexresets in .env.example is only a placeholder. Replace it with your channel username or numeric chat ID.

Telegram commands are disabled by default. To enable them safely:

TELEGRAM_ENABLE_COMMANDS=true
TELEGRAM_ALLOWED_USER_IDS=123456789,987654321
TELEGRAM_UPDATES_TIMEOUT_SECONDS=20

An empty TELEGRAM_ALLOWED_USER_IDS list is fail-closed: channel members cannot mutate service state. Supported commands are /status and /ignore-next-reset.

If TELEGRAM_ANIMATION_PATH is not set, the service uses the bundled GIF and materializes it in the state directory only when an alert is sent. You can provide a private custom GIF:

TELEGRAM_ANIMATION_PATH=/var/lib/quota-monitor/state/my-alert.gif

VPS deployment with systemd

The repository includes an installer and a hardened systemd unit for Linux. The supported layout uses a dedicated quota-monitor user and fixed paths:

Purpose Path
application /opt/quota-monitor
private env file /etc/quota-monitor/quota-monitor.env
Codex login and SQLite state /var/lib/quota-monitor/

Install Python 3.11+, Codex CLI, and a Codex login for the service user first. Then run the installer from the repository root:

sudo ./deploy/install.sh
sudoedit /etc/quota-monitor/quota-monitor.env
sudo systemctl enable --now quota-monitor
sudo systemctl status quota-monitor --no-pager
sudo journalctl -u quota-monitor -n 100 --no-pager

The environment file must be owned by root:quota-monitor with mode 0640:

sudo install -o root -g quota-monitor -m 0640 /dev/null \
  /etc/quota-monitor/quota-monitor.env
sudoedit /etc/quota-monitor/quota-monitor.env
sudo systemctl restart quota-monitor

The installer does not accept secrets as arguments, does not print environment values, and rejects non-default paths. The unit uses ProtectSystem=strict, ProtectHome=read-only, PrivateTmp, a dedicated user, and a restricted writable state directory.

See deploy/README.md for detailed deployment notes.

Security and privacy

  • the Bot token is kept only in a private env file and in process memory while calling Telegram;
  • the Codex auth home remains a separate sensitive credential store;
  • a Platform Admin API key is not used and must not be added to this project;
  • the provider removes API/OAuth/token variables from the child app-server environment;
  • SQLite and logs contain normalized data only, not raw JSON or secrets;
  • Telegram failures are logged only as short, safe error codes.

Never commit .env.private, tokens, SQLite state, or the contents of CODEX_HOME. If a Bot token appears in logs, an issue, or a backup, revoke it through BotFather and issue a new one.

Configuration

The complete template is in .env.example. Main settings:

Variable Purpose Default
CODEX_BIN Codex CLI path codex
CODEX_HOME Codex auth home unset
QUOTA_MONITOR_STATE_DIR SQLite and runtime state ~/.local/state/quota-monitor
QUOTA_MONITOR_POLL_INTERVAL_SECONDS polling interval 60
QUOTA_MONITOR_CONFIRMATION_POLLS polls required for an alert 2
QUOTA_MONITOR_RESET_SKEW_SECONDS ordinary-reset tolerance 300
TELEGRAM_CHAT_ID Telegram channel or group @codexresets placeholder
TELEGRAM_ANIMATION_PATH optional GIF bundled GIF
TELEGRAM_ENABLE_COMMANDS enable Telegram commands false

Limitations

  • the project depends on the local Codex app-server and an existing Codex login;
  • the app-server protocol may change with future Codex CLI versions;
  • the current configuration fixes the timezone to Europe/Moscow;
  • this is not an official Telegram client or a replacement for Platform API monitoring;
  • the test suite does not require network access, Codex CLI, or Telegram.

License

No license has been added yet. Before production use or public forks, choose and add an appropriate license.

About

Telegram alerts for Codex subscription quota resets

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages