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)