# Custom Scripting Guide

Create your own automations with safe, powerful scripting! Write Python-like code with if/else statements, loops, and variables to automate your business processes.

## 🎯 What You Can Do

- **Access Your Data**: Get appointments, customers, and more
- **Write Logic**: Use if/else, loops, and variables
- **Send Emails**: Contact customers automatically
- **Create Reports**: Generate custom analytics
- **Call APIs**: Integrate with external services (approved domains)

## 🔒 Safety Features

We protect your data and our servers with:

- **No Infinite Loops**: Automatically stopped after 10,000 iterations
- **Execution Timeout**: Scripts limited to 30 seconds
- **API Rate Limits**: Maximum 50 API calls per execution
- **Memory Limits**: 50MB maximum
- **No File Access**: Can't read/write files
- **No Code Injection**: Can't use eval, exec, or import
- **Sandboxed**: Runs in isolated environment

## 📚 Available API Methods

### `api.get_appointments(**filters)`

Get appointments for your business.

**Parameters:**
- `status` - Filter by status ('SCHEDULED', 'COMPLETED', 'CANCELED')
- `start_date` - Filter by start date ('YYYY-MM-DD')
- `end_date` - Filter by end date ('YYYY-MM-DD')
- `limit` - Maximum results (default: 100, max: 1000)

**Returns:** List of appointment dictionaries

**Example:**
```python
# Get all scheduled appointments
appointments = api.get_appointments(status='SCHEDULED')

# Get appointments from last week
from datetime import datetime, timedelta
start = (datetime.now() - timedelta(days=7)).strftime('%Y-%m-%d')
recent = api.get_appointments(start_date=start, limit=50)
```

### `api.get_customers(**filters)`

Get customers for your business.

**Parameters:**
- `limit` - Maximum results (default: 100, max: 1000)
- `has_email` - Only customers with email addresses (True/False)

**Returns:** List of customer dictionaries

**Example:**
```python
# Get all customers with emails
customers = api.get_customers(has_email=True)

# Get first 50 customers
top_customers = api.get_customers(limit=50)
```

### `api.send_email(to, subject, body)`

Send an email to a customer.

**Parameters:**
- `to` - Email address or customer ID
- `subject` - Email subject (max 200 characters)
- `body` - Email body (max 10,000 characters)

**Returns:** True if sent successfully

**Example:**
```python
# Send to email address
api.send_email(
    to='customer@example.com',
    subject='Special Offer',
    body='Hello! Here is a special offer just for you...'
)

# Send to customer by ID
api.send_email(
    to=123,
    subject='Appointment Reminder',
    body='Your appointment is tomorrow at 2 PM'
)
```

### `api.create_appointment(title, start_time, end_time, **kwargs)`

Create a new appointment.

**Parameters:**
- `title` - Appointment title
- `start_time` - Start datetime (ISO format: '2025-01-15T10:00:00')
- `end_time` - End datetime (ISO format: '2025-01-15T11:00:00')
- `notes` - Optional notes

**Returns:** Created appointment dictionary

**Example:**
```python
apt = api.create_appointment(
    title='Follow-up Consultation',
    start_time='2025-01-20T14:00:00',
    end_time='2025-01-20T15:00:00',
    notes='Automated follow-up'
)
```

### `api.log(message)`

Log a message for debugging.

**Example:**
```python
api.log('Script started')
api.log(f'Found {len(appointments)} appointments')
```

### `api.http_get(url, headers=None)`

Make HTTP GET request to approved domains.

**Parameters:**
- `url` - URL to fetch (must be approved)
- `headers` - Optional headers dictionary

**Returns:** Response text

**Example:**
```python
# Call Slack webhook
response = api.http_get(
    'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'
)
```

### Helper Methods

```python
# Count items
count = api.count(appointments)

# Sum numbers
total = api.sum([10, 20, 30])

# Filter with condition
active = api.filter(customers, lambda c: c['email'] != '')
```

## 📝 Script Examples

### Example 1: Simple Appointment Count

```python
# Get all appointments
appointments = api.get_appointments(limit=500)

# Count by status
scheduled = 0
completed = 0

for apt in appointments:
    if apt['status'] == 'SCHEDULED':
        scheduled += 1
    elif apt['status'] == 'COMPLETED':
        completed += 1

# Log results
api.log(f"Scheduled: {scheduled}, Completed: {completed}")

# Return result
result = {
    'scheduled': scheduled,
    'completed': completed,
    'total': len(appointments)
}
```

### Example 2: Conditional Email Campaign

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

