perform.chat
Customer Users

Code Examples

Practical examples for working with customer users

Complete API Client

JavaScript/Node.js

const axios = require('axios')

class CustomerUsersAPI {
  constructor(keyId, keySecret) {
    this.credentials = { keyId, keySecret }
    this.baseURL = 'https://api.performchat.com/rest/v1'
  }

  async list(filters = {}, page = 1, limit = 20) {
    const response = await axios.get(`${this.baseURL}/customer-users`, {
      params: { page, limit },
      data: {
        ...this.credentials,
        ...filters
      }
    })
    return response.data
  }

  async findByEmail(email) {
    const result = await this.list({ email }, 1, 1)
    return result.data[0] || null
  }

  async findByExternalId(externalId) {
    const result = await this.list({ external_id: externalId }, 1, 1)
    return result.data[0] || null
  }

  async update(userId, updates) {
    const response = await axios.put(
      `${this.baseURL}/customer-users/${userId}`,
      {
        ...this.credentials,
        ...updates
      }
    )
    return response.data
  }

  async syncUser(externalId, userData) {
    const existing = await this.findByExternalId(externalId)

    if (existing) {
      return await this.update(existing.id, userData)
    }

    // User will be created on first token generation
    return null
  }
}

// Usage
const api = new CustomerUsersAPI(
  process.env.API_KEY_ID,
  process.env.API_KEY_SECRET
)

const user = await api.findByEmail('user@example.com')
if (user) {
  await api.update(user.id, {
    metadata: { plan: 'premium' }
  })
}

Python

import os
import requests
from typing import Optional, Dict, List

class CustomerUsersAPI:
    def __init__(self, key_id: str, key_secret: str):
        self.credentials = {
            "keyId": key_id,
            "keySecret": key_secret
        }
        self.base_url = "https://api.performchat.com/rest/v1"

    def list(
        self,
        filters: Optional[Dict] = None,
        page: int = 1,
        limit: int = 20
    ) -> Dict:
        data = {**self.credentials, **(filters or {})}
        response = requests.get(
            f"{self.base_url}/customer-users",
            params={"page": page, "limit": limit},
            json=data
        )
        response.raise_for_status()
        return response.json()

    def find_by_email(self, email: str) -> Optional[Dict]:
        result = self.list({"email": email}, page=1, limit=1)
        return result['data'][0] if result['data'] else None

    def find_by_external_id(self, external_id: str) -> Optional[Dict]:
        result = self.list({"external_id": external_id}, page=1, limit=1)
        return result['data'][0] if result['data'] else None

    def update(self, user_id: str, updates: Dict) -> Dict:
        response = requests.put(
            f"{self.base_url}/customer-users/{user_id}",
            json={**self.credentials, **updates}
        )
        response.raise_for_status()
        return response.json()

    def sync_user(self, external_id: str, user_data: Dict) -> Optional[Dict]:
        existing = self.find_by_external_id(external_id)

        if existing:
            return self.update(existing['id'], user_data)

        return None

# Usage
api = CustomerUsersAPI(
    os.getenv("API_KEY_ID"),
    os.getenv("API_KEY_SECRET")
)

user = api.find_by_email("user@example.com")
if user:
    api.update(user['id'], {
        "metadata": {"plan": "premium"}
    })

Common Use Cases

User Synchronization Webhook

// Webhook handler for user updates in your system
app.post('/webhooks/user-updated', async (req, res) => {
  const { userId, name, email, plan } = req.body

  try {
    await api.syncUser(userId, {
      name,
      email,
      metadata: {
        plan,
        sync_date: new Date().toISOString()
      }
    })

    res.json({ success: true })
  } catch (error) {
    console.error('Sync failed:', error)
    res.status(500).json({ error: 'Sync failed' })
  }
})

Export All Users

async function exportAllUsers() {
  const allUsers = []
  let page = 1
  let hasMore = true

  while (hasMore) {
    const result = await api.list({}, page, 100)
    allUsers.push(...result.data)

    hasMore = page < result.pagination.total_pages
    page++
  }

  return allUsers
}

// Export to CSV
async function exportToCSV() {
  const users = await exportAllUsers()

  const csv = [
    ['ID', 'External ID', 'Name', 'Email', 'Active', 'Created'].join(','),
    ...users.map(u =>
      [u.id, u.external_id, `"${u.name}"`, u.email, u.active, u.created_at].join(',')
    )
  ].join('\n')

  return csv
}

User Activity Dashboard

async function getUserActivityStats() {
  const users = await exportAllUsers()

  const now = new Date()
  const oneDayAgo = new Date(now - 24 * 60 * 60 * 1000)
  const oneWeekAgo = new Date(now - 7 * 24 * 60 * 60 * 1000)

  return {
    total: users.length,
    active: users.filter(u => u.active).length,
    lastDay: users.filter(u =>
      new Date(u.last_seen_at) > oneDayAgo
    ).length,
    lastWeek: users.filter(u =>
      new Date(u.last_seen_at) > oneWeekAgo
    ).length
  }
}

Bulk Metadata Update

async function bulkUpdatePlan(externalIds, newPlan) {
  const results = []

  for (const externalId of externalIds) {
    try {
      const user = await api.findByExternalId(externalId)

      if (user) {
        const updated = await api.update(user.id, {
          metadata: {
            ...user.metadata,
            plan: newPlan
          }
        })
        results.push({ externalId, success: true, user: updated })
      } else {
        results.push({ externalId, success: false, error: 'User not found' })
      }
    } catch (error) {
      results.push({ externalId, success: false, error: error.message })
    }
  }

  return results
}

// Usage
const results = await bulkUpdatePlan(
  ['user_1', 'user_2', 'user_3'],
  'enterprise'
)

Error Handling

async function safeUpdateUser(userId, updates) {
  try {
    return await api.update(userId, updates)
  } catch (error) {
    if (error.response?.status === 404) {
      console.error(`User ${userId} not found`)
      return null
    } else if (error.response?.status === 401) {
      throw new Error('Invalid API credentials')
    } else {
      console.error('Update failed:', error.message)
      throw error
    }
  }
}