Subzero Labs

Free code · Subzero Labs

Etsy + Payhip customer message drafts

From the Subzero Labs video "Your AI Has Amnesia. This Free Code Makes It Remember".

Free, no sign-up. Copy it, use it, share it.

For: Etsy and Payhip sellers

The job: The same questions every day: the download link expired, can I use this commercially, can I get a refund.

You give it: messages pasted into .txt files (Etsy has no message export) or an .mbox, plus your shop FAQ / policies in Markdown.

It is one agent of the free AI OS starter (https://subzero.bodymindbeing.me/free/ai-os-starter/) - download the whole starter, it runs on sample data out of the box. Nothing is sent anywhere: replies come out as drafts.

Download the AI OS starter (zip) 65 KB

MIT licence. Python 3.10+, no other installs. Unzip, then follow README.md.

Run this one

  1. Set up the starter (the steps on the starter page).
  2. python -m aios run customer_messages
  3. Edit config.json: point "customer_messages" at your own files (paths relative to config.json).

Check it yourself

  1. Compare each draft in data/drafts/customers/ with your FAQ - a price that is not in your policies is flagged at the top.
  2. Refund and quality messages go to your attention list - you decide.

agents/customer_messages.py

"""ETSY + PAYHIP - customer message drafts. Etsy has no export for Convos, so you paste each new message into a .txt
file (or point it at an .mbox export of your shop email). It sorts them (download problem, licence / commercial use,
refund, quality problem, other) and drafts an answer from YOUR shop policies (the AI reads your FAQ from memory
first). The code checks every price in a draft is one your FAQ really has. Nothing is sent: drafts are text files in
data/drafts/customers/ that you check, edit and send yourself."""
from aios import llm, memory
from aios.config import path

from ._common import messages, save_draft
from .brand_deals import unknown_prices

TITLE = "Customer message drafts"
KINDS = ("download", "licence", "refund", "quality", "other")


def run(cfg, data, s):
    memory.sync_folder(data, s["store_project"], path(cfg, s["store_notes"]))
    policy = memory.notes_text(data, s["store_project"])
    items, attention, counts = [], [], dict.fromkeys(KINDS, 0)
    for n, (sender, subject, body) in enumerate(messages(cfg, s["messages"]), 1):
        r = llm.ask_json(f"OUR SHOP POLICIES:\n{policy}\n\nCUSTOMER MESSAGE from {sender}\nSubject: {subject}\n\n{body}"
                         f"\n\nWhich kind is it: {', '.join(KINDS)}? Draft a short, warm reply that follows our "
                         "policies exactly (never promise anything they do not say). "
                         'JSON: {"kind": "...", "reply": "..."}')
        kind = r.get("kind") if r.get("kind") in KINDS else "other"
        counts[kind] += 1
        reply = str(r.get("reply", ""))
        bad = unknown_prices(reply, policy, body)
        if bad:
            reply = f"[CHECK BEFORE SENDING: {', '.join(bad)} is not in your policies]\n\n" + reply
        f = save_draft(data, "customers", n, sender, "Re: " + subject, reply)
        items.append(f"[{kind}] {subject} - {sender.split('<')[0].strip()} -> draft {f.name}"
                     + (f" (price to check: {', '.join(bad)})" if bad else ""))
        if kind in ("refund", "quality"):
            attention.append(f"{kind.title()}: '{subject}' - read the draft before you answer")
    return {"summary": ", ".join(f"{v} {k}" for k, v in counts.items() if v) + " - drafts saved, nothing sent.",
            "items": items, "attention": attention}

Shared as shown in the video. Replace any <PLACEHOLDERS> with your own values.