.do
Service TypesAutomation

Integration Automation Services

Build services that orchestrate multi-system workflows, API choreography, event routing, service coordination, and cross-platform automation

Build sophisticated integration services that orchestrate workflows across multiple systems, coordinate APIs, route events, and automate complex cross-platform operations.

Overview

Integration automation services connect disparate systems and coordinate their interactions. They're essential for:

  • CRM Synchronization: Keep customer data in sync across platforms
  • E-commerce Integration: Connect stores, inventory, and fulfillment
  • Payment Processing: Orchestrate payment flows across systems
  • Marketing Automation: Coordinate campaigns across channels
  • Data Synchronization: Real-time bi-directional data sync
  • System Orchestration: Coordinate complex multi-system workflows

Core Concepts

Integration Architecture

import $, { db, on, send, every } from 'sdk.do'

// Define CRM integration service
const crmIntegrationService = await $.Service.create({
  name: 'Multi-Platform CRM Sync',
  type: $.ServiceType.Automation,
  subtype: 'integration',

  // Integration configuration
  integration: {
    platforms: ['salesforce', 'hubspot', 'zendesk', 'intercom'],
    syncMode: 'bidirectional',
    entities: ['contacts', 'companies', 'deals', 'tickets'],
    conflictResolution: 'last-write-wins',
    schedule: {
      realtime: ['contacts', 'tickets'],
      batch: ['companies', 'deals'],
      batchInterval: '15-minutes',
    },
  },

  // Field mapping
  mappings: {
    contact: {
      salesforce: {
        FirstName: 'firstName',
        LastName: 'lastName',
        Email: 'email',
        Phone: 'phone',
        Company: 'companyName',
      },
      hubspot: {
        firstname: 'firstName',
        lastname: 'lastName',
        email: 'email',
        phone: 'phone',
        company: 'companyName',
      },
    },
  },

  // Pricing model
  pricing: {
    model: 'per-sync',
    baseRate: 0.01, // per record synced
    volume: [
      { min: 0, max: 10000, rate: 0.01 },
      { min: 10001, max: 100000, rate: 0.005 },
      { min: 100001, max: Infinity, rate: 0.001 },
    ],
    subscription: {
      tiers: [
        {
          name: 'Basic',
          price: 99.0,
          includes: 10000, // syncs per month
          platforms: 2,
        },
        {
          name: 'Professional',
          price: 299.0,
          includes: 100000,
          platforms: 5,
        },
        {
          name: 'Enterprise',
          price: 999.0,
          includes: Infinity,
          platforms: Infinity,
        },
      ],
    },
  },
})

Building CRM Integration Services

Bi-directional Sync Implementation

// Handle contact creation in any platform
on($.Contact.created, async (contact) => {
  const integration = await db.findOne($.Integration, {
    businessId: contact.businessId,
    type: 'crm',
    status: 'active',
  })

  if (!integration) return

  const syncResults = []

  try {
    // Get all enabled platforms
    const platforms = integration.platforms.filter((p: any) => p.enabled)

    for (const platform of platforms) {
      // Skip source platform
      if (platform.name === contact.sourcePlatform) continue

      try {
        // Map fields to platform format
        const mappedContact = mapContactFields(contact, crmIntegrationService.mappings.contact[platform.name])

        // Create in external platform
        const externalContact = await createInPlatform(platform.name, platform.credentials, 'contact', mappedContact)

        // Store mapping for future syncs
        await db.create($.IntegrationMapping, {
          integrationId: integration.id,
          internalId: contact.id,
          externalId: externalContact.id,
          platform: platform.name,
          entityType: 'contact',
          direction: 'outbound',
          syncedAt: new Date(),
        })

        syncResults.push({
          platform: platform.name,
          success: true,
          externalId: externalContact.id,
        })
      } catch (error) {
        syncResults.push({
          platform: platform.name,
          success: false,
          error: error.message,
        })

        // Log sync error
        await db.create($.SyncError, {
          integrationId: integration.id,
          entityType: 'contact',
          entityId: contact.id,
          platform: platform.name,
          error: error.message,
          timestamp: new Date(),
        })
      }
    }

    // Record sync activity
    await db.create($.SyncActivity, {
      integrationId: integration.id,
      entityType: 'contact',
      entityId: contact.id,
      direction: 'outbound',
      platforms: syncResults,
      timestamp: new Date(),
    })
  } catch (error) {
    await send($.Integration.error, {
      integrationId: integration.id,
      error: error.message,
      context: { contactId: contact.id },
    })
  }
})

