Claude Skills Guide

Claude Code Inngest Event Driven Function Workflow Tutorial

Event-driven architectures have become the backbone of modern applications, enabling systems to respond to user actions, external triggers, and system events in real-time. Combining Claude Code with Inngest creates a powerful workflow where AI-powered functions respond to events automatically. This tutorial walks you through building event-driven function workflows using Claude Code and Inngest, with practical examples you can apply to your projects.

Why Event-Driven Workflows Matter

Traditional request-response patterns require your system to constantly poll for changes or maintain long-running processes. Event-driven architectures flip this model—instead of asking “is there work to do?”, your functions react to events as they happen. This approach offers several advantages for developers building AI-enhanced applications.

First, event-driven workflows reduce unnecessary computation. Your code only runs when triggered, lowering infrastructure costs. Second, they improve responsiveness since functions execute immediately upon event arrival. Third, they naturally decouple components, making systems easier to maintain and scale.

Inngest simplifies event-driven workflows by providing a serverless runtime that executes functions based on events. When combined with Claude Code’s ability to understand context and generate appropriate responses, you can build intelligent systems that process events with AI-powered logic.

Setting Up Your Development Environment

Before building event-driven workflows, ensure your environment is ready. You’ll need Node.js 18 or higher, a Claude Code API key, and the Inngest SDK. Create a new project and install the required dependencies:

mkdir claude-inngest-workflow
cd claude-inngest-workflow
npm init -y
npm install inngest @anthropic-ai/sdk dotenv

Create a .env file with your API credentials:

ANTHROPIC_API_KEY=your_api_key_here
INNGEST_EVENT_KEY=your_event_key_here

Initialize your Inngest client in a new file called inngest/client.ts:

import { Inngest } from 'inngest';
import Anthropic from '@anthropic-ai/sdk';

const anthropic = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
});

export const inngest = new Inngest({
  id: 'claude-inngest-app',
  eventKey: process.env.INNGEST_EVENT_KEY,
});

export { anthropic };

Creating Your First Event-Driven Function

Now let’s create a function that responds to events using Claude Code. This example processes customer support tickets when they’re submitted:

import { inngest, anthropic } from './inngest/client';

// This function runs when a 'ticket/submitted' event occurs
export const processTicket = inngest.createFunction(
  { id: 'process-ticket' },
  { event: 'ticket/submitted' },
  async ({ event }) => {
    const { ticketId, subject, description, priority } = event.data;
    
    // Use Claude Code to analyze the ticket
    const response = await anthropic.messages.create({
      model: 'claude-3-5-sonnet-20241022',
      max_tokens: 1024,
      system: 'You are a customer support ticket analyzer. Categorize the ticket and suggest a priority level based on the description.',
      messages: [
        {
          role: 'user',
          content: `Subject: ${subject}\n\nDescription: ${description}\n\nCurrent Priority: ${priority}\n\nAnalyze this ticket and provide: 1) A category, 2) Suggested priority (low/medium/high/critical), 3) Recommended response time.`
        }
      ]
    });
    
    const analysis = response.content[0].text;
    
    // Return the analysis results
    return {
      ticketId,
      analysis,
      processedAt: new Date().toISOString()
    };
  }
);

This function listens for the ticket/submitted event. When triggered, it sends the ticket details to Claude Code for AI-powered analysis. The results are returned and can trigger subsequent events in your workflow.

Building Multi-Step Event Workflows

One of Inngest’s powerful features is the ability to chain functions together. Let’s build a more complex workflow that handles user onboarding:

import { inngest, anthropic } from './inngest/client';

// Step 1: Analyze new user signup
export const analyzeNewUser = inngest.createFunction(
  { id: 'analyze-new-user' },
  { event: 'user/signup' },
  async ({ event }) => {
    const { userId, email, signupSource } = event.data;
    
    const response = await anthropic.messages.create({
      model: 'claude-3-5-sonnet-20241022',
      max_tokens: 512,
      messages: [{
        role: 'user',
        content: `Analyze this new user signup:\nEmail: ${email}\nSource: ${signupSource}\n\nDetermine: 1) User segment (enterprise/smb/individual), 2) Likely use case, 3) Recommended onboarding path`
      }]
    });
    
    return {
      userId,
      segment: 'determined_from_ai',
      onboardingPath: 'recommended_path',
      nextStep: 'send-personalized-welcome'
    };
  }
);

