File size: 6,726 Bytes
37185e0
 
 
 
cdbe688
c400028
37185e0
0724750
37185e0
c400028
 
 
 
 
 
 
 
052a8fc
e3f43f3
c400028
 
 
e3f43f3
c400028
37185e0
0724750
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87ccea1
0724750
 
37185e0
0724750
37185e0
 
3be9484
0724750
87ccea1
0724750
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87ccea1
c0d54a6
3be9484
37185e0
3be9484
 
 
 
 
 
0724750
37185e0
 
 
 
 
3be9484
37185e0
c0d54a6
37185e0
 
2bd7b24
09696f6
c400028
 
 
 
0724750
 
 
 
2bd7b24
0724750
 
2bd7b24
0724750
c400028
2bd7b24
c3d82ad
 
 
 
12d8a5c
87ccea1
2bd7b24
 
 
 
 
 
 
 
12d8a5c
 
 
c400028
12d8a5c
2bd7b24
 
 
 
 
 
09696f6
2bd7b24
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import gradio as gr
import requests
import os

# Load API keys securely from environment variables
proxycurl_api_key = os.getenv("PROXYCURL_API_KEY")  # Add your Proxycurl API key to your environment variables
groq_api_key = os.getenv("GROQ_CLOUD_API_KEY")
serpapi_key = os.getenv("SERPAPI_API_KEY")  # Add your SerpAPI key to your environment variables

# Function to use Proxycurl API to get the LinkedIn profile data
def get_linkedin_profile_via_proxycurl(linkedin_profile_url):
    headers = {
        "Authorization": f"Bearer {proxycurl_api_key}",
    }
    url = f"https://nubela.co/proxycurl/api/v2/linkedin?url={linkedin_profile_url}"
    
    response = requests.get(url, headers=headers)
    
    if response.status_code == 200:
        data = response.json()
        bio = data.get("summary", "No bio available")
        return bio
    else:
        return "Error: Unable to fetch LinkedIn profile"

# Function to use SerpAPI to fetch company and role information
def get_company_and_role_info(company_name, role):
    query = f"{company_name} {role} job description"
    url = f"https://serpapi.com/search.json?engine=google&q={query}&api_key={serpapi_key}"
    
    response = requests.get(url)
    
    if response.status_code == 200:
        results = response.json()
        # Extract information about the company and role from the search results
        company_info = []
        for result in results.get("organic_results", []):
            if "linkedin.com" not in result.get("link", ""):
                company_info.append(result.get("snippet", ""))
        return "\n".join(company_info[:2])  # Limit to 2 top results
    else:
        return "Error fetching company and role information."

# Helper function to call Groq Cloud LLM API to generate and correct the email
def generate_and_correct_email(bio, company_name, role, company_info):
    url = "https://api.groq.com/openai/v1/chat/completions"
    headers = {
        "Authorization": f"Bearer {groq_api_key}",
        "Content-Type": "application/json",
    }
    
    # Updated prompt with a focus on professionalism, relevance, and creativity
    prompt = f"""
    Write a professional, concise, and compelling email applying for the {role} position at {company_name}. 
    Use this bio to highlight the candidate's skills and experience: {bio}.
    
    Additionally, here is some information about the company and the role:
    {company_info}
    
    The email should:
    - Be professional, creative, and tailored to the company and role.
    - Creatively emphasize the candidate’s key skills and experience, aligning them with the job's requirements.
    - Attract the company's attention by focusing on how the candidate's background can bring value to the role and company.
    - Be concise but engaging, leaving a strong impression on the recruiter.
    - Include a clear call to action, encouraging the company to interview the candidate.
    
    Structure the email as follows:
    1. **Introduction**: Briefly introduce the candidate and the role they are applying for.
    2. **Skills & Experience**: Creatively map the candidate’s skills and experience to the job's key requirements, focusing on relevance.
    3. **Value Proposition**: Highlight how the candidate’s experience will contribute to the company's success.
    4. **Call to Action**: Encourage the company to set up an interview to explore how the candidate can add value.
    """
    
    # Construct the data payload for the API request
    data = {
        "messages": [
            {
                "role": "user",
                "content": prompt
            }
        ],
        "model": "llama3-8b-8192"
    }
    
    response = requests.post(url, headers=headers, json=data)
    
    if response.status_code == 200:
        return response.json()["choices"][0]["message"]["content"].strip()
    else:
        print(f"Error: {response.status_code}, {response.text}")
        return "Error generating email. Please check your API key or try again later."

# Main function to create the email and allow for saving, editing, or copying
def create_email(name, company_name, role, email, phone, linkedin_profile_url):
    # Step 1: Fetch LinkedIn profile using Proxycurl API if LinkedIn URL is provided
    if linkedin_profile_url:
        bio = get_linkedin_profile_via_proxycurl(linkedin_profile_url)
    else:
        bio = f"{name} is a professional."
    
    # Step 2: Fetch company and role information using SerpAPI
    company_info = get_company_and_role_info(company_name, role)
    
    # Step 3: Generate the email using Groq Cloud LLM
    generated_email = generate_and_correct_email(bio, company_name, role, company_info)
    
    # Step 4: Add the user's email, phone number, and LinkedIn profile to the signature
    signature = f"\n\nBest regards,\n{name}\nEmail: {email}\nPhone: {phone}\nLinkedIn: {linkedin_profile_url if linkedin_profile_url else 'Not provided'}"

    # Ensure the body doesn't include any redundant 'Best regards' and just append our signature
    if "Best regards" in generated_email:
        generated_email = generated_email.split("Best regards")[0].strip()

    # Return the final polished email with the signature
    return generated_email + signature

# Define interface with Gradio
def gradio_ui():
    # Define inputs
    name_input = gr.Textbox(label="Name", placeholder="Enter your name")
    
    company_name_input = gr.Textbox(label="Company Name", placeholder="Enter the name of the company you are applying to")
    role_input = gr.Textbox(label="Role", placeholder="Enter the role you are applying for")
    
    email_input = gr.Textbox(label="Email Address", placeholder="Enter your email address")
    phone_input = gr.Textbox(label="Phone Number", placeholder="Enter your phone number")
    linkedin_input = gr.Textbox(label="LinkedIn URL", placeholder="Enter your LinkedIn profile URL")  # New field for LinkedIn URL
    
    # Define output for the generated email
    email_output = gr.Textbox(label="Generated Email", placeholder="Your generated email will appear here", lines=10)
    
    # Create the Gradio interface
    demo = gr.Interface(
        fn=create_email,  # Function to call when the user submits
        inputs=[name_input, company_name_input, role_input, email_input, phone_input, linkedin_input],
        outputs=[email_output],
        title="Email Writing AI Agent",
        description="Generate a professional email for a job application by providing your basic info.",
        allow_flagging="never"  # Disable flagging
    )
    
    # Launch the Gradio app
    demo.launch()

# Start the Gradio app when running the script
if __name__ == "__main__":
    gradio_ui()