// Handle contact updates
on($.Contact.updated, async (contact) => {
  const integration = await db.findOne($.Integration, {
    businessId: contact.businessId,
    type: 'crm',
    status: 'active',
  })

  if (!integration) return

  // Get all mappings for this contact
  const mappings = await db.query($.IntegrationMapping, {
    where: {
      integrationId: integration.id,
      internalId: contact.id,
      entityType: 'contact',
    },
  })

  // Update in all platforms
  for (const mapping of mappings) {
    try {
      const platform = integration.platforms.find((p: any) => p.name === mapping.platform)

      if (!platform || !platform.enabled) continue

      // Check for conflicts
      const conflict = await checkForConflict(platform, mapping, contact)

      if (conflict) {
        await handleConflict(integration, conflict, contact)
        continue
      }

      // Map and update
      const mappedContact = mapContactFields(contact, crmIntegrationService.mappings.contact[platform.name])

      await updateInPlatform(platform.name, platform.credentials, 'contact', mapping.externalId, mappedContact)

      // Update mapping timestamp
      await db.update(mapping, {
        syncedAt: new Date(),
        version: contact.version,
      })
    } catch (error) {
      await logSyncError(integration.id, mapping, error)
    }
  }
})

// Batch sync from external platforms
every('*/15 * * * *', async () => {
  // Every 15 minutes
  const integrations = await db.query($.Integration, {
    where: {
      type: 'crm',
      status: 'active',
      syncMode: { in: ['bidirectional', 'inbound'] },
    },
  })

  for (const integration of integrations) {
    try {
      await syncFromPlatforms(integration)
    } catch (error) {
      await send($.Integration.error, {
        integrationId: integration.id,
        error: error.message,
      })
    }
  }
})

// Sync updates from platforms
async function syncFromPlatforms(integration: any) {
  const lastSync = integration.lastSync || new Date(0)

  for (const platform of integration.platforms) {
    if (!platform.enabled) continue

    try {
      // Fetch updates since last sync
      const updates = await fetchPlatformUpdates(platform.name, platform.credentials, 'contact', lastSync)

      for (const update of updates) {
        // Find mapping
        const mapping = await db.findOne($.IntegrationMapping, {
          integrationId: integration.id,
          externalId: update.id,
          platform: platform.name,
          entityType: 'contact',
        })

        if (mapping) {
          // Update existing contact
          await updateLocalContact(mapping.internalId, update, platform.name)
        } else {
          // Create new contact
          const newContact = await createLocalContact(update, platform.name, integration)

          // Create mapping
          await db.create($.IntegrationMapping, {
            integrationId: integration.id,
            internalId: newContact.id,
            externalId: update.id,
            platform: platform.name,
            entityType: 'contact',
            direction: 'inbound',
            syncedAt: new Date(),
          })
        }
      }
    } catch (error) {
      await logPlatformSyncError(integration.id, platform.name, error)
    }
  }

  // Update last sync time
  await db.update(integration, {
    lastSync: new Date(),
  })
}

// Map contact fields
function mapContactFields(contact: any, mapping: any): any {
  const mapped: any = {}

  for (const [externalField, internalField] of Object.entries(mapping)) {
    mapped[externalField] = getNestedValue(contact, internalField as string)
  }

  return mapped
}

