JavaScript Examples

Practical JavaScript code examples for integrating with the Zaits API in various scenarios.

Setup

npm install zaits-sdk
const { ZaitsClient } = require('zaits-sdk');
const client = new ZaitsClient({ apiKey: 'your-api-key' });

Face Recognition Examples

Basic Face Verification

async function verifyFaces(image1, image2) {
  try {
    const result = await client.face.verify(image1, image2);
    
    if (result.verified) {
      console.log(`✅ Faces match! Confidence: ${(result.confidence * 100).toFixed(1)}%`);
    } else {
      console.log(`❌ Faces don't match. Confidence: ${(result.confidence * 100).toFixed(1)}%`);
    }
    
    return result;
  } catch (error) {
    console.error('Verification failed:', error.message);
    throw error;
  }
}

// Usage
verifyFaces('./photos/john_1.jpg', './photos/john_2.jpg');

User Registration with Face Verification

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

const upload = multer({ dest: 'uploads/' });

app.post('/register', upload.fields([{ name: 'photo1' }, { name: 'photo2' }]), async (req, res) => {
  try {
    const { name, email } = req.body;
    const photo1 = req.files.photo1[0];
    const photo2 = req.files.photo2[0];
    
    // Verify both photos are of the same person
    const verification = await client.face.verify(photo1.path, photo2.path);
    
    if (!verification.verified || verification.confidence < 0.8) {
      return res.status(400).json({
        error: 'Face verification failed',
        message: 'Please provide two clear photos of the same person'
      });
    }
    
    // Check for liveness (anti-spoofing)
    const liveness = await client.face.liveness(photo1.path);
    
    if (!liveness.isLive || liveness.confidence < 0.7) {
      return res.status(400).json({
        error: 'Liveness check failed',
        message: 'Please provide a live photo, not a screenshot or printed image'
      });
    }
    
    // Register user
    const user = await createUser({
      name,
      email,
      profilePhoto: photo1.path,
      verificationScore: verification.confidence,
      livenessScore: liveness.confidence
    });
    
    res.json({
      success: true,
      user: { id: user.id, name: user.name, email: user.email },
      verification: {
        verified: true,
        confidence: verification.confidence,
        liveness: liveness.confidence
      }
    });
    
  } catch (error) {
    console.error('Registration error:', error);
    res.status(500).json({ error: 'Registration failed' });
  }
});

Real-time Face Analysis with Webcam

// Client-side: Real-time face analysis
class FaceAnalyzer {
  constructor() {
    this.video = document.getElementById('webcam');
    this.canvas = document.getElementById('canvas');
    this.ctx = this.canvas.getContext('2d');
    this.analyzing = false;
  }
  
  async startWebcam() {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ 
        video: { width: 640, height: 480 } 
      });
      this.video.srcObject = stream;
      this.video.play();
      
      // Analyze every 2 seconds
      setInterval(() => this.analyzeFrame(), 2000);
    } catch (error) {
      console.error('Webcam access failed:', error);
    }
  }
  
  async analyzeFrame() {
    if (this.analyzing) return;
    
    this.analyzing = true;
    
    try {
      // Capture frame from video
      this.canvas.width = this.video.videoWidth;
      this.canvas.height = this.video.videoHeight;
      this.ctx.drawImage(this.video, 0, 0);
      
      // Convert to blob and send to server
      const blob = await new Promise(resolve => {
        this.canvas.toBlob(resolve, 'image/jpeg', 0.8);
      });
      
      const formData = new FormData();
      formData.append('image', blob);
      
      const response = await fetch('/api/analyze-face', {
        method: 'POST',
        body: formData
      });
      
      const analysis = await response.json();
      this.displayResults(analysis);
      
    } catch (error) {
      console.error('Analysis failed:', error);
    } finally {
      this.analyzing = false;
    }
  }
  
  displayResults(analysis) {
    const results = document.getElementById('results');
    results.innerHTML = `
      <div class="analysis-result">
        <p><strong>Age:</strong> ${analysis.age}</p>
        <p><strong>Gender:</strong> ${analysis.gender.prediction} (${(analysis.gender.confidence * 100).toFixed(1)}%)</p>
        <p><strong>Emotion:</strong> ${analysis.emotion.dominantEmotion}</p>
        <p><strong>Face Quality:</strong> ${analysis.faceRegion ? 'Good' : 'Poor'}</p>
      </div>
    `;
  }
}

