#!/usr/bin/env python3 """ AgenticBoxes — IoT/MQTT event subscriber (drop-in helper). Don't want to write MQTT plumbing? Use this. It subscribes to your account's event topic over mutual-TLS and prints each event as JSON. Replace handle() with your own logic (wake your agent, enqueue work, etc.). Read it before you run it — it's ~70 lines of plain Python (stdlib + paho-mqtt), no obfuscation. It uses your certificate + private key ONLY to open the TLS connection to AgenticBoxes' own MQTT endpoint; nothing is sent anywhere else, and the temp credential files are deleted on exit. No `curl | bash` — save it, read it, run it. Copy and adapt it, or just use it as a reference for your own. Setup ----- 1. Provision your IoT credentials (needs an admin-scoped key): curl -s -X POST https://api.agenticboxes.email/api/v1/account/iot/provision \ -H "Authorization: Bearer $YOUR_ADMIN_KEY" > iot.json (The private key in the response is shown ONCE — iot.json is your only copy.) 2. pip install paho-mqtt 3. python iot_subscribe.py iot.json Events arrive the instant the platform emits them — mail.received, support.*, domain.ready, platform.updated, and more. No public endpoint, no polling. """ import json import os import ssl import sys import tempfile import urllib.request import paho.mqtt.client as mqtt def handle(event): """Your logic goes here. event = {"type": "...", "payload": {...}, "ts": "..."}""" print(json.dumps(event), flush=True) def _tmp(text, suffix): f = tempfile.NamedTemporaryFile("w", suffix=suffix, delete=False) f.write(text) f.close() return f.name def main(creds_path): c = json.load(open(creds_path)) cert = _tmp(c["certificate_pem"], ".pem") key = _tmp(c["private_key"], ".key") ca = _tmp(urllib.request.urlopen(c["root_ca_url"]).read().decode(), ".pem") cli = mqtt.Client(client_id=c["client_id"]) cli.tls_set(ca_certs=ca, certfile=cert, keyfile=key, tls_version=ssl.PROTOCOL_TLSv1_2) cli.on_connect = lambda cl, u, f, rc: ( print(f"connected rc={rc}, subscribing {c['topic']}", flush=True), cl.subscribe(c["topic"], qos=1), ) cli.on_message = lambda cl, u, m: handle(json.loads(m.payload.decode())) cli.reconnect_delay_set(min_delay=1, max_delay=60) cli.connect(c["iot_endpoint"], int(c.get("port", 8883)), keepalive=60) try: cli.loop_forever() # blocks; auto-reconnects finally: for p in (cert, key, ca): try: os.unlink(p) except OSError: pass if __name__ == "__main__": main(sys.argv[1] if len(sys.argv) > 1 else "iot.json")