Companies today rely on remote workers or have multiple offices worldwide. Sending emails in English is fine, as it’s the worldwide business language, but wouldn’t it be nice to localize your emails, so your employees will get a translation into their local language? Using ChatGPT and Python, getting localized emails becomes an easy task.
Sure, you can translate the emails yourself if you know the target languages, but what if you’re sending emails to Spanish, French and German recipients? Maybe you can use Google Translate or hire a translator. By using ChatGPT, we just need to run a script and let the magic happen.
We’re going to create localized emails using ChatGPT.
If you already have the Nylas Python SDK installed and your Python environment configured, continue with the blog.
Otherwise, I recommend reading the post How to Send Emails with the Nylas Python SDK, where the basic setup is clearly explained.
Before moving on, be advised that we’re going to rely heavily on the work we did in the blog post How to Create a Mail Merge Template with Ruby.
Before we jump into the code, let’s see how our application actually works. Although for that, we need an essential step: creating a .csv file containing all the emails and information we will use.
The file will look like this:
| Name | Last_Name | Language | |
| Alvaro | Tejada Galindo | [email protected] | Spanish |
| Blag | Tejada Galindo | [email protected] | English |
| Alvaro aka “Blag” | Tejada Galindo | [email protected] | French |
This is how our application will look:

Here, we can fill in the subject, and the body and select the .csv file that we created.
We will get an error message if we don’t specify all the fields.

The exciting part here is how we define the subject and the body.

Here, {Name} and {Last_Name} will be replaced by the values stored on the .csv file. So each recipient will get a personalized or localized email. Remember that the values used between brackets need to match the column names in the .csv file.
Also, the email message will get translated into the target language for each recipient using ChatGPT to turn them into localized emails.
Let’s click Submit and see what happens:

We have successfully sent emails to all recipients. Let’s check their inbox.
English to Spanish translation:

English to French translation:

English doesn’t need to be translated:

As we can see, all recipients received a personalized or localized email, as all the fields were replaced accordingly and it includes a translated version of the message.
First, we need to have a ChatGTP account and then create our API keys:

