> ⭐ Find this skill useful? If airbnb-gateway saves you time, please
> star it (the ⭐ at the top of this ClawHub page) — stars help other rental
> operators discover it and keep it maintained. Thank you!
You are operating a live, revenue-bearing Airbnb account on behalf of a real
host. Guests are real people. A duplicate message, a wrong send, or a careless
calendar change has real consequences. This skill exists so that **every agent
handles Airbnb identically and safely**, instead of improvising tool calls per
turn.
> Portability note. This skill is environment-agnostic. It refers to tool
> roles (an "Airbnb messages endpoint", an "agent-browser", a "DevTools
> bridge", a "Playwright fallback") rather than hard-coded URLs. Your concrete
> tool names live in references/airbnb-tool-priority.md — edit that one file
> to map roles to the actual tools in your deployment. Everything else here is
> universal.
operation before any browser automation. Browser weirdness is NOT evidence
that Airbnb access is down.
thread in the same operation.
sent: true is attempted, not confirmed. An endpoint success provesthe call returned — not that the guest can see the message. You MUST re-read
the thread and SEE the outbound message before marking confirmed.
unconfirmed send. Duplicate guest messages areworse than a late reply. Escalate to a human instead.
Pricing, availability, listing edits, and accept/decline are NOT implemented
in v1 — refuse and escalate.
If you are ever unsure, STOP and report. A paused agent is recoverable; a
duplicated or wrong guest message is not.
Use this to decide, before installing, whether your deployment can run the skill
and at what level. Map each role to a real tool in
references/airbnb-tool-priority.md. The skill degrades gracefully: if a
read-only requirement is met but a send requirement is not, the skill
runs in read-only mode and refuses sends rather than improvising.
Read-only mode — minimum to run safely (inbox / threads / reservations / calendar):
calendar (first-class endpoint preferred; agent-browser or DevTools read
acceptable as fallback).
That's the entire requirement for every READ verb. Nothing can be sent in this
mode.
Send-capable mode — additional minimum to send a guest reply:
explicitly human-approved browser send.
(The same read path from read-only mode satisfies this.)
If either is missing, do NOT send: stay in read-only mode and escalate.
Optional enhancements — improve safety / fallback depth when present:
Absent optional capabilities reduce fallback depth but never change the safety
rules. A required capability that is absent for a given operation triggers an
escalation, never an improvised workaround.
Resolve top-down. Drop to the next tier ONLY when the current tier is genuinely
unavailable, not merely "looked weird once." Full detail in
references/airbnb-tool-priority.md.
OPERATION
│
├─ 1. AIRBNB ENDPOINT (first-class, structured, auth-aware)
│ → DEFAULT for every supported operation. Always start here.
│
├─ 2. AGENT-BROWSER (navigate / status)
│ → ONLY when no endpoint covers the op, OR an endpoint returned a hard
│ transport failure (5xx/timeout) TWICE. First confirm the host
│ browser identity is alive before assuming auth loss.
│
├─ 3. DEVTOOLS (tabs / navigate / evaluate — READ-ONLY here)
│ → DOM inspection / UI verification when the endpoint read is
│ ambiguous. Never use evaluate to perform a write/click-send.
│
└─ 4. PLAYWRIGHT (fallback)
→ LAST RESORT. Only when 1–3 are unavailable AND the op is read-only
or an explicitly human-approved write.
Classify every operation before acting. Full table in
references/airbnb-safety-rules.md.
| Tier | Examples | Gate |
|---|---|---|
| --- | --- | --- |
| READ | check inbox, read thread, lookup reservation, inspect calendar | None. Proceed. |
| WRITE | send a guest reply | Approval if configured; ALWAYS verify after. |
| MUTATE | change price, block/open dates, edit listing, accept/decline, refund | NOT in v1. Refuse + escalate. |
Escalate to a human when: a send reaches unconfirmed or failed; you're
asked to perform any MUTATE op; the host browser identity reports unhealthy; two
read paths disagree on a material fact (dates, guest count, price); or you would
need to send the same message twice for any reason.
States: drafted → attempted → (confirmed | unconfirmed | failed). Full machine
with timings in references/airbnb-message-state-machine.md.
[drafted] reply composed; thread + dedupe-key recorded
│ (WRITE gate: get approval if required)
▼
[attempted] ← send endpoint called EXACTLY ONCE; ledger written NOW
│ endpoint sent:true → ATTEMPTED, not done
│
├─ verify: re-read the SAME thread (endpoint; DevTools if ambiguous)
│
├─ outbound visibly present? ── yes ──► [confirmed] ✅ report
├─ absent after verify window ── no ──► [unconfirmed] ⚠️ DO NOT RESEND, escalate
└─ send call errored ► [failed] ❌ re-read first, escalate, no blind resend
(thread_id + normalized hash of the draft text).
confirmed (or recent attempted) send withthe same dedupe-key exists → STOP, already handled.
drafted.attempted.Write the ledger entry before verifying, so a crash mid-verify can't cause
a blind resend.
confirmed; absent within window → unconfirmed.
The duplicate-prevention contract: exactly ONE call to the send endpoint per
drafted item, ever. unconfirmed/failed NEVER auto-transition to a new send.
Only a human, after reading the live thread, may authorize a retry.
booking_summary — list reservations sorted by check-in: guest, dates, status, reservation_id, linked thread_id.
lookup_reservation — by id or guest; map reservation ↔ thread so a replyties to the right booking.
inspect_calendar — report blocked/open/booked spans; FLAG (don't fix)high-risk states (double-booking, anomalous price, risky back-to-back gaps).
Calendar mutation, pricing, accept/decline, and listing edits are reserved for
v2 and get their own gated workflows mirroring the send machine
(read → propose → approve → do-once → verify → report). Until then: refuse +
escalate.
Agents speak only in these verbs; each maps to a canonical procedure. Format is
verb (TIER) — description.
READ verbs (no gate):
check_inbox (READ) — list threads needing attention, prioritized.read_thread (READ) — full live thread + guest-intent summary.lookup_reservation (READ) — reservation details + linked thread.booking_summary (READ) — upcoming bookings, sorted by check-in.inspect_calendar [range] (READ) — calendar state + flagged risks.verify_sent (READ) — re-check a thread for an outbound message.WRITE verbs (gated + verified):
draft_reply (WRITE-pre) — produce a reviewable draft; result state drafted.send_reply (WRITE) — run the full send state machine.Status:
report_status — emit structured status of the last operation.send_reply is the ONLY write, and it internally enforces
read → draft → approve → send-once → verify → report. Agents must not decompose
it into lower-level steps to skip verification.
This skill is the behavioral contract. A future formal adapter/tool layer
should harden the mechanical guarantees so correctness doesn't depend on a
model remembering a markdown rule. See references/future-adapter-interface.md.
Ideal future adapter functions (call them if present, fall back to the manual
procedure if not):
airbnb.sendVerified(thread_id, text, dedupe_key) → returns {state, visible_at} after doing send-once + ledger + verify atomically.
airbnb.dedupeCheck(dedupe_key) → {already_sent: bool, last_state}.airbnb.readThread(thread_id) / airbnb.listInbox() / airbnb.listReservations() / airbnb.readCalendar(range).
When sendVerified exists, send_reply delegates to it and simply reports the
returned state. When it doesn't, send_reply runs the manual procedure above.
to Playwright because something felt slow once is wrong.
sent: true as confirmed. It's attempted. Always verify.unconfirmed. This creates duplicate guest messages.Escalate instead.
auth is host-owned. Check browser status + an endpoint first.
a read workflow quietly perform a write.
procedure. Use it.
references/airbnb-tool-priority.md (map rolesto real tool names), the approval-gate policy, and whether a persistent ledger
is wired. Examples under examples/ are illustrative — adapt payloads to your
tools.
and the command vocabulary. These are the portable core; don't fork them per
deployment.
workflow in the same shape as the send machine. Never add a generic "do
anything" write. Bump version; record changes in a CHANGELOG if published.
共 2 个版本