#!/usr/bin/env python3 """g9-notify.py — poste le payload JSON (base64 dans REGISTRY_B64) dans le salon ops. Installé sur le G9 (/usr/local/bin/g9-notify.py). Lit /etc/restic/matrix.env (600 root). N'affiche JAMAIS le token. Pattern = restic-notify.sh (Bearer + room URL-encodé + PUT + txnId). """ import base64 import json import os import time import urllib.parse import urllib.request ENV_PATH = "/etc/restic/matrix.env" def load_env(): env = {} with open(ENV_PATH) as f: for line in f: line = line.strip() if not line or line.startswith("#") or "=" not in line: continue k, v = line.split("=", 1) env[k] = v.strip().strip('"') return env def main(): import sys env = load_env() # sudo ne transmet pas l'environnement (sudoers sans SETENV) : le payload passe # en argument, l'env reste accepté pour les appels cron. raw = sys.argv[1] if len(sys.argv) > 1 else os.environ.get("REGISTRY_B64", "") if not raw: print("NOTIFY_KO no-payload") return try: payload = json.loads(base64.b64decode(raw).decode()) except Exception as e: print("NOTIFY_KO bad-payload", type(e).__name__) return body = {"msgtype": "m.text", "body": json.dumps(payload, ensure_ascii=False)} room = urllib.parse.quote(env["MATRIX_ROOM"], safe="") txn = "openfox-%d" % int(time.time() * 1000) url = f"{env['MATRIX_SERVER']}/_matrix/client/v3/rooms/{room}/send/m.room.message/{txn}" req = urllib.request.Request( url, data=json.dumps(body).encode(), method="PUT", headers={"Authorization": "Bearer " + env["MATRIX_TOKEN"], "Content-Type": "application/json"}) try: with urllib.request.urlopen(req, timeout=10) as r: print("NOTIFY_OK", r.status) except Exception as e: print("NOTIFY_KO", type(e).__name__) if __name__ == "__main__": main()