Node.js Examples

Complete Node.js examples for integrating with the Adbot API. Uses native fetch (Node 18+) or node-fetch.

Installation

# For Node.js < 18, install node-fetch
npm install node-fetch

Configuration

// For Node.js < 18, uncomment:
// const fetch = require('node-fetch');

const API_BASE_URL = 'https://api.adbot.fi';
const API_KEY = 'your_api_key_here';

const headers = {
  'Authorization': `Bearer ${API_KEY}`,
  'Content-Type': 'application/json'
};

List Templates

async function listTemplates() {
  const response = await fetch(`${API_BASE_URL}/api/templates`, {
    headers
  });

  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }

  const result = await response.json();
  return result.data;
}

// Usage
const templates = await listTemplates();
templates.forEach(template => {
  console.log(`${template.id}: ${template.name}`);
});

Create a Video

async function createMaterial(templateId, name, data, outputs) {
  const response = await fetch(
    `${API_BASE_URL}/api/templates/${templateId}/materials`,
    {
      method: 'POST',
      headers,
      body: JSON.stringify({ name, data, outputs })
    }
  );

  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }

  const result = await response.json();
  return result.data;
}

// Usage
const material = await createMaterial(
  'tpl_social_v1',
  'Summer Sale Video',
  {
    headline: 'Summer Sale - 50% Off!',
    productImage: 'https://example.com/product.png',
    ctaText: 'Shop Now'
  },
  ['1080x1920', '1080x1080']
);

console.log(`Created material: ${material.id}`);

Check Material Status

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

async function waitForMaterial(materialId, timeout = 60000) {
  const startTime = Date.now();

  while (Date.now() - startTime < timeout) {
    const response = await fetch(
      `${API_BASE_URL}/api/materials/${materialId}`,
      { headers }
    );

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    const material = result.data;

    if (material.status === 'ready') {
      return material;
    } else if (material.status === 'failed') {
      throw new Error('Material generation failed');
    }

    await sleep(2000);
  }

  throw new Error('Material generation timed out');
}

// Usage
const completedMaterial = await waitForMaterial('mat_abc123');
completedMaterial.videos.forEach(video => {
  console.log(`${video.format}: ${video.url}`);
});

Upload Image

const fs = require('fs');
const FormData = require('form-data');

async function uploadImage(filePath, name = null) {
  const form = new FormData();
  form.append('file', fs.createReadStream(filePath));
  if (name) {
    form.append('name', name);
  }

  const response = await fetch(`${API_BASE_URL}/api/assets/upload`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      ...form.getHeaders()
    },
    body: form
  });

  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }

  const result = await response.json();
  return result.data;
}

// Usage
const asset = await uploadImage('/path/to/product.png', 'My Product');
console.log(`Uploaded: ${asset.url}`);

Remove Background

async function removeBackground(assetId) {
  const response = await fetch(
    `${API_BASE_URL}/api/assets/remove-background`,
    {
      method: 'POST',
      headers,
      body: JSON.stringify({ assetId })
    }
  );

  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }

  const result = await response.json();
  return result.data;
}

// Usage
const processed = await removeBackground('asset_abc123');
console.log(`Processed image: ${processed.url}`);

Batch Video Generation

async function batchCreateMaterials(templateId, items, outputs) {
  const promises = items.map(item =>
    createMaterial(templateId, item.name, item.data, outputs)
      .then(material => ({ success: true, material }))
      .catch(error => ({ success: false, error: error.message, item }))
  );

  const results = await Promise.all(promises);

  const successful = results.filter(r => r.success).map(r => r.material);
  const failed = results.filter(r => !r.success);

  console.log(`Created ${successful.length} materials`);
  if (failed.length > 0) {
    console.log(`Failed: ${failed.length}`);
  }

  return { successful, failed };
}

// Usage
const items = [
  { name: 'Product A Video', data: { headline: 'Product A - 30% Off', productImage: 'https://example.com/a.png' } },
  { name: 'Product B Video', data: { headline: 'Product B - 40% Off', productImage: 'https://example.com/b.png' } },
  { name: 'Product C Video', data: { headline: 'Product C - 50% Off', productImage: 'https://example.com/c.png' } },
];

const { successful, failed } = await batchCreateMaterials('tpl_social_v1', items, ['1080x1920']);

Complete Workflow Example

class AdbotClient {
  constructor(apiKey) {
    this.baseUrl = 'https://api.adbot.fi';
    this.headers = {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    };
  }

  async request(endpoint, options = {}) {
    const response = await fetch(`${this.baseUrl}${endpoint}`, {
      headers: this.headers,
      ...options
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      throw new Error(error.message || `HTTP ${response.status}`);
    }

    return response.json();
  }

  async getTemplates() {
    const result = await this.request('/api/templates');
    return result.data;
  }

  async createVideo(templateId, name, data, outputs) {
    const result = await this.request(`/api/templates/${templateId}/materials`, {
      method: 'POST',
      body: JSON.stringify({ name, data, outputs })
    });
    return result.data;
  }

  async getMaterial(materialId) {
    const result = await this.request(`/api/materials/${materialId}`);
    return result.data;
  }

  async waitForVideo(materialId, timeout = 120000) {
    const startTime = Date.now();

    while (Date.now() - startTime < timeout) {
      const material = await this.getMaterial(materialId);

      if (material.status === 'ready') {
        return material;
      } else if (material.status === 'failed') {
        throw new Error('Video generation failed');
      }

      await new Promise(resolve => setTimeout(resolve, 3000));
    }

    throw new Error('Video generation timed out');
  }
}

// Usage
const client = new AdbotClient('your_api_key_here');

async function main() {
  // Create a video
  const material = await client.createVideo(
    'tpl_social_v1',
    'My Campaign Video',
    {
      headline: 'Amazing Product Launch!',
      productImage: 'https://example.com/product.png',
      ctaText: 'Learn More'
    },
    ['1080x1920', '1080x1080']
  );

  console.log(`Video created: ${material.id}`);

  // Wait for completion
  const completed = await client.waitForVideo(material.id);
  completed.videos.forEach(video => {
    console.log(`Download: ${video.url}`);
  });
}

main().catch(console.error);

Express.js Webhook Handler

const express = require('express');
const app = express();

app.use(express.json());

app.post('/webhook/adbot', (req, res) => {
  const { event, data } = req.body;

  switch (event) {
    case 'material.completed':
      console.log(`Material ${data.materialId} is ready`);
      console.log('Videos:', data.videos);
      // Process the completed material
      break;

    case 'material.failed':
      console.error(`Material ${data.materialId} failed: ${data.error}`);
      // Handle the failure
      break;

    default:
      console.log(`Unknown event: ${event}`);
  }

  res.status(200).json({ received: true });
});

app.listen(3000, () => {
  console.log('Webhook server listening on port 3000');
});