Basic Mail Automation in Python


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
Enter fullscreen mode

Exit fullscreen mode


  1. Open letter_template.txt and invited_names.txt
  2. Read the files
  3. Loop through names from the invited_names.txt file
    a. Get the content
    b. Replace [name] with name
    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
Enter fullscreen mode

Exit fullscreen mode

# opening the letter_template file
with open("Input/Letters/letter_template.txt") as letter_file:
Enter fullscreen mode

Exit fullscreen mode

# opening the names file
with open("Input/Names/invited_names.txt") as name_file:
Enter fullscreen mode

Exit fullscreen mode



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()
Enter fullscreen mode

Exit fullscreen mode

  • And now for the names file:
    We can’t use the read() method for names because it returns a big string and we don’t want that.
    What we need is a list of names so that we can loop through.
    So instead of the read() method, we need to use readlines() method:
with open("Input/Names/invited_names.txt") as name_file:
    names = name_file.readlines()
Enter fullscreen mode

Exit fullscreen mode

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']
Enter fullscreen mode

Exit fullscreen mode

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]"
Enter fullscreen mode

Exit fullscreen mode



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)
Enter fullscreen mode

Exit fullscreen mode

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.
Enter fullscreen mode

Exit fullscreen mode

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']
Enter fullscreen mode

Exit fullscreen mode

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()
Enter fullscreen mode

Exit fullscreen mode

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)
Enter fullscreen mode

Exit fullscreen mode



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
Enter fullscreen mode

Exit fullscreen mode

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)
Enter fullscreen mode

Exit fullscreen mode

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
Enter fullscreen mode

Exit fullscreen mode


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)
Enter fullscreen mode

Exit fullscreen mode


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()
Enter fullscreen mode

Exit fullscreen mode

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)
Enter fullscreen mode

Exit fullscreen mode



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *