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:
- API Integration - For managing opportunities, claims, and verifications
- Webhook Setup - For real-time event notifications
- 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.
