#!/usr/bin/env python3 """ SMTP webhook server """ import os import json import smtplib import sys import time from email.header import Header from email.mime.text import MIMEText import cherrypy import logging logging.basicConfig(filename='app.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s') class SMTPWebhookApp: """ SMTP webhook server """ def _send_mail(self): if not cherrypy.request.headers.get('Content-Length'): logging.error("To: {}, error: Invalid content length.".format( TO_MAIL)) return {"status": 400, "message": "Invalid content length."} cl = cherrypy.request.headers['Content-Length'] rawbody = cherrypy.request.body.read(int(cl)) req_body = json.loads(rawbody) if not req_body.get('subject') or req_body.get('subject') == '': logging.error("To: {}, error: body field is required.".format( TO_MAIL)) return {"status": 400, "message": "subject field is required."} if not req_body.get('body') or req_body.get('body') == '': logging.error("To: {}, error: body field is required.".format( TO_MAIL)) return {"status": 400, "message": "body field is required."} subject = req_body['subject'] body = req_body['body'] try: client = smtplib.SMTP(host=SMTP_SERVER_HOST, port=SMTP_SERVER_PORT) except Exception as e: time.sleep(0.2) logging.error("To: {}, error: {}".format(TO_MAIL, e)) return {"status": 400, "message": "SMTP client error: {}.".format( e)} msg = MIMEText(body, 'plain', 'utf-8') msg['Subject'] = Header(subject, 'utf-8') msg['From'] = FROM_MAIL msg['To'] = TO_MAIL try: client.ehlo() client.starttls() client.ehlo() client.login(msg["From"], FROM_MAIL_PASSWORD) client.sendmail(msg['From'], msg['To'], msg.as_string()) response = {"status": 200, "message": "mail sent successfully"} logging.info("To: {}, mail sent successfully".format(TO_MAIL)) except smtplib.SMTPException as e: time.sleep(0.2) logging.error("To: {}, error: {}".format(TO_MAIL, e)) response = {"status": 500, "message": "some error: {}".format(e)} finally: client.quit() return response @cherrypy.expose def send_mail(self): """ api endpoint for send mail """ data = self._send_mail() cherrypy.response.status = data["status"] cherrypy.response.headers["Content-Type"] = "application/json" return json.dumps(data["status"]).encode() ROOT = SMTPWebhookApp() SMTP_SERVER_PORT = 587 CHERRYPY_SERVER_HOST = "0.0.0.0" CHERRYPY_SERVER_PORT = 8081 if __name__ == "__main__": try: SMTP_SERVER_HOST = os.environ["SMTP_SERVER_HOST"] TO_MAIL = os.environ["TO_MAIL"] FROM_MAIL = os.environ["FROM_MAIL"] FROM_MAIL_PASSWORD = os.environ["FROM_MAIL_PASSWORD"] except KeyError: raise KeyError("Please check missing environment variables: " "SMTP_SERVER_HOST, TO_MAIL, FROM_MAIL, " "FROM_MAIL_PASSWORD") cherrypy.server.socket_host = CHERRYPY_SERVER_HOST cherrypy.server.socket_port = CHERRYPY_SERVER_PORT ENGINE = cherrypy.engine cherrypy.tree.mount(ROOT, config={}) try: ENGINE.start() except Exception: # pylint: disable=broad-except sys.exit(1) else: ENGINE.block()