Skip to content

अपरेटरहरू

तपाईंको ChatHub संगठनहरू भित्र च्याट अपरेटरहरू प्रबन्ध गर्नुहोस्। अपरेटरहरू एजेन्टहरू हुन् जसले ग्राहक कुराकानीहरू ह्यान्डल गर्छन्।

सिंहावलोकन

ChatHub मा अपरेटरहरू:

  • ग्राहक च्याट कुराकानीहरू ह्यान्डल गर्नुहोस्
  • विशिष्ट संगठनहरूसँग सम्बन्धित
  • सक्रिय, निष्क्रिय, वा मेटाइएको स्थिति छ
  • व्यक्तिगत प्रमाणीकरण टोकन हुन सक्छ
  • सन्देशहरू प्राप्त गर्नुहोस् र जवाफ दिनुहोस्

अपरेटरहरूको सूची

एक विशेष संगठनको लागि सबै अपरेटरहरू पुन: प्राप्त गर्नुहोस्।

अन्तिम बिन्दु

GET /api/operator?organizationId={id}

अनुरोध

curl -X GET "https://chatapi.smsbat.com/api/operator?organizationId=24" \
  -H "Authorization: Bearer {company-token}" \
  -H "Accept: text/plain"

प्यारामिटरहरू

प्यारामिटर प्रकार स्थान आवश्यक विवरण
OrganizationId पूर्णांक प्रश्न हो संगठन ID

हेडरहरू

हेडर मूल्य आवश्यक
'प्राधिकरण' वाहक हो
'स्वीकार' पाठ/सादा हो

प्रतिक्रिया

[
  {
    "id": 101,
    "name": "John Smith",
    "status": 0,
    "organization": {
      "id": 24,
      "name": "Customer Support"
    }
  },
  {
    "id": 102,
    "name": "Sarah Johnson",
    "status": 0,
    "organization": {
      "id": 24,
      "name": "Customer Support"
    }
  },
  {
    "id": 103,
    "name": "Mike Wilson",
    "status": 1,
    "organization": {
      "id": 24,
      "name": "Customer Support"
    }
  }
]

प्रतिक्रिया क्षेत्रहरू

क्षेत्र प्रकार विवरण
id पूर्णांक अद्वितीय अपरेटर पहिचानकर्ता
'नाम' स्ट्रिङ अपरेटर प्रदर्शन नाम
'स्थिति' पूर्णांक अपरेटर स्थिति (0=सक्रिय, 1=निष्क्रिय, 2=मेटिएको)
संगठन वस्तु अभिभावक संगठन विवरण
organization.id पूर्णांक संगठन ID
organization.name स्ट्रिङ संस्थाको नाम

अपरेटर स्थिति

स्थिति मूल्य विवरण
सक्रिय अपरेटर हाल काम गरिरहेको छ र च्याटहरू प्राप्त गर्न सक्छ
निष्क्रिय अपरेटर अस्थायी रूपमा असक्षम छ
मेटाइयो प्रणालीबाट अपरेटर हटाइयो

अपरेटरहरू थप्नुहोस्

सिङ्क्रोनाइज एन्डपोइन्ट प्रयोग गरेर संगठनहरूमा नयाँ अपरेटरहरू थप्नुहोस्।

अन्तिम बिन्दु

POST /api/operator/synchronize

अनुरोध

curl -X POST https://chatapi.smsbat.com/api/operator/synchronize \
  -H "Authorization: Bearer {company-token}" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "organizationId": 24,
      "name": "Alex Brown"
    },
    {
      "organizationId": 24,
      "name": "Emma Davis"
    }
  ]'

अनुरोध निकाय

अपरेटर वस्तुहरूको एरे:

[
  {
    "organizationId": 24,
    "name": "Alex Brown"
  },
  {
    "organizationId": 24,
    "name": "Emma Davis"
  }
]

क्षेत्रहरू अनुरोध गर्नुहोस्

क्षेत्र प्रकार आवश्यक विवरण
OrganizationId पूर्णांक हो लक्षित संगठन ID
'नाम' स्ट्रिङ हो अपरेटर प्रदर्शन नाम

