# Examples

This section provides practical examples of using Buzzy Functions and Constants together to build powerful integrations and automations.

## Weather API Integration

This example shows how to create a weather function that fetches data from an external API and displays it in your Buzzy app.

### Constants Setup

```javascript
// Create these constants in your app
WEATHER_API_KEY (secret) = "your-openweathermap-api-key"
WEATHER_API_URL = "https://api.openweathermap.org/data/2.5"
DEFAULT_UNITS = "metric"
```

### Function Code

```javascript
export const main = async (event) => {
  console.log('Weather function called with:', event);
  
  try {
    const { city, units } = event.body;
    
    if (!city) {
      return {
        statusCode: 400,
        body: { error: 'City parameter is required' }
      };
    }
    
    const apiKey = process.env.WEATHER_API_KEY;
    const baseUrl = process.env.WEATHER_API_URL;
    const weatherUnits = units || process.env.DEFAULT_UNITS;
    
    const response = await axios.get(`${baseUrl}/weather`, {
      params: {
        q: city,
        appid: apiKey,
        units: weatherUnits
      }
    });
    
    const weather = response.data;
    
    return {
      statusCode: 200,
      body: {
        success: true,
        city: weather.name,
        country: weather.sys.country,
        temperature: weather.main.temp,
        description: weather.weather[0].description,
        humidity: weather.main.humidity,
        windSpeed: weather.wind.speed,
        timestamp: new Date().toISOString()
      }
    };
  } catch (error) {
    console.error('Weather API error:', error);
    return {
      statusCode: 500,
      body: {
        success: false,
        error: error.message
      }
    };
  }
};
```

### Function Environment Variables

```javascript
WEATHER_API_KEY = BUZZYCONSTANTS('WEATHER_API_KEY')
WEATHER_API_URL = BUZZYCONSTANTS('WEATHER_API_URL')
DEFAULT_UNITS = BUZZYCONSTANTS('DEFAULT_UNITS')
```

### Test Payload

```json
{
  "city": "San Francisco",
  "units": "metric"
}
```

## AI Chat Integration

Create an AI-powered chat function that integrates with OpenAI's GPT API and saves conversations to your Buzzy database.

### Constants Setup

```javascript
OPENAI_API_KEY (secret) = "sk-your-openai-api-key"
OPENAI_BASE_URL = "https://api.openai.com/v1"
OPENAI_MODEL = "gpt-4"
BUZZY_API_URL = "https://your-buzzy-instance.com"
BUZZY_API_EMAIL (secret) = "api@yourcompany.com"
BUZZY_API_PASSWORD (secret) = "your-buzzy-password"
CHAT_RESOURCE_ID = "your-chat-datatable-id"
```

### Function Code

```javascript
import { login, createMicroAppDataRow } from 'buzzy-api-nodejs';

export const main = async (event) => {
  console.log('AI Chat function called');
  
  try {
    const { message, userId, conversationId } = event.body;
    
    if (!message) {
      return {
        statusCode: 400,
        body: { error: 'Message is required' }
      };
    }
    
    // Call OpenAI API
    const openaiResponse = await axios.post(
      `${process.env.OPENAI_BASE_URL}/chat/completions`,
      {
        model: process.env.OPENAI_MODEL,
        messages: [
          { role: "user", content: message }
        ],
        max_tokens: 500
      },
      {
        headers: {
          'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
          'Content-Type': 'application/json'
        }
      }
    );
    
    const aiResponse = openaiResponse.data.choices[0].message.content;
    
    // Authenticate with Buzzy
    const auth = await login({
      url: process.env.BUZZY_API_URL,
      email: process.env.BUZZY_API_EMAIL,
      password: process.env.BUZZY_API_PASSWORD
    });
    
    // Save conversation to Buzzy
    const chatRecord = await createMicroAppDataRow({
      authToken: auth.authToken,
      resourceId: process.env.CHAT_RESOURCE_ID,
      rowData: {
        user_message: message,
        ai_response: aiResponse,
        user_id: userId,
        conversation_id: conversationId,
        timestamp: new Date().toISOString(),
        model_used: process.env.OPENAI_MODEL
      }
    });
    
    return {
      statusCode: 200,
      body: {
        success: true,
        response: aiResponse,
        chatId: chatRecord.body._id,
        timestamp: new Date().toISOString()
      }
    };
  } catch (error) {
    console.error('AI Chat error:', error);
    return {
      statusCode: 500,
      body: {
        success: false,
        error: error.message
      }
    };
  }
};
```

