Spaces:
Sleeping
Sleeping
import os | |
import gradio as gr | |
from openai import OpenAI | |
from dotenv import load_dotenv | |
# ----------------------------- | |
# Load environment variables and initialize OpenAI client | |
# ----------------------------- | |
load_dotenv() | |
client = OpenAI( | |
base_url="https://api.aimlapi.com/v1", | |
api_key=os.getenv("AIML_API_KEY"), | |
) | |
# ----------------------------- | |
# Mapping of Outreach Type to System Instruction File | |
# ----------------------------- | |
FILE_MAPPING = { | |
"Cold Email Outreach": "cold_email_outreach.txt", | |
"Warm Email Outreach": "warm_email_outreach.txt", | |
"Customer Development Outreach": "customer_development_outreach.txt", | |
"Link-Building Outreach": "link_building_outreach.txt", | |
"Influencer Outreach": "influencer_outreach.txt", | |
"Guest Blogging Outreach": "guest_blogging_outreach.txt", | |
"Review and Rating Outreach": "review_and_rating_outreach.txt", | |
} | |
# ----------------------------- | |
# Directory where the system instruction files are stored | |
# ----------------------------- | |
FILE_DIR = "prompts" | |
# ----------------------------- | |
# Configuration for Additional Fields per Outreach Type | |
# Each key is the outreach type and its value is a list of field keys. | |
# (Field keys below match the keys used for our additional input components.) | |
# ----------------------------- | |
FIELDS_CONFIG = { | |
"Cold Email Outreach": ["recipient_name", "recipient_company", "industry", "pain_points"], | |
"Warm Email Outreach": ["reference_details"], | |
"Customer Development Outreach": ["customer_insights"], | |
"Link-Building Outreach": ["target_website_url", "content_reference"], | |
"Influencer Outreach": ["influencer_platform", "collaboration_idea"], | |
"Guest Blogging Outreach": ["proposed_topics", "your_experience"], | |
"Review and Rating Outreach": ["experience_details"] | |
} | |
# ----------------------------- | |
# The order of all possible additional field keys (to ensure consistent update order) | |
# ----------------------------- | |
ALL_FIELD_KEYS = [ | |
"recipient_name", | |
"recipient_company", | |
"industry", | |
"pain_points", | |
"reference_details", | |
"customer_insights", | |
"target_website_url", | |
"content_reference", | |
"influencer_platform", | |
"collaboration_idea", | |
"proposed_topics", | |
"your_experience", | |
"experience_details", | |
] | |
# ----------------------------- | |
# Define the function that updates the visibility of additional fields | |
# based on the selected Email Outreach type. | |
# ----------------------------- | |
def update_additional_fields(selected_type): | |
# For each possible field key, set visible True if it is required for this outreach type. | |
updates = [] | |
visible_keys = FIELDS_CONFIG.get(selected_type, []) | |
for key in ALL_FIELD_KEYS: | |
if key in visible_keys: | |
updates.append(gr.update(visible=True)) | |
else: | |
updates.append(gr.update(visible=False, value="")) | |
return tuple(updates) | |
# ----------------------------- | |
# Define the function to generate the email using AI/ML API. | |
# | |
# This function will: | |
# 1. Load the system instruction (prompt) from the corresponding .txt file. | |
# 2. Combine the additional fields into a user prompt. | |
# 3. Send both messages to the API. | |
# 4. Return the generated email text (in Markdown format). | |
# ----------------------------- | |
def generate_email(email_type, | |
recipient_name, recipient_company, industry, pain_points, | |
reference_details, customer_insights, | |
target_website_url, content_reference, | |
influencer_platform, collaboration_idea, | |
proposed_topics, your_experience, | |
experience_details): | |
# Load the system instruction from file | |
filename = FILE_MAPPING.get(email_type) | |
try: | |
with open(FILE_DIR+"/"+filename, "r", encoding="utf-8") as f: | |
system_instruction = f.read() | |
except Exception as e: | |
return f"Error reading system file '{filename}': {e}" | |
# Combine additional field values into one additional-information string. | |
# Only include fields that have non-empty values. | |
additional_fields = { | |
"Recipient Name": recipient_name, | |
"Recipient Company": recipient_company, | |
"Industry": industry, | |
"Pain Points": pain_points, | |
"Reference Details": reference_details, | |
"Customer Insights": customer_insights, | |
"Target Website URL": target_website_url, | |
"Content Reference": content_reference, | |
"Influencer Platform": influencer_platform, | |
"Collaboration Idea": collaboration_idea, | |
"Proposed Topics": proposed_topics, | |
"Your Experience": your_experience, | |
"Experience Details": experience_details, | |
} | |
additional_info = "" | |
for label, value in additional_fields.items(): | |
if value.strip(): | |
additional_info += f"**{label}:** {value.strip()}\n\n" | |
if not additional_info: | |
additional_info = "No additional details provided." | |
# Build the messages list. | |
messages = [ | |
{"role": "system", "content": system_instruction}, | |
{"role": "user", "content": additional_info} | |
] | |
try: | |
response = client.chat.completions.create( | |
model="gpt-4o", | |
messages=messages, | |
) | |
email_text = response.choices[0].message.content | |
except Exception as e: | |
email_text = f"Error generating email: {e}" | |
return email_text | |
# ----------------------------- | |
# Build the Gradio App Interface | |
# ----------------------------- | |
with gr.Blocks(title="Email Crafting Tool") as demo: | |
gr.Markdown("# ✉️ AI Email Crafting Tool") | |
gr.Markdown("Craft hyper-personalized outreach emails with ease. Select an outreach type, fill in the additional details, and let the AI generate a tailored email for you.") | |
with gr.Row(): | |
email_type = gr.Dropdown( | |
label="Select Email Outreach Type", | |
choices=list(FILE_MAPPING.keys()), | |
value="Cold Email Outreach", | |
interactive=True | |
) | |
with gr.Column(variant="panel"): | |
gr.Markdown("### Additional Details") | |
# Create additional fields – all initially hidden. They will be shown conditionally. | |
recipient_name = gr.Textbox(label="Recipient Name", placeholder="Enter recipient's name", visible=False) | |
recipient_company = gr.Textbox(label="Recipient Company", placeholder="Enter recipient's company", visible=False) | |
industry = gr.Textbox(label="Industry", placeholder="Enter industry", visible=False) | |
pain_points = gr.Textbox(label="Pain Points", placeholder="Enter known challenges or pain points", lines=2, visible=False) | |
reference_details = gr.Textbox(label="Reference Details", placeholder="Mention any previous interactions", visible=False) | |
customer_insights = gr.Textbox(label="Customer Insights / Questions", placeholder="What insights or questions do you have?", lines=2, visible=False) | |
target_website_url = gr.Textbox(label="Target Website URL", placeholder="Enter the target website URL", visible=False) | |
content_reference = gr.Textbox(label="Content Reference", placeholder="Mention relevant content or article details", lines=2, visible=False) | |
influencer_platform = gr.Textbox(label="Influencer Platform", placeholder="Enter the influencer's platform (e.g., Instagram, YouTube)", visible=False) | |
collaboration_idea = gr.Textbox(label="Collaboration Idea", placeholder="Briefly describe the collaboration idea", lines=2, visible=False) | |
proposed_topics = gr.Textbox(label="Proposed Topics", placeholder="List one or more guest post topics", lines=2, visible=False) | |
your_experience = gr.Textbox(label="Your Experience", placeholder="Share your expertise or experience", lines=2, visible=False) | |
experience_details = gr.Textbox(label="Experience Details", placeholder="Describe your experience with the product/service", lines=2, visible=False) | |
# When the outreach type changes, update the visibility of the additional fields. | |
email_type.change( | |
fn=update_additional_fields, | |
inputs=email_type, | |
outputs=[ | |
recipient_name, recipient_company, industry, pain_points, | |
reference_details, customer_insights, | |
target_website_url, content_reference, | |
influencer_platform, collaboration_idea, | |
proposed_topics, your_experience, | |
experience_details | |
] | |
) | |
with gr.Row(): | |
generate_btn = gr.Button("Generate Email", variant="primary") | |
# Use a gr.Code component to render Markdown and include a built-in copy-to-clipboard button. | |
output_email = gr.Code(label="Generated Email (Markdown)", language="markdown") | |
generate_btn.click( | |
fn=generate_email, | |
inputs=[ | |
email_type, | |
recipient_name, recipient_company, industry, pain_points, | |
reference_details, customer_insights, | |
target_website_url, content_reference, | |
influencer_platform, collaboration_idea, | |
proposed_topics, your_experience, | |
experience_details | |
], | |
outputs=output_email, | |
) | |
gr.Markdown("___") | |
gr.Markdown("© 2025 AI Email Crafting Tool") | |
# Launch the app (use share=True if you need to generate a public link) | |
demo.launch(share=True) |