Files
smoothschedule/smoothschedule/SCRIPTING_EXAMPLES.md
poduck 3fef0d5749 feat: Add comprehensive plugin documentation and advanced template system
Added complete plugin documentation with visual mockups and expanded template
variable system with CONTEXT, DATE helpers, and default values.

Backend Changes:
- Extended template_parser.py to support all new template types
- Added PROMPT with default values: {{PROMPT:var|desc|default}}
- Added CONTEXT variables: {{CONTEXT:business_name}}, {{CONTEXT:owner_email}}
- Added DATE helpers: {{DATE:today}}, {{DATE:+7d}}, {{DATE:monday}}
- Implemented date expression evaluation for relative dates
- Updated compile_template to handle all template types
- Added context parameter for business data auto-fill

Frontend Changes:
- Created comprehensive HelpPluginDocs.tsx with Stripe-style API docs
- Added visual mockup of plugin configuration form
- Documented all template types with examples and benefits
- Added Command Reference section with allowed/blocked Python commands
- Documented all HTTP methods (GET, POST, PUT, PATCH, DELETE)
- Added URL whitelisting requirements and approval process
- Created Platform Staff management page with edit modal
- Added can_approve_plugins and can_whitelist_urls permissions

Platform Staff Features:
- List all platform_manager and platform_support users
- Edit user details with role-based permissions
- Superusers can edit anyone
- Platform managers can only edit platform_support users
- Permission cascade: users can only grant permissions they have
- Real-time updates via React Query cache invalidation

Documentation Highlights:
- 4 template types: PROMPT, CONTEXT, DATE, and automatic validation
- Visual form mockup showing exactly what users see
- All allowed control flow (if/elif/else, for, while, try/except, etc.)
- All allowed built-in functions (len, range, min, max, etc.)
- All blocked operations (import, exec, eval, class/function defs)
- Complete HTTP API reference with examples
- URL whitelisting process: contact pluginaccess@smoothschedule.com

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:54:07 -05:00

11 KiB

Custom Script Examples - Quick Reference

Copy and paste these examples to get started quickly!

1. Send Weekly Summary Email

# Get appointments from last 7 days
from datetime import datetime, timedelta

end = datetime.now().strftime('%Y-%m-%d')
start = (datetime.now() - timedelta(days=7)).strftime('%Y-%m-%d')

appointments = api.get_appointments(
    start_date=start,
    end_date=end,
    limit=500
)

# Count by status
scheduled = sum(1 for a in appointments if a['status'] == 'SCHEDULED')
completed = sum(1 for a in appointments if a['status'] == 'COMPLETED')
canceled = sum(1 for a in appointments if a['status'] == 'CANCELED')

# Build report
report = f"""
Weekly Summary ({start} to {end})

Total Appointments: {len(appointments)}
- Scheduled: {scheduled}
- Completed: {completed}
- Canceled: {canceled}

Completion Rate: {(completed / len(appointments) * 100):.1f}%
"""

# Send it
api.send_email(
    to='manager@yourbusiness.com',
    subject=f'Weekly Summary - {start}',
    body=report
)

result = {'total': len(appointments), 'completed': completed}

Schedule: 0 9 * * 1 (Every Monday at 9 AM)


2. Re-engage Inactive Customers

# Get appointments from last 90 days
from datetime import datetime, timedelta

cutoff = (datetime.now() - timedelta(days=90)).strftime('%Y-%m-%d')
recent_appointments = api.get_appointments(start_date=cutoff, limit=500)

# Get all customers
all_customers = api.get_customers(has_email=True, limit=200)

# Find who booked recently (simplified - in production use customer IDs)
recent_customer_emails = {apt['title'] for apt in recent_appointments}

# Find inactive customers
inactive = []
for customer in all_customers:
    if customer['email'] not in recent_customer_emails:
        inactive.append(customer)

# Send re-engagement emails (limit to 30 per run)
sent = 0
for customer in inactive[:30]:
    message = f"""Hi {customer['name']},

We noticed it's been a while since your last visit!

We'd love to see you again. Book this week and get 20% off with code: COMEBACK20

Hope to see you soon!
"""

    success = api.send_email(
        to=customer['email'],
        subject='We Miss You! 20% Off Inside',
        body=message
    )

    if success:
        sent += 1

api.log(f'Sent {sent} re-engagement emails')
result = {'inactive_found': len(inactive), 'emails_sent': sent}

Schedule: 0 10 * * 3 (Every Wednesday at 10 AM)


3. Alert on Low Bookings

# Get appointments for next 7 days
from datetime import datetime, timedelta