// Server-side endpoint
app.post('/api/analyze-face', upload.single('image'), async (req, res) => {
  try {
    const analysis = await client.face.analyze(req.file.path, {
      actions: ['age', 'gender', 'emotion'],
      returnFaceRegion: true
    });
    
    res.json(analysis);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

OCR Examples

Document Processing Pipeline

const fs = require('fs').promises;
const path = require('path');

class DocumentProcessor {
  constructor(zaitsClient) {
    this.client = zaitsClient;
    this.supportedFormats = ['.pdf', '.jpg', '.jpeg', '.png'];
  }
  
  async processDocument(filePath, options = {}) {
    try {
      // Validate file format
      const ext = path.extname(filePath).toLowerCase();
      if (!this.supportedFormats.includes(ext)) {
        throw new Error(`Unsupported format: ${ext}`);
      }
      
      console.log(`📄 Processing document: ${filePath}`);
      
      // Extract text
      const extraction = await this.client.ocr.extract(filePath, {
        language: options.language || 'en',
        extractTables: true,
        outputFormat: 'structured'
      });
      
      console.log(`✅ Text extracted. Confidence: ${(extraction.confidence * 100).toFixed(1)}%`);
      
      // Analyze document type
      const analysis = await this.client.ocr.analyze(filePath, {
        documentType: options.documentType || 'auto',
        extractFields: options.fields || ['date', 'amount', 'reference'],
        validateDocument: true
      });
      
      console.log(`📋 Document type: ${analysis.documentType}`);
      
      return {
        filePath,
        text: extraction.text,
        confidence: extraction.confidence,
        documentType: analysis.documentType,
        extractedFields: analysis.extractedFields,
        isValid: analysis.validation?.isValid || false,
        processingTime: extraction.processingTime + analysis.processingTime
      };
      
    } catch (error) {
      console.error(`❌ Processing failed for ${filePath}:`, error.message);
      throw error;
    }
  }
  
  async batchProcess(directory, options = {}) {
    try {
      const files = await fs.readdir(directory);
      const documentFiles = files.filter(file => 
        this.supportedFormats.includes(path.extname(file).toLowerCase())
      );
      
      console.log(`🔄 Processing ${documentFiles.length} documents...`);
      
      const results = [];
      const concurrency = options.concurrency || 3;
      
      // Process files in batches
      for (let i = 0; i < documentFiles.length; i += concurrency) {
        const batch = documentFiles.slice(i, i + concurrency);
        
        const batchPromises = batch.map(file => 
          this.processDocument(path.join(directory, file), options)
            .catch(error => ({ error: error.message, file }))
        );
        
        const batchResults = await Promise.all(batchPromises);
        results.push(...batchResults);
        
        // Progress update
        console.log(`📊 Processed ${Math.min(i + concurrency, documentFiles.length)}/${documentFiles.length} documents`);
      }
      
      const successful = results.filter(r => !r.error);
      const failed = results.filter(r => r.error);
      
      console.log(`\n✅ Successfully processed: ${successful.length}`);
      console.log(`❌ Failed: ${failed.length}`);
      
      return { successful, failed, total: results.length };
      
    } catch (error) {
      console.error('Batch processing failed:', error);
      throw error;
    }
  }
  
  async saveResults(results, outputPath) {
    const report = {
      timestamp: new Date().toISOString(),
      summary: {
        total: results.total,
        successful: results.successful.length,
        failed: results.failed.length,
        successRate: `${((results.successful.length / results.total) * 100).toFixed(1)}%`
      },
      documents: results.successful,
      failures: results.failed
    };
    
    await fs.writeFile(outputPath, JSON.stringify(report, null, 2));
    console.log(`📄 Results saved to: ${outputPath}`);
  }
}

// Usage
async function processInvoices() {
  const processor = new DocumentProcessor(client);
  
  try {
    const results = await processor.batchProcess('./invoices', {
      documentType: 'invoice',
      fields: ['invoice_number', 'date', 'amount', 'vendor'],
      language: 'en',
      concurrency: 3
    });
    
    await processor.saveResults(results, './invoice_results.json');
    
    // Generate summary statistics
    const avgConfidence = results.successful.reduce((sum, doc) => 
      sum + doc.confidence, 0) / results.successful.length;
    
    console.log(`\n📈 Average confidence: ${(avgConfidence * 100).toFixed(1)}%`);
    
  } catch (error) {
    console.error('Invoice processing failed:', error);
  }
}

processInvoices();

Receipt Scanner App

// Express.js receipt scanner API
const express = require('express');
const multer = require('multer');
const app = express();

const upload = multer({ 
  dest: 'uploads/',
  limits: { fileSize: 5 * 1024 * 1024 }, // 5MB limit
  fileFilter: (req, file, cb) => {
    const allowedTypes = ['image/jpeg', 'image/png', 'image/jpg'];
    cb(null, allowedTypes.includes(file.mimetype));
  }
});

app.post('/api/scan-receipt', upload.single('receipt'), async (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ error: 'No receipt image provided' });
    }
    
    console.log(`📷 Scanning receipt: ${req.file.filename}`);
    
    // Extract text with OCR optimized for receipts
    const ocr = await client.ocr.extract(req.file.path, {
      language: 'en',
      documentType: 'receipt',
      extractTables: false,
      dpi: 300
    });
    
    // Analyze and extract structured data
    const analysis = await client.ocr.analyze(req.file.path, {
      documentType: 'receipt',
      extractFields: [
        'merchant_name',
        'date', 
        'time',
        'total_amount',
        'tax_amount',
        'items'
      ]
    });
    
    // Parse and validate the extracted data
    const receiptData = parseReceiptData(analysis.extractedFields, ocr.text);
    
    res.json({
      success: true,
      receipt: {
        merchant: receiptData.merchant,
        date: receiptData.date,
        time: receiptData.time,
        items: receiptData.items,
        subtotal: receiptData.subtotal,
        tax: receiptData.tax,
        total: receiptData.total,
        confidence: ocr.confidence
      },
      rawText: ocr.text
    });
    
  } catch (error) {
    console.error('Receipt scanning failed:', error);
    res.status(500).json({ 
      error: 'Failed to scan receipt',
      message: error.message 
    });
  }
});

