import gradio as gr import os import re import requests from dotenv import load_dotenv from openai import OpenAI load_dotenv() # Environment variables OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") MAUTIC_BASE_URL = os.getenv("MAUTIC_BASE_URL") MAUTIC_USERNAME = os.getenv("MAUTIC_USERNAME") MAUTIC_PASSWORD = os.getenv("MAUTIC_PASSWORD") client = OpenAI(api_key=OPENAI_API_KEY) SECTORS = [ "Law", "HR", "Marketing", "Finance", "Healthcare", "Education", "Retail", "Manufacturing", "Real Estate", "Construction", "Transport", "Hospitality", "Media", "Entertainment", "Telecom", "Government", "Energy", "Insurance", "Agriculture", "Technology" ] PROMPTS = { sector: f"Generate a UK cybersecurity insight for the {sector} sector." for sector in SECTORS } # Spam moderation SPAM_KEYWORDS = ["free money", "urgent click", "buy now", "no cost"] def moderate_content(text): return not any(re.search(kw, text, re.IGNORECASE) for kw in SPAM_KEYWORDS) def send_to_mautic(name, email, content): try: contact_data = { "firstname": name, "email": email, "tags": "Tag A", "custom_fields[ai_insight]": content, "segment[]": ["ai-contacts"] } response = requests.post( f"{MAUTIC_BASE_URL}/api/contacts/new", auth=(MAUTIC_USERNAME, MAUTIC_PASSWORD), data=contact_data ) if response.status_code in [200, 201]: return True, "Contact synced and added to Mautic." else: return False, f"Mautic error: {response.text}" except Exception as e: return False, f"Error syncing to Mautic: {str(e)}" def generate_insight(name, email, sector, tone, temperature): base_prompt = PROMPTS.get(sector, PROMPTS["Technology"]) tone_prompt = f" Make the tone {tone.lower()} and professional." full_prompt = base_prompt + tone_prompt try: response = client.chat.completions.create( model="gpt-4", messages=[ {"role": "system", "content": "You are a UK cybersecurity newsletter assistant."}, {"role": "user", "content": full_prompt} ], temperature=temperature, max_tokens=700 ) insight = response.choices[0].message.content.strip() if not moderate_content(insight): return "", "Content flagged as spammy. Please retry." return insight, "AI-generated content ready. You can edit before sending." except Exception as e: return "", f"OpenAI error: {str(e)}" # Gradio UI def build_interface(): with gr.Blocks() as demo: with gr.Tab("Generate Insight"): name = gr.Textbox(label="Name") email = gr.Textbox(label="Email") sector = gr.Dropdown(SECTORS, label="Sector", value="Law") tone = gr.Radio(["Formal", "Friendly", "Urgent", "Compliant"], label="Tone", value="Formal") temperature = gr.Slider(0.1, 1.0, value=0.7, step=0.1, label="Creativity") generate_btn = gr.Button("Generate Insight") status = gr.Textbox(label="Status", interactive=False) raw_output = gr.Textbox(label="Generated Content", lines=10) generate_btn.click(fn=generate_insight, inputs=[name, email, sector, tone, temperature], outputs=[raw_output, status]) with gr.Tab("Preview & Send"): edited = gr.Textbox(label="Editable Email Content", lines=10) send_btn = gr.Button("Send via Mautic") send_status = gr.Textbox(label="Mautic Send Log") send_btn.click(fn=send_to_mautic, inputs=[name, email, edited], outputs=[send_status]) with gr.Tab("About"): gr.Markdown(""" ### AI Cybersecurity Newsletter Demo This app uses OpenAI GPT to generate sector-specific insights, allows editing, and integrates with Mautic. Contacts are added to the `ai-contacts` segment and emailed through `Campaign A` using the `Email Test` template. """) return demo if __name__ == "__main__": build_interface().launch()