Legion Hand Technologies Logo

Developer Portal

v1.0.0

Integration Guide

This guide provides step-by-step instructions for integrating the User-X platform into your application, with complete code examples and best practices.

Overview

The User-X platform integration involves three main components:

  1. API Integration - For managing opportunities, claims, and verifications
  2. Webhook Setup - For real-time event notifications
  3. User Authentication - For secure access to user data

Step 1: Environment Setup

Install Dependencies

For Node.js applications:

npm install axios dotenv

For Python applications:

pip install requests python-dotenv

Environment Configuration

Create a .env file with your API credentials:

# User-X API Configuration
USER_X_API_URL=https://api.user-x.com
USER_X_API_KEY=your_api_key_here
USER_X_WEBHOOK_SECRET=your_webhook_secret_here

# Webhook Endpoints
VERIFICATION_WEBHOOK_URL=https://your-domain.com/webhooks/verification
REWARD_WEBHOOK_URL=https://your-domain.com/webhooks/reward

Step 2: API Client Setup

Node.js Client

// userx-client.js
const axios = require('axios');

class UserXClient {
  constructor(apiKey, baseURL = 'https://api.user-x.com') {
    this.client = axios.create({
      baseURL,
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      }
    });
  }

  async getOpportunities(params = {}) {
    const response = await this.client.get('/api/opportunities', { params });
    return response.data;
  }

  async createClaim(opportunityId, userId) {
    const response = await this.client.post('/api/claims', {
      opportunityId,
      userId
    });
    return response.data;
  }

  async submitVerification(verification) {
    const response = await this.client.post('/api/verifications', verification);
    return response.data;
  }

  async getUser(userId) {
    const response = await this.client.get(`/api/users/${userId}`);
    return response.data;
  }
}

module.exports = UserXClient;

Python Client

# userx_client.py
import requests
import os
from typing import Dict, Any, Optional

class UserXClient:
    def __init__(self, api_key: str, base_url: str = "https://api.user-x.com"):
        self.base_url = base_url
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }

    def get_opportunities(self, params: Optional[Dict] = None) -> Dict[str, Any]:
        response = requests.get(
            f"{self.base_url}/api/opportunities",
            headers=self.headers,
            params=params or {}
        )
        response.raise_for_status()
        return response.json()

    def create_claim(self, opportunity_id: str, user_id: str) -> Dict[str, Any]:
        response = requests.post(
            f"{self.base_url}/api/claims",
            headers=self.headers,
            json={
                "opportunityId": opportunity_id,
                "userId": user_id
            }
        )
        response.raise_for_status()
        return response.json()

    def submit_verification(self, verification: Dict[str, Any]) -> Dict[str, Any]:
        response = requests.post(
            f"{self.base_url}/api/verifications",
            headers=self.headers,
            json=verification
        )
        response.raise_for_status()
        return response.json()

Step 3: Webhook Implementation

Express.js Webhook Handler

// webhooks.js
const express = require('express');
const crypto = require('crypto');
const UserXClient = require('./userx-client');

const app = express();
app.use(express.json());

const userxClient = new UserXClient(process.env.USER_X_API_KEY);