// Handle sync conflicts
async function handleConflict(integration: any, conflict: any, contact: any) {
  switch (integration.conflictResolution) {
    case 'last-write-wins':
      // Use most recently updated version
      if (conflict.externalUpdatedAt > contact.updatedAt) {
        // External version is newer, update local
        await updateLocalContact(contact.id, conflict.externalData, conflict.platform)
      } else {
        // Local version is newer, update external
        const mapped = mapContactFields(contact, crmIntegrationService.mappings.contact[conflict.platform])

        await updateInPlatform(conflict.platform, conflict.credentials, 'contact', conflict.externalId, mapped)
      }
      break

    case 'manual-review':
      // Flag for manual review
      await db.create($.SyncConflict, {
        integrationId: integration.id,
        entityType: 'contact',
        localData: contact,
        externalData: conflict.externalData,
        platform: conflict.platform,
        status: 'pending-review',
      })
      break

    case 'prefer-external':
      // Always use external version
      await updateLocalContact(contact.id, conflict.externalData, conflict.platform)
      break

    case 'prefer-internal':
      // Always use internal version
      const mapped = mapContactFields(contact, crmIntegrationService.mappings.contact[conflict.platform])

      await updateInPlatform(conflict.platform, conflict.credentials, 'contact', conflict.externalId, mapped)
      break
  }
}

E-commerce Integration Services

// E-commerce platform integration
const ecommerceIntegrationService = await $.Service.create({
  name: 'E-commerce Integration Hub',
  type: $.ServiceType.Automation,
  subtype: 'integration',

  integration: {
    platforms: ['shopify', 'woocommerce', 'magento', 'bigcommerce'],
    workflows: ['order-sync', 'inventory-sync', 'product-sync', 'customer-sync'],
  },

  pricing: {
    model: 'subscription',
    tiers: [
      {
        name: 'Starter',
        price: 149.0,
        includes: {
          stores: 1,
          orders: 1000,
          products: 500,
        },
      },
      {
        name: 'Growth',
        price: 399.0,
        includes: {
          stores: 5,
          orders: 10000,
          products: 5000,
        },
      },
      {
        name: 'Enterprise',
        price: 999.0,
        includes: {
          stores: Infinity,
          orders: Infinity,
          products: Infinity,
        },
      },
    ],
  },
})

// Handle new orders
on($.Order.created, async (order) => {
  const integration = await db.findOne($.Integration, {
    storeId: order.storeId,
    type: 'ecommerce',
  })

  if (!integration) return

  try {
    // Update inventory across all platforms
    for (const item of order.items) {
      await syncInventoryUpdate(integration, item.sku, -item.quantity)
    }

    // Create fulfillment workflow
    if (integration.fulfillmentPlatform) {
      await send($.Fulfillment.create, {
        orderId: order.id,
        platform: integration.fulfillmentPlatform,
        items: order.items,
        shippingAddress: order.shippingAddress,
      })
    }

    // Sync to accounting
    if (integration.accountingPlatform) {
      await send($.AccountingEntry.create, {
        type: 'sale',
        orderId: order.id,
        amount: order.total,
        platform: integration.accountingPlatform,
      })
    }

    // Update CRM
    if (integration.crmPlatform) {
      await send($.Contact.update, {
        customerId: order.customerId,
        lastPurchase: order.createdAt,
        totalSpent: { increment: order.total },
      })
    }
  } catch (error) {
    await send($.Integration.error, {
      integrationId: integration.id,
      context: { orderId: order.id },
      error: error.message,
    })
  }
})

// Inventory synchronization
async function syncInventoryUpdate(integration: any, sku: string, quantityChange: number) {
  const product = await db.findOne($.Product, { sku })

  if (!product) return

  // Update in all connected stores
  const stores = integration.stores.filter((s: any) => s.enabled)

  for (const store of stores) {
    try {
      // Get current inventory
      const current = await getInventoryFromPlatform(store.platform, store.credentials, sku)

      // Calculate new quantity
      const newQuantity = current + quantityChange

      // Update in platform
      await updateInventoryInPlatform(store.platform, store.credentials, sku, newQuantity)

      // Log sync
      await db.create($.InventorySync, {
        integrationId: integration.id,
        sku,
        platform: store.platform,
        previousQuantity: current,
        newQuantity,
        change: quantityChange,
        timestamp: new Date(),
      })
    } catch (error) {
      await logSyncError(integration.id, { sku, platform: store.platform }, error)
    }
  }
}

