Woody Cat Rescue

AI tools that keep a volunteer cat rescue's website up to date, so nobody has to. The founder estimates cats are now 30% more likely to be adopted.

Client
Woody Cat Rescue
Role
Design and build
Team
Me, with the founder
Type
Nonprofit, operations automation
Stack
Shelterluv, Wix, Telegram, Claude
Status
Live since July 2026
A chat message updates the rescue website CMS automatically

01 — Problem

The website was always out of date.

Woody Cat Rescue is a small, volunteer-run rescue. Cats arrived and got adopted every week, and workshops ran every month, but the website rarely changed. Only the founder could edit it, and she had no time.

An out-of-date site costs a rescue twice: people can't find the cats who need homes, and they don't trust a page that still lists cats who left months ago.

02 — How it worked before

I interviewed the founder and mapped every way content reached the site. There were three, and each one depended on her.

  • New cats. Volunteers already entered every cat in Shelterluv, their shelter system. Getting it onto the website meant doing it again by hand: open Wix, rewrite, upload photos, publish.
  • Changes. A cat on hold, new photos, an updated FAQ. All of it needed a Wix login, so in practice nobody made these changes and the site drifted.
  • Workshops. People paid through PayPal and picked a session in a Google Doc. The founder copied every signup into a Google Sheet and told people when a session was full.

03 — Where AI comes in

I used AI only where the input is messy language, and plain rules everywhere else.

New cats

New cats sync on their own. When a volunteer adds a cat to Shelterluv, an AI step turns the shelter record into a website profile and publishes it. No second entry.

Cat profile workflow, before four manual steps, after one automatic pipeline
New cats: four manual steps became one automatic sync.

Changes

Changes happen in a chat. Staff text MeowMate, a Telegram bot I built, in plain words like “Luna is now on hold”. Claude works out what they mean and which action to run.

Changes: every write is previewed and confirmed by a person.

Workshops

Workshops run from the same chat. Booking, payment and capacity live in Wix, which closes a session when it fills. MeowMate reads that through the Wix API, so the founder can create a session or check signups by texting the bot.

Workshop workflow before and after
Workshops: four tools became one, checked from a phone.

04 — Design decisions

AI prepares the change. A person approves it.

Volunteers trust the website because it's right. So Claude never writes to the site directly: the bot shows what will change, from and to, with Save and Cancel buttons. Nothing goes live until someone taps Save, and every saved change is written to an audit log. If no cat matches, several do, or nothing would change, the bot says so and stops.

That one rule made it safe to let anyone on the team update the site from their phone, without a Wix login.

Meet the team where they already work.

Volunteers already used Shelterluv and Telegram every day. Instead of a new dashboard to learn, the system listens to the tools they had, so keeping the site current became a side effect of work they were already doing.

05 — Result

The founder estimates cats are now about 30% more likely to be adopted.

  • The site stays current. New cats appear on their own, and any volunteer can update the rest from a chat.
  • 3 to 5 hours a week back for the founder, who no longer retypes cats or tracks signups by hand.
  • First donations. The site started bringing in donations for the first time: three donors so far, close to $1,000.

“Updating it is so convenient. I can do it right from my phone. And our cats are getting adopted really fast now.” Founder, Woody Cat Rescue

Site structure before and after
Before: no clear visitor pathways. After: three clear visitor actions.
Cats looking for homes page
Cat profiles on the live site
System overview of both pipelines feeding the website
Technical detailsHow MeowMate handles one request, design decisions, code and stack

One request, end to end

“Luna is now on hold.”

  1. The bot checks the sender and the rate limit.
  2. Claude reads the message and every tool definition, and returns update_cat_status with the cat's name and new status.
  3. The bot finds Luna in Wix. If no cat or several cats match, or the status is already set, it says so and stops.
  4. It parks a pending action with its own ID and replies with a From and To preview and Save and Cancel buttons.
  5. On Save, the button's ID must match the pending action, so an old or stale button does nothing.
  6. The status is updated in Wix, one line is added to the audit log, and the bot replies “Done”.

Engineering choices

  • Claude's tool use is the intent layer. There is no separate classifier, so a new feature is just a new tool file.
  • Every write is preview, then confirm. Nothing reaches the website until a person taps Save.
  • Pending actions live in memory for 15 minutes. A restart only loses a draft, which is acceptable.
  • Storage sits behind interfaces. Development ran on JSON files; production swaps in Wix with no change above it.
  • Conversation memory is short. Up to 10 messages for 15 minutes, cleared as soon as a tool runs. Photos are never kept.
  • Costs are controlled in layers. Greetings are answered without the model, menu buttons take shortcuts, routing uses Claude Haiku with a cached prompt, and per-user and global limits apply. Photo requests count double.
  • The audit log is append-only. Medical notes and image links are redacted before anything is written.

Core code

The pending-action store is the heart of preview then confirm. Lightly trimmed.

const TTL_MS = 15 * 60 * 1000
const store = new Map<number, PendingAction>()

export function setPending(userId: number, type: string, data: unknown) {
  const action = { id: uuidv4(), type, data, expiresAt: Date.now() + TTL_MS }
  store.set(userId, action)
  return action
}

export function getPending(userId: number) {
  const action = store.get(userId)
  if (!action || Date.now() > action.expiresAt) { store.delete(userId); return null }
  return action
}

Tools in the bot today: create, update, list, view and delete cats; list and edit FAQs; write social posts; create workshops and view registrations, including reading a registration screenshot.

Tech stack

Runtime
TypeScript on Node.js, run under PM2
Chat
Telegram, via Telegraf
AI
Anthropic SDK, Claude Haiku 4.5 with tool use and prompt caching
Content
Wix CMS (Data and Media APIs) behind repository adapters
Animal records
Shelterluv API, read only
Ops
Append-only audit log, retries, atomic writes, smoke tests
Next project Granny Square Studio

Keyboard shortcuts

1
Projects
2
Playground
3
Skills
← →
Previous / next project
/
Search skills
E
Copy my email
Esc
Close
?
Show this list