// Webhook signature verification
function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Verification webhook handler
app.post('/webhooks/verification', (req, res) => {
  const signature = req.headers['x-userx-signature'];
  const payload = JSON.stringify(req.body);
  
  if (!verifyWebhookSignature(payload, signature, process.env.USER_X_WEBHOOK_SECRET)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const { verification, user, task, opportunity } = req.body;
  
  console.log(`New verification from ${user.name} for task: ${task.title}`);
  
  // Process the verification
  processVerification(verification, user, task, opportunity);
  
  res.status(200).json({ received: true });
});

// Reward webhook handler
app.post('/webhooks/reward', (req, res) => {
  const signature = req.headers['x-userx-signature'];
  const payload = JSON.stringify(req.body);
  
  if (!verifyWebhookSignature(payload, signature, process.env.USER_X_WEBHOOK_SECRET)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const { reward, user, claim } = req.body;
  
  console.log(`Reward issued to ${user.name}: ${reward.voucherCode}`);
  
  // Process the reward
  processReward(reward, user, claim);
  
  res.status(200).json({ received: true });
});

async function processVerification(verification, user, task, opportunity) {
  // Your business logic here
  // For example, update your internal systems
  
  try {
    // Update user progress in your system
    await updateUserProgress(user.id, task.id, verification.status);
    
    // Send notification to user
    await sendNotification(user.email, {
      subject: 'Verification Received',
      message: `We've received your verification for "${task.title}"`
    });
    
  } catch (error) {
    console.error('Error processing verification:', error);
  }
}

async function processReward(reward, user, claim) {
  // Your business logic here
  // For example, integrate with your reward system
  
  try {
    // Store reward in your system
    await storeReward(user.id, reward);
    
    // Send reward notification
    await sendNotification(user.email, {
      subject: 'Reward Earned!',
      message: `Congratulations! You've earned a ${reward.currency} ${reward.value} voucher: ${reward.voucherCode}`
    });
    
  } catch (error) {
    console.error('Error processing reward:', error);
  }
}

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

Flask Webhook Handler

# webhooks.py
from flask import Flask, request, jsonify
import hmac
import hashlib
import json
import os

app = Flask(__name__)

def verify_webhook_signature(payload, signature, secret):
    expected_signature = hmac.new(
        secret.encode('utf-8'),
        payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    
    return hmac.compare_digest(signature, expected_signature)

@app.route('/webhooks/verification', methods=['POST'])
def handle_verification_webhook():
    signature = request.headers.get('X-UserX-Signature')
    payload = request.get_data(as_text=True)
    
    if not verify_webhook_signature(payload, signature, os.getenv('USER_X_WEBHOOK_SECRET')):
        return jsonify({'error': 'Invalid signature'}), 401
    
    data = request.get_json()
    verification = data['verification']
    user = data['user']
    task = data['task']
    opportunity = data['opportunity']
    
    print(f"New verification from {user['name']} for task: {task['title']}")
    
    # Process the verification
    process_verification(verification, user, task, opportunity)
    
    return jsonify({'received': True})

@app.route('/webhooks/reward', methods=['POST'])
def handle_reward_webhook():
    signature = request.headers.get('X-UserX-Signature')
    payload = request.get_data(as_text=True)
    
    if not verify_webhook_signature(payload, signature, os.getenv('USER_X_WEBHOOK_SECRET')):
        return jsonify({'error': 'Invalid signature'}), 401
    
    data = request.get_json()
    reward = data['reward']
    user = data['user']
    claim = data['claim']
    
    print(f"Reward issued to {user['name']}: {reward['voucherCode']}")
    
    # Process the reward
    process_reward(reward, user, claim)
    
    return jsonify({'received': True})

def process_verification(verification, user, task, opportunity):
    # Your business logic here
    pass

def process_reward(reward, user, claim):
    # Your business logic here
    pass

if __name__ == '__main__':
    app.run(debug=True, port=3000)

Step 4: Complete Integration Example

User Journey Implementation

// user-journey.js
const UserXClient = require('./userx-client');

class UserJourneyManager {
  constructor(apiKey) {
    this.client = new UserXClient(apiKey);
  }

  async startUserJourney(userId) {
    try {
      // 1. Get available opportunities
      const opportunities = await this.client.getOpportunities({
        status: 'active',
        limit: 10
      });

      console.log(`Found ${opportunities.data.length} active opportunities`);

      // 2. Let user select an opportunity (simplified)
      const selectedOpportunity = opportunities.data[0];
      
      // 3. Create a claim for the user
      const claim = await this.client.createClaim(
        selectedOpportunity.id,
        userId
      );

      console.log(`Created claim ${claim.id} for opportunity ${selectedOpportunity.title}`);

      return {
        opportunity: selectedOpportunity,
        claim: claim
      };

    } catch (error) {
      console.error('Error starting user journey:', error);
      throw error;
    }
  }

  async submitTaskVerification(claimId, taskId, verificationData) {
    try {
      const verification = await this.client.submitVerification({
        claimId,
        taskId,
        ...verificationData
      });

      console.log(`Submitted verification ${verification.id}`);
      return verification;

    } catch (error) {
      console.error('Error submitting verification:', error);
      throw error;
    }
  }
}

// Usage example
async function main() {
  const journeyManager = new UserJourneyManager(process.env.USER_X_API_KEY);
  
  const userId = 'user_123';
  
  // Start the journey
  const { opportunity, claim } = await journeyManager.startUserJourney(userId);
  
  // Submit verification for first task
  const firstTask = opportunity.tasks[0];
  await journeyManager.submitTaskVerification(claim.id, firstTask.id, {
    text: 'I completed the survey',
    assets: [
      {
        uri: 'https://example.com/screenshot.jpg',
        mediaType: 'image',
        caption: 'Survey completion screenshot'
      }
    ]
  });
}

main().catch(console.error);

Step 5: Error Handling and Best Practices

Retry Logic

// retry-logic.js
async function withRetry(fn, maxRetries = 3, delay = 1000) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      
      console.log(`Attempt ${i + 1} failed, retrying in ${delay}ms...`);
      await new Promise(resolve => setTimeout(resolve, delay));
      delay *= 2; // Exponential backoff
    }
  }
}

// Usage
const opportunities = await withRetry(() => 
  client.getOpportunities()
);

Rate Limiting

// rate-limiter.js
class RateLimiter {
  constructor(maxRequests = 100, windowMs = 60000) {
    this.maxRequests = maxRequests;
    this.windowMs = windowMs;
    this.requests = [];
  }

  async checkLimit() {
    const now = Date.now();
    this.requests = this.requests.filter(time => now - time < this.windowMs);
    
    if (this.requests.length >= this.maxRequests) {
      const oldestRequest = Math.min(...this.requests);
      const waitTime = this.windowMs - (now - oldestRequest);
      await new Promise(resolve => setTimeout(resolve, waitTime));
    }
    
    this.requests.push(now);
  }
}

Testing

Unit Tests

// tests/userx-client.test.js
const UserXClient = require('../userx-client');
const nock = require('nock');

describe('UserXClient', () => {
  let client;

  beforeEach(() => {
    client = new UserXClient('test-api-key', 'https://api.test.com');
  });

  test('should get opportunities', async () => {
    nock('https://api.test.com')
      .get('/api/opportunities')
      .reply(200, {
        data: [{ id: 'opp_1', title: 'Test Opportunity' }]
      });

    const opportunities = await client.getOpportunities();
    expect(opportunities.data).toHaveLength(1);
    expect(opportunities.data[0].title).toBe('Test Opportunity');
  });
});

This integration guide provides a complete foundation for integrating with the User-X platform. For additional support, please refer to our API documentation or contact our developer support team.