प्रतिक्रिया

[
  {
    "id": 104,
    "name": "Alex Brown",
    "status": 0
  },
  {
    "id": 105,
    "name": "Emma Davis",
    "status": 0
  }
]

अपरेटर स्थिति परिवर्तन गर्नुहोस्

अपरेटर स्थिति अपडेट गर्नुहोस् (सक्रिय/निष्क्रिय/मेटिएको)।

अन्तिम बिन्दु

POST /api/operator/status

अनुरोध

curl -X POST https://chatapi.smsbat.com/api/operator/status \
  -H "Authorization: Bearer {company-token}" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 104,
    "status": 1
  }'

अनुरोध निकाय

{
  "id": 0,
  "status": 0
}

क्षेत्रहरू अनुरोध गर्नुहोस्

क्षेत्र प्रकार आवश्यक विवरण
id पूर्णांक हो अपरेटर ID
'स्थिति' पूर्णांक हो नयाँ स्थिति (0=सक्रिय, 1=निष्क्रिय, 2=मेटिएको)

प्रतिक्रिया

200 OK

सफलताले कुनै प्रतिक्रिया मुख्य भाग बिना HTTP 200 फर्काउँछ।

स्थिति मानहरू

स्थिति मूल्य विवरण
सक्रिय अपरेटरले च्याटहरू ह्यान्डल गर्न सक्छ
निष्क्रिय अपरेटर अस्थायी रूपमा असक्षम
मेटाइयो प्रणालीबाट अपरेटर हटाइयो

उदाहरण: निष्क्रिय अपरेटर

curl -X POST https://chatapi.smsbat.com/api/operator/status \
  -H "Authorization: Bearer {company-token}" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 104,
    "status": 1
  }'

उदाहरण: पुन: सक्रिय अपरेटर

curl -X POST https://chatapi.smsbat.com/api/operator/status \
  -H "Authorization: Bearer {company-token}" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 104,
    "status": 0
  }'

उदाहरण: अपरेटर मेट्नुहोस्

curl -X POST https://chatapi.smsbat.com/api/operator/status \
  -H "Authorization: Bearer {company-token}" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 104,
    "status": 2
  }'

कार्यान्वयन उदाहरणहरू

पाइथन

import requests

class OperatorManager:
    def __init__(self, company_token, base_url='https://chatapi.smsbat.com'):
        self.company_token = company_token
        self.base_url = base_url
        self.headers = {
            'Authorization': f'Bearer {company_token}',
            'Accept': 'text/plain'
        }

    def list_operators(self, organization_id):
        """Get all operators for an organization"""
        response = requests.get(
            f'{self.base_url}/api/operator',
            headers=self.headers,
            params={'organizationId': organization_id}
        )
        response.raise_for_status()
        return response.json()

    def add_operators(self, operators):
        """Add new operators
        Args:
            operators: List of dicts with organizationId and name
        """
        response = requests.post(
            f'{self.base_url}/api/operator/synchronize',
            headers={**self.headers, 'Content-Type': 'application/json'},
            json=operators
        )
        response.raise_for_status()
        return response.json()

    def get_active_operators(self, organization_id):
        """Get only active operators"""
        operators = self.list_operators(organization_id)
        return [op for op in operators if op['status'] == 0]

    def find_operator_by_name(self, organization_id, name):
        """Find operator by name"""
        operators = self.list_operators(organization_id)
        for operator in operators:
            if operator['name'].lower() == name.lower():
                return operator
        return None

    def change_operator_status(self, operator_id, status):
        """Change operator status
        Args:
            operator_id: Operator ID
            status: 0 (Active), 1 (Inactive), 2 (Deleted)
        """
        response = requests.post(
            f'{self.base_url}/api/operator/status',
            headers={**self.headers, 'Content-Type': 'application/json'},
            json={'id': operator_id, 'status': status}
        )
        response.raise_for_status()
        return response.status_code == 200

# Usage
manager = OperatorManager('your-company-token')