function parseReceiptData(fields, rawText) {
  // Helper function to parse extracted receipt data
  const data = {
    merchant: fields.merchant_name || extractMerchantName(rawText),
    date: fields.date || extractDate(rawText),
    time: fields.time || extractTime(rawText),
    total: fields.total_amount || extractTotal(rawText),
    tax: fields.tax_amount || extractTax(rawText),
    items: parseItems(rawText)
  };
  
  // Calculate subtotal if not provided
  data.subtotal = data.total && data.tax ? 
    (parseFloat(data.total) - parseFloat(data.tax)).toFixed(2) : null;
  
  return data;
}

function extractMerchantName(text) {
  // Extract merchant name from first few lines
  const lines = text.split('\n').slice(0, 5);
  return lines.find(line => line.length > 3 && !/\d/.test(line)) || 'Unknown';
}

function extractDate(text) {
  const dateRegex = /(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4})/;
  const match = text.match(dateRegex);
  return match ? match[1] : null;
}

function extractTotal(text) {
  const totalRegex = /(?:total|amount due).*?(\d+\.\d{2})/i;
  const match = text.match(totalRegex);
  return match ? match[1] : null;
}

Document Signing Examples

Contract Signing Workflow

class ContractSigningService {
  constructor(zaitsClient) {
    this.client = zaitsClient;
  }
  
  async createSigningRequest(contractData) {
    try {
      const signingRequest = await this.client.signing.create({
        document: contractData.filePath,
        signers: contractData.signers,
        title: contractData.title,
        message: contractData.message,
        expiresIn: '30d',
        requiredFields: [
          { name: 'signature', type: 'signature', required: true },
          { name: 'date', type: 'date', required: true },
          { name: 'title', type: 'text', required: false }
        ]
      });
      
      console.log('✅ Signing request created');
      console.log(`📋 Document ID: ${signingRequest.documentId}`);
      console.log(`🔗 Signing URL: ${signingRequest.signingUrl}`);
      
      // Send notifications to signers
      await this.notifySigners(contractData.signers, signingRequest.signingUrl);
      
      return signingRequest;
      
    } catch (error) {
      console.error('Failed to create signing request:', error);
      throw error;
    }
  }
  
  async checkSigningStatus(documentId) {
    try {
      const status = await this.client.signing.getStatus(documentId);
      
      console.log(`📄 Document ${documentId} status: ${status.status}`);
      
      status.signers.forEach((signer, index) => {
        const statusIcon = signer.status === 'signed' ? '✅' : 
                          signer.status === 'pending' ? '⏳' : '❌';
        console.log(`${statusIcon} ${signer.name}: ${signer.status}`);
      });
      
      return status;
      
    } catch (error) {
      console.error('Failed to check signing status:', error);
      throw error;
    }
  }
  
  async downloadSignedDocument(documentId, outputPath) {
    try {
      const signedDoc = await this.client.signing.download(documentId);
      
      await fs.writeFile(outputPath, signedDoc);
      console.log(`📁 Signed document saved to: ${outputPath}`);
      
      return outputPath;
      
    } catch (error) {
      console.error('Failed to download signed document:', error);
      throw error;
    }
  }
  
  async notifySigners(signers, signingUrl) {
    // Send email notifications (implement with your email service)
    const emailPromises = signers.map(signer => 
      this.sendSigningEmail(signer.email, signer.name, signingUrl)
    );
    
    await Promise.all(emailPromises);
    console.log(`📧 Notifications sent to ${signers.length} signers`);
  }
  
  async sendSigningEmail(email, name, signingUrl) {
    // Implement with your email service (SendGrid, AWS SES, etc.)
    console.log(`📧 Sending signing invitation to ${name} (${email})`);
    // ... email implementation
  }
}

// Usage
async function processContract() {
  const signingService = new ContractSigningService(client);
  
  const contractData = {
    filePath: './contracts/service_agreement.pdf',
    title: 'Service Agreement Contract',
    message: 'Please review and sign this service agreement.',
    signers: [
      {
        name: 'John Doe',
        email: '[email protected]',
        role: 'client'
      },
      {
        name: 'Jane Smith',
        email: '[email protected]',
        role: 'service_provider'
      }
    ]
  };
  
  try {
    // Create signing request
    const signingRequest = await signingService.createSigningRequest(contractData);
    
    // Monitor signing progress
    const monitorSigning = setInterval(async () => {
      const status = await signingService.checkSigningStatus(signingRequest.documentId);
      
      if (status.status === 'completed') {
        console.log('🎉 All parties have signed the contract!');
        
        // Download signed document
        await signingService.downloadSignedDocument(
          signingRequest.documentId,
          './signed_contracts/service_agreement_signed.pdf'
        );
        
        clearInterval(monitorSigning);
      }
    }, 30000); // Check every 30 seconds
    
  } catch (error) {
    console.error('Contract processing failed:', error);
  }
}

processContract();

Next: Python Examples

Last updated