Social Media Chat Bot Marvin

Undergraduate dissertation: An AI-powered Telegram chatbot providing real-time social media marketing insights and analytics.

AI/MLDissertation
# features

Key Features

Core technologies and system features.

Interactive Chatbot

Telegram-based bot for querying social media marketing insights.

Data Analytics

Integration with Pandas for processing and analyzing large marketing datasets.

AI/ML Integration

Leverages AI to interpret trends and offer automated marketing recommendations.

# source

Project Source Code

Explore the primary logical modules.

EXPLORER
app.py
srcapp.py
1import os
2import io
3import pandas as pd
4from flask import Flask, render_template, request, jsonify
5from PIL import Image
6import google.generativeai as genai
7from dotenv import load_dotenv
8
9# Load local environment variables from .env if present
10load_dotenv()
11
12app = Flask(__name__)
13
14# Load FAQ dataset from CSV using robust path handling
15BASE_DIR = os.path.dirname(os.path.abspath(__file__))
16CSV_PATH = os.path.join(BASE_DIR, 'socialmedia.csv')
17
18faq_data_str = ""
19if os.path.exists(CSV_PATH):
20 try:
21 faq_df = pd.read_csv(CSV_PATH)
22 # Format the CSV dataset into a structured string context for the LLM prompt
23 formatted_faqs = []
24 for index, row in faq_df.iterrows():
25 formatted_faqs.append(f"Q: {row['Indent']}\nCategory: {row['Category']}\nA: {row['Reply']}")
26 faq_data_str = "\n\n".join(formatted_faqs)
27 print("Successfully loaded socialmedia.csv context.")
28 except Exception as e:
29 print(f"Error loading socialmedia.csv: {e}")
30else:
31 print("Warning: socialmedia.csv not found at", CSV_PATH)
32
33# Dictionary of specialized marketing persona instructions
34PERSONAS = {
35 'maven': (
36 "You are the ultimate Social Media Maven, a balanced, professional, and friendly social media marketing consultant. "
37 "You provide actionable, strategic, and engaging answers to help businesses optimize their online presence."
38 ),
39 'growth_hacker': (
40 "You are a hyper-focused, energetic Growth Hacker and Conversion Rate Optimization (CRO) expert. "
41 "Your advice centers on rapid scaling, viral mechanics, click-through rates (CTR), maximizing return on investment (ROI), "
42 "audience acquisition loops, bold metrics, and unconventional marketing tactics. You speak in a confident, high-energy tone."
43 ),
44 'instagram_expert': (
45 "You are a highly creative and trend-sensitive Instagram Specialist and Growth Coach. "
46 "Your advice focuses on maximizing Reels reach, visual grid aesthetics, stories engagement stickers, "
47 "high-converting bio optimization, hashtags vs. SEO keywords, and decoding the Instagram Explore/Feed algorithm. "
48 "You speak in a modern, visual-first, trendy, and enthusiastic tone."
49 ),
50 'content_strategist': (
51 "You are an articulate, creative Content Strategist and professional Copywriter. "
52 "Your expertise lies in writing scroll-stopping hooks, emotional triggers, readability, post formatting, visual layout, "
53 "effective hashtag categorization, and constructing editorial calendars. You are detail-oriented, trend-conscious, and stylistic."
54 ),
55 'analytics_guru': (
56 "You are a highly analytical, quantitative Analytics Guru and Performance Marketer. "
57 "You speak in numbers, CPC, CPM, CAC, attribution modeling, engagement ratios, and ROI diagnostics. "
58 "When giving advice, you focus on data-driven audits, video retention charts, conversion funnels, and structured logic."
59 ),
60 'crisis_manager': (
61 "You are a seasoned PR expert and Crisis Communications Manager. "
62 "You excel in community de-escalation, diplomatic brand representation, turning negative reviews into customer loyalty, "
63 "and brand safety guidelines. Your tone is incredibly calm, empathetic, professional, and reassuring."
64 )
65}
66
67def build_system_instruction(persona_name):
68 persona_info = PERSONAS.get(persona_name, PERSONAS['maven'])
69
70 instruction = (
71 f"{persona_info}\n\n"
72 "You are the expert conversational partner for this platform. To provide reliable, accurate information, "
73 "you have access to a verified local knowledge base of standard questions and responses. "
74 "Whenever a user asks a question closely related to this local knowledge base, align your explanation with "
75 "the verified answers provided below, while expanding on them with your custom persona styling:\n"
76 "--- VERIFIED FAQ KNOWLEDGE BASE ---\n"
77 f"{faq_data_str}\n"
78 "-------------------------------------\n\n"
79 "CRITICAL DIRECTIVES:\n"
80 "1. Answer in character. Maintain the specified persona tone at all times.\n"
81 "2. If the user uploads an image, analyze it as a social media screenshot, analytics chart, creative draft, or ad mockup. "
82 "Provide professional, persona-aligned critiques, highlighting strengths and specific areas of optimization.\n"
83 "3. Provide rich formatting with headings, bullet points, and code blocks (where relevant) using standard markdown."
84 )
85 return instruction
86
87@app.route('/')
88def home():
89 # Return index.html from templates
90 return render_template('index.html')
91
92@app.route('/get_response', methods=['POST'])
93def get_response():
94 # 1. Retrieve the client's API Key from HTTP Header or local environment
95 api_key = request.headers.get('X-Gemini-Key') or os.environ.get('GEMINI_API_KEY')
96
97 if not api_key:
98 return jsonify({
99 'response': (
100 "### 🔑 Gemini API Key Required\n\n"
101 "Please configure your Google Gemini API Key in the server environment to run the Maven AI chatbot:\n\n"
102 "1. Create a \`.env\` file in the project folder with:\n"
103 " \`\`\`env\n"
104 " GEMINI_API_KEY=your_gemini_api_key_here\n"
105 " \`\`\`\n"
106 "2. Restart the application server to apply changes."
107 ),
108 'needs_key': True
109 })
110
111 # 2. Get inputs from user form data
112 user_input = request.form.get('user_input', '').strip()
113 persona = request.form.get('persona', 'maven')
114
115 # 3. Check for uploaded image
116 uploaded_image = None
117 if 'image' in request.files:
118 image_file = request.files['image']
119 if image_file.filename != '':
120 try:
121 # Read image file into memory using Pillow
122 image_bytes = image_file.read()
123 uploaded_image = Image.open(io.BytesIO(image_bytes))
124 except Exception as e:
125 return jsonify({'response': f"❌ Error loading image file: {e}"})
126
127 if not user_input and not uploaded_image:
128 return jsonify({'response': "⚠️ Please enter a text message or upload an image."})
129
130 try:
131 # 4. Configure Gemini client and model
132 genai.configure(api_key=api_key)
133
134 # Build the dynamic instruction matching selected persona
135 system_instruction = build_system_instruction(persona)
136
137 model = genai.GenerativeModel(
138 model_name='gemini-1.5-flash',
139 system_instruction=system_instruction
140 )
141
142 # 5. Assemble content payload
143 contents = []
144 if uploaded_image:
145 contents.append(uploaded_image)
146
147 # Append text prompt. If no text was sent with image, give a default prompt
148 if user_input.startswith("[SYSTEM_COMMAND:ANALYZE_PROFILE]"):
149 handle = user_input.replace("[SYSTEM_COMMAND:ANALYZE_PROFILE]", "").strip()
150 prompt = f"Please act as an advanced AI Social Media Auditor. I have just connected my Telegram channel: {handle}. Generate a comprehensive, 4-point mock marketing audit and growth strategy for this account based on industry best practices. Assume {handle} is trying to increase engagement and subscriber growth. Include formatting, emojis, and specific actionable advice."
151 else:
152 prompt = user_input if user_input else "Analyze this social media image and provide marketing optimization recommendations."
153
154 contents.append(prompt)
155
156 # 6. Query Gemini model
157 response = model.generate_content(contents)
158
159 return jsonify({'response': response.text})
160
161 except Exception as e:
162 error_msg = str(e)
163 # Simplify common API key validation errors
164 if "API_KEY_INVALID" in error_msg or "API key not valid" in error_msg:
165 return jsonify({
166 'response': "❌ **Invalid Gemini API Key**. Please double check the key provided in the sidebar settings panel and try again."
167 })
168 return jsonify({'response': f"❌ **Gemini API Error:** {error_msg}"})
169
170if __name__ == '__main__':
171 app.run(debug=True)
# simulation

Live Simulation Output

Simulated console execution.

simulation
$_
# repositories

Source Code

GitHub repositories for this project.