Skip to content

विजेट एकीकरण

तपाइँको ग्राहकहरु को लागी वास्तविक समय च्याट समर्थन प्रदान गर्न को लागी तपाइँको वेबसाइट मा ChatHub विजेट एकीकृत गर्नुहोस्।

सिंहावलोकन

ChatHub विजेट जाभास्क्रिप्ट कम्पोनेन्ट हो जुन:

  • कुनै पनि वेबसाइट मा इम्बेड
  • वास्तविक समय च्याट इन्टरफेस प्रदान गर्दछ
  • ग्राहकहरूलाई अपरेटरहरूसँग जडान गर्दछ
  • अपरेटर प्रमाणीकरण टोकन आवश्यक छ
  • ES मोड्युलको रूपमा लोड हुन्छ

द्रुत सुरुवात

१. अपरेटर टोकन प्राप्त गर्नुहोस्

पहिले, प्रमाणीकरण प्रवाह पछी अपरेटर टोकन प्राप्त गर्नुहोस्:

// 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);

२. इम्बेड विजेट

तपाईंको 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 operator-chat-panel-script हो अद्वितीय लिपि पहिचानकर्ता
src विजेट URL हो विजेट लिपि स्थान
टोकन 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>

डायनामिक इंजेक्शन (जाभास्क्रिप्ट)

एकल-पृष्ठ अनुप्रयोगहरूको लागि, गतिशील रूपमा इन्जेक्ट गर्नुहोस्:

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();
}

टोकन रिफ्रेस

स्वचालित टोकन रिफ्रेस लागू गर्नुहोस्:

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');

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

सुरक्षा

  • ✅ टोकन सर्भर साइड उत्पन्न गर्नुहोस्
  • ✅ ग्राहकको कोडमा कम्पनीको प्रमाणहरू कहिल्यै नदेखाउनुहोस्
  • ✅ सबै API अनुरोधहरूको लागि HTTPS प्रयोग गर्नुहोस्
  • ✅ टोकन म्याद समाप्ति लागू गर्नुहोस्
  • ✅ प्रयोग गर्नु अघि टोकन प्रमाणीकरण गर्नुहोस्
  • ❌ एन्क्रिप्शन बिना स्थानीय भण्डारणमा टोकनहरू भण्डारण नगर्नुहोस्
  • ❌ संस्करण नियन्त्रणमा टोकनहरू प्रतिबद्ध नगर्नुहोस्

प्रदर्शन

  • ✅ एसिन्क्रोनस रूपमा विजेट लोड गर्नुहोस्
  • ✅ 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');
    }
  });
});

अर्को चरणहरू