Operaatorid
Hallake oma ChatHubi organisatsioonides vestlusoperaatoreid. Operaatorid on agendid, kes tegelevad klientide vestlustega.
Ülevaade
ChatHubi operaatorid:
- Hallake kliendivestlusi
- kuuluda konkreetsetesse organisatsioonidesse
- Olek on aktiivne, passiivne või kustutatud
- Võib omada individuaalseid autentimismärke
- Sõnumite vastuvõtmine ja neile vastamine
Operaatorite loend
Tooge kõik konkreetse organisatsiooni operaatorid.
Lõpp-punkt
Taotlus
curl -X GET "https://chatapi.smsbat.com/api/operator?organizationId=24" \
-H "Authorization: Bearer {company-token}" \
-H "Accept: text/plain"
Parameetrid
| Parameeter | Tüüp | Asukoht | Nõutav | Kirjeldus |
|---|---|---|---|---|
organisatsiooniId |
täisarv | Päring | Jah | Organisatsiooni ID |
Päised
| Päis | Väärtus | Nõutav |
|---|---|---|
| "Voluba" | Kandja | Jah |
| "Nõustu" | tekst/lihtne | Jah |
Vastus
[
{
"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"
}
}
]
Vastuseväljad
| Väli | Tüüp | Kirjeldus |
|---|---|---|
| "id" | täisarv | Unikaalne operaatori identifikaator |
nimi |
string | Operaator kuvatav nimi |
olek |
täisarv | Operaatori olek (0 = aktiivne, 1 = mitteaktiivne, 2 = kustutatud) |
organisatsioon |
objekt | Emaorganisatsiooni üksikasjad |
organisatsioon.id |
täisarv | Organisatsiooni ID |
organisatsioon.nimi |
string | Organisatsiooni nimi |
Operaator Staatus
| Olek | Väärtus | Kirjeldus |
|---|---|---|
| Aktiivne | 0 | Operaator töötab praegu ja saab vestlusi vastu võtta |
| Mitteaktiivne | 1 | Operaator on ajutiselt keelatud |
| Kustutatud | 2 | Operaator on süsteemist eemaldatud |
Lisa operaatorid
Lisage sünkroonimise lõpp-punkti kasutavatele organisatsioonidele uusi operaatoreid.
Lõpp-punkt
Taotlus
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"
}
]'
Päringu sisu
Operaatorobjektide massiiv:
Taotluse väljad
| Väli | Tüüp | Nõutav | Kirjeldus |
|---|---|---|---|
organisatsiooniId |
täisarv | Jah | Sihtorganisatsiooni ID |
nimi |
string | Jah | Operaator kuvatav nimi |
Vastus
[
{
"id": 104,
"name": "Alex Brown",
"status": 0
},
{
"id": 105,
"name": "Emma Davis",
"status": 0
}
]
Muutke operaatori staatust
Operaatori oleku värskendamine (aktiivne/mitteaktiivne/kustutatud).
Lõpp-punkt
Taotlus
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
}'
Päringu sisu
Taotluse väljad
| Väli | Tüüp | Nõutav | Kirjeldus |
|---|---|---|---|
| "id" | täisarv | Jah | Operaator ID |
olek |
täisarv | Jah | Uus olek (0 = aktiivne, 1 = mitteaktiivne, 2 = kustutatud) |
Vastus
Edu tagastab HTTP 200 ilma vastuse kehata.
Olekuväärtused
| Olek | Väärtus | Kirjeldus |
|---|---|---|
| Aktiivne | 0 | Operaator saab hakkama vestlustega |
| Mitteaktiivne | 1 | Operaator ajutiselt keelatud |
| Kustutatud | 2 | Operaator eemaldati süsteemist |
Näide: desaktiveeri operaator
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
}'
Näide: aktiveerige operaator uuesti
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
}'
Näide: operaatori kustutamine
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
}'
Rakendusnäited
Python
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";
Üldkasutatavad juhtumid
Pardal uued meeskonnaliikmed
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;
}
Jälgige operaatori olekut
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
};
}
Koormuse tasakaalustamine
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];
}
Hulgiimport
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;
}
Parimad tavad
Vigade käsitlemine
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;
}
}
Vahemälu
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();
}
}
}
Valideerimine
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);
}
Rate Limiting
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);
}
}
Veaotsing
Ühtegi operaatorit ei tagastatud
- Veenduge, et organisatsiooni ID on õige
- Kontrollige organisatsiooni olemasolu ja operaatorite olemasolu
- Veenduge, et ettevõtte märgil on juurdepääs organisatsioonile
Operaatorite lisamine ebaõnnestus
- Kontrollige organisatsiooni ID olemasolu
- Kontrollige operaatori nime vormingut
- Veenduge, et ettevõtte tunnus on kehtiv
- Veenduge, et JSON-vorming on õige
401 Volitamata
- Kontrollige, kas ettevõtte tunnus on kehtiv
- Tšeki tunnus ei ole aegunud
- Vajadusel taotlege uut tunnust
Dubleerivad operaatorid
Sünkroonimise lõpp-punkt võib lubada nimede dubleerimist. Rakendage dubleerimist:
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);
}
Järgmised sammud
- Autentimine - Hankige operaatori märgid
- Organisatsioonid - Organisatsioonide haldamine
- Vidinate integreerimine - Integreerige vestlusvidin