#!/usr/bin/env python3 """ Mailpit → Gotify bridge webhook. Receives POSTs from Mailpit (MP_WEBHOOK_URL) when new mail arrives. Fetches the full message from the Mailpit API, extracts useful info, and forwards a summary to Gotify. """ import logging import os import json from typing import Any, Dict import requests from dotenv import load_dotenv from flask import Flask, jsonify, request # ------------------------------------------------------------------ # # Config & logging # ------------------------------------------------------------------ # load_dotenv() MAILPIT_API = os.getenv("MAILPIT_API", "http://localhost:8025") MAILPIT_TOKEN = os.getenv("MAILPIT_TOKEN", "") GOTIFY_URL = os.getenv("GOTIFY_URL","") GOTIFY_TOKEN = os.getenv("GOTIFY_TOKEN","") LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper() logging.basicConfig( level=getattr(logging, LOG_LEVEL, logging.INFO), format="%(asctime)s [%(levelname)s] %(message)s", ) log = logging.getLogger("mailpit-hook") app = Flask(__name__) from utils.gotify_api import GotifyNotifier # ------------------------------------------------------------------ # # Helpers # ------------------------------------------------------------------ # def get_mailpit_message(message_id: str) -> Dict[str, Any]: """Retrieve full message JSON from Mailpit REST API.""" url = f"{MAILPIT_API}/api/v1/message/{message_id}" headers = {} if MAILPIT_TOKEN: headers["Authorization"] = f"Bearer {MAILPIT_TOKEN}" resp = requests.get(url, headers=headers, timeout=10) resp.raise_for_status() return resp.json() def send_gotify(title: str, message: str, priority: int = 5) -> None: """Send a message to Gotify.""" notify = GotifyNotifier(GOTIFY_URL, GOTIFY_TOKEN) result = notify.gotify(title=title,markdown=message,priority=5) if not result: log.warning("Gotify push failed") else: log.info("Gotify push OK") # ------------------------------------------------------------------ # # Webhook route # ------------------------------------------------------------------ # @app.route("/hook", methods=["POST"]) def hook(): """ Mailpit sends JSON like: { "ID": "abcdef123", "MessageID": "<...>", "From": "camera@reolink.local", "Subject": "Motion Detected", ... } """ data = request.get_json(silent=True) or {} mail_msg_id = data.get("MessageID") msg_id = data.get("ID") if not msg_id: log.warning("Webhook received malformed payload: %s", data) return jsonify({"error": "missing ID"}), 400 log.info(f"Webhook triggered for message ID={msg_id} - Email MSG_ID={mail_msg_id}") result = handle_hook(msg_id) if result: return jsonify({"status": "ok"}), 200 else: return jsonify({"error":"Error sending webhook"}), 500 def handle_hook(msg_id:str): try: msg = get_mailpit_message(msg_id) subject = msg.get("Subject", "(no subject)") text = msg.get("Text", "") or msg.get("HTML", "") preview = (text or "") if len(preview) > 200: preview = preview[:200] + "..." send_gotify(subject, preview) return True except Exception as e: log.exception("Error processing webhook: %s", e) return False # ------------------------------------------------------------------ # # Entry point # ------------------------------------------------------------------ # if __name__ == "__main__": # msg_id = "ZTUUK57e7kUoaviua6TCgP@mailpit" # msg = get_mailpit_message(msg_id) app.run(host="0.0.0.0", port=8088)