AI чатбот для сайта с ChatGPT: PHP + JavaScript виджет

AI-агенты на VDS · 19.04.2026
AI чатбот для сайта с ChatGPT: PHP + JavaScript виджет

AI чатбот для сайта с ChatGPT

Добавьте AI-ассистента на свой сайт за несколько часов. Чатбот может отвечать на вопросы о ваших продуктах, помогать с поддержкой и квалифицировать лиды — 24/7 без участия человека.

Архитектура

Frontend (JavaScript виджет) ↔ Backend API (PHP/Python) ↔ OpenAI API. Для персонализации используйте контекст о вашем продукте в System Prompt.

PHP Backend API

<?php
// api/chat.php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: https://yourdomain.com');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    exit;
}

$body = json_decode(file_get_contents('php://input'), true);
$userMessage = htmlspecialchars($body['message'] ?? '', ENT_QUOTES, 'UTF-8');

if (empty($userMessage) || strlen($userMessage) > 500) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid message']);
    exit;
}

$systemPrompt = "Ты помощник службы поддержки хостинга ZevsHost.
Отвечай кратко и по делу. Ссылки на документацию: zevshost.net/kb
Если не знаешь — предложи открыть тикет: zevshost.net/support";

$client = OpenAI::client($_ENV['OPENAI_API_KEY']);
$response = $client->chat()->create([
    'model'       => 'gpt-4o-mini',
    'messages'    => [
        ['role' => 'system', 'content' => $systemPrompt],
        ['role' => 'user',   'content' => $userMessage],
    ],
    'max_tokens'  => 400,
    'temperature' => 0.6,
]);

echo json_encode([
    'reply' => $response->choices[0]->message->content
]);

JavaScript виджет

class AiChat {
  constructor(apiUrl) {
    this.apiUrl = apiUrl;
    this.history = [];
    this.render();
  }

  render() {
    const widget = document.createElement('div');
    widget.innerHTML = `
      <div id="ai-chat" style="position:fixed;bottom:20px;right:20px;z-index:9999;">
        <button id="ai-toggle" style="width:56px;height:56px;border-radius:50%;background:#10b981;border:none;cursor:pointer;font-size:24px;">💬</button>
        <div id="ai-window" style="display:none;width:320px;background:#fff;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,.15);overflow:hidden;">
          <div style="background:#10b981;padding:14px;color:#fff;font-weight:600;">Поддержка ZevsHost</div>
          <div id="ai-messages" style="height:300px;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px;"></div>
          <div style="padding:12px;border-top:1px solid #e5e7eb;display:flex;gap:8px;">
            <input id="ai-input" placeholder="Задайте вопрос..." style="flex:1;border:1px solid #d1d5db;border-radius:8px;padding:8px 12px;outline:none;">
            <button id="ai-send" style="background:#10b981;color:#fff;border:none;border-radius:8px;padding:8px 14px;cursor:pointer;">→</button>
          </div>
        </div>
      </div>`;
    document.body.appendChild(widget);

    document.getElementById('ai-toggle').onclick = () => {
      const win = document.getElementById('ai-window');
      win.style.display = win.style.display === 'none' ? 'block' : 'none';
    };
    document.getElementById('ai-send').onclick = () => this.send();
    document.getElementById('ai-input').addEventListener('keydown', (e) => {
      if (e.key === 'Enter') this.send();
    });
  }

  async send() {
    const input = document.getElementById('ai-input');
    const msg = input.value.trim();
    if (!msg) return;
    input.value = '';
    this.addMessage(msg, 'user');

    const res = await fetch(this.apiUrl, {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({ message: msg })
    });
    const data = await res.json();
    this.addMessage(data.reply, 'bot');
  }

  addMessage(text, role) {
    const msgs = document.getElementById('ai-messages');
    const div = document.createElement('div');
    div.style.cssText = `max-width:85%;padding:8px 12px;border-radius:12px;font-size:14px;line-height:1.4;${role === 'user' ? 'align-self:flex-end;background:#10b981;color:#fff;' : 'align-self:flex-start;background:#f3f4f6;color:#111;'}`;
    div.textContent = text;
    msgs.appendChild(div);
    msgs.scrollTop = msgs.scrollHeight;
  }
}

new AiChat('/api/chat.php');
Rate limiting: Защитите API от злоупотреблений: ограничьте запросы по IP (10/минуту), добавьте CSRF-токен и валидируйте длину сообщений на сервере.
← Назад в базу знаний Задать вопрос поддержке