DEV Community

Cover image for Get Hired Faster: How to use Lyzr-Automata to draft personalised cold emails
Rasswanth Shankar
Rasswanth Shankar

Posted on

Get Hired Faster: How to use Lyzr-Automata to draft personalised cold emails

In today’s competitive job market, getting noticed by recruiters can feel like finding a needle in a haystack. What if there was a way to cut through the noise and land yourself more interviews, faster? In this blog post, we’ll explore how Lyzr-Automata can empower job seekers to accelerate their job search and increase interview callbacks.

Setup

Create a folder, set up a virtual environment and activate it. Create .env file with your OPENAI_API_KEY. Then install the following libraries to get started.

Libraries

  • streamlit: for building the web app interface.
  • lyzr_automata : for implementing our AI models, and tasks.
  • dotenv: for loading environment variables (API key).
lyzr-automata==0.1.2
streamlit==1.32.2
python-dotenv==1.0.1
Enter fullscreen mode Exit fullscreen mode

Getting Started

We will split the task into 2 files. One for frontend components (main.py) while the other for Lyzr-Automata (lyzr_functions.py)

main.py

1.Import Libraries

import streamlit as st
from pypdf import PdfReader 
import os
from lyzr_functions import send_cold_email
Enter fullscreen mode Exit fullscreen mode

2.Helper Functions

# Save information on a text file that acts as memory for LLM
def save_to_text_file(text_value, mode):
    data_directory = "data"
    os.makedirs(data_directory, exist_ok=True)

    text_file_path = os.path.join(data_directory, 'instructions.txt')
    with open(text_file_path, mode) as file:
        file.write(text_value)

# Parse Resume
def read_pdf(pdf_file_path):
    reader = PdfReader(pdf_file_path) 
    extracted_text = ''.join(page.extract_text() for page in reader.pages)
    return extracted_text
Enter fullscreen mode Exit fullscreen mode

3. Input Components

  • st.file_uploader — Upload Resume
  • st.text_area — Text area to enter job description
  • st.text_input — Text field to enter list of emails and contact info
  • st.button — Button to submit input
# Resume Input
uploaded_file = st.file_uploader("Upload Resume", type='pdf')

# Job description Input
job_description = st.text_area("Enter Job Description")

# List of emails to send Input
email_ids = st.text_input('List of Emails', placeholder='Email1, Email2,...')

# Name and contact to sign the email Input
contact_info = st.text_input('Your contact info (to sign the email)', placeholder='Name, Phone Number')

# Submit button Input
is_send_email = st.button('Send Email!')

# env Variables to send email
user_email_address = st.text_input('Your email address')
app_password = st.text_input('Your email app password')
Enter fullscreen mode Exit fullscreen mode

4. Handle Inputs

if is_send_email:
    # If fields are empty
    if not email_ids or not job_description or not uploaded_file or not contact_info or not user_email_address or not app_password:
        st.error('Enter all the fields!')
    else:
        os.environ["PASSWORD"] = app_password
        os.environ["EMAIL"] = user_email_address
        email_list = email_ids.split(',')
        email_list = [email.strip() for email in email_list] # make a list of emails
        extracted_pdf_text = read_pdf(uploaded_file) # parse pdf
        save_to_text_file(text_value = extracted_pdf_text, mode = "w") # save pdf in txt file
        save_to_text_file(text_value = "\nJob Description : \n" + job_description, mode = "a") # save job desctiption in txt file
        send_cold_email(email_list, contact_info) # send email using Lyzr Automata
        st.success("Email sent!")
Enter fullscreen mode Exit fullscreen mode

lyzr_functions.py

1.Import Libraries

from lyzr_automata.ai_models.openai import OpenAIModel
from lyzr_automata import Agent, Task
from lyzr_automata.tasks.task_literals import InputType, OutputType
from lyzr_automata.memory.open_ai import OpenAIMemory
from lyzr_automata.pipelines.linear_sync_pipeline import LinearSyncPipeline
from lyzr_automata import Logger
from lyzr_automata.tools.prebuilt_tools import send_email_by_smtp_tool
from dotenv import load_dotenv
import os

load_dotenv()

# LOAD OUR API KEY
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
PASSWORD = os.getenv("PASSWORD")
EMAIL = os.getenv("EMAIL")
Enter fullscreen mode Exit fullscreen mode

2. send_cold_email function

  • OpenAIModel — Create our models using OpenAI Key and specify the model type and name.
  • OpenAIMemory — email_writer_memory, Create a vector store memory for the agent.
  • Agent — email_writer_agent, create a Lyzr Agent for text email creation using the memory.
  • Task — email_writer_task, create Lyzr Task with instructions on writing the email and the agent.
  • Tool — email_sender_tool, initialise the pre-built email sender tool
  • Task — send_email_task, create another Lyzr Task that is going to send our email.
  • LinearSyncPipeline — Pass the Tasks in order of execution.
def send_cold_email(email_list, contact_info):
    # GPT 4 Text Model
    open_ai_model_text = OpenAIModel(
        api_key= OPENAI_API_KEY,
        parameters={
            "model": "gpt-4-turbo-preview",
            "temperature": 0.3,
            "max_tokens": 1500,
        },
    )

    # Load memory from instructions file
    email_writer_memory = OpenAIMemory(
        file_path='data/instructions.txt'
    )

    # Create Agent with Memory
    email_writer_agent = Agent(
        prompt_persona="You are an intelligent email writer agent and assume the persona of a job seeker reaching out to potential employers or recruiters. The email should be professional, concise, and persuasive, highlighting the candidate's skills, experience, and why they are a good fit for the job description.",
        role="Cold Email writer",
        memory=email_writer_memory
    )

    # Create email writer Task
    email_writer_task = Task(
        name="Cold Email Creator",
        agent=email_writer_agent,
        output_type=OutputType.TEXT,
        input_type=InputType.TEXT,
        model=open_ai_model_text,
        instructions="Use the resume information and job description to write a cold email of 250 words to be sent to the recruiter. [IMPORTANT!] send the response in html use bullets for points and beautify it professionally. Return only the email. Don't leave any field empty. My personal details are : " + contact_info,
        log_output=True,
        enhance_prompt=False,
    )

    # Initialize email sender Tool
    email_sender_tool = send_email_by_smtp_tool(
        username=EMAIL,
        password=PASSWORD,
        host="smtp.gmail.com",
        port=587,
        sender_email=EMAIL
    )

    # Create email sender Task
    send_email_task = Task(
        name = "Send Email Task",
        tool = email_sender_tool,
        instructions="Send Email",
        model=open_ai_model_text,
        input_tasks = [email_writer_task],
        default_input = email_list
    )

    # Run Tasks using a pipeline
    logger = Logger()
    LinearSyncPipeline(
        logger=logger,
        name="Cold Emailer",
        completion_message="Email Sent!",
        tasks=[
            email_writer_task,
            send_email_task
        ],
    ).run()
Enter fullscreen mode Exit fullscreen mode

Run App

streamlit run main.py

Flow Diagram

Flow Diagram

Want to create more of such amazing AI Workflows? Visit our website at GitHub to learn more about Lyzr-Automata!

Also checkout Lyzr SDKs at GitHub

Lyzr Website: Lyzr.ai
Lyzr Community Channel: Discord

Code: https://github.com/rasswanth-lyzr/cold-emailer
Video Walkthrough: https://www.youtube.com/watch?v=hXLAN0qFP9g

Top comments (0)