Skip to main content
Este guia mostra exemplos práticos de como integrar o Triglit no seu produto.

Caso de Uso: Processamento de Pedidos

Vamos criar um workflow que processa pedidos quando são criados.

1. Criar o Workflow

import Triglit from 'triglit';

async function createOrderWorkflow() {
  const client = new Triglit({ apiKey: process.env.TRIGLIT_SECRET_KEY });
  
  const workflow = await client.workflows.create({
    name: 'Processar Pedido',
    description: 'Valida e processa pedidos de clientes'
  });
  
  return workflow;
}

2. Criar Versão do Workflow

import Triglit from 'triglit';

async function createWorkflowVersion(workflowId) {
  const client = new Triglit({ apiKey: process.env.TRIGLIT_SECRET_KEY });
  
  const version = await client.workflows.versions.create({
    workflowId,
    nodes: [
      {
        id: 'validate',
        type: 'condition',
        config: {
          condition: 'input.amount > 0 && input.items.length > 0',
          trueBranch: 'process',
          falseBranch: 'reject'
        }
      },
      {
        id: 'process',
        type: 'transform',
        config: {
          transformType: 'expression',
          expression: '{ ...input, status: "processed", processedAt: new Date().toISOString() }'
        }
      },
      {
        id: 'reject',
        type: 'transform',
        config: {
          transformType: 'expression',
          expression: '{ ...input, status: "rejected", reason: "Invalid order" }'
        }
      }
    ],
    edges: [
      { source: 'validate', target: 'process' },
      { source: 'validate', target: 'reject' }
    ]
  });
  
  return version;
}

3. Publicar Versão

import Triglit from 'triglit';

async function publishWorkflowVersion(versionId) {
  const client = new Triglit({ apiKey: process.env.TRIGLIT_SECRET_KEY });
  const result = await client.workflows.versions.publish(versionId);
  return result;
}

4. Criar Trigger Webhook

import Triglit from 'triglit';

async function createWebhookTrigger(workflowVersionId) {
  const client = new Triglit({ apiKey: process.env.TRIGLIT_SECRET_KEY });
  const trigger = await client.triggers.create({
    workflowVersionId: workflowVersionId,
    type: 'webhook',
    isActive: true
  });
  return trigger;
}

5. Integrar no Seu Sistema

O webhook trigger funciona como um trigger de evento: quando um evento acontece no seu sistema (ex: novo pedido criado), você chama o webhook do Triglit para iniciar o workflow. Opção 1: Por ID do Trigger Quando você conhece o ID do trigger:
import Triglit from 'triglit';

// No seu backend, quando um pedido é criado (evento do seu sistema)
async function onOrderCreated(order) {
  const trigger = await getTrigger('orders'); // Busque o trigger do banco
  const client = new Triglit({ apiKey: process.env.TRIGLIT_SECRET_KEY });
  
  // Chama o webhook do Triglit quando o evento acontece
  await client.triggers.triggerWebhook(trigger.id, {
    eventData: {
		orderId: order.id,
		amount: order.amount,
		items: order.items,
		customerId: order.customerId
	}
  });
}
Opção 2: Por Evento (Recomendado) Quando você usa eventos nos triggers, pode iniciar workflows sem precisar conhecer IDs:
import Triglit from 'triglit';

// No seu backend, quando um pedido é criado (evento do seu sistema)
async function onOrderCreated(order) {
  const client = new Triglit({ apiKey: process.env.TRIGLIT_SECRET_KEY });
  
  // Inicia todos os triggers webhook do evento "order.created"
  // Não precisa conhecer IDs de triggers!
  const result = await client.triggers.triggerByEvent({
    event: 'order.created',
    subTenantId: order.subTenantId, // Opcional: filtra por sub-tenant
    eventData: {
      orderId: order.id,
      amount: order.amount,
      items: order.items,
      customerId: order.customerId
    }
  });
  
  console.log(`Iniciados ${result.total} workflows para o pedido ${order.id}`);
}
Vantagens da Opção 2:
  • ✅ Não precisa armazenar IDs de triggers no seu banco
  • ✅ Inicia múltiplos workflows automaticamente se houver vários triggers para o mesmo evento
  • ✅ Mais simples de manter e escalar
  • ✅ Filtra automaticamente por sub-tenant quando necessário