### Function Environment Variables

```javascript
OPENAI_API_KEY = BUZZYCONSTANTS('OPENAI_API_KEY')
OPENAI_BASE_URL = BUZZYCONSTANTS('OPENAI_BASE_URL')
OPENAI_MODEL = BUZZYCONSTANTS('OPENAI_MODEL')
BUZZY_API_URL = BUZZYCONSTANTS('BUZZY_API_URL')
BUZZY_API_EMAIL = BUZZYCONSTANTS('BUZZY_API_EMAIL')
BUZZY_API_PASSWORD = BUZZYCONSTANTS('BUZZY_API_PASSWORD')
CHAT_RESOURCE_ID = BUZZYCONSTANTS('CHAT_RESOURCE_ID')
```

## Stripe Webhook Handler

Handle Stripe payment webhooks and update your Buzzy application with payment status.

### Constants Setup

```javascript
STRIPE_WEBHOOK_SECRET (secret) = "whsec_your-webhook-secret"
STRIPE_SECRET_KEY (secret) = "sk_your-stripe-secret-key"
BUZZY_API_URL = "https://your-buzzy-instance.com"
BUZZY_API_EMAIL (secret) = "api@yourcompany.com"
BUZZY_API_PASSWORD (secret) = "your-buzzy-password"
ORDERS_RESOURCE_ID = "your-orders-datatable-id"
```

### Function Code

```javascript
import { login, updateMicroAppDataRow, getMicroAppDataRows } from 'buzzy-api-nodejs';
import crypto from 'crypto';

export const main = async (event) => {
  console.log('Stripe webhook received');
  
  try {
    // Verify webhook signature
    const signature = event.headers['stripe-signature'];
    const payload = event.body;
    
    const expectedSignature = crypto
      .createHmac('sha256', process.env.STRIPE_WEBHOOK_SECRET)
      .update(payload, 'utf8')
      .digest('hex');
    
    const signatureHeader = signature.split(',').reduce((acc, part) => {
      const [key, value] = part.split('=');
      acc[key] = value;
      return acc;
    }, {});
    
    if (signatureHeader.v1 !== expectedSignature) {
      return {
        statusCode: 401,
        body: { error: 'Invalid signature' }
      };
    }
    
    const webhookData = JSON.parse(payload);
    const { type, data } = webhookData;
    
    // Handle payment success
    if (type === 'payment_intent.succeeded') {
      const paymentIntent = data.object;
      const orderId = paymentIntent.metadata.order_id;
      
      if (orderId) {
        // Authenticate with Buzzy
        const auth = await login({
          url: process.env.BUZZY_API_URL,
          email: process.env.BUZZY_API_EMAIL,
          password: process.env.BUZZY_API_PASSWORD
        });
        
        // Find and update the order
        const orders = await getMicroAppDataRows({
          authToken: auth.authToken,
          resourceId: process.env.ORDERS_RESOURCE_ID,
          filters: { order_id: orderId }
        });
        
        if (orders.length > 0) {
          const order = orders[0];
          await updateMicroAppDataRow({
            authToken: auth.authToken,
            resourceId: process.env.ORDERS_RESOURCE_ID,
            rowID: order._id,
            rowData: {
              payment_status: 'paid',
              payment_intent_id: paymentIntent.id,
              amount_paid: paymentIntent.amount / 100,
              paid_at: new Date().toISOString()
            }
          });
        }
      }
    }
    
    return {
      statusCode: 200,
      body: { received: true }
    };
  } catch (error) {
    console.error('Stripe webhook error:', error);
    return {
      statusCode: 500,
      body: { error: error.message }
    };
  }
};
```

### Function Configuration

* **Authentication Type**: Specific Domains
* **Allowed Domains**: `['https://hooks.stripe.com']`

## Data Synchronization

Sync data between your Buzzy app and an external CRM system.

### Constants Setup

```javascript
CRM_API_KEY (secret) = "your-crm-api-key"
CRM_BASE_URL = "https://api.yourcrm.com/v1"
BUZZY_API_URL = "https://your-buzzy-instance.com"
BUZZY_API_EMAIL (secret) = "api@yourcompany.com"
BUZZY_API_PASSWORD (secret) = "your-buzzy-password"
CONTACTS_RESOURCE_ID = "your-contacts-datatable-id"
SYNC_INTERVAL_HOURS = "24"
```

### Function Code

```javascript
import { login, getMicroAppDataRows, createMicroAppDataRow, updateMicroAppDataRow } from 'buzzy-api-nodejs';

export const main = async (event) => {
  console.log('Data sync function started');
  
  try {
    const { direction = 'both', lastSyncTime } = event.body;
    
    // Authenticate with Buzzy
    const auth = await login({
      url: process.env.BUZZY_API_URL,
      email: process.env.BUZZY_API_EMAIL,
      password: process.env.BUZZY_API_PASSWORD
    });
    
    let syncResults = {
      buzzyToExternal: 0,
      externalToBuzzy: 0,
      errors: []
    };
    
    // Sync from Buzzy to external CRM
    if (direction === 'both' || direction === 'to_external') {
      const buzzyContacts = await getMicroAppDataRows({
        authToken: auth.authToken,
        resourceId: process.env.CONTACTS_RESOURCE_ID,
        filters: lastSyncTime ? { updatedAt: { $gt: lastSyncTime } } : {}
      });
      
      for (const contact of buzzyContacts) {
        try {
          const crmData = {
            name: contact.full_name,
            email: contact.email,
            phone: contact.phone,
            company: contact.company,
            external_id: contact._id
          };
          
          const response = await axios.post(
            `${process.env.CRM_BASE_URL}/contacts`,
            crmData,
            {
              headers: {
                'Authorization': `Bearer ${process.env.CRM_API_KEY}`,
                'Content-Type': 'application/json'
              }
            }
          );
          
          // Update Buzzy record with CRM ID
          await updateMicroAppDataRow({
            authToken: auth.authToken,
            resourceId: process.env.CONTACTS_RESOURCE_ID,
            rowID: contact._id,
            rowData: {
              crm_id: response.data.id,
              last_synced: new Date().toISOString()
            }
          });
          
          syncResults.buzzyToExternal++;
        } catch (error) {
          syncResults.errors.push(`Failed to sync contact ${contact._id}: ${error.message}`);
        }
      }
    }
    
    // Sync from external CRM to Buzzy
    if (direction === 'both' || direction === 'to_buzzy') {
      const crmResponse = await axios.get(
        `${process.env.CRM_BASE_URL}/contacts`,
        {
          headers: {
            'Authorization': `Bearer ${process.env.CRM_API_KEY}`
          },
          params: lastSyncTime ? { updated_since: lastSyncTime } : {}
        }
      );
      
      for (const crmContact of crmResponse.data.contacts) {
        try {
          const buzzyData = {
            full_name: crmContact.name,
            email: crmContact.email,
            phone: crmContact.phone,
            company: crmContact.company,
            crm_id: crmContact.id,
            last_synced: new Date().toISOString()
          };
          
          // Check if contact already exists
          const existing = await getMicroAppDataRows({
            authToken: auth.authToken,
            resourceId: process.env.CONTACTS_RESOURCE_ID,
            filters: { crm_id: crmContact.id }
          });
          
          if (existing.length > 0) {
            // Update existing contact
            await updateMicroAppDataRow({
              authToken: auth.authToken,
              resourceId: process.env.CONTACTS_RESOURCE_ID,
              rowID: existing[0]._id,
              rowData: buzzyData
            });
          } else {
            // Create new contact
            await createMicroAppDataRow({
              authToken: auth.authToken,
              resourceId: process.env.CONTACTS_RESOURCE_ID,
              rowData: buzzyData
            });
          }
          
          syncResults.externalToBuzzy++;
        } catch (error) {
          syncResults.errors.push(`Failed to sync CRM contact ${crmContact.id}: ${error.message}`);
        }
      }
    }
    
    return {
      statusCode: 200,
      body: {
        success: true,
        syncResults,
        timestamp: new Date().toISOString()
      }
    };
  } catch (error) {
    console.error('Data sync error:', error);
    return {
      statusCode: 500,
      body: {
        success: false,
        error: error.message
      }
    };
  }
};
```

