Spaces:
Sleeping
Sleeping
| 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() | |