# Telegram Alerts (/scripting-v2/alerts)



## Connect Telegram [#connect-telegram]

Create a bot with [BotFather](https://t.me/BotFather), then run:

```bash
mlab alert setup
```

Enter the bot token in the hidden prompt. Open the displayed Telegram link or send the one-time code to your bot in the Telegram app. The CLI finds your DM, sends a test, and asks whether you received it before saving. No chat ID lookup or browser login is needed.

For a group or an existing chat ID:

```bash
mlab alert setup --chat-id -100123456789
```

```bash
mlab alert status
mlab alert test
mlab alert remove
```

Setup requires an interactive terminal on the host running your daemon. For a remote host, connect over SSH and run `mlab --remote local alert setup` there.

## Example Alert [#example-alert]

```python
script = {
    "name": "btc-price-crossing", "version": "2", "lookback": 2,
    "params": {
        "price": {"type": "number", "required": True},
        "cooldown_seconds": {"type": "number", "default": 60},
    },
}
previous = None


def on_data(ctx, history):
    global previous

    trade = history.source("btc@trades@bulkf", 0)
    if trade is None:
        return

    price = trade["price"]
    threshold = ctx.params["price"]

    crossed = previous is not None and previous < threshold <= price
    previous = price

    if crossed:
        return {"metrics": {"alert": ctx.alert({
            "source": "telegram", "key": "btc-price-crossing",
            "message": f"Bulk BTC crossed ${threshold:,.2f}. Last: ${price:,.2f}",
            "cooldown_seconds": int(ctx.params["cooldown_seconds"]),
        })["status"]}}

```

```bash
mlab script run btc-alert.py --param price=86400 --duration 30
```

The script runs as a daemon job after the command returns; the terminal or browser does not need to stay open.

```bash
mlab script logs <job-id> --follow
mlab script stop <job-id>
```

| Input              | Rules                                     |
| ------------------ | ----------------------------------------- |
| `source`           | `"telegram"` only.                        |
| `key`              | Required stable identifier, 1-128 bytes.  |
| `message`          | Required plain text, 1-4,096 UTF-8 bytes. |
| `cooldown_seconds` | 1-86,400; default 60.                     |

`ctx.alert` returns `{"status": "buffered", "key": "..."}`. Buffering is not delivery confirmation. Run history records `script.alert.submission` (queued, suppressed or rejected) and `script.alert.result` (delivered or failed). Analysis and backtests return `simulated` and never contact Telegram. Alerts cannot be submitted from `on_finish`.

Attempt cooldowns are per job/key and survive daemon restarts. A new job ID starts a separate cooldown. Accepted requests are limited to one per second, eight per hook and a 64-message queue. Failed or uncertain sends are not retried automatically; restarting the daemon drops any unsent queue.