## Email Notification System

Send automated emails using an external email service when certain conditions are met.

### Constants Setup

```javascript
SENDGRID_API_KEY (secret) = "SG.your-sendgrid-api-key"
FROM_EMAIL = "noreply@yourcompany.com"
FROM_NAME = "Your Company"
BUZZY_API_URL = "https://your-buzzy-instance.com"
BUZZY_API_EMAIL (secret) = "api@yourcompany.com"
BUZZY_API_PASSWORD (secret) = "your-buzzy-password"
NOTIFICATIONS_RESOURCE_ID = "your-notifications-datatable-id"
```

### Function Code

```javascript
import { login, createMicroAppDataRow } from 'buzzy-api-nodejs';

export const main = async (event) => {
  console.log('Email notification function called');
  
  try {
    const { 
      to, 
      subject, 
      message, 
      template = 'default',
      userId,
      triggerEvent 
    } = event.body;
    
    if (!to || !subject || !message) {
      return {
        statusCode: 400,
        body: { error: 'to, subject, and message are required' }
      };
    }
    
    // Send email via SendGrid
    const emailData = {
      personalizations: [{
        to: [{ email: to }],
        subject: subject
      }],
      from: {
        email: process.env.FROM_EMAIL,
        name: process.env.FROM_NAME
      },
      content: [{
        type: 'text/html',
        value: message
      }]
    };
    
    const emailResponse = await axios.post(
      'https://api.sendgrid.com/v3/mail/send',
      emailData,
      {
        headers: {
          'Authorization': `Bearer ${process.env.SENDGRID_API_KEY}`,
          'Content-Type': 'application/json'
        }
      }
    );
    
    // Log notification in Buzzy
    const auth = await login({
      url: process.env.BUZZY_API_URL,
      email: process.env.BUZZY_API_EMAIL,
      password: process.env.BUZZY_API_PASSWORD
    });
    
    await createMicroAppDataRow({
      authToken: auth.authToken,
      resourceId: process.env.NOTIFICATIONS_RESOURCE_ID,
      rowData: {
        recipient: to,
        subject: subject,
        template: template,
        status: 'sent',
        user_id: userId,
        trigger_event: triggerEvent,
        sent_at: new Date().toISOString(),
        sendgrid_message_id: emailResponse.headers['x-message-id']
      }
    });
    
    return {
      statusCode: 200,
      body: {
        success: true,
        messageId: emailResponse.headers['x-message-id'],
        timestamp: new Date().toISOString()
      }
    };
  } catch (error) {
    console.error('Email notification error:', error);
    return {
      statusCode: 500,
      body: {
        success: false,
        error: error.message
      }
    };
  }
};
```

## Best Practices from Examples

### Security

* Always use Constants for API keys and sensitive data
* Verify webhook signatures for external integrations
* Implement proper error handling and logging
* Use environment variables instead of hardcoded values

### Error Handling

* Return appropriate HTTP status codes
* Include descriptive error messages
* Log errors for debugging
* Implement graceful fallbacks where possible

### Performance

* Use async/await for better performance
* Implement timeouts for external API calls
* Cache frequently accessed data when appropriate
* Monitor function execution time

### Integration Patterns

* Authenticate with Buzzy using the buzzy-api-nodejs client
* Use consistent data structures for API responses
* Implement proper data validation
* Log important events for audit trails

### Testing

* Create comprehensive test payloads
* Test error scenarios and edge cases
* Verify external API integrations work correctly
* Monitor function logs during testing


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.buzzy.buzz/the-building-blocks/buzzy-functions-and-constants/examples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
