56 lines
1.7 KiB
Python
Executable File
56 lines
1.7 KiB
Python
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 = requests.post(url, json=payload)
|
|
if r.status_code != 200:
|
|
logger.warning(f"status: {r.status_code}, response: {r.text}")
|
|
|
|
|
|
class WebhookHandler:
|
|
def __init__(self, *args, **kwargs):
|
|
logger.info("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):
|
|
envelope.rcpt_tos.append(address)
|
|
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])
|
|
matrix_msg(msg)
|
|
logger.success(f"from: {msg_from}, to: {msg_to}")
|
|
|
|
print('End of message')
|
|
return '250 Message accepted for delivery'
|