---
name: telegram-notify-python-cron
description: Send Telegram notifications from cron jobs using Python's stdlib (no curl/wget/Node.js required). Reads bot token from /proc/1/environ.
version: 1.0.0
---

# Send Telegram Notifications from Python (Restricted Cron Environment)

## When to use
You need to send a Telegram message from a cron job or restricted shell environment where `curl`, `wget`, and potentially `node` are **not** installed. Only Python3 with stdlib is available. The bot token is set as an environment variable at system level (not as a regular shell env var).

## Steps

### 1. Read the bot token
In cron environments, the bot token may not be in the shell's environment variables. Read it from `/proc/1/environ` (the init process environment):

```python
import urllib.request
import json

def get_bot_token():
    with open('/proc/1/environ', 'rb') as f:
        data = f.read().decode('utf-8', errors='replace')
    for line in data.split('\0'):
        if 'TELEGRAM_BOT_TOKEN' in line:
            return line.split('=', 1)[1]
    raise ValueError('TELEGRAM_BOT_TOKEN not found in /proc/1/environ')
```

### 2. Send a message
Use Python's built-in `urllib.request` (no external dependencies):

```python
def send_telegram(message, chat_id='5838842946', parse_mode='HTML'):
    token = get_bot_token()
    url = f'https://api.telegram.org/bot{token}/sendMessage'
    payload = json.dumps({
        'chat_id': chat_id,
        'text': message,
        'parse_mode': parse_mode
    }).encode()
    req = urllib.request.Request(url, data=payload, headers={'Content-Type': 'application/json'})
    resp = urllib.request.urlopen(req)
    result = json.loads(resp.read().decode())
    if not result.get('ok'):
        raise RuntimeError(f"Telegram API error: {result}")
    return result
```

### 3. Usage example
```python
send_telegram('✅ Deploy complete: https://example.com')
send_telegram(
    '❌ Script failed:\n<code>Exit code 1\nFile not found</code>',
    parse_mode='HTML'
)
```

## Complete one-liner (for embedding in scripts)
```python
import urllib.request, json
token = [l.split('=',1)[1] for l in open('/proc/1/environ','rb').read().decode('utf-8',errors='replace').split('\0') if 'TELEGRAM_BOT_TOKEN' in l][0]
data = json.dumps({'chat_id':'5838842946','text':'📰 Update done','parse_mode':'HTML'}).encode()
urllib.request.urlopen(urllib.request.Request(f'https://api.telegram.org/bot{token}/sendMessage', data=data, headers={'Content-Type':'application/json'}))
```

## Pitfalls
- **/proc/1/environ only works on Linux** — not on macOS or Windows. For those, use a regular env var or .env file.
- **No curl/wget**: don't try `curl` or `wget` — they're unlikely to be installed in minimal cron containers. Python `urllib.request` is always available.
- **Parse mode**: `HTML` mode supports `<b>`, `<i>`, `<code>`, `<pre>`, `<a href>`. Use `parse_mode='MarkdownV2'` for markdown (but escape special chars!).
- **Message length**: Telegram limits to 4096 characters. Longer messages get silently truncated.
- **Token storage**: If TELEGRAM_BOT_TOKEN is in a .env file instead of /proc/1/environ, use: `python3 -c "import dotenv; dotenv.load_dotenv(); import os; print(os.environ['TELEGRAM_BOT_TOKEN'])"`
- **Rate limits**: Telegram allows ~30 msg/s per chat — irrelevant for single notifications.

## Verification
Successful send returns: `{"ok": true, "result": {"message_id": N, ...}}`