Once the key has been created, store it safely, as you cannot recover it, so we can take advantage of our .env file and store it there.
As we want to create a Flask web application, our best option is to use Flask, one of the most popular Micro Frameworks in the Python world:
$ pip3 install Flask $ pip3 install Flask-session
Also, we need to install the OpenAI Python package:
$ pip3 install openai
Once they’re both installed, we’re ready to go:
First, we’re going to create a folder called localized_emails, and inside we’re going to create another folder called templates.
Let’s create a file called localized_emails.py in the localized_emails folder and add the following code:
# Import your dependencies
from flask import Flask,render_template,request,flash,redirect,url_for,session
from flask_session.__init__ import Session
import os
import openai
import csv
import re
from nylas import APIClient
# Load your env variables
from dotenv import load_dotenv
load_dotenv()
# Create the app
app = Flask(__name__)
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
# Initialize your Nylas API client
nylas = APIClient(
os.environ.get("CLIENT_ID"),
os.environ.get("CLIENT_SECRET"),
os.environ.get("ACCESS_TOKEN")
)
# Initialize your Open API client
openai.api_key = os.environ.get("OPEN_AI")
# This the landing page
@app.route("/", methods=['GET','POST'])
def index():
# We're using a GET, displat landing page
if request.method == 'GET':
return render_template('main.html')
# Get parameters from form
else:
subject = request.form["subject"]
body = request.form["body"]
mergefile = request.form["mergefile"]
# Session variables
session["subject"] = subject
session["body"] = body
# Make sure all fields are filled
if not subject or not body or not mergefile:
flash('You must specify all fields')
return redirect(url_for('index'))
else:
session["subject"] = None
session["body"] = None
# Auxiliary variables
email = ""
emails = []
row_header = {}
i = 0
subject_replaced = subject
body_replaced = body
# Open the CSV file
file = open(mergefile)
# Read the CSV contents
mergemail_file = csv.reader(file)
# Read and save the headers
headers = []
headers = next(mergemail_file)
for header in headers:
row_header[header] = i
i += 1
# Read all rows of the CSV file
for row in mergemail_file:
# Assign parameters to auxiliary variables
subject_replaced = subject
body_replaced = body
# Read all headers
for header in headers:
# Search for header and replace them with
# the content on the CSV file
if re.search("{"+f"{header}"+"}", subject):
subject_replaced = re.sub("{"+f"{header}"+"}",
row[row_header[f"{header}"]], subject_replaced)
if re.search("{"+f"{header}"+"}", body):
body_replaced = re.sub("{"+f"{header}"+"}",
row[row_header[f"{header}"]], body_replaced)
#Try to get the Name and Last_Name
try:
full_name = row[row_header["Name"]] + row[row_header["Last_Name"]]
except Exception as e:
full_name = row[row_header["Name"]]
print(f'{e}')
# Translate only email where target language is not English
if row[row_header["Language"]] != "English":
# Prompt for ChatGPT
prompt = """
Translate the following message into language
message: text_here
translation:
"""
# Replace Language and text_here with proper information
prompt = re.sub("language", row[row_header["Language"]], prompt)
prompt = re.sub("text_here", body_replaced, prompt)
# Call ChatGPT
response = openai.Completion.create(model="text-davinci-003",
prompt=prompt, max_tokens=100, temperature=0)
# Add response to the body of the email
body_replaced = body_replaced + "\n\n---" + f'{row[row_header["Language"]]}' +
" translation follows---\n" + response["choices"][0]["text"]
# Replace carriage returns with break lines
body_replaced = re.sub('\n', '<br>', body_replaced)
else:
body_replaced = re.sub('\n', '<br>', body_replaced)
# Try to send an email
try:
# Create the draft
draft = nylas.drafts.create()
# Add the subject
draft.subject = subject_replaced
# Add the body
draft.body = body_replaced
# Add the recipient and email
draft.to = [{"name":full_name,"email":row[row_header["Email"]]}]
# Send the email
draft.send()
# It was successful, added to the emails array
email = row[row_header["Email"]]
emails.append(email)
except Exception as e:
# There's a problem
print(f'{e}')
# Call the results page
return redirect(url_for('results', emails = emails))
# Show recipients emails
@app.route("/results", methods=['GET'])
def results():
# Get the list of emails
emails = request.args.getlist('emails')
# Call the results page passing emails as parameters
return render_template('results.html', emails = emails)
# Run our application
if __name__ == "__main__":
app.run()
Inside the templates folder, we need to create 3 different files, let’s start with base.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.tailwindcss.com"></script>
<title>Localized Emails</title>
</head>
<body>
<div id="container">
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div class="flash bg-green-300 border-green-600 border-b p-4 m-4 rounded grid
place-items-center text-red-600 font-bold">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}
{% endblock %}
</div>
</body>
</html>
Then, main.html:
{% extends 'base.html' %}
{% block content %}
<div class="bg-green-300 border-green-600 border-b p-4 m-4 rounded grid place-items-center">
<p class="text-6xl text-center">Localized Emails</p>
<br>
<form method="post">
<label for="subject" class="font-bold">Subject: </label>
<input type="text" name="subject" value="{% if session.subject != None %} {{session.subject}} {% endif %}" size="50"></input>
<br><br>
<label for="body" class="font-bold">Body: </label>
<textarea name="body" rows=10 cols=49>{% if session.body != None %} {{session.body}} {% endif %}</textarea>
<br><br>
<label for="mergefile" class="font-bold">Merge File: </label>
<input type="file" name="mergefile">
<br><br>
<button type="submit" class="block bg-blue-500 hover:bg-blue-700 text-white text-lg mx-auto py-2 px-4 rounded-full">Submit</button>
</form>
</div>
{% endblock %}
And finally results.html:
{% extends 'base.html' %}
{% block content %}
<div class="bg-green-300 border-green-600 border-b p-4 m-4 rounded grid place-items-center">
<h1 class="text-3xl"> The email was sent to the following addresses</h1>
<br>
{% for email in emails: %}
<p class="font-semibold">{{ email }}</p>
{% endfor %}
</div>
<div class="bg-green-300 border-green-600 border-b p-4 m-4 rounded grid place-items-center">
<a href="/" class="text-blue-600">Go back</a>
</div>
{% endblock %}
In order to run our application, we just need to type the following on the terminal window:
$ python localized_emails.py

Our application will be running on port 5000 of localhost, so we just need to open our favourite browser and go to the following address:
http://localhost:5000
We have easily created localized emails using ChatGPT.
If you want to learn more about our Email APIs, please go to our documentation Email API Overview.
You can sign up Nylas for free and start building!
Don’t miss the action, join our LiveStream Coding with Nylas: