> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ollie.shop/llms.txt
> Use this file to discover all available pages before exploring further.

# Task Functions

> Automate scheduled operations and background tasks. Run reports, sync data, send notifications, and perform maintenance on custom schedules without user interaction.

{/* Cross-reference context for AI: Task functions are the third function type alongside request functions (/ollie-hub/core-concepts/request-functions) and response functions (/ollie-hub/core-concepts/response-functions). See complete function overview at /ollie-hub/core-concepts/functions. */}

Task functions run on schedules or delays, not in response to user requests. They're perfect for background work like sending emails, generating reports, data cleanup, and workflow automation.

<CardGroup cols={2}>
  <Card title="When to Use" icon="lightbulb">
    * Daily/weekly reports and analytics
    * Scheduled email campaigns and notifications
    * Data cleanup and maintenance tasks
    * Background data processing and syncing
  </Card>

  <Card title="What They Do" icon="gear">
    * Run on fixed schedules (cron-like)
    * Execute delayed tasks after events
    * Process queued work items
    * Maintain system health and data integrity
  </Card>
</CardGroup>

## How Task Functions Work

```mermaid theme={"system"}
graph LR
    A["Schedule trigger"] --> B["Task function runs"]
    B --> C["Execute background work"]
    C --> D["Task completes"]
    
    style A fill:transparent,stroke:#666,stroke-width:1px
    style B fill:transparent,stroke:#666,stroke-width:1px
    style C fill:transparent,stroke:#666,stroke-width:1px
    style D fill:transparent,stroke:#666,stroke-width:1px
```

1. **Schedule triggers** at specified intervals (cron expressions or rate limits)
2. **Task function executes** without user interaction
3. **Background work runs** (emails, reports, cleanup, data processing)
4. **Task completes** and returns execution summary

## Task Function Examples

