How I Automated Airbnb Guest Messaging with an AI Agent
Problem
I was spending 30+ minutes every day answering the same five questions from Airbnb guests:
- “What’s the check-in code?”
- “What’s the WiFi password?”
- “Where do I park?”
- “Any restaurant recommendations?”
- “Where’s the nearest grocery store?”
Every. Single. Guest. Asked. These. Questions.
I tried using Airbnb’s saved messages. But I still had to manually read each message, find the right saved response, and click send. It still took 5-10 minutes per guest.
My First Attempt: Keyword Matching
I thought I could just use simple keyword matching. Here was my first version:
RESPONSES = { "wifi": "Network: MyWiFi\nPassword: guest123", "parking": "Free parking in the garage behind the building.", "code": "Check-in code: 1234#",}
def respond(message: str) -> str | None: for keyword, response in RESPONSES.items(): if keyword in message.lower(): return response return NoneThis worked for simple messages. But then I got this:
Hey! I'm having trouble with the WiFi, it keeps disconnecting.Also, what's the parking situation? Thanks!My bot replied with just the WiFi password. The guest was complaining about WiFi problems, not asking for the password. And I missed the parking question entirely.
Lesson: Keyword matching is too naive. You need actual intent classification.
My Second Attempt: LLM-Based Classification
I switched to using an LLM to classify messages:
import jsonfrom anthropic import Anthropic
client = Anthropic()
CATEGORIES = ["check_in", "wifi", "parking", "restaurants", "groceries", "needs_attention"]
def classify_message(message: str) -> tuple[str, bool]: """ Returns (category, needs_human) """ prompt = f"""Classify this Airbnb guest message.
Message: "{message}"
Categories:- check_in: asking about entry codes, keys, door access- wifi: asking for WiFi credentials- parking: asking about parking options- restaurants: asking for restaurant recommendations- groceries: asking about nearby stores- needs_attention: complaints, issues, special requests, or anything unclear
Respond with JSON: {{"category": "...", "needs_human": true/false}}"""
response = client.messages.create( model="claude-3-haiku-20240307", max_tokens=100, messages=[{"role": "user", "content": prompt}] )
result = json.loads(response.content[0].text) return result["category"], result["needs_human"]This worked much better. But I made another mistake: I let it auto-reply to everything.
My Third Attempt: Adding Human Oversight
I realized I needed to flag certain messages:
FLAG_KEYWORDS = [ "complaint", "problem", "issue", "broken", "not working", "emergency", "urgent", "refund", "cancel", "unhappy", "noise", "safety", "security", "help"]
def should_flag_for_human(message: str) -> bool: """Check if message needs human attention""" message_lower = message.lower()
# Flag for concerning keywords if any(keyword in message_lower for keyword in FLAG_KEYWORDS): return True
# Flag multiple questions (might be complex) if message.count('?') > 2: return True
return False
def process_message(message: str) -> dict: """Process incoming guest message""" category, needs_human = classify_message(message)
# Additional human check if should_flag_for_human(message): needs_human = True
if needs_human: return { "action": "flag", "reason": f"Category: {category}, flagged for human review", "notify_host": True }
return { "action": "auto_reply", "category": category, "response": get_response_template(category) }The Complete System
Here’s my final architecture:
+------------------+ +-------------------+ +------------------+| Guest Message | --> | Classification | --> | Decision || (Airbnb API) | | (LLM) | | |+------------------+ +-------------------+ +------------------+ | +--------------------------------+--------------------------------+ | | v v +------------------+ +------------------+ | Auto Reply | | Flag for Host | | (Template) | | (Notification) | +------------------+ +------------------+The complete responder:
from dataclasses import dataclassfrom typing import Optionalimport osfrom anthropic import Anthropic
@dataclassclass GuestResponse: auto_reply: bool message: Optional[str] category: Optional[str] flag_reason: Optional[str]
class AirbnbGuestAgent: def __init__(self): self.client = Anthropic() self.responses = { "check_in": ( "Hi! Your check-in code is {code}. " "The keypad is on the left side of the door. " "Let me know if you need any help!" ), "wifi": ( "Here's the WiFi info:\n" "Network: {ssid}\n" "Password: {password}\n" "The router is in the living room." ), "parking": ( "Free parking is available in the garage. " "Use the remote on the kitchen counter to open the gate. " "Your spot is #12." ), "restaurants": ( "Here are my favorite nearby restaurants:\n" "1. Mario's Pizza (2 blocks) - best pizza in town\n" "2. Sushi Bay (3 blocks) - fresh and affordable\n" "3. The Local Diner (1 block) - great breakfast" ), "groceries": ( "Nearest grocery stores:\n" "- Whole Foods: 4 blocks north\n" "- Corner Market: 1 block east (open until 10pm)" ), } self.property_config = { "code": "1234#", "ssid": "GuestWiFi", "password": "welcome2024", } self.flag_keywords = [ "complaint", "problem", "issue", "broken", "not working", "emergency", "urgent", "refund", "cancel", "unhappy", "noise", "safety", "security", "help", "wrong" ]
def classify(self, message: str) -> tuple[str, bool]: """Classify message intent""" prompt = f"""Classify this Airbnb guest message. Be conservative - when in doubt, flag for human.
Message: "{message}"
Categories: check_in, wifi, parking, restaurants, groceries, needs_attention
JSON response: {{"category": "...", "confident": true/false}}"""
response = self.client.messages.create( model="claude-3-haiku-20240307", max_tokens=50, messages=[{"role": "user", "content": prompt}] )
import json result = json.loads(response.content[0].text) return result["category"], result["confident"]
def needs_human(self, message: str, category: str, confident: bool) -> tuple[bool, str]: """Determine if human review is needed""" message_lower = message.lower()
# Check for flag keywords for keyword in self.flag_keywords: if keyword in message_lower: return True, f"Detected keyword: {keyword}"
# Check for multiple questions if message.count('?') > 2: return True, "Multiple questions - may be complex"
# Low confidence classification if not confident: return True, "Low classification confidence"
return False, ""
def process(self, message: str) -> GuestResponse: """Process a guest message""" category, confident = self.classify(message) needs_review, reason = self.needs_human(message, category, confident)
if needs_review: return GuestResponse( auto_reply=False, message=None, category=category, flag_reason=reason )
# Get response template template = self.responses.get(category) if not template: return GuestResponse( auto_reply=False, message=None, category=category, flag_reason="Unknown category" )
# Fill in property details response_text = template.format(**self.property_config)
return GuestResponse( auto_reply=True, message=response_text, category=category, flag_reason=None )Results
After running this for a month:
| Metric | Before | After |
|---|---|---|
| Daily time on messages | 30+ min | ~5 min |
| Messages auto-handled | 0% | ~70% |
| Response time | 5-10 min | <1 min (auto) |
| Guest satisfaction | 4.7 | 4.8 |
The 5 minutes I now spend is just reviewing the flagged messages to make sure the agent classified them correctly.
What I Learned
1. Start with the five most common questions
Don’t try to automate everything. The 80/20 rule applies here - 80% of questions fall into 5 categories.
2. Be conservative with auto-replies
It’s better to flag too many messages than to send an inappropriate auto-response. A delayed human response is better than a tone-deaf bot response.
3. Keep templates updated
I forgot to update my parking template when the garage changed spot numbers. Got a confused message from a guest. Now I review templates monthly.
4. Review flagged messages daily
The agent isn’t perfect. I catch misclassifications during my 5-minute daily review and add them to my test set.
5. Don’t automate complaints
One guest wrote “The WiFi is slow and parking is terrible.” My early version would have sent the WiFi password and parking instructions. Not helpful. Now these go straight to me.
Common Mistakes to Avoid
+--------------------------------+--------------------------------+| MISTAKE | SOLUTION |+--------------------------------+--------------------------------+| Auto-reply to everything | Flag uncertain cases || | || Stale templates | Monthly review schedule || | || Robotic tone | Use natural language templates || | || No human oversight | Daily review of flagged msgs || | || Missing edge cases | Build test set from failures |+--------------------------------+--------------------------------+Summary
I automated 70% of my Airbnb guest messaging with a simple AI agent. The key insight: AI agents excel at pattern-matching on repetitive, factual questions. They don’t need to be creative - they need to be accurate and consistent.
The time savings are real: 30+ minutes per day reduced to 5 minutes of review. More importantly, guests get instant responses for common questions, which improves their experience.
If you’re an Airbnb host drowning in repetitive messages, this is a practical automation you can build in a weekend.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Reddit: Real-world OpenClaw automation stories
- 👨💻 LangChain Documentation
- 👨💻 Airbnb Host Community
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments