Social media moves fast. One viral complaint can turn into a PR crisis before your team finishes coffee. In this tutorial, I will show you how to build a lightweight brand reputation monitor that ingests raw social mentions, classifies sentiment, flags urgent issues, and drafts response suggestions, all running on Oxlo.ai's flat per-request API.
What you'll need
- Python 3.10 or newer
- An Oxlo.ai API key from https://portal.oxlo.ai
- The OpenAI SDK:
pip install openai
Step 1: Initialize the Oxlo.ai client
The OpenAI SDK works as a drop-in client for Oxlo.ai. There is no custom library to learn. I start by creating the client pointing at the Oxlo.ai base URL.
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
Step 2: Ingest and normalize mentions
Real pipelines pull from the Twitter, Reddit, or Instagram APIs. To keep this runnable without extra credentials, I simulate a fetch with a plain Python list. Each mention carries an ID, platform, author, raw text, and timestamp.
def fetch_mentions():
return [
{
"id": "tw_001",
"platform": "twitter",
"author": "@frustrated_user",
"text": "Been waiting 3 weeks for my refund. Customer service keeps closing my tickets. This is ridiculous.",
"timestamp": "2025-01-15T09:23:00Z"
},
{
"id": "rd_002",
"platform": "reddit",
"author": "u/happy_camper",
"text": "Just got my new headset and the spatial audio is incredible. Best purchase this year.",
"timestamp": "2025-01-15T10:05:00Z"
},
{
"id": "tw_003",
"platform": "twitter",
"author": "@tech_reviewer",
"text": "Noticed the latest app update drained 40% battery in two hours. Anyone else seeing this?",
"timestamp": "2025-01-15T11:17:00Z"
}
]
Step 3: Write the analysis system prompt
The system prompt is the core of the agent. It forces structured JSON output so downstream code can route alerts automatically. I keep the instructions strict and specific.
SYSTEM_PROMPT = """You are a brand reputation analyst. Analyze the social media mentions provided in the user message.
For each mention, output a JSON object with these keys:
- mention_id: echo the provided id
- sentiment: one of [positive, neutral, negative, critical]
- urgency: one of [low, medium, high]
- category: one of [billing, product_defect, feature_request, praise, general]
- summary: max 20 words
- recommended_action: one of [ignore, monitor, respond_publicly, escalate]
Rules:
- Anger, repeated frustration, or churn threats get urgency high.
- Potential bugs affecting many users get urgency high and category product_defect.
- Output ONLY a valid JSON array. No markdown, no explanations."""
Step 4: Create the batch analysis function
This function serializes the raw mentions into JSON and sends them to Oxlo.ai. I use qwen-3-32b because it handles agentic instruction following reliably, including multilingual text you often see in social streams.
import json
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
def analyze_mentions(mentions):
user_content = json.dumps(mentions, ensure_ascii=False, indent=2)
response = client.chat.completions.create(
model="qwen-3-32b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_content},
],
temperature=0.2,
max_tokens=1500,
)
raw = response.choices[0].message.content.strip()
if raw.startswith("
```"):
raw = raw.split("```
")[1].replace("json", "").strip()
return json.loads(raw)
Step 5: Filter alerts and draft responses
High-urgency items that need a public reply get a drafted response. I use deepseek-v3.2 for this step because it is available on Oxlo.ai's free tier, which keeps experimental costs low while I iterate on tone.
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
RESPONSE_PROMPT = """You are a senior community manager. Write a concise, empathetic public response to the following social media mention.
Mention: {text}
Platform: {platform}
Author: {author}
Guidelines:
- Acknowledge the issue without corporate jargon.
- If it is a complaint, apologize and offer a concrete next step.
- Keep it under 280 characters if the platform is twitter, otherwise under 150 words.
- Output only the response text."""
def draft_responses(raw_mentions, analyzed):
id_map = {m["id"]: m for m in raw_mentions}
alerts = [
a for a in analyzed
if a["urgency"] == "high" and a["recommended_action"] == "respond_publicly"
]
results = []
for record in alerts:
mention = id_map[record["mention_id"]]
prompt = RESPONSE_PROMPT.format(
text=mention["text"],
platform=mention["platform"],
author=mention["author"]
)
response = client.chat.completions.create(
model="deepseek-v3.2",
messages=[{"role": "user", "content": prompt}],
temperature=0.7,
max_tokens=300,
)
results.append({
"mention_id": record["mention_id"],
"draft": response.choices[0].message.content.strip()
})
return results
Step 6: Build the daily report summary
Stakeholders need prose, not JSON. This function turns the structured analysis into a short narrative summary. I use llama-3.3-70b because it produces clean, executive-ready text.
import json
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
def generate_report(analyzed):
data = json.dumps(analyzed, indent=2)
prompt = f"""Summarize the following brand mention analysis for a daily stand-up report.
Data:
{data}
Provide:
1. Total mentions processed.
2. Breakdown by sentiment.
3. List of high-urgency items with IDs.
4. One sentence recommendation for the community team.
Keep it under 150 words."""
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[{"role": "user", "content": prompt}],
temperature=0.3,
max_tokens=500,
)
return response.choices[0].message.content.strip()
Run it
This block wires everything together. It fetches the simulated mentions, analyzes them, drafts replies for urgent items, and prints the daily report.
import json
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
SYSTEM_PROMPT = """You are a brand reputation analyst. Analyze the social media mentions provided in the user message.
For each mention, output a JSON object with these keys:
- mention_id: echo the provided id
- sentiment: one of [positive, neutral, negative, critical]
- urgency: one of [low, medium, high]
- category: one of [billing, product_defect, feature_request, praise, general]
- summary: max 20 words
- recommended_action: one of [ignore, monitor, respond_publicly, escalate]
Rules:
- Anger, repeated frustration, or churn threats get urgency high.
- Potential bugs affecting many users get urgency high and category product_defect.
- Output ONLY a valid JSON array. No markdown, no explanations."""
RESPONSE_PROMPT = """You are a senior community manager. Write a concise, empathetic public response to the following social media mention.
Mention: {text}
Platform: {platform}
Author: {author}
Guidelines:
- Acknowledge the issue without corporate jargon.
- If it is a complaint, apologize and offer a concrete next step.
- Keep it under 280 characters if the platform is twitter, otherwise under 150 words.
- Output only the response text."""
def fetch_mentions():
return [
{
"id": "tw_001",
"platform": "twitter",
"author": "@frustrated_user",
"text": "Been waiting 3 weeks for my refund. Customer service keeps closing my tickets. This is ridiculous.",
"timestamp": "2025-01-15T09:23:00Z"
},
{
"id": "rd_002",
"platform": "reddit",
"author": "u/happy_camper",
"text": "Just got my new headset and the spatial audio is incredible. Best purchase this year.",
"timestamp": "2025-01-15T10:05:00Z"
},
{
"id": "tw_003",
"platform": "twitter",
"author": "@tech_reviewer",
"text": "Noticed the latest app update drained 40% battery in two hours. Anyone else seeing this?",
"timestamp": "2025-01-15T11:17:00Z"
}
]
def analyze_mentions(mentions):
user_content = json.dumps(mentions, ensure_ascii=False, indent=2)
response = client.chat.completions.create(
model="qwen-3-32b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_content},
],
temperature=0.2,
max_tokens=1500,
)
raw = response.choices[0].message.content.strip()
if raw.startswith("
```"):
raw = raw.split("```
")[1].replace("json", "").strip()
return json.loads(raw)
def draft_responses(raw_mentions, analyzed):
id_map = {m["id"]: m for m in raw_mentions}
alerts = [a for a in analyzed if a["urgency"] == "high" and a["recommended_action"] == "respond_publicly"]
results = []
for record in alerts:
mention = id_map[record["mention_id"]]
prompt = RESPONSE_PROMPT.format(
text=mention["text"],
platform=mention["platform"],
author=mention["author"]
)
response = client.chat.completions.create(
model="deepseek-v3.2",
messages=[{"role": "user", "content": prompt}],
temperature=0.7,
max_tokens=300,
)
results.append({
"mention_id": record["mention_id"],
"draft": response.choices[0].message.content.strip()
})
return results
def generate_report(analyzed):
data = json.dumps(analyzed, indent=2)
prompt = f"""Summarize the following brand mention analysis for a daily stand-up report.
Data:
{data}
Provide:
1. Total mentions processed.
2. Breakdown by sentiment.
3. List of high-urgency items with IDs.
4. One sentence recommendation for the community team.
Keep it under 150 words."""
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[{"role": "user", "content": prompt}],
temperature=0.3,
max_tokens=500,
)
return response.choices[0].message.content.strip()
if __name__ == "__main__":
raw = fetch_mentions()
print(f"Fetched {len(raw)} mentions.\n")
analysis = analyze_mentions(raw)
print("Analysis results:")
print(json.dumps(analysis, indent=2))
print()
drafts = draft_responses(raw, analysis)
print("Draft responses for high-urgency items:")
for d in drafts:
print(f" {d['mention_id']}: {d['draft']}")
print()
report = generate_report(analysis)
print("Daily report:")
print(report)
Example output:
Fetched 3 mentions.
Analysis results:
[
{
"mention_id": "tw_001",
"sentiment": "critical",
"urgency": "high",
"category": "billing",
"summary": "Customer waiting 3 weeks for refund, tickets closed repeatedly.",
"recommended_action": "respond_publicly"
},
{
"mention_id": "rd_002",
"sentiment": "positive",
"urgency": "low",
"category": "praise",
"summary": "User praises new headset spatial audio quality.",
"recommended_action": "ignore"
},
{
"mention_id": "tw_003",
"sentiment": "negative",
"urgency": "high",
"category": "product_defect",
"summary": "App update causing severe battery drain.",
"recommended_action": "escalate"
}
]
Draft responses for high-urgency items:
tw_001: @frustrated_user We are really sorry this happened. A 3 week wait is unacceptable. I have personally escalated this to our billing lead and you will receive an update within 24 hours.
Daily report:
We processed 3 mentions today. Sentiment breakdown: 1 critical, 1 negative, 1 positive. High urgency items are tw_001 (billing escalation) and tw_003 (product defect). I recommend the community team issue a public response for the billing case and loop in engineering on the battery drain reports immediately.
Wrap-up
This script is a solid foundation you can drop into a cron job or a lightweight FastAPI service. Two concrete next steps: wire it to live social APIs using Tweepy or PRAW, and add a Slack webhook so high-urgency alerts hit your team channel in real time. Because Oxlo.ai uses flat per-request pricing, you can pass long threads or full article text into the context window without the cost scaling with input size. See https://oxlo.ai/pricing for plan details.
Top comments (0)