today = datetime.now().strftime('%Y-%m-%d')
next_week = (datetime.now() + timedelta(days=7)).strftime('%Y-%m-%d')

upcoming = api.get_appointments(
    start_date=today,
    end_date=next_week,
    status='SCHEDULED',
    limit=200
)

# If less than 10 appointments, send alert
if len(upcoming) < 10:
    alert = f"""
⚠️ LOW BOOKING ALERT

Only {len(upcoming)} appointments scheduled for the next 7 days.

Recommendation: Run a promotion or send reminders to past customers.

This is below your normal booking rate.
"""

    api.send_email(
        to='owner@yourbusiness.com',
        subject='⚠️ Low Booking Alert',
        body=alert
    )

    result = {'alert_sent': True, 'upcoming_count': len(upcoming)}
else:
    result = {'alert_sent': False, 'upcoming_count': len(upcoming)}

Schedule: 0 8 * * * (Every day at 8 AM)


4. Birthday Campaign

# Get all customers
customers = api.get_customers(has_email=True, limit=500)

# Today's date (simplified birthday check)
from datetime import datetime
today = datetime.now()

# Send birthday wishes (simplified - in production check actual birthdays)
birthday_customers = []

for customer in customers:
    # In real usage, you'd have birthday field
    # This is a placeholder
    is_birthday = False  # Replace with actual birthday check

    if is_birthday:
        birthday_customers.append(customer)

        message = f"""Happy Birthday, {customer['name']}! 🎉

Celebrate with us! Get 25% off any service this week with code: BIRTHDAY25

We hope you have an amazing day!
"""

        api.send_email(
            to=customer['email'],
            subject='🎉 Happy Birthday! Special Gift Inside',
            body=message
        )

api.log(f'Sent {len(birthday_customers)} birthday emails')
result = {'birthday_emails_sent': len(birthday_customers)}

Schedule: 0 9 * * * (Every day at 9 AM)


5. Appointment Reminder (Day Before)

# Get appointments for tomorrow
from datetime import datetime, timedelta

tomorrow_start = (datetime.now() + timedelta(days=1)).replace(hour=0, minute=0).strftime('%Y-%m-%d')
tomorrow_end = (datetime.now() + timedelta(days=1)).replace(hour=23, minute=59).strftime('%Y-%m-%d')

tomorrow_appointments = api.get_appointments(
    start_date=tomorrow_start,
    end_date=tomorrow_end,
    status='SCHEDULED',
    limit=100
)

# Send reminders
sent = 0
for apt in tomorrow_appointments:
    # Extract time
    time_str = apt['start_time'].split('T')[1][:5]  # Get HH:MM

    reminder = f"""Appointment Reminder

You have an appointment tomorrow at {time_str}.

Title: {apt['title']}
Time: {time_str}

See you then!

Reply CANCEL to cancel or RESCHEDULE to change the time.
"""

    # In production, you'd get customer email from appointment
    # This is simplified
    customer_email = 'customer@example.com'

    success = api.send_email(
        to=customer_email,
        subject='Reminder: Appointment Tomorrow',
        body=reminder
    )

    if success:
        sent += 1

result = {'reminders_sent': sent, 'appointments_tomorrow': len(tomorrow_appointments)}

Schedule: 0 18 * * * (Every day at 6 PM)


6. Monthly Performance Report

# Get last month's data
from datetime import datetime, timedelta

# Calculate last month
today = datetime.now()
first_of_this_month = today.replace(day=1)
last_month_end = (first_of_this_month - timedelta(days=1)).strftime('%Y-%m-%d')
last_month_start = (first_of_this_month - timedelta(days=31)).replace(day=1).strftime('%Y-%m-%d')

appointments = api.get_appointments(
    start_date=last_month_start,
    end_date=last_month_end,
    limit=1000
)

# Calculate metrics
total = len(appointments)
completed = sum(1 for a in appointments if a['status'] == 'COMPLETED')
canceled = sum(1 for a in appointments if a['status'] == 'CANCELED')
no_show_rate = (canceled / total * 100) if total > 0 else 0

# Group by week
weekly_counts = {}
for apt in appointments:
    # Get week number
    date_str = apt['start_time'].split('T')[0]
    weekly_counts[date_str[:7]] = weekly_counts.get(date_str[:7], 0) + 1

# Build report
report = f"""
Monthly Performance Report
Period: {last_month_start} to {last_month_end}

OVERVIEW
--------
Total Appointments: {total}
Completed: {completed}
Canceled: {canceled}
No-Show Rate: {no_show_rate:.1f}%

WEEKLY BREAKDOWN
----------------
"""