# Get recent appointments
from datetime import datetime, timedelta
cutoff = (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d')
recent_apts = api.get_appointments(start_date=cutoff)

# Find customers who booked recently
recent_customer_ids = set()
for apt in recent_apts:
    # In real usage, you'd extract customer ID from appointment
    pass

# Send emails to inactive customers
sent = 0
for customer in customers:
    # If customer hasn't booked recently
    if customer['id'] not in recent_customer_ids:
        success = api.send_email(
            to=customer['email'],
            subject='We Miss You!',
            body=f"Hi {customer['name']},\n\nIt's been a while! Come back and get 15% off."
        )
        if success:
            sent += 1

result = {'emails_sent': sent}
```

### Example 3: Weekly Summary Report

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

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

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

# Group by day
daily_counts = {}
for apt in appointments:
    # Extract date from ISO timestamp
    date = apt['start_time'].split('T')[0]
    daily_counts[date] = daily_counts.get(date, 0) + 1

# Build report
report = "Weekly Appointment Summary\n\n"
for date in sorted(daily_counts.keys()):
    report += f"{date}: {daily_counts[date]} appointments\n"
report += f"\nTotal: {len(appointments)}"

# Send report
api.send_email(
    to='manager@business.com',
    subject='Weekly Summary',
    body=report
)

result = {'total_appointments': len(appointments)}
```

### Example 4: Smart Customer Segmentation

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

# Get all appointments
appointments = api.get_appointments(limit=1000)

# Count visits per customer (simplified)
visit_counts = {}
for apt in appointments:
    # In real usage, extract customer ID
    customer_id = 'placeholder'
    visit_counts[customer_id] = visit_counts.get(customer_id, 0) + 1

# Segment customers
new_customers = []
loyal_customers = []

for customer in customers:
    visits = visit_counts.get(customer['id'], 0)

    if visits == 1:
        new_customers.append(customer)
    elif visits >= 5:
        loyal_customers.append(customer)

# Send different messages to each segment
for customer in new_customers:
    api.send_email(
        to=customer['email'],
        subject='Welcome!',
        body=f"Hi {customer['name']}, thanks for trying us! Here's 20% off your next visit."
    )

for customer in loyal_customers:
    api.send_email(
        to=customer['email'],
        subject='VIP Offer',
        body=f"Hi {customer['name']}, you're a valued customer! Exclusive offer inside..."
    )

result = {
    'new_customers': len(new_customers),
    'loyal_customers': len(loyal_customers)
}
```

### Example 5: Dynamic Pricing Alert

```python
# Get upcoming appointments
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'
)

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

# Find slow days (less than 3 bookings)
slow_days = []
for date, count in daily_bookings.items():
    if count < 3:
        slow_days.append(date)

# Alert manager
if slow_days:
    message = f"Slow booking days detected:\n\n"
    for date in slow_days:
        count = daily_bookings[date]
        message += f"{date}: only {count} booking(s)\n"
    message += "\nConsider running a promotion!"

    api.send_email(
        to='manager@business.com',
        subject='⚠️ Low Booking Alert',
        body=message
    )

result = {'slow_days': slow_days}
```

## 🎨 Using Script Templates

Pre-built templates make it even easier! Just fill in the parameters.

### Example: Conditional Email Template

```bash
curl -X POST http://lvh.me:8000/api/scheduled-tasks/ \
  -H "Content-Type: application/json" \
  -d '{
    "name": "VIP Customer Campaign",
    "plugin_name": "script_template",
    "plugin_config": {
      "template": "conditional_email",
      "parameters": {
        "condition_field": "visits",
        "condition_value": "5",
        "email_subject": "You are a VIP!",
        "email_body": "Hi {name}, you are one of our best customers!"
      }
    },
    "schedule_type": "CRON",
    "cron_expression": "0 10 * * 1"
  }'
```

## 🚀 Creating a Scheduled Script

### Via API

```bash
curl -X POST http://lvh.me:8000/api/scheduled-tasks/ \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Custom Automation",
    "description": "Weekly customer re-engagement",
    "plugin_name": "custom_script",
    "plugin_config": {
      "script": "# Your Python code here\nappointments = api.get_appointments()\napi.log(f\"Found {len(appointments)} appointments\")\nresult = len(appointments)",
      "description": "Counts appointments and logs the result"
    },
    "schedule_type": "CRON",
    "cron_expression": "0 9 * * 1",
    "status": "ACTIVE"
  }'
```

### Schedule Types

**Every Monday at 9 AM:**
```json
{
  "schedule_type": "CRON",
  "cron_expression": "0 9 * * 1"
}
```

**Every Hour:**
```json
{
  "schedule_type": "INTERVAL",
  "interval_minutes": 60
}
```

**One-Time on Specific Date:**
```json
{
  "schedule_type": "ONE_TIME",
  "run_at": "2025-02-01T10:00:00Z"
}
```

## 📖 Built-in Functions

You can use these Python built-ins:

```python
# Math
len([1, 2, 3])        # Length
min([1, 2, 3])        # Minimum
max([1, 2, 3])        # Maximum
sum([1, 2, 3])        # Sum
abs(-5)               # Absolute value
round(3.14159, 2)     # Round to 2 decimals

# Type conversion
int('42')             # Convert to integer
float('3.14')         # Convert to float
str(123)              # Convert to string
bool(1)               # Convert to boolean