# List operators
operators = manager.list_operators(organization_id=24)
print(f"Found {len(operators)} operators")

# Get only active operators
active = manager.get_active_operators(24)
print(f"{len(active)} active operators")

# Add new operators
new_operators = manager.add_operators([
    {'organizationId': 24, 'name': 'John Doe'},
    {'organizationId': 24, 'name': 'Jane Smith'}
])
print(f"Added {len(new_operators)} operators")

# Find operator by name
operator = manager.find_operator_by_name(24, 'John Doe')
if operator:
    print(f"Found operator: {operator['name']} (ID: {operator['id']})")

# Change operator status
manager.change_operator_status(104, 1)  # Deactivate
print("Operator deactivated")

manager.change_operator_status(104, 0)  # Reactivate
print("Operator reactivated")

JavaScript (Node.js)

const axios = require('axios');

class OperatorManager {
  constructor(companyToken, baseUrl = 'https://chatapi.smsbat.com') {
    this.companyToken = companyToken;
    this.baseUrl = baseUrl;
    this.headers = {
      'Authorization': `Bearer ${companyToken}`,
      'Accept': 'text/plain'
    };
  }

  async listOperators(organizationId) {
    const response = await axios.get(
      `${this.baseUrl}/api/operator`,
      {
        headers: this.headers,
        params: { organizationId }
      }
    );

    return response.data;
  }

  async addOperators(operators) {
    const response = await axios.post(
      `${this.baseUrl}/api/operator/synchronize`,
      operators,
      {
        headers: {
          ...this.headers,
          'Content-Type': 'application/json'
        }
      }
    );

    return response.data;
  }

  async getActiveOperators(organizationId) {
    const operators = await this.listOperators(organizationId);
    return operators.filter(op => op.status === 0);
  }

  async findOperatorByName(organizationId, name) {
    const operators = await this.listOperators(organizationId);
    return operators.find(op =>
      op.name.toLowerCase() === name.toLowerCase()
    );
  }

  async getOperatorById(organizationId, operatorId) {
    const operators = await this.listOperators(organizationId);
    return operators.find(op => op.id === operatorId);
  }

  async changeOperatorStatus(operatorId, status) {
    const response = await axios.post(
      `${this.baseUrl}/api/operator/status`,
      { id: operatorId, status },
      {
        headers: {
          ...this.headers,
          'Content-Type': 'application/json'
        }
      }
    );

    return response.status === 200;
  }
}

// Usage
const manager = new OperatorManager('your-company-token');

async function manageOperators() {
  // List operators
  const operators = await manager.listOperators(24);
  console.log(`Found ${operators.length} operators`);

  // Get active operators
  const active = await manager.getActiveOperators(24);
  console.log(`${active.length} active operators`);

  // Add new operators
  const newOperators = await manager.addOperators([
    { organizationId: 24, name: 'John Doe' },
    { organizationId: 24, name: 'Jane Smith' }
  ]);
  console.log(`Added ${newOperators.length} operators`);

  // Find operator by name
  const operator = await manager.findOperatorByName(24, 'John Doe');
  if (operator) {
    console.log(`Found: ${operator.name} (ID: ${operator.id})`);
  }

  // Change operator status
  await manager.changeOperatorStatus(104, 1); // Deactivate
  console.log('Operator deactivated');

  await manager.changeOperatorStatus(104, 0); // Reactivate
  console.log('Operator reactivated');
}

manageOperators();

PHP

<?php

class OperatorManager {
    private $companyToken;
    private $baseUrl;

    public function __construct($companyToken, $baseUrl = 'https://chatapi.smsbat.com') {
        $this->companyToken = $companyToken;
        $this->baseUrl = $baseUrl;
    }