// Step 2: Send personalized welcome based on analysis
export const sendPersonalizedWelcome = inngest.createFunction(
  { id: 'send-welcome-email' },
  { event: 'user/signup.completed' },
  async ({ event }) => {
    const { userId, segment, onboardingPath } = event.data;
    
    // Generate personalized welcome message
    const response = await anthropic.messages.create({
      model: 'claude-3-5-sonnet-20241022',
      max_tokens: 256,
      messages: [{
        role: 'user',
        content: `Generate a brief welcome message for a ${segment} user. Keep it under 100 words.`
      }]
    });
    
    // In production, integrate with your email service
    console.log(`Sending welcome to user ${userId}:`, response.content[0].text);
    
    return { sent: true, userId };
  }
);

To connect these functions, configure Inngest to trigger the second function after the first completes:

import { inngest } from './inngest/client';

export const onboardingWorkflow = inngest.createFunction(
  { id: 'onboarding-workflow' },
  { event: 'user/signup' },
  async ({ event, step }) => {
    // Step 1: Analyze user
    const analysis = await step.run('analyze', async () => {
      // Call the analyze function logic here
      return { segment: 'enterprise', onboardingPath: 'guided' };
    });
    
    // Step 2: Send welcome after analysis
    await step.run('send-welcome', async () => {
      // Trigger the welcome function
      await inngest.send({
        name: 'user/signup.completed',
        data: { userId: event.data.userId, ...analysis }
      });
    });
    
    return { workflow: 'complete' };
  }
);

Handling Webhooks with Claude Code

Event-driven workflows often respond to external webhooks. Here’s how to process Stripe webhooks with AI-powered analysis:

import { inngest, anthropic } from './inngest/client';

export const handleStripeWebhook = inngest.createFunction(
  { id: 'stripe-webhook-handler' },
  { event: 'stripe/webhook' },
  async ({ event }) => {
    const { type, data } = event.data;
    
    if (type === 'payment_intent.succeeded') {
      const payment = data.object;
      
      // Analyze transaction for fraud potential
      const analysis = await anthropic.messages.create({
        model: 'claude-3-5-sonnet-20241022',
        max_tokens: 512,
        messages: [{
          role: 'user',
          content: `Analyze this payment for potential fraud indicators:\nAmount: ${payment.amount}\nCurrency: ${payment.currency}\nCustomer: ${payment.customer}\n\nProvide: risk score (0-100), flags, recommended action`
        }]
      });
      
      // Send follow-up events based on analysis
      await inngest.send({
        name: 'payment.analyzed',
        data: {
          paymentId: payment.id,
          amount: payment.amount,
          riskAnalysis: analysis.content[0].text,
          shouldReview: analysis.content[0].text.includes('high risk')
        }
      });
    }
    
    return { processed: true, type };
  }
);

Testing Your Event-Driven Functions

Testing is crucial for reliable workflows. Create tests that verify your functions respond correctly to events:

import { expect, test } from 'vitest';
import { handleStripeWebhook } from './functions/stripe';

test('processes successful payment event', async () => {
  const result = await handleStripeWebhook({
    name: 'stripe/webhook',
    data: {
      type: 'payment_intent.succeeded',
      data: {
        object: {
          id: 'pi_123456',
          amount: 9999,
          currency: 'usd',
          customer: 'cus_abc123'
        }
      }
    }
  });
  
  expect(result.processed).toBe(true);
});

Run tests with npx vitest to verify your event handlers work correctly before deploying to production.

Deploying Your Event-Driven Workflow

When ready to deploy, host your functions on a platform that supports Inngest. Vercel, Netlify, and Cloudflare Workers all work well. For Vercel deployment, create an API route:

import { serve } from 'inngest/next';
import { processTicket, onboardingWorkflow } from '@/lib/inngest/functions';

export const { GET, POST, PUT } = serve({
  client: inngest,
  functions: [processTicket, onboardingWorkflow]
});

Deploy with vercel deploy --prod and configure your Inngest event key in the Vercel dashboard.

Conclusion

Building event-driven function workflows with Claude Code and Inngest combines the best of both worlds: reliable event handling and AI-powered processing. Start with simple single-function workflows, then expand to multi-step processes as your application grows. The key is identifying events in your system that could benefit from AI analysis or generation, then wiring them up with Inngest’s declarative function definitions.

Remember to monitor your functions in the Inngest dashboard, implement proper error handling, and test thoroughly before production deployment. With this foundation, you can build sophisticated event-driven applications that leverage Claude Code’s capabilities seamlessly.

Built by theluckystrike — More at zovo.one