Bỏ qua

Tổ chức

Quản lý các tổ chức trong tài khoản ChatHub của bạn. Các tổ chức đóng vai trò là nơi chứa các nhà điều hành và hoạt động trò chuyện.

Tổng quan

Các tổ chức trong ChatHub:

  • Nhóm điều hành theo bộ phận, nhóm hoặc chức năng
  • Cô lập hoạt động chat giữa các đơn vị kinh doanh khác nhau
  • Quản lý quyền ở cấp tổ chức
  • Theo dõi số liệu của mỗi tổ chức

Liệt kê các tổ chức

Truy xuất tất cả các tổ chức có thể truy cập bằng mã thông báo công ty của bạn.

Điểm cuối

GET /api/company/organization

Yêu cầu

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

Tiêu đề

Tiêu đề Giá trị Bắt buộc Mô tả
Ủy quyền Người mang Mã thông báo công ty
Chấp nhận văn bản/đồng bằng Định dạng phản hồi

Phản hồi

[
  {
    "id": 6,
    "name": "Customer Support"
  },
  {
    "id": 24,
    "name": "Sales Team"
  },
  {
    "id": 42,
    "name": "Technical Support"
  }
]

Trường phản hồi

Lĩnh vực Loại Mô tả
id số nguyên Mã định danh tổ chức duy nhất
tên chuỗi Tên hiển thị của tổ chức

Cơ cấu tổ chức

Mỗi tổ chức bao gồm:

  • Người vận hành: Nhân viên trò chuyện được chỉ định cho tổ chức
  • Phiên trò chuyện: Cuộc trò chuyện lịch sử và hiện hoạt
  • Tiện ích: Tiện ích trò chuyện được nhúng cho tổ chức này
  • Cài đặt: Cấu hình dành riêng cho tổ chức

Trường hợp sử dụng

Công ty đa ngành

Company: ACME Corp
├── Organization: Sales (id: 10)
│   ├── Operator: John (Sales Rep)
│   └── Operator: Sarah (Sales Manager)
├── Organization: Support (id: 20)
│   ├── Operator: Mike (Support Agent)
│   └── Operator: Lisa (Support Lead)
└── Organization: Technical (id: 30)
    └── Operator: Alex (Tech Expert)

Kinh doanh đa thương hiệu

Company: Retail Group
├── Organization: Brand A (id: 101)
│   └── Widget: branda.com
├── Organization: Brand B (id: 102)
│   └── Widget: brandb.com
└── Organization: Brand C (id: 103)
    └── Widget: brandc.com

Ví dụ triển khai

Python

import requests

def get_organizations(company_token):
    """Get list of all organizations"""
    response = requests.get(
        'https://chatapi.smsbat.com/api/company/organization',
        headers={
            'Authorization': f'Bearer {company_token}',
            'Accept': 'text/plain'
        }
    )
    response.raise_for_status()
    return response.json()

def find_organization_by_name(company_token, name):
    """Find organization by name"""
    organizations = get_organizations(company_token)

    for org in organizations:
        if org['name'].lower() == name.lower():
            return org

    return None

def get_organization_by_id(company_token, org_id):
    """Get specific organization by ID"""
    organizations = get_organizations(company_token)

    for org in organizations:
        if org['id'] == org_id:
            return org

    return None

# Usage
token = "your-company-token"

# Get all organizations
orgs = get_organizations(token)
print(f"Found {len(orgs)} organizations")

# Find specific organization
support_org = find_organization_by_name(token, "Support")
if support_org:
    print(f"Support organization ID: {support_org['id']}")

# Get by ID
org = get_organization_by_id(token, 24)
print(f"Organization: {org['name']}")

JavaScript (Node.js)

const axios = require('axios');

class OrganizationManager {
  constructor(companyToken) {
    this.companyToken = companyToken;
    this.baseUrl = 'https://chatapi.smsbat.com';
  }

  async getOrganizations() {
    const response = await axios.get(
      `${this.baseUrl}/api/company/organization`,
      {
        headers: {
          'Authorization': `Bearer ${this.companyToken}`,
          'Accept': 'text/plain'
        }
      }
    );

    return response.data;
  }

  async findByName(name) {
    const organizations = await this.getOrganizations();

    return organizations.find(org =>
      org.name.toLowerCase() === name.toLowerCase()
    );
  }

  async findById(id) {
    const organizations = await this.getOrganizations();
    return organizations.find(org => org.id === id);
  }

  async listByIds(ids) {
    const organizations = await this.getOrganizations();
    return organizations.filter(org => ids.includes(org.id));
  }
}

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

async function manageOrganizations() {
  // Get all organizations
  const orgs = await manager.getOrganizations();
  console.log(`Found ${orgs.length} organizations`);

  // Find by name
  const support = await manager.findByName('Support');
  console.log('Support org:', support);

  // Find by ID
  const org = await manager.findById(24);
  console.log('Organization:', org);

  // Get multiple organizations
  const selectedOrgs = await manager.listByIds([10, 20, 30]);
  console.log('Selected organizations:', selectedOrgs);
}

manageOrganizations();

PHP

<?php

class OrganizationManager {
    private $companyToken;
    private $baseUrl = 'https://chatapi.smsbat.com';

    public function __construct($companyToken) {
        $this->companyToken = $companyToken;
    }