for week in sorted(weekly_counts.keys()):
    report += f"{week}: {weekly_counts[week]} appointments\n"

report += f"\n{'📈' if completed > 50 else '📉'} "
report += "Great month!" if completed > 50 else "Consider increasing marketing"

# Send report
api.send_email(
    to='owner@yourbusiness.com',
    subject=f'Monthly Report - {last_month_start}',
    body=report
)

result = {
    'total': total,
    'completed': completed,
    'no_show_rate': round(no_show_rate, 2)
}

Schedule: 0 9 1 * * (First day of month at 9 AM)


7. VIP Customer Recognition

# Get appointments from last 6 months
from datetime import datetime, timedelta

six_months_ago = (datetime.now() - timedelta(days=180)).strftime('%Y-%m-%d')
appointments = api.get_appointments(start_date=six_months_ago, limit=1000)

# Count visits per customer (simplified)
customer_visits = {}
for apt in appointments:
    # In production, extract actual customer ID
    customer_id = apt.get('customer_id', 'unknown')
    customer_visits[customer_id] = customer_visits.get(customer_id, 0) + 1

# Find VIP customers (5+ visits)
vip_count = sum(1 for visits in customer_visits.values() if visits >= 5)

# Get customers
customers = api.get_customers(has_email=True, limit=100)

# Send VIP recognition
sent = 0
for customer in customers:
    visits = customer_visits.get(customer['id'], 0)

    if visits >= 5:
        message = f"""Hi {customer['name']},

You're officially a VIP! 🌟

You've visited us {visits} times in the last 6 months, and we truly appreciate your loyalty.

As a thank you, here's an exclusive 30% off code: VIP30

Valid for your next 3 visits!

Thank you for being amazing!
"""

        success = api.send_email(
            to=customer['email'],
            subject='🌟 You are a VIP Customer!',
            body=message
        )

        if success:
            sent += 1

result = {'vip_customers': vip_count, 'emails_sent': sent}

Schedule: 0 10 1 * * (First of month at 10 AM)


8. Capacity Optimization Alert

# Get next 30 days of appointments
from datetime import datetime, timedelta

today = datetime.now().strftime('%Y-%m-%d')
thirty_days = (datetime.now() + timedelta(days=30)).strftime('%Y-%m-%d')

upcoming = api.get_appointments(
    start_date=today,
    end_date=thirty_days,
    status='SCHEDULED',
    limit=500
)

# Group by date
daily_bookings = {}
for apt in upcoming:
    date = apt['start_time'].split('T')[0]
    daily_bookings[date] = daily_bookings.get(date, 0) + 1

# Find issues
overbooked = []
underbooked = []

for date, count in daily_bookings.items():
    if count > 15:  # More than 15 per day = overbooked
        overbooked.append(f"{date}: {count} appointments")
    elif count < 3:  # Less than 3 = underbooked
        underbooked.append(f"{date}: {count} appointments")

# Send alert if needed
if overbooked or underbooked:
    alert = "Capacity Alert\n\n"

    if overbooked:
        alert += "⚠️ OVERBOOKED DAYS:\n"
        alert += "\n".join(overbooked)
        alert += "\n\nConsider adding staff or limiting bookings.\n\n"

    if underbooked:
        alert += "📉 UNDERBOOKED DAYS:\n"
        alert += "\n".join(underbooked)
        alert += "\n\nConsider running promotions.\n"

    api.send_email(
        to='manager@yourbusiness.com',
        subject='Capacity Alert - Action Needed',
        body=alert
    )

result = {
    'overbooked_days': len(overbooked),
    'underbooked_days': len(underbooked)
}

Schedule: 0 7 * * 1 (Every Monday at 7 AM)


Tips for Success

  1. Start Simple - Copy one example and modify it
  2. Test First - Use "Execute Now" to test before scheduling
  3. Check Logs - Review execution logs for errors
  4. Add Logging - Use api.log() to debug
  5. Limit Batches - Don't send too many emails at once
  6. Schedule Wisely - Consider your business hours

Common Modifications

Change Email Content

# Replace the message string with your own text
message = f"""Your custom message here

Use {customer['name']} for personalization
"""

Adjust Date Ranges

# Change the number of days
days_back = 30  # Instead of 7, 14, 90, etc.
start = (datetime.now() - timedelta(days=days_back)).strftime('%Y-%m-%d')

Filter by Status

# Only get specific statuses
appointments = api.get_appointments(
    status='COMPLETED',  # or 'SCHEDULED', 'CANCELED'
    limit=100
)

Limit Results

# Process fewer customers
customers = api.get_customers(limit=20)  # Instead of 100

Happy automating! 🚀