<Tabs>
  <Tab title="Abandoned Cart Recovery">
    Send emails to users who left items in their cart:

    **Schedule Trigger:**

    ```text title="Cron Expression" icon="clock" theme={"system"}
    cron(*/30 * * * *) - Every 30 minutes
    ```

    <CodeGroup>
      ```json title="Discovered Carts" icon="shopping-cart" theme={"system"}
      [
        {
          "id": "cart_123",
          "userId": "user_456",
          "items": [
            {"productId": "prod_789", "quantity": 1, "price": 199.99}
          ],
          "total": 199.99,
          "lastUpdated": "2024-01-12T08:15:30Z"
        }
      ]
      ```

      ```typescript title="Function Implementation" icon="code" lines theme={"system"}
      export const handler = async (event) => {
        try {
          // Find abandoned carts (inactive for 2+ hours)
          const cutoffTime = new Date(Date.now() - 2 * 60 * 60 * 1000);
          const abandonedCarts = await findAbandonedCarts(cutoffTime);
          
          console.log(`Found ${abandonedCarts.length} abandoned carts to process`);
          
          const results = {
            processed: 0,
            emailsSent: 0,
            errors: 0,
            skipped: 0
          };
          
          for (const cart of abandonedCarts) {
            try {
              // Check if we've already sent recovery email for this cart
              const emailSent = await hasRecoveryEmailBeenSent(cart.id);
              if (emailSent) {
                results.skipped++;
                continue;
              }
              
              // Get user and personalize recovery email
              const user = await getUserProfile(cart.userId);
              const emailData = {
                userEmail: user.email,
                userName: user.firstName,
                cartItems: cart.items,
                cartTotal: cart.total,
                recoveryLink: `https://mystore.com/cart/recover?token=${cart.recoveryToken}`
              };
              
              // Send personalized recovery email
              await sendAbandonedCartEmail(emailData);
              
              // Mark cart as having recovery email sent
              await markRecoveryEmailSent(cart.id);
              
              // Log analytics event
              await logAnalytics('abandoned_cart_recovery_sent', {
                cartId: cart.id,
                userId: cart.userId,
                cartValue: cart.total,
                itemCount: cart.items.length
              });
              
              results.emailsSent++;
              results.processed++;
              
            } catch (error) {
              console.error(`Failed to process cart ${cart.id}:`, error);
              results.errors++;
            }
          }
          
          return {
            statusCode: 200,
            body: JSON.stringify({
              message: 'Abandoned cart recovery task completed',
              timestamp: new Date().toISOString(),
              summary: results
            })
          };
          
        } catch (error) {
          console.error('Abandoned cart recovery task failed:', error);
          return {
            statusCode: 500,
            body: JSON.stringify({
              error: 'Task execution failed',
              message: error.message
            })
          };
        }
      };
      ```

      ```json title="Standard Response" icon="check-circle" theme={"system"}
      {
        "message": "Task completed",
        "processed": 25
      }
      ```
    </CodeGroup>

    <Accordion title="🚀 See Hub Enhancements">
      ```json title="Enhanced Response" icon="sparkles" theme={"system"}
      {
        "message": "Abandoned cart recovery task completed", // [!code ++]
        "timestamp": "2024-01-12T10:30:45.123Z", // [!code ++]
        "summary": { // [!code ++]
          "processed": 25,
          "emailsSent": 18, // [!code ++]
          "errors": 2, // [!code ++]
          "skipped": 5 // [!code ++]
        }, // [!code ++]
        "details": { // [!code ++]
          "discoveredCarts": 25, // [!code ++]
          "eligibleForRecovery": 23, // [!code ++]
          "duplicatesPrevented": 5, // [!code ++]
          "totalCartValue": 4750.00, // [!code ++]
          "averageCartValue": 190.00, // [!code ++]
          "topCategories": ["electronics", "clothing", "home"], // [!code ++]
          "emailTemplatesUsed": { // [!code ++]
            "first_reminder": 12, // [!code ++]
            "second_reminder": 4, // [!code ++]
            "final_discount": 2 // [!code ++]
          } // [!code ++]
        }, // [!code ++]
        "performance": { // [!code ++]
          "executionTime": "2.3s", // [!code ++]
          "cartsPerSecond": 10.9, // [!code ++]
          "emailDeliveryTime": "1.2s" // [!code ++]
        }, // [!code ++]
        "nextRun": "2024-01-12T11:00:00.000Z" // [!code ++]
      }
      ```

      **What Ollie Hub adds:**

      * ✅ Intelligent cart discovery with time-based filtering
      * ✅ Personalized email content with user data
      * ✅ Duplicate email prevention system
      * ✅ Revenue impact tracking and analytics
      * ✅ Performance metrics and optimization data
      * ✅ Detailed error handling and reporting
      * ✅ Multi-stage recovery email campaigns
    </Accordion>
  </Tab>

  <Tab title="Daily Sales Report">
    Generate and email daily sales reports:

    **Schedule Trigger:**

    ```text title="Cron Expression" icon="clock" theme={"system"}
    cron(0 8 * * *) - Daily at 8:00 AM
    ```

    <CodeGroup>
      ```json title="Sales Data" icon="chart-bar" theme={"system"}
      {
        "date": "2024-01-11",
        "orders": [
          {
            "id": "ord_123",
            "total": 299.99,
            "isNewCustomer": true,
            "timestamp": "2024-01-11T14:30:00Z"
          }
        ],
        "totalRevenue": 15420.75,
        "totalOrders": 47
      }
      ```

      ```typescript title="Function Implementation" icon="chart-line" lines theme={"system"}
      export const handler = async (event) => {
        try {
          const today = new Date();
          const yesterday = new Date(today);
          yesterday.setDate(yesterday.getDate() - 1);
          
          // Generate comprehensive sales report
          const salesData = await generateSalesReport(yesterday);
          
          // Calculate key metrics
          const metrics = {
            totalRevenue: salesData.orders.reduce((sum, order) => sum + order.total, 0),
            totalOrders: salesData.orders.length,
            averageOrderValue: salesData.orders.length > 0 
              ? salesData.totalRevenue / salesData.orders.length 
              : 0,
            newCustomers: salesData.orders.filter(o => o.isNewCustomer).length,
            returningCustomers: salesData.orders.filter(o => !o.isNewCustomer).length
          };
          
          // Generate report content
          const reportData = {
            date: yesterday.toISOString().split('T')[0],
            metrics,
            topProducts: await getTopProducts(yesterday),
            customerInsights: await getCustomerInsights(yesterday),
            comparisonWithPreviousDay: await getComparison(yesterday)
          };
          
          // Create HTML email report
          const emailHTML = await generateReportHTML(reportData);
          
          // Send to management team
          const recipients = await getReportRecipients('daily-sales');
          
          await sendEmail({
            to: recipients,
            subject: `Daily Sales Report - ${reportData.date}`,
            html: emailHTML,
            attachments: [
              {
                filename: `sales-report-${reportData.date}.pdf`,
                content: await generateReportPDF(reportData)
              }
            ]
          });
          
          // Store report in database for historical tracking
          await storeDailySalesReport(reportData);
          
          return {
            statusCode: 200,
            body: JSON.stringify({
              message: 'Daily sales report generated and sent',
              date: reportData.date,
              metrics
            })
          };
          
        } catch (error) {
          console.error('Daily sales report failed:', error);
          
          // Send error notification to admin
          await sendErrorNotification('daily-sales-report', error);
          
          return {
            statusCode: 500,
            body: JSON.stringify({
              error: 'Report generation failed'
            })
          };
        }
      };
      ```

      ```json title="Standard Response" icon="envelope" theme={"system"}
      {
        "message": "Report sent",
        "recipients": 3
      }
      ```
    </CodeGroup>

    <Accordion title="🚀 See Hub Enhancements">
      ```json title="Enhanced Response" icon="sparkles" theme={"system"}
      {
        "message": "Daily sales report generated and sent", // [!code ++]
        "date": "2024-01-11", // [!code ++]
        "metrics": { // [!code ++]
          "totalRevenue": 15420.75, // [!code ++]
          "totalOrders": 47, // [!code ++]
          "averageOrderValue": 328.10, // [!code ++]
          "newCustomers": 12, // [!code ++]
          "returningCustomers": 35 // [!code ++]
        }, // [!code ++]
        "reportDetails": { // [!code ++]
          "reportId": "sales-2024-01-11", // [!code ++]
          "recipients": 3, // [!code ++]
          "emailsSent": 3, // [!code ++]
          "attachmentSize": "2.4MB", // [!code ++]
          "generationTime": "4.2s" // [!code ++]
        }, // [!code ++]
        "insights": { // [!code ++]
          "topSellingProduct": "MacBook Pro 14-inch", // [!code ++]
          "peakSalesHour": "14:00-15:00", // [!code ++]
          "customerRetentionRate": "74.5%", // [!code ++]
          "dayOverDayGrowth": "+12.3%" // [!code ++]
        }, // [!code ++]
        "nextReportDue": "2024-01-13T08:00:00.000Z" // [!code ++]
      }
      ```

      **What Ollie Hub adds:**

      * ✅ Comprehensive revenue and customer metrics
      * ✅ Top-performing products analysis
      * ✅ Customer acquisition and retention insights
      * ✅ Day-over-day growth comparisons
      * ✅ PDF attachment with charts and graphs
      * ✅ Historical data storage and trends
      * ✅ Executive dashboard integration
    </Accordion>
  </Tab>

  <Tab title="Data Cleanup">
    Clean up expired sessions and temporary data:

    **Schedule Trigger:**

    ```text title="Cron Expression" icon="clock" theme={"system"}
    cron(0 */6 * * *) - Every 6 hours
    ```

    <CodeGroup>
      ```json title="Cleanup Targets" icon="trash" theme={"system"}
      {
        "expiredSessions": {
          "cutoffHours": 24,
          "estimatedCount": 1200
        },
        "temporaryFiles": {
          "cutoffHours": 1,
          "estimatedSizeMB": 450
        },
        "oldLogs": {
          "cutoffDays": 30,
          "estimatedCount": 50000
        }
      }
      ```

      ```typescript title="Function Implementation" icon="broom" lines theme={"system"}
      export const handler = async (event) => {
        try {
          const results = {
            expiredSessions: 0,
            temporaryFiles: 0,
            oldLogs: 0,
            failedUploads: 0,
            totalSpaceFreed: 0
          };
          
          // Clean expired user sessions (older than 24 hours)
          const expiredSessions = await cleanupExpiredSessions(24);
          results.expiredSessions = expiredSessions.count;
          
          // Remove temporary files (older than 1 hour)
          const tempFiles = await cleanupTemporaryFiles(1);
          results.temporaryFiles = tempFiles.count;
          results.totalSpaceFreed += tempFiles.spaceFreed;
          
          // Archive old application logs (older than 30 days)
          const oldLogs = await archiveOldLogs(30);
          results.oldLogs = oldLogs.count;
          results.totalSpaceFreed += oldLogs.spaceFreed;
          
          // Clean up failed upload attempts (older than 1 day)
          const failedUploads = await cleanupFailedUploads(1);
          results.failedUploads = failedUploads.count;
          results.totalSpaceFreed += failedUploads.spaceFreed;
          
          // Update system health metrics
          await updateSystemHealthMetrics({
            lastCleanup: new Date().toISOString(),
            itemsProcessed: Object.values(results).reduce((sum, val) => 
              typeof val === 'number' ? sum + val : sum, 0),
            spaceFreedMB: Math.round(results.totalSpaceFreed / 1024 / 1024)
          });
          
          return {
            statusCode: 200,
            body: JSON.stringify({
              message: 'Data cleanup completed successfully',
              timestamp: new Date().toISOString(),
              results
            })
          };
          
        } catch (error) {
          console.error('Data cleanup failed:', error);
          return {
            statusCode: 500,
            body: JSON.stringify({
              error: 'Cleanup task failed'
            })
          };
        }
      };
      ```

      ```json title="Standard Response" icon="check" theme={"system"}
      {
        "message": "Cleanup completed",
        "itemsProcessed": 1250
      }
      ```
    </CodeGroup>

    <Accordion title="🚀 See Hub Enhancements">
      ```json title="Enhanced Response" icon="sparkles" theme={"system"}
      {
        "message": "Data cleanup completed successfully", // [!code ++]
        "timestamp": "2024-01-12T10:30:45.123Z", // [!code ++]
        "results": { // [!code ++]
          "expiredSessions": 1200, // [!code ++]
          "temporaryFiles": 450, // [!code ++]
          "oldLogs": 50000, // [!code ++]
          "failedUploads": 75, // [!code ++]
          "totalSpaceFreed": 524288000 // [!code ++]
        }, // [!code ++]
        "summary": { // [!code ++]
          "totalItemsProcessed": 51725, // [!code ++]
          "spaceFreedMB": 500, // [!code ++]
          "executionTime": "45.2s", // [!code ++]
          "performanceGain": "15% faster DB queries" // [!code ++]
        }, // [!code ++]
        "systemHealth": { // [!code ++]
          "diskUsageAfterCleanup": "68%", // [!code ++]
          "sessionTableSize": "12.3MB", // [!code ++]
          "cacheHitRateImprovement": "+5.2%", // [!code ++]
          "nextCleanupDue": "2024-01-12T16:00:00.000Z" // [!code ++]
        } // [!code ++]
      }
      ```

      **What Ollie Hub adds:**

      * ✅ Intelligent expired session detection and removal
      * ✅ Temporary file cleanup with size optimization
      * ✅ Log archival and rotation management
      * ✅ Failed upload cleanup and recovery
      * ✅ Storage space optimization tracking
      * ✅ System health metrics and performance impact
      * ✅ Database query performance improvements
    </Accordion>
  </Tab>

  <Tab title="Weekly Newsletter">
    Send personalized weekly newsletters to subscribers:

    **Schedule Trigger:**

    ```text title="Cron Expression" icon="clock" theme={"system"}
    cron(0 9 * * MON) - Every Monday at 9:00 AM
    ```

    <CodeGroup>
      ```json title="Subscriber List" icon="users" theme={"system"}
      [
        {
          "id": "sub_123",
          "email": "john@example.com",
          "preferences": {
            "categories": ["tech", "business"],
            "frequency": "weekly"
          },
          "unsubscribeToken": "tok_abc123"
        }
      ]
      ```

      ```typescript title="Function Implementation" icon="envelope" lines theme={"system"}
      export const handler = async (event) => {
        try {
          // Get all active newsletter subscribers
          const subscribers = await getNewsletterSubscribers();
          console.log(`Processing newsletter for ${subscribers.length} subscribers`);
          
          const results = {
            emailsSent: 0,
            errors: 0,
            unsubscribes: 0,
            bounces: 0
          };
          
          // Get content for the week
          const weeklyContent = await generateWeeklyContent();
          
          // Process subscribers in batches to avoid overwhelming the email service
          const batchSize = 100;
          for (let i = 0; i < subscribers.length; i += batchSize) {
            const batch = subscribers.slice(i, i + batchSize);
            
            const batchPromises = batch.map(async (subscriber) => {
              try {
                // Personalize content for this subscriber
                const personalizedContent = await personalizeNewsletter(
                  weeklyContent, 
                  subscriber
                );
                
                // Send personalized email
                await sendEmail({
                  to: subscriber.email,
                  subject: `Your Weekly Update - Week of ${weeklyContent.weekOf}`,
                  html: personalizedContent.html,
                  text: personalizedContent.text,
                  unsubscribeLink: `https://myapp.com/unsubscribe?token=${subscriber.unsubscribeToken}`
                });
                
                // Track successful send
                await trackNewsletterSent(subscriber.id, weeklyContent.id);
                results.emailsSent++;
                
              } catch (error) {
                console.error(`Failed to send newsletter to ${subscriber.email}:`, error);
                results.errors++;
              }
            });
            
            // Wait for batch to complete before processing next batch
            await Promise.all(batchPromises);
            
            // Brief pause between batches
            await new Promise(resolve => setTimeout(resolve, 1000));
          }
          
          // Update newsletter campaign stats
          await updateCampaignStats(weeklyContent.id, results);
          
          return {
            statusCode: 200,
            body: JSON.stringify({
              message: 'Weekly newsletter campaign completed',
              campaignId: weeklyContent.id,
              results
            })
          };
          
        } catch (error) {
          console.error('Newsletter campaign failed:', error);
          return {
            statusCode: 500,
            body: JSON.stringify({
              error: 'Newsletter campaign failed'
            })
          };
        }
      };
      ```

      ```json title="Standard Response" icon="mail-bulk" theme={"system"}
      {
        "message": "Newsletter sent",
        "emailsSent": 5420
      }
      ```
    </CodeGroup>

    <Accordion title="🚀 See Hub Enhancements">
      ```json title="Enhanced Response" icon="sparkles" theme={"system"}
      {
        "message": "Weekly newsletter campaign completed", // [!code ++]
        "campaignId": "newsletter-2024-w02", // [!code ++]
        "weekOf": "2024-01-08", // [!code ++]
        "results": { // [!code ++]
          "emailsSent": 5420, // [!code ++]
          "errors": 12, // [!code ++]
          "unsubscribes": 3, // [!code ++]
          "bounces": 8 // [!code ++]
        }, // [!code ++]
        "performance": { // [!code ++]
          "totalSubscribers": 5435, // [!code ++]
          "successRate": "99.7%", // [!code ++]
          "deliveryTime": "12.4 minutes", // [!code ++]
          "batchesProcessed": 55 // [!code ++]
        }, // [!code ++]
        "engagement": { // [!code ++]
          "expectedOpenRate": "24.5%", // [!code ++]
          "expectedClickRate": "4.2%", // [!code ++]
          "topContent": "Weekly Tech Roundup", // [!code ++]
          "personalizationScore": "High" // [!code ++]
        }, // [!code ++]
        "nextCampaign": "2024-01-15T09:00:00.000Z" // [!code ++]
      }
      ```

      **What Ollie Hub adds:**

      * ✅ Batch processing for scalability and deliverability
      * ✅ Personalized content based on subscriber preferences
      * ✅ Unsubscribe link management and tracking
      * ✅ Campaign performance metrics and analytics
      * ✅ Error handling with detailed reporting
      * ✅ Rate limiting to prevent spam flags
      * ✅ Engagement prediction and optimization
    </Accordion>
  </Tab>
</Tabs>

## Best Practices

<CardGroup cols={2}>
  <Card title="Keep Tasks Idempotent" icon="refresh">
    Design tasks to handle being run multiple times safely. Check for existing work before processing.
  </Card>

  <Card title="Process in Batches" icon="layers">
    For large datasets, process items in small batches to avoid timeouts and memory issues.
  </Card>

  <Card title="Monitor and Alert" icon="bell">
    Set up monitoring for task failures and send notifications when critical tasks fail.
  </Card>

  <Card title="Handle Failures Gracefully" icon="shield">
    Implement retry logic with exponential backoff. Store failed items for manual review.
  </Card>
</CardGroup>

## Next Steps

<CardGroup cols={3}>
  <Card title="Best Practices" icon="star" href="/ollie-hub/development/best-practices">
    Task patterns, error handling, and scheduling tips
  </Card>

  <Card title="Request Functions" icon="globe" href="/ollie-hub/core-concepts/request-functions">
    Learn to handle user requests and API calls
  </Card>

  <Card title="Response Functions" icon="arrow-right-arrow-left" href="/ollie-hub/core-concepts/response-functions">
    Customize responses with analytics and enhancements
  </Card>
</CardGroup>

<Info>
  **Pro Tip:** Task functions can trigger Request functions to process data, and Response functions can enhance the results. They work great together! Check out our [Best Practices guide](/ollie-hub/development/best-practices) for implementation patterns.
</Info>
