A content engine that is not allowed to make things up
An AI-assisted marketing operations platform (weekly LinkedIn drafts, sourced news, funding alerts, competitor tracking and a media library) where funding and statistics claims need a verified source and nothing publishes without approval.

- serverless functions, 5 scheduled workflows
- 33
- unattended publisher runs in two weeks
- 4,000+
The problem
A small marketing team had to keep two brands visible on LinkedIn and in the press, track competitors and funding schemes, and reuse project photography, while statistics and grant claims in the sector's content are often wrong, out of date or unsourced. Generative tools make the volume problem trivial and the accuracy problem worse.
Customer projects are the best material and the riskiest: posting a client's site without their consent is a problem the team cannot afford, however good the draft is.
The working material was scattered: a shared mailbox of company updates, a SharePoint library of photographs named by project code, and a feed of policy news no one had time to read.
What we built
Drafts, never auto-publishing
A weekly job builds four drafts for the days the team posts, each from a different source: a partner spotlight or news item, a team update, a topic from the energy-management brand and a consented project. A registry stops any source being used twice, and every draft lands in an approval queue rather than going out.
Honest fallbacks instead of invented copy
When there is no sourced news, no unused team update or no consented project, the slot becomes an explicit 'add a sourced record' placeholder rather than a plausible filler post. Partner claims must be verifiable against the official product page or the model returns nothing.
A news pipeline the model cannot corrupt
Feeds are parsed in parallel, filtered to the last week, capped, de-duplicated by URL and every URL is checked to resolve. The model only classifies and summarises; the link and the title come from the feed, so it has no way to invent a source. Every run, successful or not, is logged.
Claims need a verified source, and approval enforces it
The generation prompt allows funding and statistics only from verified funding records; anything else is dropped or flagged. The approvals screen blocks approval while unverified claims remain, across emails, social posts, blog posts and press articles in one queue.
Consent as a hard gate
Project-led posts use only installs flagged as consented for publicity. If none are, the system falls back to generic process copy instead of reaching for a client's site. The data backs the caution up: none of the installs on record had yet been flagged, so none had been used.
Mail and photo libraries made usable
A shared mailbox is polled for company updates from two allow-listed domains only, de-duplicated by message ID, with text extracted from Word, Excel, PDF and text attachments and stored beside a grounded rewrite. A SharePoint sync parses project codes, shoot dates and tags from folder and file names and indexes the photos and videos so the team can find them by project.
A publisher that tells you when it fails
Every five minutes the publisher takes whatever is due, posts to a person or organisation page as configured, stores the post identifier and writes a run record. A failed post becomes an urgent action item and is retried by the scheduler, so a silent failure is not a state the system can be in.

The outcome
A steady, reviewable flow of on-brand drafts for two brands, with sourced news, verified funding alerts, tracked competitors and a searchable media library behind it.
Over four thousand scheduled publisher runs in two weeks with no failed publishes: the system doing its job unattended, most of it by doing nothing.
Modules for email sequences, blog and press are built and gated behind approval but had not yet carried traffic at the time of the last data export; they are described as built, not as used.
It runs on the AI app platform it was created on, with its integrations (mail, document storage, LinkedIn and analytics), each limited to the scopes it needs. No time-saved or lead figures are claimed because the data does not support them.
Built with
- React
- Vite
- Deno
- Claude
- Microsoft Graph
- SharePoint
- LinkedIn API
- Google Analytics
- TanStack Query
Page copy drafted with AI assistance. Skofi is accountable for it. Editorial policy
Have something shaped like this?
If any part of the above resembles a problem you are living with, a short call is the fastest way to find out whether it is the same problem underneath.
What happens on the call
- 15 minutes, no deck
- We map the process on the call
- A written scope, or an honest no