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

// 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

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

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

Test Payload

{
  "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

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) = "[email protected]"
BUZZY_API_PASSWORD (secret) = "your-buzzy-password"
CHAT_RESOURCE_ID = "your-chat-datatable-id"

Function Code

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

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

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) = "[email protected]"
BUZZY_API_PASSWORD (secret) = "your-buzzy-password"
ORDERS_RESOURCE_ID = "your-orders-datatable-id"

Function Code

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

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) = "[email protected]"
BUZZY_API_PASSWORD (secret) = "your-buzzy-password"
CONTACTS_RESOURCE_ID = "your-contacts-datatable-id"
SYNC_INTERVAL_HOURS = "24"

Function Code

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

SENDGRID_API_KEY (secret) = "SG.your-sendgrid-api-key"
FROM_EMAIL = "[email protected]"
FROM_NAME = "Your Company"
BUZZY_API_URL = "https://your-buzzy-instance.com"
BUZZY_API_EMAIL (secret) = "[email protected]"
BUZZY_API_PASSWORD (secret) = "your-buzzy-password"
NOTIFICATIONS_RESOURCE_ID = "your-notifications-datatable-id"

Function Code

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

Last updated