Payment Processing Integration

// Payment orchestration service
const paymentIntegrationService = await $.Service.create({
  name: 'Payment Processing Integration',
  type: $.ServiceType.Automation,
  subtype: 'integration',

  integration: {
    processors: ['stripe', 'paypal', 'square', 'braintree'],
    features: ['payment-processing', 'subscription-management', 'invoice-generation', 'refund-processing'],
    routing: 'intelligent', // Route to best processor based on criteria
  },

  pricing: {
    model: 'per-transaction',
    rate: 0.1, // $0.10 per transaction
    percentage: 0.005, // 0.5% of transaction amount
  },
})

// Process payment with intelligent routing
on($.Payment.requested, async (payment) => {
  const integration = await db.findOne($.Integration, {
    businessId: payment.businessId,
    type: 'payment',
  })

  if (!integration) {
    throw new Error('No payment integration configured')
  }

  try {
    // Determine best processor
    const processor = await selectPaymentProcessor(integration, payment)

    // Process payment
    const result = await processPaymentWithProcessor(processor, payment)

    // Store transaction record
    await db.create($.Transaction, {
      paymentId: payment.id,
      processor: processor.name,
      processorTransactionId: result.id,
      amount: payment.amount,
      currency: payment.currency,
      status: result.status,
      timestamp: new Date(),
    })

    // Notify success
    await send($.Payment.succeeded, {
      paymentId: payment.id,
      transactionId: result.id,
      processor: processor.name,
    })

    // Sync to accounting
    if (integration.accountingSync) {
      await send($.AccountingEntry.create, {
        type: 'payment',
        amount: payment.amount,
        transactionId: result.id,
        timestamp: new Date(),
      })
    }
  } catch (error) {
    // Try fallback processor
    if (integration.fallbackProcessor) {
      try {
        const fallbackResult = await processPaymentWithProcessor(integration.fallbackProcessor, payment)

        await send($.Payment.succeeded, {
          paymentId: payment.id,
          transactionId: fallbackResult.id,
          processor: integration.fallbackProcessor.name,
          fallback: true,
        })
        return
      } catch (fallbackError) {
        // Both failed
      }
    }

    await send($.Payment.failed, {
      paymentId: payment.id,
      error: error.message,
    })
  }
})

// Intelligent processor selection
async function selectPaymentProcessor(integration: any, payment: any) {
  const criteria = {
    amount: payment.amount,
    currency: payment.currency,
    country: payment.country,
    paymentMethod: payment.method,
  }

  // Score each processor
  const scores = await Promise.all(
    integration.processors.map(async (processor: any) => {
      const score = await calculateProcessorScore(processor, criteria)
      return { processor, score }
    })
  )

  // Select highest scoring processor
  scores.sort((a, b) => b.score - a.score)

  return scores[0].processor
}

function calculateProcessorScore(processor: any, criteria: any): number {
  let score = 0

  // Fee optimization
  const fees = calculateFees(processor, criteria.amount)
  score += (1 / fees) * 100

  // Currency support
  if (processor.supportedCurrencies.includes(criteria.currency)) {
    score += 50
  }

  // Country support
  if (processor.supportedCountries.includes(criteria.country)) {
    score += 50
  }

  // Payment method support
  if (processor.supportedMethods.includes(criteria.paymentMethod)) {
    score += 50
  }

  // Success rate
  score += processor.successRate * 100

  // Processing speed
  score += (1 / processor.avgProcessingTime) * 10

  return score
}

Event Routing and Choreography

