TWOSPOON • 2024

Automating Social Media Campaign Reporting

Automating Social Media Campaign Reporting
ROLEFullstack Developer
TIMELINESept 2024 - Dec 2024
SKILLSFrontend & Backend Development
TECH STACKNextjs, Tailwind CSS, FastAPI, MongoDB
OVERVIEW

Rebuilding campaign analytics from the ground up

Rebuilt a social listening analytics dashboard end-to-end, transitioning from a manual developer-dependent workflow to a fully automated self-serve product for a marketing agency client.
THE PROBLEM

Developer time shouldn't be spent copy-pasting numbers

The client, a marketing agency managing Instagram pages for brands and running campaigns, relied on a manual reporting process. When they needed campaign reports, they would provide post links to a developer who had to run a Python script to get metrics, then manually enter the values into the frontend by cloning static pages for each campaign. This took 2-4 hours of promised turnaround time, could not handle simultaneous requests, and was not scalable.
THE SOLUTION

A dashboard that processes campaigns in minutes, not hours

Built an admin dashboard where the client can enter campaign details and post links themselves, and a dynamic frontend that displays processed data based on the campaign being viewed.
Flow: Client logs into admin dashboard → Creates campaign with metadata and post links → Submits form → Backend triggers processing pipeline (fetch post details from APIs, recursively get comments with exponential backoff for rate limiting, send to OpenAI for sentiment analysis, send to Claude for topic modelling, push to MongoDB) → Frontend displays processing status → Client opens URL to view campaign dashboard with metrics.
TECHNICAL DECISIONS

Choosing speed and flexibility over perfection

Next.js with App Router
Migrated from Pages Router to App Router. Previously the developer cloned static pages and changed metadata for each campaign; now the frontend dynamically fetches and displays campaign data based on URL parameters.
FastAPI Backend
Modified existing Python scripts into a full backend with API endpoints and async handling. The core processing logic was already in Python, so I wrapped it in FastAPI rather than rewriting.
MongoDB
Chose a non-relational database to move fast without schema migrations as requirements changed.
LLM Pipeline
Send batches of comments to OpenAI to label language (for column charts), emotion (from 10 predefined categories like joy, humor, frustration - pie charts), and sentiment (positive/negative/neutral - pie charts). Send to Claude for topic modelling.
Data Sources
Instagram, YouTube, and some Twitter data via RapidAPI (not official APIs).
KEY FEATURES

One frontend, infinite campaigns

Dynamic Dashboard
Single frontend application that displays different campaign data and visualizations based on the campaign being viewed, replacing the previous static page cloning approach.
Custom Visualizations
Built components for ad-hoc visualization requests specific to particular campaigns. For example, for a car brand, added charts showing intent distribution, most criticized and appreciated features, and purchase journey sankey charts alongside regular metrics. For a podcaster, added per-episode sentiment and fans voice charts. Implemented this using conditional rendering based on URL checks to display specific components without rebuilding the entire system.
UI Improvements
Redesigned the client dashboard using shadcn/ui components, changing charts and improving colors/contrast. Added loading states and caching.
IMPACT

Turning hours into minutes

Reduced turnaround time from 2-4 hours to a few minutes. A campaign with 30 posts averaging 500 comments each now takes 5-10 minutes to process, whereas before a developer spent about an hour and the company promised a 3-hour window. The client can now create campaigns independently without developer involvement, though processing time varies based on post virality due to API rate limits when fetching large comment volumes.
CHALLENGES

Handling one-off requests without breaking the system

Handling ad-hoc requests for new visualizations and metrics specific to single campaigns for different brand types. Solved this by building modular components that render conditionally based on the campaign, allowing custom metrics for specific clients while maintaining a single codebase.
REFLECTION

Building for change, not just for today

Building conditional rendering architecture allowed the system to handle both standard campaigns and one-off enterprise requirements without forking the codebase.