# A tiny SMTP server for Omnara's API that hands each message to exe.dev's # email gateway (https://exe.dev/docs/send-email). It listens on # 127.0.0.1:2525 inside the api container's network only. import json, socketserver, sys, urllib.request from email import message_from_bytes, policy GATEWAY = "http://169.254.169.254/gateway/email/send" def send(rcpts, data): msg = message_from_bytes(data, policy=policy.default) part = msg.get_body(("plain",)) body = part.get_content() if part else "" for to in rcpts: req = urllib.request.Request(GATEWAY, method="POST", headers={"Content-Type": "application/json"}, data=json.dumps({"to": to, "subject": str(msg["subject"] or ""), "body": body}).encode()) try: with urllib.request.urlopen(req, timeout=20) as r: print("sent", repr(msg["subject"]), "to", to, flush=True) except urllib.error.HTTPError as e: err = e.read().decode(errors="replace")[:300] print("exe.dev refused mail to", to, ":", err, "\n--- message ---\n" + body + "\n---", flush=True) return "550 exe.dev refused: " + " ".join(err.split()) return "250 sent" class SMTP(socketserver.StreamRequestHandler): def reply(self, line): self.wfile.write(line.encode() + b"\r\n") def handle(self): self.reply("220 exe-mail ESMTP") rcpts = [] while line := self.rfile.readline(65536): cmd = line.decode(errors="replace").strip() verb = cmd[:4].upper() if verb in ("EHLO", "HELO"): self.reply("250 exe-mail") elif verb == "MAIL": rcpts = [] self.reply("250 ok") elif verb == "RCPT": rcpts.append(cmd.split(":", 1)[1].strip().strip("<>").split(">")[0]) self.reply("250 ok") elif verb == "DATA": self.reply("354 end with .") lines = [] while (l := self.rfile.readline(1 << 20)) not in (b".\r\n", b".\n", b""): lines.append(l[1:] if l.startswith(b".") else l) self.reply(send(rcpts, b"".join(lines))) rcpts = [] elif verb == "QUIT": self.reply("221 bye") return elif verb in ("RSET", "NOOP"): self.reply("250 ok") else: self.reply("502 not implemented") socketserver.ThreadingTCPServer.allow_reuse_address = True with socketserver.ThreadingTCPServer(("127.0.0.1", 2525), SMTP) as server: print("exe-mail listening on 127.0.0.1:2525", flush=True) server.serve_forever()