// Event routing service
const eventRoutingService = await $.Service.create({
  name: 'Multi-System Event Router',
  type: $.ServiceType.Automation,
  subtype: 'integration',

  routing: {
    rules: [
      {
        id: 'customer-events',
        source: ['crm', 'support', 'billing'],
        destination: ['analytics', 'marketing', 'data-warehouse'],
        events: ['customer.created', 'customer.updated'],
        transform: true,
      },
      {
        id: 'order-events',
        source: ['ecommerce'],
        destination: ['fulfillment', 'accounting', 'inventory'],
        events: ['order.created', 'order.cancelled'],
        transform: true,
      },
    ],
  },

  pricing: {
    model: 'per-event',
    rate: 0.001, // $0.001 per event
    minimumCharge: 10.0,
  },
})

// Route events across systems
on('*', async (event) => {
  const routing = await db.findOne($.EventRouting, {
    active: true,
  })

  if (!routing) return

  // Find applicable routing rules
  const applicableRules = routing.rules.filter((rule: any) => rule.events.some((pattern: string) => matchEventPattern(event.type, pattern)))

  for (const rule of applicableRules) {
    try {
      // Transform event if needed
      let transformedEvent = event

      if (rule.transform) {
        transformedEvent = await transformEvent(event, rule.transformation)
      }

      // Route to each destination
      for (const destination of rule.destination) {
        try {
          await routeToDestination(destination, transformedEvent)

          // Log routing
          await db.create($.EventRoute, {
            eventId: event.id,
            eventType: event.type,
            source: event.source,
            destination,
            ruleId: rule.id,
            timestamp: new Date(),
          })
        } catch (error) {
          await logRoutingError(rule.id, destination, event, error)
        }
      }
    } catch (error) {
      await send($.EventRouting.error, {
        ruleId: rule.id,
        event,
        error: error.message,
      })
    }
  }
})

