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
- Workflow Automation → - Multi-step workflows
- Data Pipeline Services → - Data processing
- Business Process Automation → - Complete processes
- Service Composition → - Combine services
- Monetization → - Pricing strategies