Booking Manager
by @cskar10
AI-powered booking manager that connects to any existing booking system and lets business owners manage appointments through their phone (Telegram, WhatsApp,...
clawhub install booking-managerπ About This Skill
name: booking-manager version: 1.3.2 description: > AI-powered booking manager that connects to any existing booking system and lets business owners manage appointments through their phone (Telegram, WhatsApp, etc.). Use when: setting up an AI assistant to monitor bookings, notify owners of new enquiries, confirm/reschedule/cancel appointments conversationally, send professional customer emails with calendar invites, and provide schedule summaries. Works with any data source: SQL databases (PostgreSQL, SQLite/Turso, MySQL), REST APIs (Calendly, Square, Fresha), Google Sheets, or webhooks. Triggers on: "booking assistant", "appointment manager", "manage bookings via phone", "AI receptionist", "booking notifications", "salon booking system". homepage: https://github.com/Cskar10/booking-manager repository: https://github.com/Cskar10/booking-manager metadata: openclaw: requires: config: - env.SMTP_HOST - env.SMTP_USER - env.SMTP_PASSWORD env_vars: required: - name: SMTP_HOST description: "SMTP server hostname (e.g. smtp.gmail.com)" - name: SMTP_USER description: "Email address used to send confirmations" - name: SMTP_PASSWORD description: "SMTP app password (never a primary password)" optional: - name: BOOKING_DB_URL description: "Turso/LibSQL database URL" - name: BOOKING_DB_TOKEN description: "Turso/LibSQL auth token (scoped to bookings table)" - name: BOOKING_DB_HOST description: "PostgreSQL host" - name: BOOKING_DB_PORT description: "PostgreSQL port" - name: BOOKING_DB_USER description: "PostgreSQL user (limited to bookings table)" - name: BOOKING_DB_PASSWORD description: "PostgreSQL password" - name: BOOKING_DB_NAME description: "PostgreSQL database name" - name: GOOGLE_SHEET_ID description: "Google Sheets spreadsheet ID" - name: GOOGLE_SHEETS_TOKEN description: "Google Sheets API access token (scoped service account)" - name: SHEET_RANGE description: "Google Sheets range (e.g. Sheet1!A:H)" network: description: > The agent makes outbound requests to the configured data source (Turso API, PostgreSQL, Google Sheets API, or third-party booking APIs) and to the configured SMTP server for sending emails. No other external endpoints are contacted. Polling frequency is configurable via HEARTBEAT.md (default: every 15-30 minutes). endpoints: - "Configured SMTP server (env: SMTP_HOST, port 465/587)" - "Configured database URL (env: BOOKING_DB_URL or BOOKING_DB_HOST)" - "Google Sheets API v4 (if using Sheets as data source)" - "Third-party booking APIs (if using Calendly/Square/Fresha)" security: - "All credentials stored in openclaw.json env block, never in workspace files" - "Use least-privilege: scoped service accounts, DB users limited to bookings table" - "SMTP app passwords only, never primary account passwords" - "Rotate credentials after testing"
Booking Manager
An AI assistant layer that sits on top of any booking system, turning your phone into a full booking management interface via Telegram, WhatsApp, or any supported channel.
How It Works
Customer books β Data saved (DB/API/Sheet) β Agent polls for new bookings
β
Notifies owner via phone (Telegram/WhatsApp)
β
Owner replies: "confirm" / "reschedule" / "delete"
β
Agent updates data + emails customer
Setup
0. First-Run Onboarding
On any booking-related request, check if TOOLS.md contains a ## Business section
AND a ## Services section. If either is missing, this is a first-run β begin
onboarding before doing anything else.
Primary flow (form paste):
1. Greet the customer:
Hi! I'm your new booking assistant. πTo get started, please paste the completed onboarding form you received
and I'll set everything up from that.
If you don't have a form, just let me know and I'll walk you through
the setup step by step.
2. When the customer pastes the form, parse it for these fields:
| Field | Required | TOOLS.md Section |
|---|---|---|
| Business name | β
| ## Business |
| Business address | Optional | ## Business |
| Phone number | Optional | ## Business |
| Website | Optional | ## Business |
| Timezone | β
| ## Business |
| Services (name, duration, price) | β
| ## Services |
| Operating hours per day | β
| ## Operating Hours |
| Confirmation email (name + address) | β
| ## Email |
| Booking/cancellation policy | Optional | ## Booking Policy |
| Existing booking system | Optional | ## Booking Data Source |
| Notification preference | Optional | ## Notifications |
| Mobile number | Optional | ## Notifications |
| Additional notes | Optional | ## Notes |
3. Write the parsed config to TOOLS.md:
## Business
Name: [business name]
Address: [address]
Phone: [phone]
Website: [website]
Timezone: [timezone] Services
[Service 1]: [duration] min β $[price]
[Service 2]: [duration] min β $[price] Operating Hours
Monday: [open] β [close]
Tuesday: [open] β [close]
...
Sunday: Closed Email
From: [Business Name] <[email address]> Booking Policy
[policy text or "No specific policy"] Booking Data Source
Type: [system mentioned or "pending setup"]
Connection: [pending admin configuration] Notifications
Channel: [preference]
Mobile: [number]
4. Show a summary for confirmation:
β
All set! Here's what I've got:π [Business Name]
π [address]
π [hours summary]
Services:
β’ [Service 1] β [duration] min β $[price]
β’ [Service 2] β [duration] min β $[price]
Confirmations from: [email]
Policy: [policy summary]
Everything look right? If you need to change anything, just tell me.
5. Note about data source: "I'll need your booking system connected before I can see bookings β your admin will set that up for you."
Security: The onboarding flow collects business information only (name, services,
hours, policy). It must NEVER ask for or accept credentials (passwords, tokens, API
keys) through chat. Credentials are configured by the admin directly in openclaw.json
under env. If a customer pastes credentials in chat, do NOT store them β instruct
them to contact their admin instead.
Fallback flow (step-by-step):
If the customer says they don't have a form, collect info conversationally:
1. "What's your business called?" 2. "What services do you offer? For each one, I'll need the name, how long it takes, and the price." 3. "What days and hours are you open?" 4. "What timezone are you in?" 5. "What email address should booking confirmations come from?" 6. "Do you have any booking or cancellation policies?" 7. "Anything else I should know about how you run bookings?"
Write to TOOLS.md using the same format and show the same summary.
Validation:
Edge cases:
The onboarding form template is in references/onboarding-form.md.
1. Identify the data source
Determine how the business stores bookings. Read references/data-sources.md for
connection patterns for each supported platform.
2. Configure credentials
Store connection details as environment variables in openclaw.json under env,
never in plaintext in TOOLS.md or any workspace file. Reference them in TOOLS.md by
name only:
## Booking Data Source
Type: [turso | postgres | google-sheets | api]
Env vars configured: yes/no Email
From: [Business Name]
SMTP env vars configured: yes/no
Never store credentials in plaintext in TOOLS.md, SOUL.md, or any workspace file.
See references/data-sources.md for which environment variables each data source expects.
3. Set up heartbeat polling
Add to HEARTBEAT.md to check for new bookings every 15-30 minutes:
## Check for new bookings
Query the data source for bookings created since last check
If new bookings found: notify the owner with details and send acknowledgement email
4. Configure the agent identity
Set SOUL.md with the business context:
You are the booking manager for [Business Name].Your Role
Monitor for new booking enquiries and notify the owner on their phone
Confirm, reschedule, or delete bookings when instructed
Send professional emails to customers
Provide schedule summaries on demand Rules
All times in [timezone]
Always clean up booking locks when confirming or deleting
Send calendar invites (.ics) when confirming
Core Workflows
New booking notification
When a new booking is detected, notify the owner:
π New booking enquiry!Name: [name]
Service: [service] ([duration] min)
Date: [formatted date and time]
Phone: [phone]
Email: [email]
Reply: "confirm [id]", "reschedule [id] to [date] [time]", or "delete [id]"
Send an acknowledgement email to the customer. See references/email-templates.md.
Confirm booking
1. Mark booking as confirmed in data source 2. Remove any booking lock for the customer's email 3. Send confirmation email with .ics calendar invite attached 4. Notify owner: "β Booking #[id] confirmed. Email sent to [name]."
Reschedule booking
1. Update date/time in data source 2. Remove booking lock 3. Delete existing reminder record (so a new reminder sends for the updated time) 4. Send updated confirmation email with new .ics 5. Notify owner: "β Booking #[id] rescheduled to [new date/time]. Email sent."
Delete booking
1. Record the customer email before deleting 2. Delete the booking from data source 3. Remove booking lock 4. Optionally send cancellation email 5. Notify owner: "ποΈ Booking #[id] deleted."
Schedule queries
Respond naturally to:
Calendar Invites
Generate .ics files when confirming. See references/ics-format.md for the template
and timezone/DST conversion logic.
Email Sending
Send via Gmail SMTP using environment variables for credentials (never inline).
See references/email-templates.md for HTML templates and the secure sending pattern.
Booking Locks
Many booking systems use a lock/hold mechanism to prevent duplicate pending enquiries from the same customer. Always release locks when confirming or deleting a booking, otherwise the customer cannot book again.
Automated Reminder Emails
Send reminder emails to customers 24 hours before their appointment. This feature is added to the heartbeat/cron polling cycle alongside new booking checks.
Setup
Add a booking_reminders table to the data source to track sent reminders and prevent
duplicates. See references/data-sources.md for the schema.
Add reminder configuration to TOOLS.md:
## Reminders
Lead time: 24h (how far before the appointment to send)
Window: Β±1h (send if appointment is 23β25h away β accounts for polling gaps)
Include cancel/reschedule info: [yes | no]
Custom footer: [optional policy reminder text, e.g. "Cancellations within 48h..."]
The cancel/reschedule option and footer text are entirely business-specific. Some businesses allow changes up until the appointment; others enforce strict late-cancellation penalties. Configure per client.
Heartbeat integration
Add to HEARTBEAT.md alongside the new-booking check:
## Send appointment reminders
Query for confirmed bookings with appointments 23β25 hours from now
Skip any booking IDs already in the booking_reminders table
For each eligible booking: send reminder email, then record in booking_reminders
If any reminders sent: notify owner "π¬ Sent [n] reminder(s) for tomorrow's appointments"
Workflow
1. Query confirmed bookings where appointment time is 23β25 hours from now
2. Left-join against booking_reminders to exclude already-sent reminders
3. For each unsent reminder:
a. Send reminder email (see references/email-templates.md)
b. Insert a record into booking_reminders with the booking ID and timestamp
4. Notify the owner with a summary (if any were sent)
Reminder query (Turso/SQLite example)
SELECT b.*
FROM bookings b
LEFT JOIN booking_reminders r ON b.id = r.booking_id
WHERE b.status = 'confirmed'
AND b.appointment_datetime_utc > datetime('now', '+23 hours')
AND b.appointment_datetime_utc <= datetime('now', '+25 hours')
AND r.booking_id IS NULL;
Edge cases
booking_reminders table prevents duplicates even
if the same booking falls in the window across multiple polls.
Adapting to Different Businesses
Customise these per client:
βοΈ Configuration
0. First-Run Onboarding
On any booking-related request, check if TOOLS.md contains a ## Business section
AND a ## Services section. If either is missing, this is a first-run β begin
onboarding before doing anything else.
Primary flow (form paste):
1. Greet the customer:
Hi! I'm your new booking assistant. πTo get started, please paste the completed onboarding form you received
and I'll set everything up from that.
If you don't have a form, just let me know and I'll walk you through
the setup step by step.
2. When the customer pastes the form, parse it for these fields:
| Field | Required | TOOLS.md Section |
|---|---|---|
| Business name | β
| ## Business |
| Business address | Optional | ## Business |
| Phone number | Optional | ## Business |
| Website | Optional | ## Business |
| Timezone | β
| ## Business |
| Services (name, duration, price) | β
| ## Services |
| Operating hours per day | β
| ## Operating Hours |
| Confirmation email (name + address) | β
| ## Email |
| Booking/cancellation policy | Optional | ## Booking Policy |
| Existing booking system | Optional | ## Booking Data Source |
| Notification preference | Optional | ## Notifications |
| Mobile number | Optional | ## Notifications |
| Additional notes | Optional | ## Notes |
3. Write the parsed config to TOOLS.md:
```markdown