DEV Community

shashank ms
shashank ms

Posted on

Using LLM for Social Media Monitoring

We are building a social media monitoring agent that ingests a batch of posts, classifies sentiment, extracts topics, and flags items that need a human response. It is designed for brand or community managers who want structured insight without paying token-based costs for every long post or thread. We will use Oxlo.ai's flat per-request pricing to keep analysis costs predictable even when context grows.

What you'll need

  • Python 3.10 or newer
  • The OpenAI SDK: pip install openai
  • An Oxlo.ai API key from https://portal.oxlo.ai. The free plan includes 60 requests per day, which is enough to prototype this pipeline.
  • A few sample posts, or use the mock data below

Step 1: Ingest raw posts

I will start with a hardcoded list to keep the tutorial reproducible. In production, replace this with pulls from the X API, Reddit, or a webhook.

import json

RAW_POSTS = [
    {
        "id": "post_001",
        "platform": "twitter",
        "author": "@dev_user",
        "text": "The new API docs are completely broken. None of the Python examples compile. This is blocking our release.",
        "timestamp": "2024-05-20T14:32:00Z"
    },
    {
        "id": "post_002",
        "platform": "reddit",
        "author": "u/ai_enthusiast",
        "text": "Just ran a 128k context window through Oxlo.ai and the flat per-request pricing saved me a ton compared to my old token-based provider. Highly recommend for long docs.",
        "timestamp": "2024-05-20T15:10:00Z"
    },
    {
        "id": "post_003",
        "platform": "twitter",
        "author": "@random_gamer",
        "text": "Love the new update! Dark mode is finally here.",
        "timestamp": "2024-05-20T16:45:00Z"
    }
]

def load_posts():
    return RAW_POSTS

Step 2: Define the system prompt

The system prompt forces the model to return strict JSON so I can parse it programmatically. I ask for sentiment, topics, urgency, and a recommended action.

SYSTEM_PROMPT = """You are a social media monitoring analyst.
Analyze the provided batch of social posts and return a single JSON object.
Do not include markdown formatting or explanations outside the JSON.

The JSON must have this structure:
{
  "summary": "One sentence overview of the batch",
  "posts": [
    {
      "id": "post id",
      "sentiment": "negative | neutral | positive",
      "topics": ["topic1", "topic2"],
      "urgency": "low | medium | high",
      "action": "ignore | monitor | respond",
      "reason": "Brief justification"
    }
  ]
}

Rules:
- sentiment is about the author's attitude toward the product or brand.
- urgency is high if the post describes a bug, outage, security issue, or angry customer.
- action is respond only if urgency is high and a human reply is clearly needed.
"""

Step 3: Analyze with Oxlo.ai

I batch the posts into a single user message to minimize API calls. Because Oxlo.ai charges a flat rate per request, this keeps costs predictable even when the combined text is long.

from openai import OpenAI
import json

client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")

def analyze_posts(posts):
    user_message = (
        "Analyze the following posts and return JSON only.\n\n"
        + json.dumps(posts, indent=2)
    )

    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_message},
        ],
    )

    raw = response.choices[0].message.content
    # Strip markdown fences if the model returns them despite instructions
    cleaned = raw.replace("

```json", "").replace("```

", "").strip()
    return json.loads(cleaned)

Step 4: Format the report

After parsing the JSON, I print a human-readable digest and filter for anything that needs a response today.

def print_report(analysis):
    print(f"Batch Summary: {analysis['summary']}\n")
    print(f"{'ID':<12} {'Sentiment':<10} {'Urgency':<8} {'Action':<8} Reason")
    print("-" * 70)

    for item in analysis["posts"]:
        print(f"{item['id']:<12} {item['sentiment']:<10} {item['urgency']:<8} {item['action']:<8} {item['reason']}")

    flagged = [p for p in analysis["posts"] if p["action"] == "respond"]
    if flagged:
        print(f"\nALERT: {len(flagged)} post(s) require immediate response.")
        for p in flagged:
            print(f"  - {p['id']}: {p['reason']}")
    else:
        print("\nNo immediate responses required.")

Run it

Wire the pieces together and execute. Replace YOUR_OXLO_API_KEY with your actual key from the Oxlo.ai portal.

if __name__ == "__main__":
    posts = load_posts()
    result = analyze_posts(posts)
    print_report(result)

Example output:

Batch Summary: The batch contains mixed sentiment, with one high-urgency bug report, one positive pricing feedback, and one positive feature reaction.

ID           Sentiment  Urgency  Action   Reason
----------------------------------------------------------------------
post_001     negative   high     respond  Author reports broken API docs blocking a release.
post_002     positive   low      monitor  Praise about pricing; no action needed.
post_003     positive   low      ignore   General praise about dark mode.

ALERT: 1 post(s) require immediate response.
  - post_001: Author reports broken API docs blocking a release.

Next steps

Connect the load_posts function to a live source such as the X API or a Reddit RSS feed, and pipe high-urgency alerts into a Slack webhook or PagerDuty integration. If your volumes grow, keep an eye on Oxlo.ai's request-based pricing. For heavy long-context workloads, switching from a token-based provider to Oxlo.ai can cut costs significantly because the flat per-request rate does not scale with input length.

Top comments (0)