Small Python script that watches a Google Sheet and posts alerts to a Telegram group when items expire.
What it does
- Reads worksheet
Currentfrom a Google Sheet (rangeA1:I). - Expects these headers at minimum:
Appeal Number,End time,Status,URLs. - Filters rows where:
URLsis not empty, andEnd timeis not empty, andStatusis NOT one ofDoneorCompleted by others.
- If a row’s
End timeis within the last 5 minutes, sends a Telegram message:- Message format:
Appeal no: <Appeal Number>\nExpired at: <End time>
- Message format:
Important date/time details
End timemust be a string in the exact format%m/%d/%Y %H:%M:%S(e.g.,10/15/2025 17:00:00).- The script uses the machine’s local time for “now”; ensure your server timezone matches the sheet’s interpretation.
- Because the window is “expired within the last 5 minutes,” if you run this every minute, a single row will be sent multiple times during that 5-minute window. Adjust logic if you need strict one-time delivery.
Prerequisites
- Python 3.10+ recommended.
- A Google Cloud Service Account with the Google Sheets API enabled.
- Share the target Google Sheet with the service account email so it can read the sheet.
- A Telegram Bot API token from @BotFather.
- The numeric chat ID of your Telegram group (e.g., from bots like @RawDataBot or @userinfobot).
Project layout
main.py— core script; reads the sheet and sends messages.requirements.txt— Python dependencies.Secrets/— ignored by git; holds your localsecrets.jsonand any logs.
Setup
- Create and activate a virtual environment
python3 -m venv .venv
source .venv/bin/activate- Install dependencies
pip install -r requirements.txt- Create
Secrets/secrets.json
Place a file at Secrets/secrets.json with this structure (placeholders shown):
{
"GOOGLE_SHEETS_CREDENTIALS": "<the entire service-account JSON, as a single JSON-escaped string>",
"GOOGLE_SHEETS_ID": "<your_google_sheet_id>",
"TELEGRAM_BOT_TOKEN": "<your_telegram_bot_token>",
"TELEGRAM_GROUP_CHAT_ID": "<your_group_chat_id>"
}Notes on credentials
GOOGLE_SHEETS_CREDENTIALSis the full Service Account key JSON embedded as a string.- One way to produce the JSON-escaped string from a file
sa.jsonis:-
macOS/Linux (zsh):
python -c 'import json,sys; print(json.dumps(open("sa.json").read()))' -
Then paste the output into
GOOGLE_SHEETS_CREDENTIALS.
-
- One way to produce the JSON-escaped string from a file
GOOGLE_SHEETS_IDis the ID portion of the sheet URL:https://docs.google.com/spreadsheets/d/<THIS_PART>/edit.
Run it
python main.pyIf there are rows that expired within the last 5 minutes (and match the filters), the script will send a message to your Telegram group.
Scheduling (optional)
- To run every minute via cron:
* * * * * cd /path/to/alert-bot && . .venv/bin/activate && python main.py >> Secrets/output.log 2>&1- On macOS, you can also use launchd or a process supervisor (pm2, supervisord, systemd on Linux, etc.).
Customizing
- Sheet name/range: edit
SHEET_NAMEandSHEET_RANGEconstants inmain.py. - Filter logic: update the pandas filtering section in
main.pyto match your rules. - Message format: change the construction of the
Messagecolumn inmain.py.
Troubleshooting
- Google auth errors: ensure the service account has access to the sheet and that
GOOGLE_SHEETS_CREDENTIALSis valid JSON (as a JSON string). - Sheet not found: verify
GOOGLE_SHEETS_IDand that the sheet is shared with the service account email. - Telegram errors: double-check
TELEGRAM_BOT_TOKENandTELEGRAM_GROUP_CHAT_ID. - No messages: confirm the row actually meets all filters and that
End timeis in the expected format and window. - Duplicate messages: expected if the job runs multiple times within the 5-minute window; adjust logic if undesired.
Security
Secrets/is git-ignored; keep your keys here and never commit them.- Rotate tokens/keys if exposed.
License
- This project is licensed under the GPL-3.0 (see
LICENSE).