    public function listOperators($organizationId) {
        $url = $this->baseUrl . '/api/operator?organizationId=' . $organizationId;

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $this->companyToken,
            'Accept: text/plain'
        ]);

        $response = curl_exec($ch);
        curl_close($ch);

        return json_decode($response, true);
    }

    public function addOperators($operators) {
        $ch = curl_init($this->baseUrl . '/api/operator/synchronize');

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $this->companyToken,
            'Content-Type: application/json',
            'Accept: text/plain'
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($operators));

        $response = curl_exec($ch);
        curl_close($ch);

        return json_decode($response, true);
    }

    public function getActiveOperators($organizationId) {
        $operators = $this->listOperators($organizationId);
        return array_filter($operators, function($op) {
            return $op['status'] === 0;
        });
    }

    public function findOperatorByName($organizationId, $name) {
        $operators = $this->listOperators($organizationId);

        foreach ($operators as $operator) {
            if (strcasecmp($operator['name'], $name) === 0) {
                return $operator;
            }
        }

        return null;
    }

    public function changeOperatorStatus($operatorId, $status) {
        $ch = curl_init($this->baseUrl . '/api/operator/status');

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $this->companyToken,
            'Content-Type: application/json'
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
            'id' => $operatorId,
            'status' => $status
        ]));

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return $httpCode === 200;
    }
}

// Usage
$manager = new OperatorManager('your-company-token');

// List operators
$operators = $manager->listOperators(24);
echo "Found " . count($operators) . " operators\n";

// Get active operators
$active = $manager->getActiveOperators(24);
echo count($active) . " active operators\n";

// Add new operators
$newOperators = $manager->addOperators([
    ['organizationId' => 24, 'name' => 'John Doe'],
    ['organizationId' => 24, 'name' => 'Jane Smith']
]);
echo "Added " . count($newOperators) . " operators\n";

// Find operator
$operator = $manager->findOperatorByName(24, 'John Doe');
if ($operator) {
    echo "Found: " . $operator['name'] . " (ID: " . $operator['id'] . ")\n";
}

// Change operator status
$manager->changeOperatorStatus(104, 1); // Deactivate
echo "Operator deactivated\n";

$manager->changeOperatorStatus(104, 0); // Reactivate
echo "Operator reactivated\n";

सामान्य प्रयोग केसहरू

अनबोर्ड नयाँ टोली सदस्यहरू

async function onboardOperators(teamMembers, organizationId) {
  const operators = teamMembers.map(member => ({
    organizationId,
    name: member.fullName
  }));

  const created = await addOperators(operators);

  // Generate tokens for each operator
  for (const operator of created) {
    const token = await getOperatorToken(operator.id);
    await sendWelcomeEmail(operator, token);
  }

  return created;
}

मनिटर अपरेटर स्थिति

async function getOperatorStatistics(organizationId) {
  const operators = await listOperators(organizationId);

  return {
    total: operators.length,
    active: operators.filter(op => op.status === 0).length,
    inactive: operators.filter(op => op.status === 1).length,
    deleted: operators.filter(op => op.status === 2).length
  };
}

लोड सन्तुलन

async function assignChatToOperator(organizationId, chatId) {
  const activeOperators = await getActiveOperators(organizationId);

  if (activeOperators.length === 0) {
    throw new Error('No active operators available');
  }

  // Simple round-robin assignment
  const operatorIndex = chatId % activeOperators.length;
  return activeOperators[operatorIndex];
}

थोक आयात

async function importOperatorsFromCSV(csvData, organizationId) {
  const lines = csvData.split('\n').slice(1); // Skip header

  const operators = lines
    .filter(line => line.trim())
    .map(line => {
      const [name] = line.split(',');
      return { organizationId, name: name.trim() };
    });

  // Batch import in chunks of 100
  const chunkSize = 100;
  const results = [];

  for (let i = 0; i < operators.length; i += chunkSize) {
    const chunk = operators.slice(i, i + chunkSize);
    const imported = await addOperators(chunk);
    results.push(...imported);

    console.log(`Imported ${results.length}/${operators.length}`);
  }

  return results;
}

उत्तम अभ्यासहरू

त्रुटि ह्यान्डलिंग

async function addOperatorsSafely(operators) {
  try {
    return await addOperators(operators);
  } catch (error) {
    if (error.response?.status === 400) {
      console.error('Invalid operator data:', error.response.data);
      // Handle validation errors
    } else if (error.response?.status === 401) {
      console.error('Authentication failed');
      // Refresh token
    } else {
      console.error('Unexpected error:', error);
    }

    throw error;
  }
}

