JavaScript Examples
Practical JavaScript code examples for integrating with the Zaits API in various scenarios.
Setup
npm install zaits-sdkconst { 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