Send groups of files to a custom distribution - israel-dryer/Outlook-Python-Tutorial GitHub Wiki

In this example, I have a csv file with a list of recipients. As you can see, the list of files is unique, so I need to find a way to group the files by name and email so that I can have a single email per person with all of the relevant files attached:

Name Email File
John Cleese [email protected] file_1.csv
John Cleese [email protected] file_2.csv
John Cleese [email protected] file_3.csv
Stephen Fry [email protected] file_4.csv
Jack Whitehall [email protected] file_5.csv
Jack Whitehall [email protected] file_6.csv

Like anything in python, there are a bunch of different ways to achieve this goal, such as using the itertools.groupby function. However, I have found that the easiest to use and understand method is as follows:

import os
import csv
import win32com.client as client

# open the distro list [(Name, Email, FileName)]
with open('distro.csv', newline='') as f:
    reader = csv.reader(f)
    distro = list(reader)

# group the distibuton by name and email
grouped = {}
for name, email, file in distro:
    if (name, email) not in grouped:
        # a tuple can be used as a dictionary key because it's immutable
        grouped[(name, email)] = [file]
    else:
        grouped[(name, email)].append(file)

# start an instance of outlook
outlook = client.Dispatch('Outlook.Application')

for (name, email), files in grouped.items():
    message = outlook.CreateItem(0)
    message.To = email
    message.Body = "Hello, " + name + ". Please see the attached files."
    
    # assuming files are in my current working directory
    for file in files:
        filepath = os.getcwd() + r'\\' + file
        message.Attachments.Add(filepath)
        print(filepath)

    # save or send the email
    message.Save()

The end result of this exercise is 3 unique email with the relevant files attached for each recipient.