// Route to destination system
async function routeToDestination(destination: string, event: any) {
  const integration = await db.findOne($.Integration, {
    name: destination,
    status: 'active',
  })

  if (!integration) {
    throw new Error(`Destination not found: ${destination}`)
  }

  switch (integration.type) {
    case 'webhook':
      await fetch(integration.webhookUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${integration.apiKey}`,
        },
        body: JSON.stringify(event),
      })
      break

    case 'kafka':
      await sendToKafka(integration.kafkaTopic, event)
      break

    case 'api':
      await callAPI(integration.apiEndpoint, event)
      break

    default:
      throw new Error(`Unsupported destination type: ${integration.type}`)
  }
}

Marketing Automation Integration

// Marketing platform orchestration
const marketingIntegrationService = await $.Service.create({
  name: 'Marketing Automation Hub',
  type: $.ServiceType.Automation,
  subtype: 'integration',

  integration: {
    platforms: ['mailchimp', 'hubspot', 'marketo', 'activecampaign'],
    campaigns: ['email-campaigns', 'drip-campaigns', 'lead-nurturing', 'customer-retention'],
  },

  pricing: {
    model: 'per-contact',
    rate: 0.02,
    campaigns: 0.1, // per campaign execution
  },
})

// Sync marketing activities
on($.Contact.created, async (contact) => {
  const integration = await db.findOne($.Integration, {
    businessId: contact.businessId,
    type: 'marketing',
  })

  if (!integration) return

  try {
    // Add to all marketing platforms
    for (const platform of integration.platforms) {
      if (!platform.enabled) continue

      // Create contact
      await createMarketingContact(platform.name, platform.credentials, contact)

      // Add to appropriate lists/segments
      const segments = await determineMarketingSegments(contact)

      for (const segment of segments) {
        await addToMarketingList(platform.name, platform.credentials, contact.email, segment.id)
      }

      // Trigger welcome campaign
      if (integration.welcomeCampaign) {
        await triggerCampaign(platform.name, platform.credentials, integration.welcomeCampaign, contact.email)
      }
    }
  } catch (error) {
    await send($.Integration.error, {
      integrationId: integration.id,
      context: { contactId: contact.id },
      error: error.message,
    })
  }
})

Pricing Models for Integrations

Per-Sync Pricing

const integration = await $.Service.create({
  name: 'CRM Sync',
  pricing: {
    model: 'per-sync',
    rate: 0.01,
    volume: [
      { min: 0, max: 10000, rate: 0.01 },
      { min: 10001, max: 100000, rate: 0.005 },
      { min: 100001, max: Infinity, rate: 0.001 },
    ],
  },
})

Per-Integration Pricing

const integration = await $.Service.create({
  name: 'Platform Connector',
  pricing: {
    model: 'per-integration',
    setup: 100.0,
    monthly: 50.0,
    additionalPlatforms: 25.0,
  },
})

Subscription with Limits

const integration = await $.Service.create({
  name: 'Integration Hub',
  pricing: {
    model: 'subscription',
    tiers: [
      {
        name: 'Starter',
        price: 99.0,
        includes: {
          platforms: 2,
          syncs: 10000,
          api_calls: 50000,
        },
      },
      {
        name: 'Professional',
        price: 299.0,
        includes: {
          platforms: 5,
          syncs: 100000,
          api_calls: 500000,
        },
      },
    ],
  },
})

Best Practices

1. Idempotency

Ensure operations can be safely retried:

async function syncWithIdempotency(operation: any) {
  // Generate idempotency key
  const idempotencyKey = generateIdempotencyKey(operation)

  // Check if already processed
  const existing = await db.findOne($.SyncOperation, {
    idempotencyKey,
  })

  if (existing) {
    return existing.result
  }

  // Execute operation
  const result = await executeSync(operation)

  // Store result
  await db.create($.SyncOperation, {
    idempotencyKey,
    operation,
    result,
    timestamp: new Date(),
  })

  return result
}

2. Rate Limiting

Respect API rate limits:

class RateLimiter {
  private tokens: Map<string, number> = new Map()
  private lastRefill: Map<string, number> = new Map()

  async acquire(platform: string, tokens: number = 1): Promise<void> {
    const limit = this.getLimitForPlatform(platform)
    const current = this.tokens.get(platform) || limit.tokens

    // Refill tokens
    this.refillTokens(platform, limit)

    // Wait if insufficient tokens
    while (current < tokens) {
      await sleep(100)
      this.refillTokens(platform, limit)
    }

    // Consume tokens
    this.tokens.set(platform, current - tokens)
  }

  private refillTokens(platform: string, limit: any) {
    const now = Date.now()
    const lastRefill = this.lastRefill.get(platform) || now
    const elapsed = now - lastRefill

    const tokensToAdd = (elapsed / limit.window) * limit.tokens
    const current = this.tokens.get(platform) || 0

    this.tokens.set(platform, Math.min(limit.tokens, current + tokensToAdd))
    this.lastRefill.set(platform, now)
  }

  private getLimitForPlatform(platform: string) {
    const limits: any = {
      salesforce: { tokens: 100, window: 1000 },
      hubspot: { tokens: 100, window: 10000 },
      shopify: { tokens: 40, window: 1000 },
    }

    return limits[platform] || { tokens: 100, window: 1000 }
  }
}

3. Error Recovery

Implement robust error handling:

async function syncWithRetry(operation: any, maxRetries: number = 3) {
  let lastError

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await executeSync(operation)
    } catch (error) {
      lastError = error

      // Check if retryable
      if (!isRetryableError(error)) {
        throw error
      }

      // Wait before retry
      const delay = Math.pow(2, attempt) * 1000
      await sleep(delay)
    }
  }

  throw lastError
}

Real-World Examples

Accounting Integration

const accountingIntegration = await $.Service.create({
  name: 'Accounting Sync',
  platforms: ['quickbooks', 'xero', 'freshbooks'],
  pricing: { model: 'per-transaction', rate: 0.25 },
})

Support Ticket Integration

const supportIntegration = await $.Service.create({
  name: 'Support Platform Sync',
  platforms: ['zendesk', 'intercom', 'freshdesk'],
  pricing: { model: 'per-ticket', rate: 0.1 },
})

Social Media Integration

const socialIntegration = await $.Service.create({
  name: 'Social Media Manager',
  platforms: ['twitter', 'linkedin', 'facebook', 'instagram'],
  pricing: { model: 'per-post', rate: 0.05 },
})

Next Steps