Անցնել պարունակությանը

Վիդջեթի ինտեգրում

Ինտեգրեք ChatHub վիջեթը ձեր վեբկայքում՝ ձեր հաճախորդներին իրական ժամանակում զրույցի աջակցություն տրամադրելու համար:

Տեսություն

ChatHub վիջեթը JavaScript բաղադրիչ է, որը.

  • Ներդրվում է ցանկացած կայքում
  • Ապահովում է իրական ժամանակի զրույցի ինտերֆեյս
  • Հաճախորդներին կապում է օպերատորների հետ
  • Պահանջում է օպերատորի նույնականացման նշան
  • Բեռնվում է որպես ES մոդուլ

Արագ մեկնարկ

1. Ստացեք օպերատորի նշան

Նախ, ստացեք օպերատորի նշան՝ հետևելով authentication flow:

// 1. Get company token
const companyToken = await getCompanyToken(login, password);

// 2. Get organization
const organizations = await getOrganizations(companyToken);
const orgId = organizations[0].id;

// 3. Get operator
const operators = await getOperators(companyToken, orgId);
const operatorId = operators[0].id;

// 4. Generate operator token
const operatorToken = await getOperatorToken(
  companyToken,
  operatorId,
  expiresAt
);

// 5. Validate token
const isValid = await validateToken(companyToken, operatorToken);

2. Տեղադրել վիջեթը

Ավելացրեք վիդջեթի սցենարը ձեր HTML-ում.

<!DOCTYPE html>
<html>
<head>
    <title>Your Website</title>
</head>
<body>
    <!-- Your website content -->

    <!-- ChatHub Widget -->
    <script type="module" id="operator-chat-panel-script"
      src="https://widget.smsbat.com/operator-chat-panel/widget-script.js"
      token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."></script>
</body>
</html>

սցենարի պարամետրեր

Հատկանիշ Արժեք Պահանջվում է Նկարագրություն
«տեսակ» «մոդուլ» Այո ES մոդուլի տեսակը
«id» «օպերատոր-chat-panel-script» Այո Սկրիպտի եզակի նույնացուցիչ
«src» Վիջեթի URL Այո Վիջեթի սցենարի գտնվելու վայրը
«token» JWT նշան Այո Օպերատորի նույնականացման նշան

Ինտեգրման մեթոդներ

Ստատիկ HTML

Ստատիկ կայքերի համար ուղղակիորեն ներկառուցեք HTML-ում.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My Website</title>
</head>
<body>
    <h1>Welcome to My Website</h1>

    <!-- ChatHub Widget -->
    <script type="module" id="operator-chat-panel-script"
      src="https://widget.smsbat.com/operator-chat-panel/widget-script.js"
      token="YOUR_OPERATOR_TOKEN"></script>
</body>
</html>

Դինամիկ ներարկում (JavaScript)

Մեկ էջանոց հավելվածների համար դինամիկ ներարկեք.

function loadChatHubWidget(operatorToken) {
  // Check if widget already loaded
  const existing = document.getElementById('operator-chat-panel-script');
  if (existing) {
    existing.remove();
  }

  // Create script element
  const script = document.createElement('script');
  script.type = 'module';
  script.id = 'operator-chat-panel-script';
  script.src = 'https://widget.smsbat.com/operator-chat-panel/widget-script.js';
  script.setAttribute('token', operatorToken);

  // Append to body
  document.body.appendChild(script);
}

// Usage
const token = await getOperatorToken();
loadChatHubWidget(token);

Արձագանքեք

import { useEffect } from 'react';

function ChatHubWidget({ operatorToken }) {
  useEffect(() => {
    if (!operatorToken) return;

    // Load widget
    const script = document.createElement('script');
    script.type = 'module';
    script.id = 'operator-chat-panel-script';
    script.src = 'https://widget.smsbat.com/operator-chat-panel/widget-script.js';
    script.setAttribute('token', operatorToken);

    document.body.appendChild(script);

    // Cleanup on unmount
    return () => {
      const existing = document.getElementById('operator-chat-panel-script');
      if (existing) {
        existing.remove();
      }
    };
  }, [operatorToken]);

  return null;
}

// Usage
function App() {
  const [token, setToken] = useState('');

  useEffect(() => {
    async function init() {
      const operatorToken = await fetchOperatorToken();
      setToken(operatorToken);
    }
    init();
  }, []);

  return (
    <div>
      <h1>My App</h1>
      <ChatHubWidget operatorToken={token} />
    </div>
  );
}

Vue.js