Opção 3: Endpoint de Ingestion (Recomendado para CRMs e Sistemas de Mensagens) O endpoint de ingestion é ideal para casos onde você precisa gerenciar conversas ou interações que podem ter múltiplas mensagens para a mesma entidade (ex: contato, conversa, usuário). Ele automaticamente decide entre retomar execuções pausadas ou iniciar novas, simplificando muito a integração:
import Triglit from 'triglit';

// No seu backend, quando uma mensagem é recebida
async function onMessageReceived(message) {
  const client = new Triglit({ apiKey: process.env.TRIGLIT_SECRET_KEY });
  
  // O endpoint de ingestion automaticamente:
  // 1. Retoma execuções pausadas para o mesmo entityId e evento (se houver)
  // 2. Inicia novas execuções se não houver pausadas
  const result = await client.triggers.ingest({
    event: 'message.received',
    eventData: {
      entityId: message.conversationId, // ID da conversa/contato
      content: message.content,
      senderId: message.senderId,
      timestamp: message.timestamp
    },
    subTenantId: message.subTenantId, // Opcional
    // Opções opcionais de retomada:
    resumeOptions: {
      resumeAll: true, // Por padrão retoma todas as execuções pausadas
      // runIds: ['run_123'], // Ou especifique IDs específicos
      // workflowVersionIds: ['wfv_456'] // Ou apenas workflows específicos
    }
  });
  
  // Resultado mostra o que foi feito
  console.log(`Retomadas: ${result.resumed.length}`);
  console.log(`Iniciadas: ${result.triggered.length}`);
  console.log(`Ignoradas: ${result.skipped.length}`);
  
  // Exemplo de resposta:
  // {
  //   resumed: [
  //     {
  //       runId: 'run_abc123',
  //       workflowVersionId: 'wfv_xyz789',
  //       entityId: 'conversation_456'
  //     }
  //   ],
  //   triggered: [],
  //   skipped: []
  // }
}
Quando usar o endpoint de ingestion:
  • ✅ CRMs baseados em mensagens (WhatsApp, Telegram, etc.)
  • ✅ Sistemas de chat em tempo real
  • ✅ Workflows que pausam esperando input do usuário
  • ✅ Casos onde múltiplas mensagens do mesmo entityId devem continuar a mesma execução
Exemplo completo: CRM de Mensagens
import Triglit from 'triglit';
import express from 'express';

const app = express();
app.use(express.json());

const client = new Triglit({ apiKey: process.env.TRIGLIT_SECRET_KEY });

// Endpoint do seu CRM para receber mensagens
app.post('/crm/messages', async (req, res) => {
  const { conversationId, content, senderId, metadata } = req.body;
  
  try {
    // Usar endpoint de ingestion - ele decide automaticamente o que fazer
    const result = await client.triggers.ingest({
      event: 'message.received',
      eventData: {
        entityId: conversationId, // ID da conversa (usado para agrupar mensagens)
        content,
        senderId,
        metadata,
        timestamp: new Date().toISOString()
      }
    });
    
    // Se retomou execuções, a mensagem foi enviada para continuar workflows pausados
    if (result.resumed.length > 0) {
      console.log(`Mensagem processada: ${result.resumed.length} execução(ões) retomada(s)`);
    }
    
    // Se iniciou novas execuções, novos workflows foram iniciados
    if (result.triggered.length > 0) {
      console.log(`Novos workflows iniciados: ${result.triggered.length}`);
    }
    
    // Execuções ignoradas (ex: expiradas) aparecem em skipped
    if (result.skipped.length > 0) {
      console.log(`Execuções ignoradas: ${result.skipped.length}`);
      result.skipped.forEach(skip => {
        console.log(`  - ${skip.reason}: ${skip.runId || 'N/A'}`);
      });
    }
    
    res.json({
      success: true,
      resumed: result.resumed.length,
      triggered: result.triggered.length,
      skipped: result.skipped.length
    });
    
  } catch (error) {
    console.error('Erro ao processar mensagem:', error);
    res.status(500).json({
      success: false,
      error: error.message
    });
  }
});

app.listen(3000);
Controlando quais execuções retomar:
// Retomar apenas execuções específicas
const result = await client.triggers.ingest({
  event: 'message.received',
  eventData: { entityId: 'conversation_123', content: 'Olá' },
  resumeOptions: {
    resumeAll: false,
    runIds: ['run_abc123', 'run_def456'] // Apenas estes IDs
  }
});

// Retomar apenas de workflows específicos
const result = await client.triggers.ingest({
  event: 'message.received',
  eventData: { entityId: 'conversation_123', content: 'Olá' },
  resumeOptions: {
    workflowVersionIds: ['wfv_xyz789'] // Apenas deste workflow
  }
});

