56 lines
1.7 KiB
Executable File

import os
from email.parser import Parser
from email.policy import default
from aiosmtpd.controller import Controller
import requests
from loguru import logger
def matrix_msg(msg, room=None, prefix=None):
url = os.environ['MATRIX_WEBHOOK_URL']
if room is None:
room = os.environ['MATRIX_WEBHOOK_ROOM']
payload = {
'token': os.environ['MATRIX_WEBHOOK_TOKEN'],
'text': msg,
'room': room,
'prefix': prefix
r =, json=payload)
if r.status_code != 200:
logger.warning(f"status: {r.status_code}, response: {r.text}")
class WebhookHandler:
def __init__(self, *args, **kwargs):"started the smtpd webhook bridge")
matrix_msg('ready', prefix="matrix-smtp-webhook")
return super().__init__(*args, **kwargs)
async def handle_RCPT(self, server, session, envelope, address, rcpt_options):
return '250 OK'
async def handle_DATA(self, server, session, envelope):
p = Parser(policy=default).parsestr(
envelope.content.decode('utf8', errors='replace'))
content = p.get_body(preferencelist="plain").get_content()
body = "\n".join([f" {a.strip()}" for a in content.splitlines()])
msg_from = envelope.mail_from
msg_to = ", ".join(envelope.rcpt_tos)
headers = "<br>".join([
f"**From**: `{msg_from}`",
f"**To**: `{msg_to}`",
f"**Subject**: `{p.get('subject', '')}`"
msg = "\n\n".join([headers, body])
logger.success(f"from: {msg_from}, to: {msg_to}")
print('End of message')
return '250 Message accepted for delivery'