You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

56 lines
1.7 KiB

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'