Yet one more vacation season has arrived. It’s certainly probably the most fantastic time of the yr. It’s additionally that point of the yr when working professionals set the identical previous out-of-office reply to each e-mail they get. Properly, the issue with automating e-mail responses this fashion is that it offers the identical flavourless replies to all of the emails – each related and irrelevant ones. That is when even adults begin wishing Santa would present them an e-mail workflow optimisation resolution or an AI e-mail assistant that offers good replies. Properly, this yr, Santa has come dressed as CrewAI! On this weblog, we’ll study automating e-mail responses by constructing an agentic AI system with CrewAI to answer to your out-of-office emails well and guarantee good e-mail administration.
Understanding the Context
First, let’s attempt to perceive the context of our downside assertion.
This screenshot captures the essence of the issue. If you happen to look carefully, you’ll find emails the place my direct intervention is required, after which you’ll find emails with subscribed newsletters and calendar notifications that don’t require any reply.
The prevailing ‘Trip Responder’ responds to all of the messages with no functionality to vary the title of the recipient or the contents of the mail primarily based on who it’s responding to. Additionally, it responds to irrelevant emails, which embody newsletters, verification code emails, OTP emails, and many others.
That is the place the CrewAI framework involves the rescue for e-mail response administration. With CrewAI, you’ll be able to rapidly construct an e-mail responder agent system, with some easy coding. Relieved? So, let’s construct an agentic AI system for automating e-mail responses with CrewAI and produce a layer of optimisation to your e-mail workflow.
Additionally Learn: Automating E-mail Sorting and Labelling with CrewAI
Google Authentication
Earlier than we soar to the code for automating e-mail responses in Gmail, you have to allow the Gmail API and generate the OAuth 2.0 credentials. This can give your e-mail responder agentic system entry to your emails. Right here’s the right way to get this completed.
Step 1: Create a New Mission in Google Cloud
Go to the Google Cloud console and log in along with your e-mail tackle. First-time customers might want to create an account.
Then choose “New Mission” within the dropdown, give it a reputation, and click on Create. This venture could have the required API-related configurations. Whereas including the brand new venture, select your organisation title as the situation, as we’ve chosen analyticsvidhya.com.
Step 2: Allow Gmail API
Click on the Navigation Menu from the console’s Dashboard and head to Discover and Allow APIs below the Getting Began part.
On the left-hand aspect of the display screen, choose Library, and seek for “Gmail API”. Allow it for the venture you created.
Step 3: Set Up OAuth 2.0 Credentials
Subsequent, arrange the OAuth consent display screen below APIs & Providers. Then click on Configure Consent Display.
Select the kind (e.g., Exterior for apps utilized by anybody). We’ll selected Inside since we’re utilizing it for our personal e-mail ID. Then click on Create.
Then, title your app and add the Person assist e-mail and Developer contact data. Right here’s the place you must add your work e-mail ID. As soon as completed, click on on SAVE AND CONTINUE on the backside of the display screen.
Now, we have to outline the scopes within the consent display screen setup. Scopes, within the context of Google Console, dictate what the API can entry. For email-related duties, you’ll want the next: ‘https://www.googleapis.com/auth/gmail.modify‘. This scope will permit the e-mail responder system to ship and modify emails in your Gmail account. Click on on ADD OR REMOVE SCOPES after which choose the scope talked about above.
Then click on on Replace. You may see that the scope has been added. Press SAVE AND CONTINUE.
Now undergo the abstract, after which click on BACK TO DASHBOARD.
Step 4: Create Credentials
Now select Credentials below APIs & Providers and click on CREATE CREDENTIALS.
Then choose OAuth consumer ID.
For native growth, we are going to select the Desktop App possibility, after which press CREATE.
Step 5: Obtain the Credential.json
Now obtain the JSON file and reserve it domestically at your most popular location.
And that concludes our use of Google Search Console.
To allow CrewAI brokers to carry out internet searches and data retrieval from the web, it’ll want the API to the SerperDev Software. The SerperDev Software is a Python utility that interfaces with the Serper API, an economical and speedy Google Search API. It permits builders to programmatically retrieve and course of Google Search outcomes, together with reply containers, data graphs, and natural listings.
Let’s undergo the steps to get the API.
- Go to serper.dev and click on on Join.
- Create your account and login. You will note the Dashboard when you login.
- On the left of the display screen, click on on API Key.
Now, let’s soar to the Python code and construct our AI e-mail assistant for automated e-mail responses.
Python Code for Automating E-mail Responses
Step 1: Import Obligatory Libraries
We’ll start by importing the related libraries to construct an agentic system for automating e-mail responses.
# Importing essential libraries
import os # Supplies features to work together with the working system
# Importing modules from the CrewAI framework
# CrewAI is a framework for managing brokers, duties, processes, and instruments.
from crewai import Agent, Process, Crew, Course of # Handle brokers, duties, and processes
from crewai_tools import SerperDevTool # Software from CrewAI for connecting to Google search
# Importing modules for Google OAuth2 authentication and API interplay
from google.auth.transport.requests import Request # To deal with token refresh requests
from google.oauth2.credentials import Credentials # To handle OAuth2 credentials
from google_auth_oauthlib.circulation import InstalledAppFlow # To deal with OAuth2 login flows
from googleapiclient.discovery import construct # To create service objects for Google APIs
# Importing modules for e-mail creation
import base64 # To encode e-mail messages in base64
from e-mail.mime.textual content import MIMEText # To create MIME-compliant e-mail messages
Step 2: Set Scopes
Now, let’s set the SCOPES variable that defines permissions for the Gmail API. ‘gmail_modify’ permits studying, sending, and modifying emails, excluding everlasting deletion, guaranteeing restricted entry.
# Gmail API setup
SCOPES = ['https://www.googleapis.com/auth/gmail.modify']
Subsequent, we create the get_gmail_service perform that authenticates and connects to the Gmail API. It checks for saved credentials in token.json, refreshing them if expired. If unavailable, it initiates a brand new login circulation utilizing credentials.json. It saves legitimate credentials for reuse, and returns a Gmail API service object for e-mail operations.
# Perform to authenticate and join gmail API
def get_gmail_service():
creds = None
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
if not creds or not creds.legitimate:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
circulation = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
creds = circulation.run_local_server(port=0)
with open('token.json', 'w') as token:
token.write(creds.to_json())
return construct('gmail', 'v1', credentials=creds)
Step 3: Set Up E-mail Retrieval
Then, we create the get_unread_emails perform to retrieve unread emails from the Gmail inbox. It makes use of the Gmail API service object to listing messages with the labels ‘INBOX’ and ‘UNREAD’. The outcomes are executed as a question, and the perform returns a listing of messages or an empty listing if none exist.
# Perform to retrieve unread emails
def get_unread_emails(service):
outcomes = service.customers().messages().listing(userId='me', labelIds=['INBOX', 'UNREAD']).execute()
return outcomes.get('messages', [])
Subsequent, we create the get_email_content perform to retrieve and parse e-mail particulars from Gmail utilizing the message ID. It fetches the complete e-mail, extracts the topic and sender from headers, and decodes the physique. It helps multi-part emails (extracting plain textual content) and single-part emails by decoding the Base64-encoded content material. The perform returns a dictionary containing the e-mail’s topic, sender, and physique, guaranteeing complete dealing with of various e-mail codecs.
def get_email_content(service, msg_id):
message = service.customers().messages().get(userId='me', id=msg_id, format="full").execute()
payload = message['payload']
headers = payload['headers']
topic = subsequent(header['value'] for header in headers if header['name'] == 'Topic')
sender = subsequent(header['value'] for header in headers if header['name'] == 'From')
physique = ''
if 'elements' in payload:
for half in payload['parts']:
if half['mimeType'] == 'textual content/plain':
physique = base64.urlsafe_b64decode(half['body']['data']).decode('utf-8')
break
else:
physique = base64.urlsafe_b64decode(payload['body']['data']).decode('utf-8')
return {'topic': topic, 'sender': sender, 'physique': physique}
Step 4: Set Up E-mail Filters
Now, we come to an important piece of code. The half that helps us filter out irrelevant emails primarily based on sure key phrases within the physique of the mail or the sender. For me, I don’t want my agentic system to reply to emails that are- “subscribed newsletters”, “advertising emails”, “automated reviews”, “calendar notifications”, “verification code emails”, “OTP emails”, “HRMS”, “emails containing the phrases like ‘don’t reply’, ‘no-reply’, ‘accepted your invitation’, ‘rejected your invitation’, and many others.”
So, we are going to create the filter_emails perform that identifies emails to disregard primarily based on predefined standards. It makes use of two lists: ignore_keywords for phrases like “publication,” “OTP,” or “advertising” that point out irrelevant content material, and ignore_senders for sender patterns like “noreply” or “calendar-notification.” The perform checks if the sender matches any ignored patterns or if the topic or physique accommodates any ignored key phrases. It converts textual content(sender’s e-mail id + physique of the e-mail) to lowercase for constant, case-insensitive comparisons. If an e-mail matches any standards, the perform returns True to filter it out; in any other case, it returns False.
# Perform to filter out emails
def filter_emails(email_content, sender, topic):
ignore_keywords = [
"newsletter", "marketing", "automated report", "calendar notifications", "verification code", "otp", "Join with Google Meet",
"HRMS", "do not reply", "no-reply", "accepted your invitation", "rejected your invitation", "Accepted:"
]
ignore_senders = [
"[email protected]", "calendar-notification", "noreply", "no-reply", "calendar-server.bounces.google.com"
]
# Examine sender
if any(ignore in sender.decrease() for ignore in ignore_senders):
return True
# Examine topic and physique for key phrases
if any(key phrase in topic.decrease() or key phrase in email_content.decrease() for key phrase in ignore_keywords):
return True
return False
Step 5: Create the Ship Reply Perform
Subsequent, we create the send_reply perform that replies to an e-mail utilizing the Gmail API. To keep up the context of the dialog, we are going to create a message with the desired recipient (to), physique, and thread ID. The message is Base64-encoded and despatched by way of the API. This perform ensures replies are linked to the unique thread for seamless communication.
def send_reply(service, to, topic, physique, thread_id):
message = MIMEText(physique)
message['to'] = to
raw_message = base64.urlsafe_b64encode(message.as_bytes()).decode('utf-8')
return service.customers().messages().ship(
userId='me',
physique={'uncooked': raw_message, 'threadId': thread_id}
).execute()
Step 6: Construct the AI Brokers
Now, we are going to construct the three brokers required to execute the duty: the email_analyzer, response_drafter, and proofreader brokers. I’ve added the related prompts to every agent as per my desire. I like to recommend you undergo the backstory and aim accordingly.
# Outline brokers
email_analyzer = Agent(
function="E-mail Analyzer",
aim="Analyze incoming emails and decide applicable responses to related emails",
backstory="You are an skilled at understanding e-mail content material and context. "
"With this understanding, you establish whether or not to answer to a specific e-mail or not. "
"You could ignore emails which might be newsletters, advertising emails, Google doc feedback, google doc notifications,"
"calendar notifications, HRMS mails, automated reviews, and many others.",
verbose=True,
instruments=[SerperDevTool()],
allow_delegation=False
)
response_drafter = Agent(
function="Response Drafter",
aim="Draft applicable responses to emails",
backstory="You are expert at crafting skilled and contextually applicable e-mail responses."
"Don't Generate responses to emails which might be unread newsletters, advertising emails,"
"googl doc feedback(from: [email protected]), calendar notifications, HRMS mails, automated reviews, and many others."
"Make the responses crisp. Guarantee it's recognized to those who the I'm celebrating the Holidays and can be capable of ship any required paperwork as soon as I'm be part of again on third January 2025."
"YOUR NAME is my title and that is the title for use within the sign-off for every mail you generate response for."
"Within the salutation use the recipient's title after 'Hello'",
verbose=True
)
proofreader = Agent(
function="Proofreader",
aim="Guarantee e-mail responses are error-free and polished",
backstory="You may have a eager eye for element and wonderful grammar expertise. Make sure the response is crisp and to the purpose"
"Additionally discard e-mail replies generated for emails which might be newsletters, advertising emails, googl doc feedback, calendar notifications, HRMS mails, automated reviews, and many others.",
verbose=True
)
Now we are going to outline three completely different duties for the three brokers we’ve created. The outline will mirror the instructions written within the backstory of their respective brokers.
# Outline job for email_analyzer agent
def analyze_email(email_content):
return Process(
description=f"Analyze the content material and context of the next e-mail:nn{email_content}n"
f"Decide if this e-mail requires a response. Ignore newsletters, advertising emails, "
f"Google doc feedback (from: [email protected]), Google doc notifications, calendar invitations, "
f"HRMS mails, automated reviews, and many others.",
expected_output="An in depth evaluation of the e-mail content material and context, together with whether or not it requires a response",
agent=email_analyzer
)
# Outline job for response_drafter agent
def draft_response(evaluation):
return Process(
description=(
f"Draft knowledgeable and contextually applicable response to the next e-mail evaluation:nn{evaluation}nn"
f"Make sure the response is crisp and fascinating. Keep away from producing e-mail responses for newsletters, advertising emails, "
f"Google doc feedback (from: [email protected]), Google doc notifications, "
f"calendar invitations, HRMS mails, and automatic reviews. "
f"Moreover, embody a word indicating that the sender is celebrating the vacations and can be capable of present "
f"any required paperwork or help after returning."
f"YOUR NAME is the title of the sender and this must be utilized in sign-off for every mail you generate response for."
f"Within the salutation use the recipient's title after 'Hello'"
),
expected_output="A well-crafted e-mail response primarily based on the evaluation",
agent=response_drafter
)
# Outline job for proofreader agent
def proofread_response(draft):
return Process(
description=f"Evaluate and refine the next drafted e-mail response:nn{draft}",
expected_output="A cultured, error-free e-mail response",
agent=proofreader
)
Step 7: Add the Course of E-mail Perform
Subsequent, we create the process_email perform to course of an e-mail by first making use of filter_emails to disregard irrelevant messages. If the e-mail passes the filter, a crew occasion manages the sequential execution of duties: analyzing the e-mail, drafting a response, and proofreading it. The result’s evaluated to verify if a response is required. If not, it returns None; in any other case, it returns the processed output. This perform automates e-mail dealing with effectively with clear decision-making at every step.
# Process_email to incorporate filtering logic
def process_email(email_content, sender, topic):
if filter_emails(email_content, sender, topic):
print(f"Filtered out e-mail from: {sender}")
return None
crew = Crew(
brokers=[email_analyzer, response_drafter, proofreader],
duties=[
analyze_email(email_content),
draft_response(""),
proofread_response("")
],
course of=Course of.sequential,
verbose=True
)
consequence = crew.kickoff()
# Examine if the result's a CrewOutput object
if hasattr(consequence, 'consequence'):
final_output = consequence.consequence
else:
final_output = str(consequence)
# Now verify if a response is required
if "requires response: false" in final_output.decrease():
return None
return final_output
Step 8: Create the Ship Reply Perform
And now we come to our closing perform for this code. We’ll create the run_email_replier perform which automates e-mail administration for CrewAI brokers. It fetches unread emails, analyzes their content material, and responds if wanted. It does this by retrieving detailed e-mail data (physique, sender, topic), processing it with process_email to filter irrelevant messages, and figuring out if a response is required. If that’s the case, it sends a reply whereas sustaining the e-mail thread; in any other case, it skips the e-mail. This streamlined course of effectively handles e-mail triage, guaranteeing solely related emails obtain consideration and automating responses the place essential.
# Run_email_replier to move sender and topic to process_email
def run_email_replier():
service = get_gmail_service()
unread_emails = get_unread_emails(service)
for e-mail in unread_emails:
email_content = get_email_content(service, e-mail['id'])
response = process_email(email_content['body'], email_content['sender'], email_content['subject'])
if response:
send_reply(service, email_content['sender'], email_content['subject'], response, e-mail['threadId'])
print(f"Replied to e-mail: {email_content['subject']}")
else:
print(f"Skipped e-mail: {email_content['subject']}")
Step 9: Set the Surroundings Variables for API Keys
Lastly, we set the atmosphere variables for API keys (OPENAI_API_KEY, SERPER_API_KEY that you simply saved) required for e-mail processing. It executes the run_email_replier perform to automate e-mail administration utilizing CrewAI brokers, together with analyzing, filtering, and replying to unread emails. The if __name__ == “__main__”: block ensures the method runs solely when executed instantly.
# units atmosphere variables
if __name__ == "__main__":
# Arrange atmosphere variables
os.environ['OPENAI_API_KEY'] = 'Your API Key'
os.environ['SERPER_API_KEY'] = 'Your API Key'
# Run the e-mail replier
run_email_replier()
And that’s our e-mail response administration agent in full motion!
Let’s take a look on the emails. As you’ll be able to see, for emails the place my direct intervention was required, it has generated a custom-made e-mail as per the context.
And for emails resembling newsletters and notifications from HRMs, the place replies aren’t required, it has not given any reply.
And there you will have it! A totally practical autonomous agentic system for automating e-mail responses for out-of-office replies This manner you should use AI brokers for e-mail workflow optimization. In case you are glad with the responses you’ll be able to arrange a job scheduler to mechanically run this code at particular occasions through the day. When the code is run it’ll mechanically reply to the related unread emails.
Additionally Learn: Construct LLM Brokers on the Fly With out Code With CrewAI
Conclusion
Automating e-mail responses with Brokers(Crew AI, Langchain, AutoGen) can remodel how we handle replies to out-of-office emails. Furthermore, establishing such a system gives a glimpse right into a extra hopeful future for office effectivity. As AI continues to evolve, instruments like CrewAI will empower us to keep up seamless communication with out compromise, paving the way in which for a future the place know-how enhances each productiveness and private well-being. The chances are vivid, and the longer term is promising!
Regularly Requested Questions
A. CrewAI is an open-source Python framework designed to assist the event and administration of multi-agent AI programs. Utilizing crewAI, you’ll be able to construct LLM backed AI brokers that may autonomously make selections inside an atmosphere primarily based on the variables current.
A. Sure! You should use crewAI for e-mail workflow optimisation by automating e-mail responses.
A. For automating e-mail responses in Gmail, you should use as many brokers as you want. It is determined by your agentic system construction. It is strongly recommended that you simply construct one agent per job.
A. crewAI can carry out numerous duties, together with sorting and writing emails, planning tasks, producing articles, scheduling and posting social media content material, and extra.
A. To automate e-mail sorting utilizing crewAI, you merely must outline the brokers with a descriptive backstory throughout the Agent perform, outline duties for every agent utilizing Process performance, after which create a Crew to allow completely different brokers to collaborate with one another.