# Collections
list((1, 2, 3))       # Create list
dict(a=1, b=2)        # Create dictionary
range(10)             # Number sequence
sorted([3, 1, 2])     # Sort list
reversed([1, 2, 3])   # Reverse list

# Iteration
enumerate(['a', 'b']) # Index and value
zip([1, 2], ['a', 'b']) # Combine lists
any([True, False])    # Any true?
all([True, True])     # All true?
```

## ❌ What's NOT Allowed

```python
# ❌ Import statements
import os  # Error!

# ❌ Eval/exec
eval('1 + 1')  # Error!

# ❌ Function definitions (for now)
def my_function():  # Error!
    pass

# ❌ Class definitions
class MyClass:  # Error!
    pass

# ❌ File operations
open('file.txt')  # No file access!

# ❌ Network (except approved APIs)
requests.get('http://example.com')  # Error!
```

## 🐛 Debugging Tips

### Use Logging

```python
api.log('Script started')

customers = api.get_customers()
api.log(f'Found {len(customers)} customers')

for customer in customers:
    api.log(f'Processing {customer["name"]}')
    # ... do something

api.log('Script finished')
```

### Check Execution Logs

```bash
# Get logs for task #1
curl http://lvh.me:8000/api/scheduled-tasks/1/logs/

# Filter by status
curl http://lvh.me:8000/api/task-logs/?status=FAILED
```

### Test Scripts Manually

```bash
# Execute task immediately (don't wait for schedule)
curl -X POST http://lvh.me:8000/api/scheduled-tasks/1/execute/
```

## ⚡ Performance Tips

### 1. Limit Data Fetching

```python
# ❌ Bad: Fetch everything
appointments = api.get_appointments(limit=1000)

# ✅ Good: Fetch only what you need
appointments = api.get_appointments(
    status='SCHEDULED',
    start_date='2025-01-01',
    limit=50
)
```

### 2. Use Efficient Loops

```python
# ❌ Bad: Nested loops
for customer in customers:
    for apt in appointments:
        if apt['customer_id'] == customer['id']:
            # ...

# ✅ Good: Build lookup first
customer_apts = {}
for apt in appointments:
    cid = apt['customer_id']
    if cid not in customer_apts:
        customer_apts[cid] = []
    customer_apts[cid].append(apt)

for customer in customers:
    apts = customer_apts.get(customer['id'], [])
    # Much faster!
```

### 3. Batch Operations

```python
# ❌ Bad: Individual calls
for customer in customers:
    api.send_email(customer['email'], 'Subject', 'Body')

# ✅ Good: Filter first, then send
active_customers = [c for c in customers if c['status'] == 'active']
for customer in active_customers:
    api.send_email(customer['email'], 'Subject', 'Body')
```

## 💡 Common Use Cases

### 1. Abandoned Cart Recovery
```python
# Find customers with unpaid appointments
unpaid = api.get_appointments(status='SCHEDULED')
# Send reminder emails
```

### 2. Birthday Campaigns
```python
# Get customers with birthdays this week
# Send birthday wishes with discount code
```

### 3. Review Requests
```python
# Get completed appointments from yesterday
# Send review request emails
```

### 4. Capacity Alerts
```python
# Count upcoming appointments
# Alert if fully booked or too empty
```

### 5. Customer Lifecycle
```python
# Identify customer segments (new, active, at-risk)
# Send targeted campaigns
```

## 🔐 Security Best Practices

1. **Never hardcode secrets** in scripts
   - Use environment variables or settings
   - Don't put API keys in code

2. **Validate input data**
   ```python
   email = customer.get('email', '')
   if '@' in email:
       api.send_email(email, 'Subject', 'Body')
   ```

3. **Limit batch sizes**
   ```python
   # Don't spam - send max 50 emails per run
   customers = api.get_customers(limit=50)
   ```

4. **Handle errors gracefully**
   ```python
   success = api.send_email(email, subject, body)
   if not success:
       api.log(f'Failed to send to {email}')
   ```

## 📊 Script Result Format

Your script should set a `result` variable with execution results:

```python
# Your script logic here
appointments = api.get_appointments()

# Set result variable
result = {
    'total': len(appointments),
    'scheduled': 10,
    'completed': 25,
    'message': 'Processing completed successfully'
}
```

This result is stored in the execution log and can be used for tracking and analytics.

## 🆘 Getting Help

- **Execution Failed?** Check the error message in logs
- **Need More API Methods?** Contact support to request new features
- **Performance Issues?** Review the performance tips above
- **Template Request?** Suggest new templates to add

## 📈 Pricing

| Plan | Custom Scripts | Executions/Month | Support |
|------|----------------|------------------|---------|
| Free | 1 active | 100 | Community |
| Pro | 5 active | 1,000 | Email |
| Business | Unlimited | Unlimited | Priority |

Start automating your business today! 🚀
