# -*- coding: utf-8 -*- import os from dotenv import load_dotenv import gradio as gr from openai import OpenAI from datetime import datetime, timedelta # --- Configurazione Iniziale --- load_dotenv() api_key = os.getenv('OPENAI_API_KEY') if not api_key: raise ValueError("Errore: OPENAI_API_KEY non trovata.") client = OpenAI(api_key=api_key) # --- Variabili Globali Editabili: Nuances e Contesti --- # Nuances Personificazioni (v3.5) NUANCE_GABRIELLA = "meticolosa e attenta ai dettagli, pratica e organizzativa." NUANCE_DANIELA = "calda, empatica e focalizzata sul comfort e benessere degli ospiti." NUANCE_NICOLETTA = "efficiente, molto informata su Venezia, diretta e pratica." NUANCE_CARLA = "calma, rassicurante e paziente, ottima per gestire richieste particolari." NUANCE_RECEPTION_FRIENDLY = "esperta, amichevole e disponibile per accoglienza e info generali." NUANCE_RECEPTION_FORMAL = "precisa, professionale e chiara per prenotazioni, amministrazione, problemi formali." NUANCE_COACH = "orientato a migliorare performance team con neuroscienze applicate, copy efficace, strategie alberghiere semplici e motivanti." NUANCE_INSPIRING_CREATIVE = "altamente creativa, focus su idee innovative per ospitalità, storytelling social, esperienze uniche e contenuti visuali." NUANCE_NEUROSCIENTIST = "analitica e strategica, applica principi neuroscientifici (bias, framing, social proof) per ottimizzare comunicazione e persuasione marketing." NUANCE_MANAGER = "manager senior con visione strategica, orientato a risultati e gestione efficiente team/operazioni." NUANCE_BRAND = "voce ufficiale e impersonale dell'Hotel Tintoretto, comunicazione chiara e professionale." NUANCE_TIKTOK_STRATEGIST = "un'esperta di neuromarketing e TikTok strategy nel travel. Identifica **trend audio/video ADATTABILI** in modo *originale* (non banale). Crea script brevi (15-60s) **realistici ma con potenziale virale**, suggerendo setting **facilmente realizzabili**, angolazioni **dinamiche e inaspettate** (POV, zoom rapidi, low angle), montaggio **ritmato con J-cuts/L-cuts**, e **neuro-hook ultra-rapidi** (pattern interrupt, curiosity gap, strong visual statement) per catturare l'attenzione nei primi 1-2 secondi. Usa neuro-copy per i testi overlay. Focus su autenticità, valore, umorismo situazionale (vita/viaggi a Venezia) e risoluzione problemi comuni del turista." NUANCE_INSTAGRAM_STRATEGIST = "una visual storyteller e Instagram strategist esperta in **community building ed estetica raffinata**. Crea script per Reels (fino a 90s) con **storytelling emozionale e archi narrativi chiari**, idee **pronte all'uso** per **sequenze di Stories interattive e strategiche** (poll, quiz, Q&A mirati, sticker 'link' se appropriato), e concept per post/caroselli **esteticamente impeccabili** e coerenti con il brand (autentico, accogliente, dettagli curati). Punta a **ispirare il desiderio** di un'esperienza veneziana genuina, stimolare l'engagement **di qualità** e guidare azioni concrete (salvataggi, condivisioni, visite al sito)." NUANCE_TIKTOK_CAMPAIGNER = "pianificatrice strategica di campagne TikTok per travel. Idea campagne tematiche (1-2 mesi) **realistiche, misurabili e creative**. Definisce concept **forte e originale**, target preciso, obiettivi (KPI chiari: es. % completamento video, click-through rate), **pilastri di contenuto differenzianti** con esempi video *specifici* (non generici), frequenza/mix formati **ottimizzato per l'algoritmo**, e strategia hashtag **a più livelli**." NUANCE_INSTAGRAM_CAMPAIGNER = "pianificatrice strategica di campagne Instagram per travel. Idea campagne (1-2 mesi) focalizzate su **estetica distintiva, storytelling cross-format e crescita community**. Definisce concept, **visual moodboard dettagliato** (descrittivo), obiettivi (engagement rate, UGC di qualità, lead generation), **content mix strategico** (Reels per reach, Stories per engagement, Post per informazione/ispirazione, Guide), **piano di interazione proattivo** (risposte a commenti/DM, interazione con UGC), e **funnel di conversione** con CTA chiare." # Clausola Privacy privacy_clause = """ Please note that data submitted by you shall be processed using electronic means in compliance with the principles set forth in applicable data privacy laws and regulations (EU Regulation n. 679, 2016), solely for the purpose of providing you with the information requested, and potentially for placing/confirming your booking of room(s) and other services/amenities. The complete privacy policy on processing methods and purposes is available at the following link www.hoteltintoretto.com/privacy-policy (Nota: Verificare URL esatto). If you are interested in receiving our newsletter / periodic updates on special rates and promotions (to be sent to an address supplied by you), you must provide explicit consent to the same. You may at any time thereafter revoke such consent, as noted in the policy. """ # --- FUNZIONE PER LINK BOOKING BASE --- def generate_booking_link(language="English"): """Genera il link BASE alla pagina di disponibilità (senza date/ospiti).""" base_url = "https://www.hoteltintoretto.com" hotel_id = "SYN2595" if language == "Italian": path = "/disponibilita.html" else: path = "/EN/availability.html" return f"{base_url}{path}?id_hotel={hotel_id}" # --- Genera i link base ORA --- link_base_it = generate_booking_link(language='Italian') link_base_en = generate_booking_link(language='English') # Contesto Principale Hotel Tintoretto hotel_context="""" --- Hotel Overview --- Nome Hotel: Hotel Tintoretto # ... (omesso per brevità, invariato da v3.3) ... --- Prenotazioni & Offerte --- - Booking Diretto: **Fortemente incoraggiato tramite il sito ufficiale www.hoteltintoretto.com per ottenere la migliore tariffa disponibile e offerte speciali.** - (Nota per AI: Quando inviti a prenotare, suggerisci di visitare il sito www.hoteltintoretto.com o fornisci il link base appropriato alla lingua, spiegando che l'utente dovrà inserire date e ospiti. NON inserire date/ospiti nel link.) - Link base IT: {link_it} - Link base EN/Altro: {link_en} - Pagina Offerte: Disponibile sul sito ufficiale. --- Hotel Partner (Alternativa se Tintoretto pieno) --- # ... (omesso per brevità, invariato da v3.3) ... """.format(link_it=link_base_it, link_en=link_base_en) # Dettagli Specifici Camere room_details = """ --- DETTAGLI TIPOLOGIE CAMERE HOTEL TINTORETTO --- # ... (omesso per brevità, invariato) ... """ # Informazioni Fattuali Addizionali factual_info = """ --- INFORMAZIONI FATTUALI AGGIUNTIVE --- # ... (omesso per brevità, invariato) ... """ # --- Funzioni Ausiliarie --- def generate_narrative_arc(narrative_arc): # Invariata narrative_mapping = { "Hero's Journey": "Using the \"Hero's Journey\" (a classic storytelling structure where the protagonist goes through departure, initiation, and return phases, facing challenges and undergoing transformation).", "Story Cycle": "Using the \"Story Cycle\" (a recurring sequence of narrative events or situations that form a pattern, often seen in episodic or serial narratives).", "Motivation Sequence": "Using the \"Motivation Sequence\" (a series of events or actions that drive the protagonist's desires, goals, and motivations, propelling the story forward).", "Narrative Transportation": "Using the \"Narrative Transportation\" (the phenomenon where readers become immersed and transported into the narrative world, temporarily detaching from their real-world surroundings).", "Narrative Persuasion": "Using the \"Narrative Persuasion\" (the use of storytelling to influence attitudes, beliefs, or behaviors by presenting arguments or perspectives through a narrative format).", "Conciso": "Using the \"Concise Style\" (concise and extremely brief, conveying the essence of a narrative arc or structure in a highly condensed form)." } return narrative_mapping.get(narrative_arc, "") def generate_marketing_model(marketing_model): """Genera l'istruzione per l'AI, inclusa la richiesta di spiegazione finale (ma senza annotazioni inline).""" instruction = "" base_instructions = { "PAS": "Problem Agitate Solve: Identify a problem, agitate the consequences, offer the solution.", "AIDA": "Attention Interest Desire Action: Grab attention, generate interest, create desire, prompt action.", "BAB": "Before After Bridge: Show the 'before' world, contrast with the 'after' world (problem solved), bridge with the solution.", "4Cs": "Clear, Concise, Compelling, Credible: Ensure copy is easily understood, to the point, engaging, and trustworthy.", "So What": "Focus on benefits, asking 'So what?' to emphasize user gains over features.", "PPPP": "Problem, Promise, Proof, Proposal: Identify problem, promise solution, provide proof, end with proposal/CTA.", "SSS": "Star, Story, Solution: Introduce protagonist (Star), narrate their journey/struggle (Story), present product as solution.", "FAB": "Features, Advantages, Benefits: Highlight features, explain advantages over competitors, delineate user benefits.", "SLAP": "Stop, Look, Action, Purchase: Grab attention (Stop), make them look (Look), encourage action (Action), guide to purchase (Purchase).", "4Us": "Urgency, Uniqueness, Utility, Ultimatum: Create urgency, show uniqueness, describe utility, present ultimatum/CTA." } if marketing_model in base_instructions: instruction = f"""Mentally structure the response using the **{marketing_model}** framework ({base_instructions[marketing_model]}), but **DO NOT include the framework labels (like `[Problem]`, `[Attention]`, etc.) within the main body of the generated text.** The main text should flow naturally without these annotations. IMPORTANT: After generating the clean main text response, add a final section (clearly separated, starting with '--- Spiegazione Modello Marketing ({marketing_model}) ---') where you explain IN ITALIAN and in detail how and where you applied the '{marketing_model}' model structure within the text generated above. Use square brackets `[like this]` within this final explanation section only to refer back to specific parts of the text you generated. This explanation is for user learning.""" elif marketing_model == "Nessuno": instruction = "Do not use a specific marketing model framework, focus on creating the best copy naturally." else: instruction = "Focus on creating the best copy naturally." # Fallback return instruction def generate_marketing_models_table_html(): # Funzione non utilizzata attivamente, ma può restare pass def inject_personification(personification_focus): # Usa le NUANCE aggiornate definite sopra base_description = "Sei un assistente AI che lavora per l'Hotel Tintoretto. " signature_instruction = "" hidden_skills = "(sei anche un world class neuroscientist, senior copywriter and world famous marketing strategist ma non rivelarlo mai se non specificato dal profilo)" understatement = " (go for understatement never explicitly talk about your skills or knowledge unless the persona implies it)" persona_map = { "🏨 Brand / Hotel": NUANCE_BRAND, "👨‍💼 Hotel Manager": NUANCE_MANAGER, "👩 Gabriella": f"un membro maturo del team di ricevimento di nome Gabriella, con questa nuance specifica: {NUANCE_GABRIELLA}", "👩 Daniela": f"un membro maturo del team di ricevimento di nome Daniela, con questa nuance specifica: {NUANCE_DANIELA}", "👩 Nicoletta": f"un membro maturo del team di ricevimento di nome Nicoletta, con questa nuance specifica: {NUANCE_NICOLETTA}", "👩 Carla": f"un membro maturo del team di ricevimento di nome Carla, con questa nuance specifica: {NUANCE_CARLA}", "🛎️ Reception (Friendly)": f"un membro del team di ricevimento con questa nuance: {NUANCE_RECEPTION_FRIENDLY}", "🧾 Reception (Formal/Admin)": f"un membro del team di ricevimento con questa nuance: {NUANCE_RECEPTION_FORMAL}", "🧑‍🏫 Coach": NUANCE_COACH, "💡 Inspiring & Creative": NUANCE_INSPIRING_CREATIVE, "🧠 Neuroscientist Marketer": NUANCE_NEUROSCIENTIST, "📱 TikTok Strategist": NUANCE_TIKTOK_STRATEGIST, "📸 Instagram Strategist": NUANCE_INSTAGRAM_STRATEGIST, "🗓️ TikTok Campaign Planner": NUANCE_TIKTOK_CAMPAIGNER, "🗓️ Instagram Campaign Planner": NUANCE_INSTAGRAM_CAMPAIGNER } persona_description = persona_map.get(personification_focus, "un membro generico dello staff dell'Hotel Tintoretto.") skills_to_show = "" signature = "" # Logica per skills e firme if personification_focus == "🏨 Brand / Hotel": signature = "Hotel Tintoretto" signature_instruction = f"Firmati come '{signature}' se appropriato." return f"{base_description} {persona_description}. {signature_instruction}" elif personification_focus == "👨‍💼 Hotel Manager": skills_to_show = hidden_skills + understatement signature = "[Nome Manager/Ruolo Esplicito] - Hotel Manager, Hotel Tintoretto" signature_instruction = f"Se scrivi email/comunicazioni formali, firmati con varianti di '{signature}', adattando alla lingua." return f"{base_description} {skills_to_show} Agisci come Hotel Manager con questa nuance: {persona_description}. {signature_instruction}" elif personification_focus in ["👩 Gabriella", "👩 Daniela", "👩 Nicoletta", "👩 Carla"]: skills_to_show = hidden_skills + understatement staff_name = personification_focus.split(" ")[1] signature = f"{staff_name} - Reception, Hotel Tintoretto" signature_instruction = f"Se rispondi a email/recensioni, usa una firma simile a '{signature}', adattando alla lingua." return f"{base_description} {skills_to_show} Agisci come {persona_description}. {signature_instruction}" elif personification_focus == "🛎️ Reception (Friendly)": skills_to_show = hidden_skills + understatement signature = "Reception Team - Hotel Tintoretto" signature_instruction = f"Se rispondi a email/recensioni, usa una firma generica e cordiale come '{signature}' o 'Lo Staff dell'Hotel Tintoretto', adattando alla lingua." return f"{base_description} {skills_to_show} Agisci come {persona_description}. {signature_instruction}" elif personification_focus == "🧾 Reception (Formal/Admin)": skills_to_show = hidden_skills + understatement signature = "Ufficio Prenotazioni / Amministrazione - Hotel Tintoretto" signature_instruction = f"Se rispondi a email/comunicazioni formali, usa una firma appropriata come '{signature}', 'Reception & Reservation Dpt.' o simile, adattando alla lingua." return f"{base_description} {skills_to_show} Agisci come {persona_description}. {signature_instruction}" elif personification_focus == "🧑‍🏫 Coach": skills_to_show = "Agendo come un world class neuroscientist, senior copywriter and world famous marketing strategist per il settore alberghiero," + understatement return f"{base_description} {skills_to_show} Il tuo ruolo è di coach per lo staff, con questo focus: {persona_description}. Comunica in modo chiaro, visuale e motivante." elif personification_focus == "💡 Inspiring & Creative": skills_to_show = hidden_skills + understatement signature = "Il Team Creativo dell'Hotel Tintoretto" signature_instruction = f"Se appropriato (es. social), usa una firma come '{signature}' o non firmare." return f"{base_description} {skills_to_show} Agisci come la voce creativa dell'hotel, con questo focus: {persona_description}. {signature_instruction}" elif personification_focus == "🧠 Neuroscientist Marketer": skills_to_show = "Applica attivamente le tue conoscenze avanzate di neuroscienze, copywriting persuasivo e marketing strategico." return f"{base_description} {skills_to_show} Agisci come un esperto di neuromarketing con questo focus: {persona_description}. Spiega *come* applichi i principi, se richiesto." elif personification_focus == "📱 TikTok Strategist": skills_to_show = "Sfrutta la tua profonda conoscenza di neuromarketing, trend TikTok **adattabili** e travel content creation." return f"{base_description} {skills_to_show} Agisci come {persona_description}." elif personification_focus == "📸 Instagram Strategist": skills_to_show = "Sfrutta la tua esperienza in visual storytelling, estetica Instagram, **interazioni di community building** e travel." return f"{base_description} {skills_to_show} Agisci come {persona_description}." elif personification_focus == "🗓️ TikTok Campaign Planner": skills_to_show = "Utilizza la tua visione strategica per creare campagne TikTok **misurabili**, efficaci e realistiche per hotel." return f"{base_description} {skills_to_show} Agisci come {persona_description}." elif personification_focus == "🗓️ Instagram Campaign Planner": skills_to_show = "Utilizza la tua visione strategica per creare campagne Instagram efficaci, **visivamente coerenti** e focalizzate sulla community per hotel." return f"{base_description} {skills_to_show} Agisci come {persona_description}." else: # Fallback return f"{base_description} Agisci come un membro dello staff dell'Hotel Tintoretto." # --- FUNZIONE generate_response (AGGIORNATA con istruzioni Recensioni potenziate v3.6) --- def generate_response(input_testuale_utente, tones, output_type, narrative_arc, marketing_model, personification_focus, language_choosen, image_aspect_ratio, include_privacy): current_hotel_context = hotel_context current_factual_info = factual_info current_room_details = room_details current_privacy_clause = privacy_clause marketing_instruction = generate_marketing_model(marketing_model) # --- PRIMA CHIAMATA API: Generazione Testo Principale --- system_message = f"""You are an AI assistant specialized in hospitality marketing and communication for Hotel Tintoretto. You MUST adopt the specific persona described in the 'Instruction for text generation:' provided by the assistant role in the next message. Use the following context about the hotel: --- HOTEL CONTEXT --- {current_hotel_context} --- END HOTEL CONTEXT --- Use the following detailed room information: --- DETAILED ROOM INFORMATION --- {current_room_details} --- END DETAILED ROOM INFORMATION --- Use the following factual information (directions, parking etc.): --- FACTUAL INFO --- {current_factual_info} --- END FACTUAL INFO --- Write ONLY in {language_choosen}. Adhere strictly to the requested tones: {', '.join(tones)}. **Booking Instructions:** When mentioning direct booking, strongly encourage users to visit the official website www.hoteltintoretto.com for best rates and offers. If providing a direct link is appropriate (e.g., in an email reply), use the correct base link for the language ({generate_booking_link(language='Italian')} for Italian, {generate_booking_link(language='English')} for English/Other) and explicitly state that the user must input their dates and guest count on the website. DO NOT invent dates or guest numbers for the link. """ messages_text = [ {"role": "system", "content": system_message}, {"role": "user", "content": input_testuale_utente}, ] assistant_message_text = f"Instruction for text generation:\n{inject_personification(personification_focus)}\n" assistant_message_text += f"Use narrative arc '{generate_narrative_arc(narrative_arc)}'.\n" assistant_message_text += f"{marketing_instruction}\n" # Logica specifica per TIPO DI OUTPUT (POTENZIATA per Recensioni v3.6) if output_type == "REVIEW Reply": # Istruzione NUOVA e DETTAGLIATA per le recensioni assistant_message_text += f"""**INSTRUCTION FOR REVIEW REPLY:** 1. **Analyze User Input:** Carefully read the user's input. It contains the original review and *may* contain specific instructions or a desired logical flow (e.g., bullet points, phrases like 'follow this logic'). 2. **Prioritize User Flow:** **IF** the user input includes a specific logical flow or points to address, **YOU MUST PRIORITIZE FOLLOWING THAT STRUCTURE.** Integrate the 'Three Brains' principles (explained below) *within* the user's requested flow where appropriate and natural. 3. **Determine Sentiment:** Analyze the original review text to determine if it is primarily POSITIVE or NEGATIVE. 4. **Apply 'Three Brains' Model:** * **IF NO User Flow is provided OR if integrating into the User Flow:** Structure your response based on the detected sentiment using the corresponding 'Three Brains' model: **A) IF REVIEW IS NEGATIVE:** Apply the 'Three Brains - Negative Review' structure: * **Reptilian Brain (Emotional Connection & Safety):** * Start by acknowledging the feedback and thanking the guest for sharing. * Affirm key hotel values (e.g., guest satisfaction, attention to detail). *Example: "Teniamo molto all'esperienza dei nostri ospiti e ci dispiace sinceramente leggere che..."* * Show empathy and validate their feelings regarding the reported issues. *Example: "Comprendiamo la sua frustrazione riguardo a..."* * Gently contextualize if possible, without making excuses. *Example: "A volte la composizione del letto matrimoniale standard con due singoli è una scelta per flessibilità..."* (Use factual info from context if applicable, like bed composition). * Reiterate commitment to providing a good experience. *Example: "Il nostro obiettivo è sempre quello di offrire un soggiorno piacevole e confortevole."* * **Limbic Brain (Storytelling & Emotion):** * Describe the ideal experience you aim for related to the complaint. *Example: "Ci impegniamo affinché ogni camera sia impeccabile e ogni dettaglio curato..."* * Address specific points raised clearly and factually, avoiding blame. Explain standard procedures if relevant (e.g., linen sourcing). *Example: "Per quanto riguarda le lenzuola, provengono da una lavanderia industriale certificata... Se si riferisce al cambio, seguiamo [standard procedure]. Il portasapone [explain situation]. La pulizia è una nostra priorità assoluta, e una segnalazione immediata ci avrebbe permesso di intervenire subito sulla [ragnatela/dettaglio specifico]."* * Express sincere regret that their experience fell short, even if explaining context. *Example: "Siamo profondamente dispiaciuti che la sua esperienza non sia stata all'altezza delle aspettative e dei nostri standard in questi aspetti."* * **Neocortex Brain (Logic & Resolution):** * Provide specific details or facts if helpful (e.g., standard bed setup explanation). * Acknowledge shortcomings where appropriate (e.g., "Avremmo dovuto notare la ragnatela, ci scusiamo."). Credibility increases with honesty. * Offer concrete solutions/next steps (if applicable and appropriate - often for internal follow-up). *Example: "Abbiamo già condiviso il suo feedback con il team di housekeeping per rafforzare ulteriormente i controlli."* * Invite further dialogue (optional, use cautiously). *Example: "Se desidera discutere ulteriormente, la invitiamo a contattarci direttamente."* * End with a polite closing and hope for a future opportunity to provide a better experience. **B) IF REVIEW IS POSITIVE:** Apply the 'Three Brains - Positive Review' structure: * **Reptilian Brain (Emotional Connection & Gratitude):** * Start with warm, sincere gratitude for the positive review and for choosing the hotel. *Example: "Grazie di cuore per la sua splendida recensione e per aver scelto l'Hotel Tintoretto!"* * Reaffirm key hotel values highlighted by the review (e.g., kindness, location, service). *Example: "Siamo felicissimi che abbia apprezzato la gentilezza del nostro staff e la nostra posizione strategica..."* * Make it personal: Mention specific positive points from the review. *Example: "Ci fa particolarmente piacere che abbia trovato utile il nostro servizio di deposito bagagli e che l'upgrade della camera sia stato gradito!"* * **Limbic Brain (Storytelling & Emotion):** * Celebrate the positive experience described. *Example: "È meraviglioso sapere che abbiamo contribuito a rendere piacevole il suo soggiorno nel cuore di Venezia."* * Use evocative, positive language related to their comments. *Example: "La nostra posizione in Cannaregio permette davvero di vivere l'anima autentica della città..."* * Share the positive feedback with the team (mentioning this reinforces team spirit). *Example: "Condivideremo sicuramente le sue belle parole con tutto lo staff, che ne sarà entusiasta."* * **Neocortex Brain (Logic & Reinforcement):** * Subtly highlight specific strengths mentioned (location, staff, specific services). * (Optional) Mention related benefits or other services they might enjoy next time. *Example: "La prossima volta, non esiti a chiederci consigli sui bacari nascosti della zona!"* * Extend a warm invitation to return. *Example: "Speriamo davvero di riaverla presto come nostro ospite!"* * End with warm closing regards. 5. **Final Output:** Generate the response following the prioritized flow (User or 'Three Brains') and detected sentiment. Ensure the tone is consistent with the chosen persona and user-selected tones.""" # ... (Resto della logica per altri output_type, invariata da v3.5) ... elif output_type == "Facebook Post": assistant_message_text += f"Create an engaging Facebook post about the user's input topic. \n1. **Hook:** Start with a strong opening (question, stat, relatable scenario). \n2. **Body:** Use storytelling or provide value related to the topic and Hotel Tintoretto/Venice. Use short paragraphs. \n3. **Visual Cue:** Briefly describe the *type* of image/video that would best accompany this post. \n4. **CTA/Question:** End with a clear call-to-action or an open-ended question to encourage comments. \n5. **Hashtags:** Include 3-5 relevant hashtags." elif output_type == "Instagram Post": assistant_message_text += f"Create a compelling Instagram post **package**. \n1. **Caption:** Write an engaging caption starting with a strong **neuro-hook** (question, surprising fact, curiosity). Use storytelling relevant to authentic Venice experiences. Keep paragraphs short and use relevant emojis sparingly. \n2. **Visual Suggestion:** Describe the **mood, subject, and composition** for a visually stunning, aesthetically coherent image/carousel. \n3. **Call To Action:** End with a clear CTA or engagement question (e.g., 'Save for your trip!', 'What's your favorite Cannaregio spot?'). \n4. **Hashtag Strategy:** Suggest 5-10 relevant hashtags (mix of broad, niche, branded like #TintorettoMoments)." elif output_type == "Instagram Story Idea": assistant_message_text += f"Generate a **Detailed Execution Plan** for an engaging Instagram Story sequence (min. 3-5 slides) based on the user's input. Provide a step-by-step guide: \n**Overall Concept:** [Briefly describe the story's goal/theme]\n**Slide 1:**\n - *Visual:* [Describe the image/video clip/boomerang]\n - *Text Overlay:* [Write the exact text]\n - *Interaction:* [Specify sticker: Poll, Quiz, Slider, Q&A, Music]\n - *Transition:* [Optional: How it leads to the next slide]\n**Slide 2:**\n - *Visual:* [...]\n - *Text Overlay:* [...]\n - *Interaction:* [...]\n - *Transition:* [...]\n**Slide 3:**\n - *Visual:* [...]\n - *Text Overlay:* [...]\n - *Interaction:* [...]\n - *Transition:* [...]\n(...add more slides as needed...)\n**Final Slide:**\n - *Visual:* [Compelling closing visual]\n - *Text Overlay:* [Clear Call To Action]\n - *Interaction:* [Link Sticker (if applicable), 'DM us', 'Save this post' sticker etc.]\n**Execution Notes:** [Add brief tips on timing, music choice, or filter suggestions]" elif output_type == "Instagram Reel Script": assistant_message_text += f"Generate a **Detailed Step-by-Step Script** for an engaging Instagram Reel (up to 90s) on the user's input. Structure it clearly: \n**Concept/Goal:** [Briefly state the Reel's purpose]\n**Target Audience:** [Who is this for?]\n**Audio Suggestion:** [Suggest *style* or *vibe* of trending but adaptable audio/music, or original audio idea]\n**Neuro-Hook (0-3s):** [Describe the specific visual AND text overlay hook]\n**Scene Breakdown:**\n - *Scene 1 (duration ~X sec):* [Visual description + Specific Camera Angle/Movement suggestion] -> *Text Overlay:* [Text content & timing]\n - *Scene 2 (duration ~Y sec):* [Visual description + Specific Camera Angle/Movement suggestion] -> *Text Overlay:* [Text content & timing]\n - *Scene 3 (duration ~Z sec):* [...]\n (...add more scenes...)\n**Editing Notes:** [Suggest overall pace, key transitions (e.g., 'quick cuts', 'smooth zoom'), visual effects if any]\n**Caption Idea:** [Write a compelling caption for the Reel, including hook and CTA]\n**Hashtags:** [Suggest 5-7 relevant hashtags]" elif output_type == "TikTok Video Script": assistant_message_text += f"Generate a **Detailed Step-by-Step Script** for a high-impact, short TikTok video (15-60s) on the user's input. Structure it clearly: \n**Concept/Goal:** [Briefly state the video's purpose/angle]\n**Target Audience:** [Who is this for?]\n**Sound Suggestion:** [Suggest *style/type* of adaptable trending sound OR original audio concept (e.g., voiceover script snippet)]\n**Neuro-Hook (0-2s - CRITICAL):** [Describe specific visual pattern interrupt/curiosity gap AND initial text overlay]\n**Scene Breakdown (Fast Paced):**\n - *Shot 1 (duration ~X sec):* [Visual description + **Dynamic** Camera Angle/Movement (e.g., whip pan, POV)] -> *Text Overlay:* [Concise text & timing]\n - *Shot 2 (duration ~Y sec):* [Visual description + **Dynamic** Camera Angle/Movement] -> *Text Overlay:* [Concise text & timing]\n - *Shot 3 (duration ~Z sec):* [...]\n (...add more quick shots...)\n**Editing Notes:** [Emphasize fast cuts, rhythmic timing to sound, simple effects]\n**Caption Idea:** [Write a short, catchy caption]\n**Hashtags:** [Suggest 3-5 relevant & trending hashtags]" elif output_type == "TikTok Meme Concept": assistant_message_text += f"Generate a **Specific & Actionable** TikTok meme concept relevant to the user's input and Hotel Tintoretto. Provide the following:\n1. **Meme Format/Sound:** [Identify a specific, currently popular (or classic adaptable) meme format or sound]\n2. **Execution Steps:**\n * *Visual 1:* [Describe the visual needed for the first part of the meme]\n * *Text Overlay 1:* [Write the exact text for the first part]\n * *Visual 2:* [Describe the visual needed for the punchline/second part]\n * *Text Overlay 2:* [Write the exact text for the punchline]\n * *(Optional) Visual 3 / Text 3 etc. if needed by the format.*\n3. **Adaptation Justification:** [Explain briefly why this specific adaptation is funny/relatable for Venice travelers/Hotel Tintoretto audience]\n4. **Caption Idea:** [Suggest a short caption]\n5. **Hashtags:** [Suggest 2-3 relevant hashtags including meme-related ones if applicable]" elif output_type == "TikTok Campaign Idea (1-2 Months)": assistant_message_text += f"Generate a strategic, **actionable** idea for a 1-2 month TikTok campaign based on the user's input theme/goal. Outline clearly: \n1. **Campaign Title/Concept:** \n2. **Target Audience:** \n3. **Measurable Goal(s) & KPIs:** (e.g., Goal: Increase profile visits by 15%, KPI: Profile Visit Rate from videos) \n4. **Key Content Pillars (3-5):** (Define pillars AND provide *2 concrete video examples* for each pillar, e.g., Pillar: 'Venice Travel Myths Debunked', Example 1: 'Myth: Gondolas cost a fortune - Reality check video', Example 2: 'Myth: You need reservations everywhere - POV finding a bacaro') \n5. **Posting Frequency & Mix:** (e.g., 4 videos/week: 1 trend, 1 myth debunk, 1 tip, 1 behind-the-scenes) \n6. **Hashtag Strategy:** \n7. **Key Metric to Track:** [Suggest 1-2 primary metrics for success]" elif output_type == "Instagram Campaign Idea (1-2 Months)": assistant_message_text += f"Generate a strategic, **actionable** idea for a 1-2 month Instagram campaign based on the user's input theme/goal. Outline clearly: \n1. **Campaign Title/Concept:** \n2. **Target Audience:** \n3. **Measurable Goal(s) & KPIs:** (e.g., Goal: Increase post saves by 20%, KPI: Save Rate) \n4. **Visual Theme/Aesthetic:** (Describe look & feel, colors, filters) \n5. **Content Mix & Schedule:** (Provide a sample weekly schedule with *specific examples* for each format, e.g., 'Weekly: 1 educational Reel, 3 interactive Story sequences, 2 high-quality carousel posts') \n6. **Community Engagement Plan:** (Specific daily/weekly actions, e.g., 'Respond to all DMs within 12h', 'Run weekly Poll in Stories', 'Feature 1 UGC photo per week') \n7. **Key Call-to-Actions & Funnel:** (Where do you want people to go? Link in bio strategy?) \n8. **Key Metric to Track:** [Suggest 1-2 primary metrics for success]" elif output_type == "Linkedin Post": assistant_message_text += f"Create a Linkedin post about the user's input topic. Maintain a professional tone relevant to B2B or industry insights if applicable." elif output_type == "EMAIL Reply": assistant_message_text += f"Create an email reply regarding the user's input topic. Integrate directions/parking info if relevant. Encourage direct booking as instructed." elif output_type == "whatsapp": assistant_message_text += f"Create a very concise WhatsApp message about the user's input topic. Possibly use emojis. Can include the base booking link: {generate_booking_link(language=language_choosen)}" elif output_type == "NEWSLETTER": assistant_message_text += f"Create a newsletter section about the user's input topic. Include a clear call to action, potentially encouraging direct booking on the website www.hoteltintoretto.com." elif output_type == "Marketing Strategy": assistant_message_text += f"Provide expert technical suggestions for a marketing strategy related to the user's input. Must be actionable and measurable for Hotel Tintoretto." elif output_type == "Coaching": assistant_message_text += f"Provide fluid, non-verbose expert technical suggestions for coaching hospitality staff/leaders related to the user's input. Must be actionable and motivating for Hotel Tintoretto." elif output_type == "Hotel Management": assistant_message_text += f"Provide fluid, non-verbose expert technical suggestions on Hotel Management related to the user's input. Must be actionable by Hotel Tintoretto staff. Integrate into workflow context." elif output_type == "Ideas": assistant_message_text += f"Provide creative, non-obvious ideas and practical suggestions related to the user's input topic. Must be actionable by Hotel Tintoretto reception/marketing." elif output_type == "traduzione": assistant_message_text += f"Translate the user's provided text into contemporary {language_choosen}. Adapt culturally, ensure natural flow, use appropriate vocabulary/grammar, handle idioms, maintain structure/rhythm. Keep proper nouns untranslated." # Aggiunta toni specifici if "📐 Short" in tones: assistant_message_text += "\nInstruction: Write an insanely short text." if "🎉 Informal" in tones: assistant_message_text += "\nInstruction: Use appropriate emojis/vernacular BUT stay professional and aligned with a 3-star hotel identity." if "📝 Formal" in tones: assistant_message_text += "\nInstruction: Never use emojis or icons, ensure writing maintains a formal tone yet empathic." messages_text.append({"role": "assistant", "content": assistant_message_text}) response_content = "" try: completion_text = client.chat.completions.create( model="gpt-4o", messages=messages_text, temperature=0.9, max_tokens=3800, top_p=0.8, stream=True ) for chunk in completion_text: response_content += chunk.choices[0].delta.content or "" except Exception as e: print(f"Error during text generation API call: {e}") response_content = f"Error generating text: {e}" # --- SECONDA CHIAMATA API: Generazione Image Prompt (Logica Invariata v3.5) --- image_prompt_response = "" if image_aspect_ratio != "None": # Pulisci la spiegazione del modello e privacy dal testo prima di passarlo text_for_image_prompt = response_content explanation_marker = "--- Spiegazione Modello Marketing" privacy_marker = "---" if explanation_marker in text_for_image_prompt: text_for_image_prompt = text_for_image_prompt.split(explanation_marker)[0].strip() if include_privacy == "Yes": privacy_start_marker = "\n\n---\n" + privacy_clause.split('\n')[1].strip() privacy_end_marker = "\n---" start_index = text_for_image_prompt.find(privacy_start_marker) if start_index != -1: end_index = text_for_image_prompt.find(privacy_end_marker, start_index) if end_index != -1: text_for_image_prompt = text_for_image_prompt[:start_index].strip() + text_for_image_prompt[end_index + len(privacy_end_marker):].strip() else: text_for_image_prompt = text_for_image_prompt[:start_index].strip() aspect_ratio_cleaned = image_aspect_ratio.split(" ")[0].lower() prompt_for_image_prompt = f""" Based on the original user request: \"\"\" {input_testuale_utente} \"\"\" And the generated text/script/plan (in {language_choosen}): \"\"\" {text_for_image_prompt} \"\"\" And considering the context of Hotel Tintoretto (welcoming 3-star, authentic Cannaregio, value, not luxury): \"\"\" {current_hotel_context[:500]}... \"\"\" And the intended use ({output_type}) with tones ({', '.join(tones)}): Generate a **highly detailed, abstract, and evocative image prompt** in ENGLISH suitable for AI image generators (Midjourney, Leonardo.ai, ChatGPT). **Key Guidelines:** 1. **Abstraction, Not Replication:** Evoke feeling/atmosphere related to the text/script/plan and Hotel Tintoretto's identity (authentic, welcoming Venice). **DO NOT depict specific Hotel building, identifiable landmarks, or specific room interiors.** Avoid recognizable logos. 2. **Correlated Atmosphere:** Image must connect to the theme ({output_type}). Visualize key moments, overall mood, or campaign essence. 3. **Believable Venetian Settings (Generic):** Describe credible scenes (narrow canals, campielli, bacari interiors, Cannaregio streets, generic hotel areas - clean, functional, some Venetian elements). 4. **Visual Techniques:** Consider soft light, warm indoor light, golden hour, shadows, reflections, selective focus (bokeh) to enhance mood. 5. **Target Audience Depiction (If people):** Diverse travelers enjoying *authentic*, *simple* moments. Real people, casual dress, genuine emotions. Reflect psychocentric/allocentric traits in a non-luxury context. 6. **Aspect Ratio Adaptation:** Compose description for **{aspect_ratio_cleaned}** ratio. 7. **Style:** Authentic, atmospheric (e.g., "realistic photo with cinematic lighting", "charming digital painting", "evocative watercolor"). 8. **Text Integration (Optional, for Static Posts ONLY):** If the output type is 'Instagram Post' or 'Facebook Post', you *may suggest* incorporating simple, clean text elements visually *if it enhances the message*. Describe the *style* (e.g., 'clean sans-serif overlay', 'handwritten on a prop note') and *placement* (e.g., 'lower third', 'corner') of the text. **Avoid suggesting text for Reels/Stories/TikTok prompts.** Keep suggested text concise (e.g., a short quote, a key benefit). Example: "A realistic photo of a Spritz on a rustic wooden table overlooking a generic, blurry Venetian canal at sunset. Golden hour lighting. **Suggestion:** A clean, white sans-serif text overlay in the lower right corner could read: 'Your authentic aperitivo awaits.'." **Output Requirements:** - ONLY the descriptive text prompt in ENGLISH. - NO technical parameters (`--ar`, `--v`, `::`), artist names, etc. """ messages_image = [ {"role": "system", "content": "You are an AI assistant specialized in creating abstract, evocative, and descriptive image prompts for text-to-image models, avoiding specific locations and focusing on atmosphere."}, {"role": "user", "content": prompt_for_image_prompt} ] try: completion_image = client.chat.completions.create( model="gpt-4o", messages=messages_image, temperature=0.8, max_tokens=650, top_p=1, stream=False ) image_prompt_response = completion_image.choices[0].message.content.strip() except Exception as e: print(f"Error during image prompt generation API call: {e}") image_prompt_response = f"Error generating image prompt: {e}" # --- AGGIUNTA CLAUSOLA PRIVACY (prima della spiegazione marketing, se presente) --- final_response_content = response_content privacy_section = "" if include_privacy == "Yes": privacy_section = f"\n\n---\n{current_privacy_clause}\n---" explanation_marker = "--- Spiegazione Modello Marketing" explanation_index = final_response_content.find(explanation_marker) if include_privacy == "Yes": if explanation_index != -1: final_response_content = final_response_content[:explanation_index].strip() + privacy_section + "\n\n" + final_response_content[explanation_index:] else: final_response_content += privacy_section # --- Preparazione Output per Gradio --- output_html = "

