Files
openclaw/integrations/paradiz-web/wordpress-plugin/paradiz-web-chat/paradiz-web-chat.php
2026-03-02 21:42:24 +03:00

202 lines
7.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Plugin Name: Paradiz Web Chat
* Description: Чат-плагин для сайта vparadize.ru, который отправляет вопросы в изолированного агента OpenClaw paradizweb.
* Version: 1.0.4
* Author: EVA
*/
if (!defined('ABSPATH')) exit;
class ParadizWebChat {
const OPT_ENDPOINT = 'paradizweb_endpoint';
const OPT_TOKEN = 'paradizweb_token';
private $widget_rendered = false;
public function __construct() {
add_action('admin_menu', [$this, 'admin_menu']);
add_action('admin_init', [$this, 'register_settings']);
add_shortcode('paradiz_web_chat', [$this, 'render_shortcode']);
add_action('wp_enqueue_scripts', [$this, 'enqueue_assets']);
add_action('wp_footer', [$this, 'render_global_widget']);
add_action('wp_ajax_paradiz_web_chat', [$this, 'handle_chat']);
add_action('wp_ajax_nopriv_paradiz_web_chat', [$this, 'handle_chat']);
}
public function admin_menu() {
add_options_page('Paradiz Web Chat', 'Paradiz Web Chat', 'manage_options', 'paradiz-web-chat', [$this, 'settings_page']);
}
public function register_settings() {
register_setting('paradiz_web_chat_group', self::OPT_ENDPOINT);
register_setting('paradiz_web_chat_group', self::OPT_TOKEN);
}
public function settings_page() {
?>
<div class="wrap">
<h1>Paradiz Web Chat</h1>
<form method="post" action="options.php">
<?php settings_fields('paradiz_web_chat_group'); ?>
<table class="form-table">
<tr>
<th scope="row">Endpoint</th>
<td><input type="text" name="<?php echo self::OPT_ENDPOINT; ?>" value="<?php echo esc_attr(get_option(self::OPT_ENDPOINT, 'https://ai.pve-keeper.ru/chat')); ?>" class="regular-text" /></td>
</tr>
<tr>
<th scope="row">Bearer Token</th>
<td><input type="password" name="<?php echo self::OPT_TOKEN; ?>" value="<?php echo esc_attr(get_option(self::OPT_TOKEN, '')); ?>" class="regular-text" autocomplete="off" /></td>
</tr>
</table>
<?php submit_button(); ?>
</form>
<p>Вставь шорткод <code>[paradiz_web_chat]</code> на страницу бронирования.</p>
</div>
<?php
}
public function enqueue_assets() {
wp_register_script('paradiz-web-chat', plugins_url('chat.js', __FILE__), [], '1.0.2', true);
wp_localize_script('paradiz-web-chat', 'ParadizWebChatCfg', [
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('paradiz_web_chat_nonce')
]);
}
public function render_shortcode() {
return $this->render_widget_markup();
}
public function render_global_widget() {
if (is_admin() || wp_doing_ajax() || $this->widget_rendered) {
return;
}
echo $this->render_widget_markup();
}
private function render_widget_markup() {
if ($this->widget_rendered) {
return '';
}
$this->widget_rendered = true;
wp_enqueue_script('paradiz-web-chat');
ob_start(); ?>
<style>
#paradiz-web-chat-fab {
position: fixed;
right: 24px;
bottom: 24px;
z-index: 99999;
border: none;
border-radius: 999px;
padding: 12px 16px;
background: #1e88e5;
color: #fff;
font-weight: 600;
box-shadow: 0 8px 24px rgba(0,0,0,.2);
cursor: pointer;
}
#paradiz-web-chat-modal {
position: fixed;
right: 24px;
bottom: 84px;
width: min(420px, calc(100vw - 32px));
max-height: 70vh;
background: #fff;
border: 1px solid #ddd;
border-radius: 14px;
box-shadow: 0 10px 30px rgba(0,0,0,.2);
z-index: 99999;
display: none;
overflow: hidden;
}
#paradiz-web-chat-head {
padding: 12px 14px;
font-weight: 700;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
}
#paradiz-web-chat-close {
border: none;
background: transparent;
font-size: 20px;
cursor: pointer;
line-height: 1;
}
#paradiz-web-chat-log {
padding: 10px 12px;
height: 280px;
overflow: auto;
background: #fafafa;
font-size: 14px;
}
.paradiz-msg { margin: 0 0 8px 0; white-space: pre-wrap; }
.paradiz-user { color: #1e88e5; }
.paradiz-bot { color: #222; }
#paradiz-web-chat-controls {
border-top: 1px solid #eee;
padding: 10px;
background: #fff;
}
#paradiz-web-chat-input { width: 100%; box-sizing: border-box; }
#paradiz-web-chat-send { margin-top: 8px; width: 100%; }
</style>
<button id="paradiz-web-chat-fab" type="button">💬 Чат бронирования</button>
<div id="paradiz-web-chat-modal" aria-live="polite">
<div id="paradiz-web-chat-head">
<span>Помощник Парадиз</span>
<button id="paradiz-web-chat-close" type="button" aria-label="Закрыть">×</button>
</div>
<div id="paradiz-web-chat-log">
<p class="paradiz-msg paradiz-bot">Здравствуйте! Помогу с подбором номера и бронированием.</p>
</div>
<div id="paradiz-web-chat-controls">
<textarea id="paradiz-web-chat-input" rows="3" placeholder="Например: 2 взрослых и 1 ребёнок, с 10 по 15 июля"></textarea>
<button id="paradiz-web-chat-send" type="button">Отправить</button>
</div>
</div>
<?php return ob_get_clean();
}
public function handle_chat() {
check_ajax_referer('paradiz_web_chat_nonce', 'nonce');
$question = isset($_POST['question']) ? sanitize_text_field($_POST['question']) : '';
if (!$question) wp_send_json_error(['message' => 'Пустой вопрос']);
$endpoint = get_option(self::OPT_ENDPOINT, '');
$token = get_option(self::OPT_TOKEN, '');
if (!$endpoint || !$token) wp_send_json_error(['message' => 'Не настроены endpoint/token']);
$resp = wp_remote_post($endpoint, [
'timeout' => 45,
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $token
],
'body' => wp_json_encode(['question' => $question])
]);
if (is_wp_error($resp)) {
wp_send_json_error(['message' => $resp->get_error_message()]);
}
$body = json_decode(wp_remote_retrieve_body($resp), true);
if (!is_array($body) || empty($body['ok'])) {
wp_send_json_error(['message' => $body['error'] ?? 'Ошибка upstream']);
}
wp_send_json_success(['answer' => $body['answer'] ?? '']);
}
}
new ParadizWebChat();