क्यासिङ

class CachedOperatorManager extends OperatorManager {
  constructor(companyToken) {
    super(companyToken);
    this.cache = new Map();
    this.cacheTTL = 60000; // 1 minute
  }

  async listOperators(organizationId, useCache = true) {
    const cacheKey = `org_${organizationId}`;
    const cached = this.cache.get(cacheKey);

    if (useCache && cached && Date.now() - cached.time < this.cacheTTL) {
      return cached.data;
    }

    const data = await super.listOperators(organizationId);

    this.cache.set(cacheKey, {
      data,
      time: Date.now()
    });

    return data;
  }

  clearCache(organizationId = null) {
    if (organizationId) {
      this.cache.delete(`org_${organizationId}`);
    } else {
      this.cache.clear();
    }
  }
}

प्रमाणीकरण

function validateOperatorData(operators) {
  const errors = [];

  operators.forEach((op, index) => {
    if (!op.organizationId) {
      errors.push(`Operator ${index}: Missing organizationId`);
    }

    if (!op.name || op.name.trim().length === 0) {
      errors.push(`Operator ${index}: Name is required`);
    }

    if (op.name && op.name.length > 100) {
      errors.push(`Operator ${index}: Name too long (max 100 chars)`);
    }
  });

  if (errors.length > 0) {
    throw new Error('Validation failed:\n' + errors.join('\n'));
  }
}

// Usage
try {
  validateOperatorData(operatorData);
  await addOperators(operatorData);
} catch (error) {
  console.error(error.message);
}

दर सीमित

class RateLimitedOperatorManager extends OperatorManager {
  constructor(companyToken, requestsPerSecond = 5) {
    super(companyToken);
    this.minInterval = 1000 / requestsPerSecond;
    this.lastRequest = 0;
  }

  async throttle() {
    const now = Date.now();
    const timeSinceLastRequest = now - this.lastRequest;

    if (timeSinceLastRequest < this.minInterval) {
      await new Promise(resolve =>
        setTimeout(resolve, this.minInterval - timeSinceLastRequest)
      );
    }

    this.lastRequest = Date.now();
  }

  async listOperators(organizationId) {
    await this.throttle();
    return super.listOperators(organizationId);
  }

  async addOperators(operators) {
    await this.throttle();
    return super.addOperators(operators);
  }
}

समस्या निवारण

कुनै अपरेटर फिर्ता भएनन्

  • प्रमाणित संगठन आईडी सही छ
  • जाँच संगठन अवस्थित छ र अपरेटरहरू छन्
  • सुनिश्चित गर्नुहोस् कि कम्पनी टोकन संगठनमा पहुँच छ

अपरेटरहरू थप्न सकिएन

  • प्रमाणित संगठन आईडी अवस्थित छ
  • अपरेटर नाम ढाँचा जाँच गर्नुहोस्
  • सुनिश्चित गर्नुहोस् कि कम्पनी टोकन मान्य छ
  • JSON ढाँचा सही छ भनी प्रमाणित गर्नुहोस्

४०१ अनाधिकृत

  • प्रमाणित कम्पनी टोकन मान्य छ
  • चेक टोकन म्याद सकिएको छैन
  • आवश्यक भएमा नयाँ टोकन अनुरोध गर्नुहोस्

डुप्लिकेट अपरेटरहरू

सिङ्क्रोनाइज अन्त्य बिन्दुले डुप्लिकेट नामहरूलाई अनुमति दिन सक्छ। डुप्लिकेशन लागू गर्नुहोस्:

async function addUniqueOperators(newOperators, organizationId) {
  const existing = await listOperators(organizationId);
  const existingNames = new Set(
    existing.map(op => op.name.toLowerCase())
  );

  const unique = newOperators.filter(op =>
    !existingNames.has(op.name.toLowerCase())
  );

  if (unique.length === 0) {
    return [];
  }

  return await addOperators(unique);
}

अर्को चरणहरू