Summarize an Email Newsletter with ChatGPT

perd1x
9 min readMar 9, 2023
Photo by Brett Jordan on Unsplash

Are you tired of spending countless hours sifting through newsletters in your inbox, trying to find the most important information? If so, you’re not alone. With the amount of newsletters that we receive every day, it can be difficult to find the key takeaways that are relevant to us.

That’s where the SumMail comes in. With just a few lines of code, you can use it to summarize your newsletters and get the key takeaways in a fraction of the time it would take you to read them in full.

The script I created is designed to read emails from one specific sender, making it ideal if you want to resume newsletters from a specific email. This script fetch the latest email, extract the body text, split it into smaller chunks, and use the OpenAI API to summarize each chunk. In just a few minutes, you’ll have a concise summary of the newsletter that highlights the most important information and key takeaways.

So, if you’re tired of drowning in newsletters and want to get the most out of them without sacrificing your time or sanity, keep reading. I’ll show you how to use the SumMail to summarize your newsletters and get the key takeaways in a fraction of the time.

To get started, you’ll need the following:

  • Python 3.7 or higher installed on your computer.
  • pip3 (Python package manager) installed.
  • A paid OpenAI API key to access the API’s summarization capabilities.

With these three prerequisites in place, you’ll be ready to create a script that summarizes your newsletters and saves you valuable time!

Photo by Joshua Aragon on Unsplash

Step 1: Prepare your enviroment

To get started, you’ll need to create a new Python project and set up your environment. Open a terminal and navigate to a directory where you want to store your project files. Then, create a new virtual environment for your project by running:

python3 -m venv myenv

Activate the virtual environment by running:

source myenv/bin/activate

Next, install the necessary Python packages by running:

pip3 install openai requests html2text python-dotenv
Photo by Scott Graham on Unsplash

Step 2: Prepare the script structure

To ensure that the script runs smoothly, it is necessary to organize its structure into functions and import variables from the .env file. The following libraries will be used in the script: os, email, openai, imaplib, requests, html2text, and dotenv. Here’s an outline of the functions that will be implemented:

  1. fetch_latest_email(): This function will fetch the latest email from a specified mailbox and parse its content. The email's subject and text content will be extracted and processed.
  2. summarize_chunks(chunks): This function will use OpenAI's text-davinci-003 model to summarize each chunk of text into a bullet point. The bullet points will then be joined into a single string.
  3. main(): This function will call the fetch_latest_email() and summarize_chunks(chunks) functions and print the email subject and the resulting bullet points.
import os
import email
import openai
import imaplib
import requests
import html2text
from dotenv import load_dotenv
from email.header import decode_header

def fetch_latest_email():
try:
# Load environment variables from .env file
# Set the email credentials
# Set the email sender
# Connect to the IMAP server
# Select the mailbox and search for the latest email
# Fetch the latest email
# Parse the email content using the email module
# Extract the subject and decode it
# Extract the text content of the email
# Convert only to Text and remove html
# Split the email body into chunks of 2037 tokens (max 2048)
except Exception as e:
print(f"An error occurred: {e}")
return None, []

def summarize_chunks(chunks):
try:
# Set up the OpenAI API client
# Set up the API endpoint
# Set up the request headers
# Summarize each chunk using OpenAI's text-davinci-003 model
# Join the bullet points into a single string
return bullet_list
except Exception as e:
print(f"An error occurred: {e}")

def main():
# print the subject and bullet list

if __name__ == "__main__":
main()
Photo by CHUTTERSNAP on Unsplash

Step 3: Import variables

To keep sensitive information like email credentials and OpenAI API keys secure, it is recommended to store them in a separate file that is not version-controlled, such as an .env file.

To create a new .env file in the project directory, add the following lines:

IMAP_SERVER=your_imap_server_address
IMAP_USERNAME=your_email_username
IMAP_PASSWORD=your_email_password
SENDER_EMAIL=sender_email_address
OPENAI_API_KEY=your_openai_api_key

These variables will be used in the Python script.

To load the variables from the .env file in your Python script, add the following lines:

import os
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

# Set up email account credentials
IMAP_SERVER = os.getenv('IMAP_SERVER')
IMAP_USERNAME = os.getenv('IMAP_USERNAME')
IMAP_PASSWORD = os.getenv('IMAP_PASSWORD')

# Set up email sender
SENDER_EMAIL = os.getenv('SENDER_EMAIL')

# Set up OpenAI API key
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')

These lines load the environment variables from the .env file using the os and dotenv libraries. They set the IMAP_SERVER, IMAP_USERNAME, IMAP_PASSWORD, and SENDER_EMAIL variables to their respective values from the .env file. Additionally, they set the OPENAI_API_KEY variable to the value of the OPENAI_API_KEY environment variable.

By using the .env file to store sensitive information, you can keep your script secure and avoid accidentally sharing your private information.

Photo by Kenny Eliason on Unsplash

Step 4: Fetch the latest email

To fetch the latest email from a specified sender, we’ll use the imaplib and email modules in Python. Here's a function that fetches the latest email from a specified sender:

  1. Connect to the IMAP server using the IMAP4_SSL() method.
  2. Login to the IMAP server using the provided credentials.
  3. Select the mailbox (in this case, the inbox) and search for the latest email from the specified sender using the search() method.
  4. Get the email IDs of the search results and select the latest email.
  5. Fetch the contents of the latest email using the fetch() method.
  6. Parse the raw email content using the email.message_from_bytes() method.
  7. Extract the subject of the email and decode it if necessary using the decode_header() method.
  8. Extract the text content of the email using the walk() method and filter only the plain text content.
  9. Convert the email body to plain text and remove any HTML tags using the html2text package.
  10. Split the email body into chunks of 2037 tokens (OpenAI’s text completion API has a maximum token limit of 2048) using list comprehension.
  11. Return the email subject and the list of email body chunks as a tuple.