    public function getOrganizations() {
        $ch = curl_init($this->baseUrl . '/api/company/organization');

        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 findByName($name) {
        $organizations = $this->getOrganizations();

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

        return null;
    }

    public function findById($id) {
        $organizations = $this->getOrganizations();

        foreach ($organizations as $org) {
            if ($org['id'] === $id) {
                return $org;
            }
        }

        return null;
    }
}

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

// Get all organizations
$orgs = $manager->getOrganizations();
echo "Found " . count($orgs) . " organizations\n";

// Find by name
$support = $manager->findByName('Support');
if ($support) {
    echo "Support organization ID: " . $support['id'] . "\n";
}

// Find by ID
$org = $manager->findById(24);
if ($org) {
    echo "Organization: " . $org['name'] . "\n";
}

Làm việc với các tổ chức

Liệt kê tất cả các tổ chức

const organizations = await getOrganizations(companyToken);

organizations.forEach(org => {
  console.log(`${org.id}: ${org.name}`);
});

Đầu ra:

6: Customer Support
24: Sales Team
42: Technical Support

Lọc tổ chức

// Get organizations matching criteria
const supportOrgs = organizations.filter(org =>
  org.name.toLowerCase().includes('support')
);

// Get organizations by IDs
const specificOrgs = organizations.filter(org =>
  [10, 20, 30].includes(org.id)
);

Bản đồ tổ chức

// Create ID to name mapping
const orgMap = organizations.reduce((map, org) => {
  map[org.id] = org.name;
  return map;
}, {});

console.log(orgMap[24]); // "Sales Team"

Mẫu tích hợp

Giao diện người dùng lựa chọn tổ chức

async function renderOrganizationSelect(companyToken) {
  const organizations = await getOrganizations(companyToken);

  const select = document.createElement('select');
  select.id = 'organization-select';

  organizations.forEach(org => {
    const option = document.createElement('option');
    option.value = org.id;
    option.textContent = org.name;
    select.appendChild(option);
  });

  return select;
}

Định tuyến cuộc trò chuyện theo tổ chức

async function routeChatToOrganization(chatRequest) {
  const organizations = await getOrganizations(companyToken);

  // Route based on business logic
  let targetOrg;

  if (chatRequest.department === 'sales') {
    targetOrg = organizations.find(org =>
      org.name.toLowerCase().includes('sales')
    );
  } else if (chatRequest.department === 'support') {
    targetOrg = organizations.find(org =>
      org.name.toLowerCase().includes('support')
    );
  }

  return targetOrg?.id;
}

Số liệu của tổ chức

class OrganizationMetrics {
  async getMetrics(companyToken, orgId) {
    // Get operators for organization
    const operators = await getOperators(companyToken, orgId);

    // Get chat statistics (example)
    return {
      organizationId: orgId,
      operatorCount: operators.length,
      activeOperators: operators.filter(op => op.isActive).length,
      // Add more metrics as needed
    };
  }

  async getAllMetrics(companyToken) {
    const organizations = await getOrganizations(companyToken);

    const metrics = await Promise.all(
      organizations.map(org =>
        this.getMetrics(companyToken, org.id)
      )
    );

    return metrics;
  }
}

Các phương pháp hay nhất

Bộ nhớ đệm

Danh sách tổ chức bộ nhớ đệm để giảm lệnh gọi API:

class CachedOrganizationManager {
  constructor(companyToken, cacheTTL = 300000) { // 5 minutes
    this.companyToken = companyToken;
    this.cacheTTL = cacheTTL;
    this.cache = null;
    this.cacheTime = 0;
  }

  async getOrganizations(forceRefresh = false) {
    const now = Date.now();

    if (!forceRefresh &&
        this.cache &&
        now - this.cacheTime < this.cacheTTL) {
      return this.cache;
    }

    this.cache = await fetchOrganizations(this.companyToken);
    this.cacheTime = now;

    return this.cache;
  }

  clearCache() {
    this.cache = null;
    this.cacheTime = 0;
  }
}

Xử lý lỗi

async function getOrganizationsWithRetry(companyToken, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      return await getOrganizations(companyToken);
    } catch (error) {
      if (error.response?.status === 401) {
        throw new Error('Invalid or expired company token');
      }

      if (i === retries - 1) throw error;

      // Wait before retry
      await new Promise(resolve =>
        setTimeout(resolve, Math.pow(2, i) * 1000)
      );
    }
  }
}

Xác thực

function validateOrganizationId(organizations, orgId) {
  const org = organizations.find(o => o.id === orgId);

  if (!org) {
    throw new Error(`Organization ${orgId} not found`);
  }

  return org;
}

// Usage
const organizations = await getOrganizations(companyToken);
const org = validateOrganizationId(organizations, requestedOrgId);

Khắc phục sự cố

Danh sách tổ chức trống

  • Xác minh mã thông báo của công ty là hợp lệ
  • Kiểm tra mã thông báo có quyền truy cập tổ chức
  • Đảm bảo các tổ chức tồn tại trong tài khoản

Không tìm thấy tổ chức

  • Xác minh ID tổ chức là chính xác
  • Kiểm tra tổ chức không bị xóa
  • Làm mới danh sách tổ chức

401 trái phép

  • Xác minh mã thông báo của công ty là hợp lệ và chưa hết hạn
  • Yêu cầu mã thông báo công ty mới nếu cần
  • Kiểm tra định dạng mã thông báo là chính xác

Các bước tiếp theo