Skip to content

Instantly share code, notes, and snippets.

@ZenithClown
Last active April 4, 2024 11:34
Show Gist options
  • Save ZenithClown/b57fa50bc77cf47eb5066313f7de57df to your computer and use it in GitHub Desktop.
Save ZenithClown/b57fa50bc77cf47eb5066313f7de57df to your computer and use it in GitHub Desktop.
A set of utility functions for sending emails

Automatic Email Application

Zenith Clown REPO:ADMIN CODE:DOCUMENTATION
send email from python using defined clients
⚠⚠⚠THIS CODE IS NOT FINALIZED, AND IS SUBJECT TO CHANGE⚠⚠⚠


Getting Started

The code is publically available at GitHub gists which is a simple platform for sharing code snippets with the community. To use the code, simply clone the code like:

git clone https://gist.github.com/ZenithClown/b57fa50bc77cf47eb5066313f7de57df.git mailer
export PYTHONPATH="${PYTHONPATH}:mailer"

Done, you can now easily import the function with python notebooks/code-files like:

import mailer

Example File:

Python 3.9.13 | packaged by Anaconda, Inc. | (main, Sep 11 2017, 13:24:38) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import mailer
>>> mail = mailer.OutlookEmail(sender = "john.doe@example.com", receiver = ["john.doe@example.com"], subject = "Hey There!", mailbody = "This is a test email from python application...")
>>> mail.display()
>>> mail.send()
>>>
# -*- encoding: utf-8 -*-
"""
A Set of Custom Functions for Sending EMails
Sending emails from a python application can be done using inbuilt
libraries like `smtplib` or a custom defined library like `email`
which is a wrapper developed on `smtplib`. However, this function
typically focuses on sending email through "outlook" client using
the `WIN32` python library to control the application installed
in a windows machine.
@author: Debmalya Pramanik
@version: v0.0.1
"""
import win32com.client as win32
class EMail(object):
"""
Base Class for for Sending Custom Automated EMails using Python
The base class is used to define basic information which is must
required by all types of libraries and is constant to any
automation platform.
:type sender: str
:param sender: Sender's email address. This should be a valid
address, and additional verification/authentication like AUTH
in GMAIL has to be configured seperately.
:type receiver: list or str
:param receiver: A list of receiver's email address, this should
be sent as an list, and typically an email client accepts
multiple email seperated by comma/semicolon which is done
internally in the base object.
Keyword Arguments
-----------------
* **subject** (*str*): Subject of the email, defaults to
"Email Subject" which is used for testing placeholders.
* **mailbody** (*str*): Mail body, which can be either simple
string, or may also be HTML content which is accepted by
many clients. The `mailbody` uses the testing placeholder
and defaults to "Email Body, Multiple Format Accepted".
* **cc** / **bcc** (*list* or *str*): A list of email address
that is added as cc- or bcc- address, and defaults to None.
"""
def __init__(self, sender : str, receiver : list | str, **kwargs) -> None:
self.sender = sender
self.receiver = self.__get_emails__(receiver)
# in addition, we can also accept cc- end bcc- emails like:
self.cc, self.bcc = map(
self.__get_emails__,
[kwargs.get("cc", ""), kwargs.get("bcc", "")]
)
# set of properties for email document, default value for testing
self.subject = kwargs.get("subject", "Email Subject")
self.mailbody = kwargs.get("mailbody", "Email Body, Multiple Format")
def __get_emails__(self, address : list | str, sep : str = ";") -> str:
"""
EMail Addresses are Parsed from User Input
The email addresses can either be `iterable` (i.e., `list` or `tuple`)
or a single address. In case multiple email address are passed, then
the function internally `.join()` the emails based on the
specified seperators or defaults to `;` which is accepted by most of
the email clients.
"""
retval = None
if isinstance(address, str):
retval = address
elif hasattr(address, "__iter__"):
retval = sep.join(map(str, address))
else:
raise ValueError(f"Email Address: `{address}` is not Valid.")
return retval
class OutlookEmail(EMail):
def __init__(self, sender : str, receiver : list, **kwargs):
super().__init__(sender = sender, receiver = receiver, kwargs = kwargs)
self.mailbody = kwargs.get("mailbody", "Email Body, Multiple Format Accepted")
self.attachments = kwargs.get("attachments", [])
self.client = self.windowsClient()
def windowsClient(self):
olApp = win32.Dispatch('Outlook.Application')
# construct email object with details
mailItem = olApp.CreateItem(0)
mailItem.Subject = self.subject
# construct mail body
mailItem.HTMLBody = self.mailbody
# mail sensitivity and to email address
mailItem.To = self.receiver
# add emails for cc- and bcc- if exists:
if self.cc:
mailItem.CC = self.cc
if self.bcc:
mailItem.BCC = self.bcc
# ? if email contains attachement, then add the file(s)
if self.attachments:
for attachment in self.attachments:
mailItem.Attachments.Add(attachment)
return mailItem
def display(self):
return self.client.Display()
def send(self):
return self.client.Send()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment