AI-powered social engagement

Sotto

We built Sotto for agencies running social engagement across dozens of client accounts. It scrapes the feeds, scores every post, drafts comments in each client's exact voice, and hands the agency a ready queue every morning. The agency clicks post when they're happy.

Live on sotto.social
Visit sotto.social
An Italian piazza scene with diverse characters gathered around a fountain, scrolling phones together

What we built

Sotto is a multi-tenant SaaS for social media agencies. Every account is a Clerk organisation, every client lives under that organisation, and every monitored Facebook or Instagram page hangs off the client. Clean separation, no cross-tenant leakage, twelve tables that all join through orgId.

The product is the pipeline. Scrape feeds with Playwright. Score each post with the client's preferred AI provider. Generate brand-voice comments. Queue them. Email a digest. Hand the agency a Chrome extension that drops the chosen comment straight into Facebook or Instagram with one click.

Most of the engineering complexity sits in two places. The first is the brand-voice config: every client gets a tone, an expertise list, an emoji style, example comments, and topics to avoid. The second is the AI provider router that dispatches each job to Claude, OpenAI, or Gemini based on client choice and post type.

Why we built it

Engagement is the cheapest reach a brand can buy. Comments, replies, conversations under other people's posts. The algorithm rewards it, the audience expands, the brand grows. But doing it well, in the client's voice, on the right posts, every morning, does not scale by hand.

Agencies were burning the same hour every day on it. Scroll the feeds, screenshot anything interesting, paste into a chatbot, copy a suggestion back, post it. We watched the workflow, mapped it, and rebuilt it as a system that does everything except the final click.

The five-minute morning review replaced the hour-long morning scroll. The agency still picks every comment. Sotto just does the work that the agency was never paid enough to enjoy.

How it works

Five stages, every morning.

  1. 01

    Scrape

    A Playwright crawler reads each client's monitored Facebook and Instagram pages. Selector-health tracking watches for DOM drift so the scraper stays alive when Meta ships changes.

  2. 02

    Score

    Each new post runs through an AI scorer. It produces a summary, an engagement score from 1 to 10, and a list of tones that would land. Anything below 5 is filed away.

  3. 03

    Generate

    For each top-scoring post, Sotto drafts multiple comments in the client's exact voice. The model reads the last 20 comments for that page so nothing repeats.

  4. 04

    Queue

    Comments land in a morning queue. A Resend digest emails the agency a one-line summary so they know there is work to look at.

  5. 05

    Paste

    The Chrome extension drops the chosen comment straight into the Facebook or Instagram comment box. The agency stays in control of every post.

Brand voice

Every client,
their own voice

Each client gets their own tone, expertise list, emoji style, example comments, and topics to avoid. Sotto reads the config and writes accordingly. Supportive for a charity, sharp for a tech startup, warm for a hospitality brand. Same product, different voices.

Characters gathered around a fountain, speech bubbles rising like water, each voice unique
Non-profitSupportive

This is such an important conversation. Thank you for sharing your experience and helping others feel less alone.

SaaSExpert

Fascinating approach to edge computing. The latency improvements align with what we saw in our own infrastructure migration last quarter.

HospitalityWarm

Nothing beats that first morning view from the terrace. Hope you enjoyed every moment, you deserve the rest.

FitnessMotivating

That form is looking solid. The consistency is clearly paying off. Keep pushing, the results speak for themselves.

HealthcareCompassionate

Thank you for normalising this conversation. So many people need to hear that it's okay to ask for help.

Real estateProfessional

Stunning property. The natural light in that living area is a real standout. Would love to know more about the neighbourhood.

Food and bevPlayful

Okay but that cheese pull is absolutely criminal. Saving this for when I need convincing to order delivery tonight.

BeautyEnthusiastic

The glow. That skincare routine is clearly working. Would love to know what serum you used in step three.

Pet careHeartfelt

That face. You can just tell how loved this little one is. Wishing them the speediest recovery.

The AI router

One product, three model providers.

Each agency client picks Claude, OpenAI, or Gemini for their brand. The router handles the rest. Different prompt templates, different streaming behaviour, different rate limits, all hidden behind one interface so the engine code stays clean.

Anthropic Claude

Default for most agencies

Strong on tone, holds character across long brand-voice prompts. Picked by most agencies for text-led posts.

OpenAI GPT

Legacy and edge cases

Familiar to agencies migrating from existing GPT pipelines. Good for short, punchy comment styles.

Google Gemini

Fall-through for video

Video posts always route to Gemini regardless of client preference. It is the only provider that natively processes video frames.

The principle

We chose not to
auto-post.

The engineering work to push every approved comment back into Facebook or Instagram automatically was small. We had the session, the cookies, the page object. We deliberately did not ship it.

Auto-commenting at scale gets accounts banned. Meta's spam detectors look for it. The whole point of the product is to expand agency reach, not collapse it. So Sotto stops at the queue. The Chrome extension is the bridge: a human reviews each comment, clicks once, and the comment lands as if they typed it.

Engagement is supposed to grow accounts, not get them banned.

The bridge

A Chrome extension that keeps it human.

The queue lives on the server. The posting lives in the browser. Sotto's Chrome extension is the bridge between them, opening as a Chrome side panel right next to whichever Facebook, Instagram, or TikTok page the agency is reviewing.

Side panel UX

Manifest V3, side-panel surface

Pinned to the side of the browser, not a popup that disappears on click. Built on the latest Chrome extension API so the UX persists across tabs.

Three platforms

Facebook, Instagram, TikTok

Host permissions scoped to the platforms the agency actually engages on. The extension knows which platform the visible tab is on and surfaces the right comments.

Token auth

Per-user tokens, revocable

Each browser holds a hashed extension token tied to a Clerk user. Tokens can be revoked from the dashboard if a device is lost. No password ever lives in the extension.

Approve the comment in the side panel. One click. The text drops into the platform's native comment box, ready to post as if the agency typed it themselves.

Resilience

Selector-health tracking

Meta breaks Facebook and Instagram DOM constantly. Class names shuffle, container hierarchy shifts, attributes change. Every scraper that targets these platforms ages.

Sotto's scraper logs every selector hit and every miss against a health table. Within hours of a Meta change, we know which CSS path stopped resolving. We patch in business hours, the product keeps running, agencies do not notice.

Health snapshot
Post container
98.4%
Author handle
97.1%
Media URL
82.6%
Posted-at timestamp
99.0%
Comment count
0.0%

Illustrative. Actual health stays under our agency dashboard.

The build journey

From a daily hour to a five-minute review.

Problem

An hour a day, every day, on the same workflow

Social media agencies were paying staff to scroll a wall of feeds, screenshot interesting posts, paste them into ChatGPT for comment ideas, and post the result. The same loop, every morning, across every client. We wanted to compress that hour into a five-minute review.

Architecture

Multi-tenant from day one

Every client's brand voice, every page they monitor, every comment ever posted. All of it lives in a single Postgres schema scoped by Clerk organisation id. Twelve tables, every query filtered by orgId, no cross-tenant leakage possible.

AI router

One product, three model providers

We routed each client's traffic to their preferred provider (Anthropic, OpenAI, or Gemini) and built a fall-through for video. Video posts always go to Gemini because it natively processes video frames. Image and text use whichever model the agency picked.

Resilience

Selector-health tracking

Meta breaks Facebook and Instagram DOM constantly. The scraper logs each selector hit and miss, so we know within hours when a CSS path stops resolving. The product keeps running while we patch.

The principle

We chose not to auto-post

The engineering work to auto-post comments was small. We deliberately did not build it. Auto-posting at scale gets accounts banned by Meta, and the whole point of the product is to grow agency reach, not torch it.

Live

Sotto.social, in the wild

Live multi-tenant SaaS, agencies onboarding, comments shipping out of the queue every morning. Built and shipped end-to-end from our Sant studio in Christchurch, NZ.

What we learned

The lessons we carry forward.

Auto-posting is the trap.

We could have shipped fully automated posting. We chose not to. Engagement is supposed to grow account reach, not get accounts banned. The Chrome extension keeps the human in the loop on purpose.

Brand voice is the product.

The hardest part wasn't the scraping or the queueing. It was getting the AI to write like a charity, and like a tech startup, and like a hospitality brand, on the same morning. The voice config schema took more iterations than the rest of the stack.

Selector tracking buys you nights and weekends.

Without it, every Meta DOM change would have woken someone up. With it, we get an alert, we patch in business hours, the product keeps running.

Provider switching matters more than provider choice.

Different agencies have different opinions on which model writes best. Building a clean router meant we never had to argue. Each client picks. Video falls to Gemini. The team focuses on the product, not the model.

Built with

The Sant services that shipped this product.