Mail automation is a python script and is usually called “Mail Merge Generator” but I like mail automation more, so that’s what I’m gonna call it for my article.
This article is very beginner friendly and what we’re gonna do is to get our letter template and replace [name]
with each names and create a new mail for each names.
This is our directory, folders and starting files that we’re gonna be working with for this article.
/Main_Folder/
├── main.py <-- we are here
├── Input
│ ├── Letters
│ │ └── letter_template.txt <-- we need to get this file
│ └── Names
│ └── invited_names.txt <-- and this file
└── Output
- Open
letter_template.txt
andinvited_names.txt
- Read the files
- Loop through names from the
invited_names.txt
file
a. Get the content
b. Replace[name]
withname
c. Write the output for each letter
1. Opening Files:
├── main.py <-- we are here
├── Input
│ ├── Letters
│ │ └── letter_template.txt <-- we need to get this file
│ └── Names
│ └── invited_names.txt <-- and this file
└── Output
# opening the letter_template file
with open("Input/Letters/letter_template.txt") as letter_file:
# opening the names file
with open("Input/Names/invited_names.txt") as name_file:
2. Reading files:
- Starting with the
letter_template
file.
We know that for reading the file we use the read()
method.
with open("Input/Letters/letter_template.txt") as letter_file:
letter_content = letter_file.read()
- And now for the names file:
We can’t use theread()
method for names because it returns a big string and we don’t want that.
What we need is alist
of names so that we can loop through.
So instead of theread()
method, we need to usereadlines()
method:
with open("Input/Names/invited_names.txt") as name_file:
names = name_file.readlines()
And if you print out the names
, the result would be :
with open("Input/Names/invited_names.txt") as name_file:
names = name_file.readlines()
print(names)
# ['Alice\n', 'Bob\n', 'Charlie\n', 'Diana\n', 'Ethan\n', 'Fiona\n', 'Greg\n', 'Hannah\n']
Before we go the next step and loop through names, let’s create a constant
for [name]
at the top of main.py
:
PLACEHOLDER = "[name]"
3. Looping through names:
Basically what we need to do here is to get the letter content, and replace the PLACEHOLDER ([name])
by each names:
with open("Input/Names/invited_names.txt") as name_file:
names = name_file.readlines()
for name in names:
new_letter = letter_content.replace(PLACEHOLDER, name)
Now if you print out the new_letter
the result might look a bit weird:
Hello Fiona
,
We're writing to formally invite you to our annual end-of-year celebration.
Hello Ethan
,
We're writing to formally invite you to our annual end-of-year celebration.
You see? the line breaks after each name and that’s because of the readlines()
method
# ['Alice\n', 'Bob\n', 'Charlie\n', 'Diana\n', 'Ethan\n', 'Fiona\n', 'Greg\n', 'Hannah\n']
As you can see, there’s line break after each name, \n
and we need to get rid of that with the strip()
method, meaning we need to clean the words first:
cleaned_word = name.strip()
with open("Input/Names/invited_names.txt") as name_file:
names = name_file.readlines()
for name in names:
cleaned_name = name.strip()
new_letter = letter_content.replace(PLACEHOLDER, cleaned_name)
4.
The last and final step is to print out a new separate letter for each names:
Inside our for loop, we need to go to the Output
folder and write the new letter there.
├── main.py
├── Input
│ ├── Letters
│ │ └── letter_template.txt
│ └── Names
│ └── invited_names.txt
└── Output <-- we need to create the new letters inside this folder
In order to write in a file, we need to switch to the w
(write) mode:
with open(f"Output/ReadyToSend/letter_for_{cleaned_name}.txt", "w") as output:
output.write(new_letter)
Now if you run your code, you’ll have some new letters for each names in the Output
folder
├── main.py
├── Input
│ ├── Letters
│ │ └── letter_template.txt
│ └── Names
│ └── invited_names.txt
├── Output
├── ReadyToSend
└── letter_for_Alice.txt
└── letter_for_Bob.txt
└── letter_for_Charlie.txt
└── and so on
Here’s the whole code snippet:
PLACEHOLDER = "[name]"
with open("Input/Letters/letter_template.txt") as letter_file:
letter_content = letter_file.read()
with open("Input/Names/invited_names.txt") as name_file:
names = name_file.readlines()
for name in names:
cleaned_name = name.strip()
new_letter = letter_content.replace(PLACEHOLDER, cleaned_name)
with open(f"Output/ReadyToSend/letter_for_{cleaned_name}.txt", "w") as output:
output.write(new_letter)
Note:
We can also combine the reading step like this:
# Combine reading of both files into a single block
with open("Input/Letters/letter_template.txt") as letter_file, \
open("Input/Names/invited_names.txt") as name_file:
letter_content = letter_file.read()
names = name_file.readlines()
with open("Input/Letters/letter_template.txt") as letter_file, \
open("Input/Names/invited_names.txt") as name_file:
letter_content = letter_file.read()
names = name_file.readlines()
for name in names:
cleaned_name = name.strip()
new_letter = letter_content.replace(PLACEHOLDER, cleaned_name)
with open(f"Output/ReadyToSend/letter_for_{cleaned_name}.txt", "w") as output:
output.write(new_letter)