feat: add multi-chat routing and bill-specific dashboard countdown
This commit is contained in:
59
README.md
59
README.md
@@ -1,7 +1,8 @@
|
||||
# Daily Blackout Check
|
||||
|
||||
Checks the official SAAPA planned-outage API and sends Persian notifications to
|
||||
an Eitaa chat when an outage is added, changed, cancelled, or restored.
|
||||
the Eitaa chats configured for each bill when an outage is added, changed,
|
||||
cancelled, or restored.
|
||||
|
||||
The checker is designed for an hourly Gitea Actions workflow. Its deduplication
|
||||
state is stored in `state/outages.json` and committed back to this repository.
|
||||
@@ -9,14 +10,16 @@ state is stored in `state/outages.json` and committed back to this repository.
|
||||
## Behavior
|
||||
|
||||
- Queries each configured bill ID from today through five days ahead.
|
||||
- Routes each bill's notifications to all of its configured Eitaa chats.
|
||||
- Uses Tehran time regardless of the runner container's timezone.
|
||||
- Sends all upcoming outages when starting with empty state.
|
||||
- Treats an existing outage number with changed time, address, date, reason, or
|
||||
planned status as an update.
|
||||
- Reports a future outage as cancelled only after two consecutive successful
|
||||
checks omit it.
|
||||
- Records a notification only after Eitaa accepts it. This favors delivery over
|
||||
perfect deduplication: a failed state push can cause a duplicate next hour.
|
||||
- Records a notification only after every configured chat accepts it. This
|
||||
favors delivery over perfect deduplication: if one chat fails, successful
|
||||
destinations may receive a retry on the next run.
|
||||
- Rejects malformed responses and snapshots larger than the configured safety
|
||||
limit without changing that bill's state.
|
||||
|
||||
@@ -50,8 +53,7 @@ python -m blackout_notifier check
|
||||
| --- | --- | --- | --- |
|
||||
| `BARGHEMAN_TOKEN` | Yes | — | SAAPA bearer token |
|
||||
| `EITAAYAR_TOKEN` | Yes | — | EitaaYar bot token |
|
||||
| `CHAT_ID` | Yes | — | Destination Eitaa chat |
|
||||
| `BILL_IDS` | Yes | — | Comma-separated decimal bill IDs |
|
||||
| `BILL_CHAT_MAP` | Yes | — | Comma-separated `BILL_ID:CHAT_ID` routes |
|
||||
| `STATE_FILE` | No | `state/outages.json` | Durable notification state |
|
||||
| `LOOKAHEAD_DAYS` | No | `5` | Query horizon, from 1 to 30 days |
|
||||
| `REQUEST_TIMEOUT_SECONDS` | No | `15` | HTTP timeout, from 1 to 120 seconds |
|
||||
@@ -59,6 +61,18 @@ python -m blackout_notifier check
|
||||
|
||||
Shell and Gitea-provided variables take precedence over `.env`.
|
||||
|
||||
For example, this sends bill `7356609804429` to chats `10251670` and `20873456`,
|
||||
while bill `7619314604429` is sent only to chat `30984567`:
|
||||
|
||||
```dotenv
|
||||
BILL_CHAT_MAP=7356609804429:10251670,7356609804429:20873456,7619314604429:30984567
|
||||
```
|
||||
|
||||
Repeat a bill ID with another chat ID to add destinations; duplicate identical
|
||||
routes are ignored. The old `CHAT_ID` plus `BILL_IDS` configuration is still
|
||||
accepted when `BILL_CHAT_MAP` is absent, but it sends every bill to the same chat
|
||||
and is intended only for backward compatibility.
|
||||
|
||||
## Gitea deployment
|
||||
|
||||
This repository targets Gitea 1.25.x and a Docker-based runner advertising the
|
||||
@@ -91,8 +105,7 @@ set to **Read and Write**. Add these repository Actions secrets:
|
||||
| `REGISTRY_TOKEN` | Personal access token with package Read and Write permission |
|
||||
| `BARGHEMAN_TOKEN` | SAAPA bearer token |
|
||||
| `EITAAYAR_TOKEN` | EitaaYar bot token |
|
||||
| `CHAT_ID` | Destination chat ID |
|
||||
| `BILL_IDS` | Comma-separated bill IDs |
|
||||
| `BILL_CHAT_MAP` | Comma-separated `BILL_ID:CHAT_ID` routes |
|
||||
|
||||
The registry token is used to publish the image and as `container.credentials`
|
||||
when Gitea Runner pulls the private image before starting a job.
|
||||
@@ -183,6 +196,16 @@ It requires Bash, `curl`, `jq`, and GNU `date`:
|
||||
./main.sh
|
||||
```
|
||||
|
||||
On macOS, install the modern Bash and GNU `date` implementations with Homebrew:
|
||||
|
||||
```sh
|
||||
brew install bash coreutils
|
||||
```
|
||||
|
||||
`main.sh` automatically switches from Apple's Bash 3.2 to Homebrew Bash and
|
||||
adds Homebrew's GNU utilities to `PATH`, so both `./main.sh` and
|
||||
`bash ./main.sh` work after installation.
|
||||
|
||||
The display uses a flicker-free alternate terminal screen and runs until `q` is
|
||||
pressed (or it is interrupted with `Ctrl+C`). It updates the countdown every
|
||||
second and refetches the committed state every 10 minutes. Set a different whole
|
||||
@@ -192,12 +215,22 @@ minute interval with `-i`/`--interval`:
|
||||
./main.sh --interval 5
|
||||
```
|
||||
|
||||
The dashboard uses Tehran time to show a large `HH : mm : ss` countdown for the outage
|
||||
currently in progress or the nearest upcoming outage. A compact schedule below it
|
||||
lists all active current and future events, including emergency outages. The
|
||||
terminal output uses English-only labels and omits the stored address and reason
|
||||
text. When there are no qualifying events it prints an `ALL CLEAR` screen and exits
|
||||
successfully.
|
||||
Select one bill for the large countdown with `-b`/`--bill-id`:
|
||||
|
||||
```sh
|
||||
./main.sh --bill-id 7356609804429
|
||||
```
|
||||
|
||||
The dashboard uses Tehran time to show a large `HH : mm : ss` countdown for the
|
||||
selected bill's ongoing or nearest upcoming outage. The compact schedule below
|
||||
continues to list active current and future events for every bill, including
|
||||
emergency outages. If the selected bill has no qualifying outage, the countdown
|
||||
area says so while the full schedule remains visible. Without `--bill-id`, the
|
||||
countdown retains the original behavior and selects across all bills.
|
||||
|
||||
The terminal output uses English-only labels and omits the stored address and
|
||||
reason text. When there are no qualifying events for any bill it prints an `ALL
|
||||
CLEAR` screen and exits successfully.
|
||||
|
||||
Colors are enabled only when output is attached to a terminal. Set `NO_COLOR` to
|
||||
disable them explicitly, or set `COLUMNS` to control the rendered width:
|
||||
|
||||
Reference in New Issue
Block a user