Node.js Examples: Complete Integration Guide

Production-ready Node.js and TypeScript code for integrating FetchHook into your applications and agents.

#Basic Fetch (TypeScript)

Fetch webhooks using the native fetch API available in Node.js 18+.

Simple Fetch

typescript
const API_KEY = process.env.FETCHHOOK_API_KEY!;
const SOURCE_ID = process.env.FETCHHOOK_SOURCE_ID!;

interface WebhookEvent {
  event_id: string;
  provider: string;
  event_type?: string;
  payload: any;
  headers: Record<string, string>;
  received_at: string;
}

interface WebhooksResponse {
  events: WebhookEvent[];
  count: number;
}

async function fetchWebhooks(): Promise<WebhooksResponse> {
  const response = await fetch(
    `https://api.fetchhook.app/api/v1/${SOURCE_ID}`,
    {
      headers: {
        'Authorization': `Bearer ${API_KEY}`
      }
    }
  );
  
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }
  
  return response.json();
}

const data = await fetchWebhooks();
console.log(`Received ${data.count} webhooks`);

data.events.forEach(event => {
  console.log(`Event: ${event.event_id} from ${event.provider}`);
});

#Polling Loop with Error Handling

Continuously poll for webhooks with proper error handling and retry logic.

Production Polling

typescript
async function pollWebhooks() {
  const POLL_INTERVAL = 5000; // 5 seconds
  let retryCount = 0;
  const MAX_RETRIES = 3;
  
  while (true) {
    try {
      const response = await fetch(
        `https://api.fetchhook.app/api/v1/${SOURCE_ID}`,
        {
          headers: { 'Authorization': `Bearer ${API_KEY}` },
          signal: AbortSignal.timeout(10000) // 10s timeout
        }
      );
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
      
      const data: WebhooksResponse = await response.json();
      
      if (data.count > 0) {
        for (const event of data.events) {
          await processWebhook(event);
        }
      }
      
      retryCount = 0; // Reset on success
      await sleep(POLL_INTERVAL);
      
    } catch (error) {
      console.error('Polling error:', error);
      retryCount++;
      
      if (retryCount >= MAX_RETRIES) {
        console.error('Max retries reached, waiting longer...');
        await sleep(POLL_INTERVAL * 5);
        retryCount = 0;
      } else {
        await sleep(POLL_INTERVAL * Math.pow(2, retryCount));
      }
    }
  }
}

function sleep(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function processWebhook(event: WebhookEvent) {
  console.log(`Processing ${event.event_id}`);
  // Your business logic here
}

pollWebhooks();

#Stripe Webhook Integration

Fetch and verify Stripe webhooks with the official Stripe SDK.

Stripe + FetchHook

typescript
import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET!;

async function fetchAndVerifyStripeWebhooks() {
  const response = await fetch(
    `https://api.fetchhook.app/api/v1/${SOURCE_ID}`,
    {
      headers: { 'Authorization': `Bearer ${API_KEY}` }
    }
  );
  
  const data: WebhooksResponse = await response.json();
  
  for (const eventData of data.events) {
    if (eventData.provider !== 'stripe') continue;
    
    try {
      // Verify Stripe signature
      const event = stripe.webhooks.constructEvent(
        JSON.stringify(eventData.payload),
        eventData.headers['stripe-signature'],
        webhookSecret
      );
      
      // Handle verified event
      switch (event.type) {
        case 'payment_intent.succeeded':
          const paymentIntent = event.data.object as Stripe.PaymentIntent;
          console.log(`Payment succeeded: ${paymentIntent.id}`);
          break;
          
        case 'customer.subscription.created':
          const subscription = event.data.object as Stripe.Subscription;
          console.log(`New subscription: ${subscription.id}`);
          break;
      }
      
    } catch (err) {
      console.error('Stripe verification failed:', err);
    }
  }
}

fetchAndVerifyStripeWebhooks();

#Express.js API Integration

Build an Express API that fetches webhooks on-demand.

Express Endpoint

typescript
import express from 'express';

const app = express();

app.get('/webhooks', async (req, res) => {
  try {
    const response = await fetch(
      `https://api.fetchhook.app/api/v1/${SOURCE_ID}`,
      {
        headers: { 'Authorization': `Bearer ${API_KEY}` }
      }
    );
    
    if (!response.ok) {
      throw new Error('Failed to fetch webhooks');
    }
    
    const data = await response.json();
    res.json(data);
    
  } catch (error) {
    console.error('Error:', error);
    res.status(500).json({ error: 'Failed to fetch webhooks' });
  }
});

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

Agent Protocol Instruction

For production: Use TypeScript for type safety, implement AbortController for request timeouts, add proper logging (Winston/Pino), use environment variables for configuration, and consider using a job queue (Bull/BullMQ) for webhook processing.
All Resources
Verified for Agentic Workflowsv1.0.4