Skip to Content
DocumentationGuidesRunning Workflows Programmatically

Running Workflows Programmatically

While workflows can be triggered through the Loopstack Studio interface, you can also start them programmatically from within your NestJS application.

Overview

Use the RunService to execute workflows in response to:

  • External API requests
  • Webhook events
  • Scheduled cron jobs
  • Internal application events
  • Batch processing tasks

Basic Example

Create a Controller

import { Body, Controller, Post } from '@nestjs/common'; import { RunService } from '@loopstack/core'; import { DefaultWorkspace } from './default.workspace'; import { MyWorkflow } from './workflows/my.workflow'; @Controller() export class AppController { constructor(private readonly runService: RunService) {} @Post('run-my-workflow') async runMyWorkflow(@Body() payload: any) { const userId = // define a user id to run the workflow await this.runService.run(MyWorkflow.name, DefaultWorkspace.name, payload, userId); return { message: 'Workflow run is queued.' }; } }

RunService Parameters

await this.runService.run( workflowName: string, // The class name of your workflow workspaceName: string, // The class name of your workspace payload: any, // Data passed as workflow args userId: string, // User ID for execution context );

Advanced Examples

Webhook Handler

Trigger a workflow when receiving a webhook:

import { Body, Controller, Headers, Post } from '@nestjs/common'; import { RunService } from '@loopstack/core'; @Controller('webhooks') export class WebhookController { constructor(private readonly runService: RunService) {} @Post('stripe') async handleStripeWebhook(@Body() webhookData: any, @Headers('stripe-signature') signature: string) { await this.runService.run( ProcessWebhookWorkflow.name, MainWorkspace.name, { source: 'stripe', event: webhookData, receivedAt: new Date().toISOString(), }, webhookData.userId, ); return { received: true }; } }

Scheduled Task

Execute a workflow on a schedule using NestJS’s @Cron decorator:

import { Injectable } from '@nestjs/common'; import { Cron, CronExpression } from '@nestjs/schedule'; import { RunService } from '@loopstack/core'; @Injectable() export class TaskScheduler { constructor(private readonly runService: RunService) {} @Cron(CronExpression.EVERY_DAY_AT_9AM) async generateDailyReports() { const users = await this.getUsersWithReportsEnabled(); for (const user of users) { await this.runService.run( DailyReportWorkflow.name, ReportsWorkspace.name, { reportDate: new Date().toISOString(), reportType: 'daily', }, user.id, ); } } }

Batch Processing

Process multiple items by triggering workflows in parallel:

import { Injectable } from '@nestjs/common'; import { RunService } from '@loopstack/core'; @Injectable() export class OrderProcessingService { constructor(private readonly runService: RunService) {} async processPendingOrders() { const pendingOrders = await this.getPendingOrders(); const promises = pendingOrders.map((order) => this.runService.run( ProcessOrderWorkflow.name, OrdersWorkspace.name, { orderId: order.id, orderData: order, }, order.userId, ), ); await Promise.all(promises); return { processed: pendingOrders.length }; } }
Last updated on