<template>
  <div id="app">
    <h1>My App</h1>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      operatorToken: ''
    };
  },
  async mounted() {
    // Get operator token
    this.operatorToken = await this.fetchOperatorToken();

    // Load widget
    this.loadWidget();
  },
  methods: {
    async fetchOperatorToken() {
      // Your token fetching logic
      const response = await fetch('/api/chathub/token');
      return response.text();
    },
    loadWidget() {
      if (!this.operatorToken) return;

      const script = document.createElement('script');
      script.type = 'module';
      script.id = 'operator-chat-panel-script';
      script.src = 'https://widget.smsbat.com/operator-chat-panel/widget-script.js';
      script.setAttribute('token', this.operatorToken);

      document.body.appendChild(script);
    }
  },
  beforeUnmount() {
    const script = document.getElementById('operator-chat-panel-script');
    if (script) {
      script.remove();
    }
  }
};
</script>

Անկյունային

import { Component, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-root',
  template: '<h1>My App</h1>'
})
export class AppComponent implements OnInit, OnDestroy {
  private operatorToken: string = '';

  async ngOnInit() {
    // Get operator token
    this.operatorToken = await this.fetchOperatorToken();

    // Load widget
    this.loadWidget();
  }

  ngOnDestroy() {
    const script = document.getElementById('operator-chat-panel-script');
    if (script) {
      script.remove();
    }
  }

  private async fetchOperatorToken(): Promise<string> {
    const response = await fetch('/api/chathub/token');
    return response.text();
  }

  private loadWidget() {
    if (!this.operatorToken) return;

    const script = document.createElement('script');
    script.type = 'module';
    script.id = 'operator-chat-panel-script';
    script.src = 'https://widget.smsbat.com/operator-chat-panel/widget-script.js';
    script.setAttribute('token', this.operatorToken);

    document.body.appendChild(script);
  }
}

Նշանների կառավարում

Սերվերի կողմից նշանների ստեղծում

Երբեք մի բացահայտեք ընկերության հավատարմագրերը հաճախորդի կողմի կոդում: Ստեղծեք նշաններ ձեր սերվերի վրա.

// Node.js Express example
const express = require('express');
const app = express();

app.get('/api/chathub/token', async (req, res) => {
  try {
    // Authenticate your user first
    const userId = req.session.userId;
    if (!userId) {
      return res.status(401).json({ error: 'Unauthorized' });
    }

    // Get company token (stored securely on server)
    const companyToken = process.env.CHATHUB_COMPANY_TOKEN;

    // Get operator ID for this user
    const operatorId = await getOperatorIdForUser(userId);

    // Generate operator token
    const operatorToken = await generateOperatorToken(
      companyToken,
      operatorId
    );

    res.json({ token: operatorToken });
  } catch (error) {
    res.status(500).json({ error: 'Failed to generate token' });
  }
});

async function generateOperatorToken(companyToken, operatorId) {
  const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000); // 24 hours

  const response = await fetch(
    'https://chatapi.smsbat.com/api/operator/get-token',
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${companyToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        id: operatorId,
        expiresAt: expiresAt.toISOString()
      })
    }
  );

  return response.text();
}

Token Refresh

Իրականացնել նշանի ավտոմատ թարմացում.

class WidgetTokenManager {
  constructor() {
    this.token = null;
    this.expiresAt = null;
    this.refreshInterval = null;
  }

  async initialize() {
    await this.refreshToken();

    // Refresh token 1 hour before expiration
    this.refreshInterval = setInterval(
      () => this.checkAndRefresh(),
      60 * 60 * 1000 // Check every hour
    );
  }

  async refreshToken() {
    const response = await fetch('/api/chathub/token');
    const data = await response.json();

    this.token = data.token;
    this.expiresAt = new Date(data.expiresAt);

    this.reloadWidget();
  }

  async checkAndRefresh() {
    const oneHour = 60 * 60 * 1000;
    const timeUntilExpiry = this.expiresAt - Date.now();

    if (timeUntilExpiry < oneHour) {
      await this.refreshToken();
    }
  }

  reloadWidget() {
    // Remove old widget
    const existing = document.getElementById('operator-chat-panel-script');
    if (existing) {
      existing.remove();
    }

    // Load new widget with fresh token
    const script = document.createElement('script');
    script.type = 'module';
    script.id = 'operator-chat-panel-script';
    script.src = 'https://widget.smsbat.com/operator-chat-panel/widget-script.js';
    script.setAttribute('token', this.token);

    document.body.appendChild(script);
  }

  destroy() {
    if (this.refreshInterval) {
      clearInterval(this.refreshInterval);
    }
  }
}

// Usage
const widgetManager = new WidgetTokenManager();
await widgetManager.initialize();

Բազմաթիվ կազմակերպություններ

Բեռնել տարբեր վիդջեթներ տարբեր կազմակերպությունների համար.