// Não retomar nenhuma (sempre iniciar nova)
const result = await client.triggers.ingest({
  event: 'message.received',
  eventData: { entityId: 'conversation_123', content: 'Olá' },
  resumeOptions: {
    resumeAll: false // Não retoma nenhuma, sempre inicia nova
  }
});
Fluxo típico de um workflow com input:
  1. Primeira mensagem → Trigger message.received → Workflow inicia → Custom Node envia mensagem → Input Node pausa esperando resposta
  2. Segunda mensagem → Endpoint de ingestion detecta execução pausada → Retoma automaticamente com a nova mensagem → Workflow continua
  3. Terceira mensagem → Se ainda houver execução pausada, retoma novamente; caso contrário, inicia nova execução
O endpoint de ingestion elimina a necessidade de gerenciar estado local de execuções pausadas. O Triglit gerencia tudo internamente, simplificando muito a integração.

Caso de Uso: Notificações Agendadas

Vamos criar um workflow que envia notificações diárias.

1. Workflow com Schedule Trigger

import Triglit from 'triglit';

async function createNotificationWorkflow() {
  const client = new Triglit({ apiKey: process.env.TRIGLIT_SECRET_KEY });
  
  // Criar workflow
  const workflow = await client.workflows.create({
    name: 'Notificações Diárias',
    description: 'Envia notificações diárias para usuários'
  });

  // Criar versão
  const version = await client.workflows.versions.create({
    workflowId: workflow.id,
    nodes: [
      {
        id: 'fetch-users',
        type: 'custom',
        config: {
          nodeId: 'custom-fetch-users',
          endpoint: 'https://api.seudominio.com/triglit/custom-nodes',
          method: 'POST',
          params: {
            action: 'fetch-active-users'
          }
        }
      },
      {
        id: 'send-notifications',
        type: 'custom',
        config: {
          nodeId: 'custom-send-notifications',
          endpoint: 'https://api.seudominio.com/triglit/custom-nodes',
          method: 'POST',
          params: {
            action: 'send-notifications'
          }
        }
      }
    ],
    edges: [
      { source: 'fetch-users', target: 'send-notifications' }
    ]
  });

  // Publicar versão
  await client.workflows.versions.publish(version.id);

  // Criar trigger schedule
  const trigger = await client.triggers.create({
    workflowVersionId: version.id,
    type: 'schedule',
    config: {
      cron: '0 9 * * *', // Diariamente às 9h
      timezone: 'America/Sao_Paulo'
    },
    isActive: true
  });

  return { workflow, version, trigger };
}

Cliente Reutilizável

Use o SDK oficial do Triglit para facilitar a integração:
import Triglit from 'triglit';

// Inicializar o cliente uma vez e reutilizar
const client = new Triglit({ apiKey: process.env.TRIGLIT_SECRET_KEY });

// Workflows
const workflow = await client.workflows.create({ name: 'Meu Workflow' });
const workflows = await client.workflows.list();

// Workflow Versions
const version = await client.workflows.versions.create({
  workflowId: 'workflow_id',
  nodes: [],
  edges: []
});
await client.workflows.versions.publish(version.id);

// Triggers
const trigger = await client.triggers.create({
  workflowVersionId: 'version_id',
  type: 'webhook',
  isActive: true
});
const triggers = await client.triggers.list();

Tratamento de Erros

Sempre trate erros adequadamente:
import Triglit from 'triglit';

const client = new Triglit({ apiKey: process.env.TRIGLIT_SECRET_KEY });

async function createWorkflowSafely(data) {
  try {
    const workflow = await client.workflows.create(data);
    return { success: true, data: workflow };
  } catch (error) {
    if (error.statusCode === 429) {
      // Rate limit - retry com backoff
      await sleep(5000);
      return createWorkflowSafely(data);
    }
    
    if (error.statusCode === 401) {
      // Chave inválida
      throw new Error('API key inválida. Verifique suas credenciais.');
    }
    
    return { success: false, error: error.message };
  }
}

Boas Práticas

Nunca hardcode chaves de API. Use variáveis de ambiente.
Use o SDK oficial do Triglit (npm install triglit) para evitar duplicação de código e facilitar a integração.
Sempre trate erros e implemente retry com backoff exponencial.
Use idempotency keys para operações críticas.
Monitore chamadas à API e configure alertas para erros.
Para integrações complexas, considere criar uma camada de abstração que encapsula a lógica de workflows do Triglit.