# connect to the IMAP server
mail = imaplib.IMAP4_SSL(IMAP_SERVER, 993)
mail.login(IMAP_USERNAME, IMAP_PASSWORD)

# select the mailbox and search for the latest email
mail.select("inbox")
status, response = mail.search(None, "FROM", SENDER_EMAIL)
email_ids = response[0].split()
latest_email_id = email_ids[-1]

# fetch the latest email
status, response = mail.fetch(latest_email_id, "(RFC822)")
raw_email = response[0][1]

# parse the email content using the email module
email_message = email.message_from_bytes(raw_email)

# extract the subject and decode it
subject = decode_header(email_message["Subject"])[0][0]
if isinstance(subject, bytes):
# if it's bytes, decode to string
subject = subject.decode()

# extract the text content of the email
body = ""

for part in email_message.walk():
content_type = part.get_content_type()
if content_type == "text/plain":
charset = part.get_content_charset()
body += str(part.get_payload(decode=True), str(charset), "ignore")

# Convert only to Text and remove html
body = html2text.html2text(body)

# split the email body into chunks of 2037 tokens (max 2048)
chunk_size = 2037
chunks = [body[i:i+chunk_size] for i in range(0, len(body), chunk_size)]

return subject, chunk
Photo by Andreas Klassen on Unsplash

Step 5: Summarize the email

The final step is to summarize the email chunks using OpenAI’s API. Here’s a function that takes in a list of email body chunks and uses OpenAI’s text completion API to summarize each chunk. It concatenates the resulting summaries into a bullet point list and returns it.

  1. First, set up the OpenAI API client by loading the API key from the .env file using os.getenv().
  2. Next, set up the API endpoint for the OpenAI text completion API.
  3. Set up the request headers for the API call, including the authorization header with the API key.
  4. Loop through each chunk of the email body text passed to the function.
  5. For each chunk, create a prompt for the OpenAI text completion API. The prompt is a string that asks the API to summarize the content of the email chunk.
  6. Create a data object with the model, prompt, temperature, and max_tokens parameters required by the OpenAI text completion API.
  7. Make an HTTP POST request to the OpenAI API endpoint with the data object and request headers.
  8. Extract the summary text from the response JSON object and append it to a list of summaries.
  9. After all chunks have been summarized, join the list of summaries into a bullet point list.
  10. Return the bullet point list of summaries.
# set up the OpenAI API client
openai.api_key = os.getenv('OPENAI_API_KEY')

# set up the API endpoint
openai_url = "https://api.openai.com/v1/completions"

# set up the request headers
headers = {
"Authorization": f"Bearer {openai.api_key}",
"Content-Type": "application/json",
}

# summarize each chunk using OpenAI's text-davinci-003 model
summaries = []
for chunk in chunks:
prompt = f"Summarize the content of this string: {chunk}"
data = {
"model": "text-davinci-003",
"prompt": prompt,
"temperature": 1,
"max_tokens": 1000
}

# make the HTTP request
response = requests.post(openai_url, headers=headers, json=data)

# extract the summary from the response
summary = response.json()["choices"][0]["text"].strip()
summaries.append(summary)

# join the bullet points into a single string
bullet_list = "\n- ".join(summaries)

return bullet_list
Photo by Ruthson Zimmerman on Unsplash

Step 6: Tie everything together

In this step, we’ll tie everything together by creating a main function that calls fetch_latest_email() to get the latest email from the specified sender, summarize_chunks(chunks) to summarize the email's body, and then prints the resulting summary.

  1. Define the main() function that calls fetch_latest_email() and summarize_chunks(chunks) to fetch and summarize the latest email from the specified sender.
  2. If no email chunks are returned from fetch_latest_email(), print a message indicating there are no email chunks to summarize and return.
  3. If summarize_chunks(chunks) fails to summarize the email chunks, print a message indicating the failure and return.
  4. Otherwise, print the email subject and bullet point summary.
  5. Add the if __name__ == "__main__": block to call the main() function when the script is run.
def main():
subject, chunks = fetch_latest_email()
if not chunks:
print("No email chunks to summarize")
return

bullet_list = summarize_chunks(chunks)

if not bullet_list:
print("Failed to summarize email chunks")
return

# print the subject and bullet list
print("Subject: " + subject)
print("Summary: \n- " + bullet_list)


if __name__ == "__main__":
main()

To run the script, save the file as main.py and run the following command in the terminal:

python3 main.py

With this script, you can easily extract key information and important takeaways from your emails, allowing you to stay on top of your inbox and prioritize your time more efficiently.

But the benefits of email summarization go beyond just saving time. By using this script, you’ll also be able to better absorb and retain important information from your emails. Instead of sifting through large blocks of text and struggling to find the most relevant information, you’ll have a clear and concise summary that you can quickly and easily refer to.

And best of all, this script is highly customizable, allowing you to easily tailor it to your specific needs and preferences. Whether you’re looking to streamline your email management for personal or professional reasons, this script can help you achieve your goals.

Photo by Possessed Photography on Unsplash

Examples

Check out these sample outputs from the AI-powered script for summarizing email newsletters. Although there are some adjustments that can be made, it’s still impressive and diverse.

Email from disable service
Resuming hotel tips or email about create images it’s not a problem.
Nintendo Newsletter or your favorite site of recipes

Why waste time scrolling through emails?

Try this script today and experience the convenience and efficiency of automatic email summarization. You can find the full code in my repository.

Don’t forget to give it a clap and subscribe for more useful tips and tricks!

--

--

perd1x

I am a security engineer and here I express my opinions on various topics. Here you can find the most varied subjects that are part of the cyber security world.