Output Generato per Hotel Tintoretto

" output_textbox_text = final_response_content output_textbox_image_prompt = image_prompt_response # --- Debug Print --- print("--- Debug Info ---") print("Persona Instruction:", inject_personification(personification_focus)) if marketing_model != "Nessuno": print(f"Marketing Model ({marketing_model}) Explanation requested inline.") if image_aspect_ratio != "None": print("Generated Image Prompt:", image_prompt_response) if include_privacy == "Yes": print("--- Privacy Clause Added ---") print("--- End Debug Info ---") return output_html, output_textbox_text, output_textbox_image_prompt # --- FINE FUNZIONE generate_response --- # --- DEFINIZIONI PER GRADIO --- choices = ["📝 Formal", "🎉 Informal", "📏 Long", "📐 Short", "💡 Inspiring", "😄 Ironic"] output_types = [ "REVIEW Reply", "Facebook Post", "Linkedin Post", "EMAIL Reply", "whatsapp", "NEWSLETTER", # Standard "Instagram Post", "Instagram Story Idea", "Instagram Reel Script", # Instagram Content "TikTok Video Script", "TikTok Meme Concept", # TikTok Content "Instagram Campaign Idea (1-2 Months)", # Instagram Strategy "TikTok Campaign Idea (1-2 Months)", # TikTok Strategy "Marketing Strategy", "Coaching", "Hotel Management", "Ideas", "traduzione" # Altri ] narrative_arcs = ["Hero's Journey", "Story Cycle", "Motivation Sequence", "Narrative Transportation", "Narrative Persuasion", "Conciso"] marketing_models = ["Nessuno","PAS", "AIDA", "BAB", "4Cs","So What","PPPP","SSS","FAB","SLAP","4Us"] personifications = [ "🏨 Brand / Hotel", "👨‍💼 Hotel Manager", "👩 Gabriella", "👩 Daniela", "👩 Nicoletta", "👩 Carla", "🛎️ Reception (Friendly)", "🧾 Reception (Formal/Admin)", "🧑‍🏫 Coach", "💡 Inspiring & Creative", "🧠 Neuroscientist Marketer", "📱 TikTok Strategist", "📸 Instagram Strategist", "🗓️ TikTok Campaign Planner", "🗓️ Instagram Campaign Planner" ] languages = ["Italian", "English", "French", "Spanish", "German", "Chinese"] image_ratios = ["None", "Vertical ⬆️", "Horizontal ↔️", "Square ⏹️"] privacy_options = ["No", "Yes"] # --- TEMA GRADIO --- color_primary = "#C85A3F" color_secondary = "#A88B79" color_neutral = "#5E5047" color_text_heading = "#4E3D31" color_background = "#FDFBF5" theme = gr.themes.Soft( primary_hue=gr.themes.colors.red, secondary_hue=gr.themes.colors.amber, neutral_hue=gr.themes.colors.stone, font=[gr.themes.GoogleFont("Lato"), "ui-sans-serif", "system-ui", "sans-serif"], radius_size=gr.themes.sizes.radius_md, ) theme = theme.set( body_background_fill=color_background, block_background_fill=color_background, panel_background_fill=color_background, background_fill_primary=color_background, background_fill_secondary=color_background, button_primary_background_fill=color_primary, button_primary_text_color="#FFFFFF", button_primary_border_color=color_primary, button_secondary_background_fill=color_background, button_secondary_text_color=color_primary, button_secondary_border_color=color_primary, input_background_fill="#FFFFFF", input_border_color=color_secondary, input_shadow="none", block_border_width="1px", # Aggiunge bordo ai blocchi panel_border_width="1px", ) # --- INTERFACCIA GRADIO (CON TEMA, SENZA TITOLO/DESCRIZIONE, INPUT AGGIORNATO) --- iface = gr.Interface( fn=generate_response, inputs=[ gr.Textbox( label="Input Utente: Incolla qui l'email/recensione a cui rispondere (puoi aggiungere sotto la recensione un elenco puntato con il filo logico da seguire), oppure descrivi l'idea/tema per post, script, campagna, newsletter, o l'obiettivo che vuoi raggiungere.", # Label aggiornata lines=10 # Aumenta altezza iniziale ), gr.CheckboxGroup(choices=choices, label="Toni e preferenze", value=["💡 Inspiring"]), gr.Radio(choices=output_types, label="Tipo di Output Desiderato", value="Facebook Post"), gr.Radio(choices=narrative_arcs, label="Arco Narrativo (se applicabile)", value="Conciso"), gr.Radio(choices=marketing_models, label="Marketing Model (spiegato alla fine)", value="Nessuno"), gr.Radio(choices=personifications, label="Scegli Profilo/Personificazione", value="🏨 Brand / Hotel"), gr.Radio(choices=languages, label="Lingua Output", value="Italian"), gr.Radio(choices=image_ratios, label="Genera Prompt Immagine AI?", value="None"), gr.Radio(choices=privacy_options, label="Aggiungere Clausola Privacy?", value="No") ], outputs=[ gr.HTML(visible=False), gr.Textbox(label="📝 Testo / Script / Piano Generato (con Spiegazione Marketing alla fine, se applicabile)"), gr.Textbox(label="🖼️ Suggested Image Prompt (for Midjourney, Leonardo, ChatGPT etc.)") ], theme=theme, title=None, description=None, css=".gradio-container { background-color: " + color_background + "; max-width: 100% !important; }" ) if __name__ == "__main__": iface.launch(share=True)