function loadWidgetForOrganization(organizationId) {
  return new Promise((resolve, reject) => {
    // Get operator for this organization
    fetch(`/api/chathub/token?org=${organizationId}`)
      .then(response => response.json())
      .then(data => {
        const script = document.createElement('script');
        script.type = 'module';
        script.id = `operator-chat-panel-script-${organizationId}`;
        script.src = 'https://widget.smsbat.com/operator-chat-panel/widget-script.js';
        script.setAttribute('token', data.token);

        script.onload = () => resolve();
        script.onerror = () => reject(new Error('Failed to load widget'));

        document.body.appendChild(script);
      })
      .catch(reject);
  });
}

// Usage
await loadWidgetForOrganization('sales');
await loadWidgetForOrganization('support');

Լավագույն պրակտիկա

Անվտանգություն

  • ✅ Ստեղծեք նշաններ սերվերի կողմից
  • ✅ Երբեք մի բացահայտեք ընկերության հավատարմագրերը հաճախորդի կոդը
  • ✅ Օգտագործեք HTTPS բոլոր API հարցումների համար
  • ✅ Իրականացնել նշանի ժամկետի ավարտը
  • ✅ Վավերացրեք նշանները օգտագործելուց առաջ
  • ❌ Մի պահեք նշանները localStorage-ում առանց կոդավորման
  • ❌ Մի հանձնեք նշաններ տարբերակի վերահսկմանը

Կատարում

  • ✅ Բեռնել վիջեթը ասինխրոն կերպով
  • ✅ Օգտագործեք ES մոդուլներ (ժամանակակից բրաուզերներ)
  • ✅ Իրականացնել նշանների քեշավորում
  • ✅ Սխալներին նրբորեն վարվեք
  • ❌ Մի արգելափակեք էջի բեռնումը

Օգտագործողի փորձ

  • ✅ Ցույց տալ բեռնման վիճակը, մինչ վիջեթը սկզբնավորվում է
  • ✅ Կառավարեք ցանցի սխալները
  • ✅ Տրամադրել հետադարձ կապի մեթոդ
  • ✅ Փորձարկում տարբեր բրաուզերների և սարքերի վրա

Սխալների կառավարում

async function loadWidgetSafely(operatorToken) {
  try {
    // Validate token first
    const isValid = await validateToken(operatorToken);

    if (!isValid) {
      console.error('Invalid operator token');
      showFallbackContact();
      return;
    }

    // Load widget
    await loadWidget(operatorToken);

  } catch (error) {
    console.error('Failed to load chat widget:', error);
    showFallbackContact();
  }
}

function showFallbackContact() {
  // Show alternative contact method
  const fallback = document.createElement('div');
  fallback.innerHTML = `
    <div class="chat-fallback">
      <p>Chat is temporarily unavailable.</p>
      <p>Contact us: <a href="mailto:support@example.com">support@example.com</a></p>
    </div>
  `;
  document.body.appendChild(fallback);
}

Անսարքությունների վերացում

Վիջեթը չի բեռնվում

  1. Ստուգեք օպերատորի նշանի վավերականությունը
  2. Ստուգեք, որ նշանը ժամկետանց չէ
  3. Համոզվեք, որ սցենարի URL-ը ճիշտ է
  4. Ստուգեք բրաուզերի վահանակը սխալների համար
  5. Ստուգեք ցանցի միացումը

նշանը ժամկետանց է

// Detect expired token and refresh
window.addEventListener('error', async (event) => {
  if (event.message.includes('token expired')) {
    console.log('Token expired, refreshing...');
    await refreshWidgetToken();
  }
});

Բազմաթիվ վիդջեթների դեպքեր

Համոզվեք, որ միաժամանակ միայն մեկ վիջեթ է բեռնվում.

function loadWidgetOnce(token) {
  // Remove any existing widgets
  const existingScripts = document.querySelectorAll(
    'script[id^="operator-chat-panel-script"]'
  );

  existingScripts.forEach(script => script.remove());

  // Load new widget
  loadWidget(token);
}

Խաչաձեւ ծագման խնդիրներ

Համոզվեք, որ ձեր տիրույթը սպիտակ ցուցակում է: Կապվեք աջակցության հետ, եթե հանդիպեք CORS սխալների:

Թեստավորում

Տեղական զարգացում

// Use test token for development
const isDevelopment = process.env.NODE_ENV === 'development';
const token = isDevelopment
  ? 'test-token-for-development'
  : await getProductionToken();

loadWidget(token);

Ինտեգրման թեստավորում

describe('ChatHub Widget', () => {
  it('should load widget with valid token', async () => {
    const token = await getTestToken();
    loadWidget(token);

    await waitFor(() => {
      const widget = document.getElementById('operator-chat-panel-script');
      expect(widget).toBeTruthy();
    });
  });

  it('should handle invalid token', async () => {
    const invalidToken = 'invalid-token';

    try {
      await loadWidget(invalidToken);
    } catch (error) {
      expect(error.message).toContain('Invalid token');
    }
  });
});

Հաջորդ քայլերը