PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.7.7
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.7.7
8.7.7 8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 8.5.7 8.5.6 8.5.5 8.5.4 8.5.3 8.5.2 All 533 releases
chatbot / includes / admin / templates / ai-actions.php

ai-actions.php in WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services 8.7.7, at includes/admin/templates/ai-actions.php

954 lines 48.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
4 if ( isset( $_POST['submit'] ) && check_admin_referer( 'wp_chatbot_ai_actions', '_wpnonce' ) && current_user_can( 'manage_options' ) ) {
5
6 $ai_forms = array();
7 if ( isset( $_POST['ai_form_title'] ) && is_array( $_POST['ai_form_title'] ) ) {
8 $titles = $_POST['ai_form_title'];
9 $prompts = isset( $_POST['ai_form_prompt'] ) ? $_POST['ai_form_prompt'] : array();
10 $interactive = isset( $_POST['ai_form_interactive'] ) ? $_POST['ai_form_interactive'] : array();
11 $email = isset( $_POST['ai_form_email'] ) ? $_POST['ai_form_email'] : array();
12 $email_addresses = isset( $_POST['ai_form_email_addresses'] ) ? $_POST['ai_form_email_addresses'] : array();
13
14 for ( $i = 0; $i < count( $titles ); $i++ ) {
15 $title = sanitize_text_field( wp_unslash( $titles[$i] ) );
16 $prompt = isset( $prompts[$i] ) ? sanitize_textarea_field( wp_unslash( $prompts[$i] ) ) : '';
17 if ( ! empty( $title ) && ! empty( $prompt ) ) {
18 $ai_forms[] = array(
19 'title' => $title,
20 'prompt' => $prompt,
21 'interactive' => isset($interactive[$i]) ? intval($interactive[$i]) : 0,
22 'email' => isset($email[$i]) ? intval($email[$i]) : 1,
23 'email_addresses' => isset($email_addresses[$i]) ? sanitize_textarea_field( wp_unslash( $email_addresses[$i] ) ) : '',
24 );
25 }
26 }
27 }
28 update_option( 'wpbot_ai_forms', $ai_forms );
29
30 if ( isset( $_POST['qcld_ai_default_email'] ) ) {
31 $raw_emails = wp_unslash( $_POST['qcld_ai_default_email'] );
32 // Sanitize each email individually, preserving comma-separated list
33 $emails = array_map( 'sanitize_email', array_map( 'trim', explode( ',', $raw_emails ) ) );
34 $emails = array_filter( $emails ); // remove any invalid entries
35 update_option( 'qcld_ai_default_email', implode( ', ', $emails ) );
36 }
37
38 update_option( 'enable_ai_interactive_form', '1' );
39
40 echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'Settings saved.', 'chatbot' ) . '</p></div>';
41 }
42
43 $saved_forms = get_option( 'wpbot_ai_forms', array() );
44
45 // One-time migration: Ensure all existing forms have email enabled by default.
46 $migrated = false;
47 if ( is_array( $saved_forms ) ) {
48 foreach ( $saved_forms as &$f ) {
49 if ( ! isset( $f['email_migrated'] ) ) {
50 $f['email'] = 1;
51 $f['email_migrated'] = 1;
52 $migrated = true;
53 }
54 }
55 if ( $migrated ) {
56 update_option( 'wpbot_ai_forms', $saved_forms );
57 }
58 }
59 if ( ! is_array( $saved_forms ) ) {
60 $saved_forms = array();
61 }
62 ?>
63 <div class="wrap qcld-main-wrapper qcld-ai-actions-page">
64 <div class="qcld-wp-chatbot-wrap-header-aisection">
65 <div class="qcld-wp-chatbot-wrap-header">
66 <div class="qcld-wp-chatbot-wrap-header-logo">
67 <a href="#" class="qcld-wp-chatbot-wrap-site__logo">
68 <img src="<?php echo esc_url( QCLD_wpCHATBOT_IMG_URL . '/chatbot.png' ); ?>" alt="WPBot"> WPBot Control Panel
69 </a>
70 <p><strong>Core Version:</strong> v<?php echo esc_html( QCLD_wpCHATBOT_VERSION ); ?></p>
71 </div>
72 <ul class="qcld-wp-chatbot-wrap-version-wrapper">
73 <li><a class="wpchatbot-Upgrade" href="https://www.wpbot.pro/" target="_blank">Upgrade To Pro</a></li>
74 </ul>
75 </div>
76 </div>
77
78 <div class="wp-chatbot-wrap">
79 <section class="wp-chatbot-tab-container-inner">
80 <div class="wp-chatbot-tabs wp-chatbot-tabs-style-flip qcld-ai-actions-layout">
81
82 <nav>
83 <ul class="qcld-ai-sidebar-menu">
84 <li class="tab-current">
85 <a href="#ai-new-action-tab" class="ai-sidebar-link active">
86 <span class="wpwbot-admin-tab-icon"><span class="dashicons dashicons-plus-alt"></span></span>
87 <span class="wpwbot-admin-tab-name"><?php esc_html_e('Add New Action', 'chatbot'); ?></span>
88 </a>
89 </li>
90 <li class="qcld-ai-saved-parent">
91 <a href="#" class="ai-sidebar-parent-link">
92 <span class="wpwbot-admin-tab-icon"><span class="dashicons dashicons-portfolio"></span></span>
93 <span class="wpwbot-admin-tab-name"><?php esc_html_e('Saved Actions', 'chatbot'); ?></span>
94 <span class="dashicons dashicons-arrow-down-alt2 qcld-ai-saved-toggle"></span>
95 </a>
96 <ul class="ai-saved-actions-submenu">
97 <?php
98 $counter = 1;
99 if ( ! empty( $saved_forms ) ) {
100 foreach ( $saved_forms as $form ) {
101 $tab_id = 'ai-action-tab-' . $counter;
102 echo '<li><a href="#' . esc_attr( $tab_id ) . '" class="ai-sidebar-link ai-sidebar-saved-link" data-id="' . esc_attr( $tab_id ) . '">' . esc_html( $form['title'] ) . '</a></li>';
103 $counter++;
104 }
105 } else {
106 echo '<li class="ai-no-saved-actions">' . esc_html__( 'No saved actions', 'chatbot' ) . '</li>';
107 }
108 ?>
109 </ul>
110 </li>
111 </ul>
112 </nav>
113
114 <div class="content-wrap qcld-ai-actions-content">
115 <form action="" method="POST" id="ai-actions-main-form">
116 <?php wp_nonce_field( 'wp_chatbot_ai_actions', '_wpnonce' ); ?>
117
118 <div id="ai-new-action-tab" class="ai-content-pane active">
119 <?php
120 $no_ai_active = (get_option( 'ai_enabled' ) != 1 &&
121 get_option( 'qcld_openrouter_enabled' ) != 1 &&
122 get_option( 'qcld_gemini_enabled' ) != 1 &&
123 get_option( 'qcld_grok_enabled' ) != 1 &&
124 get_option( 'qcld_claude_enabled' ) != 1);
125 if($no_ai_active):
126 ?>
127 <div class="qcld-ai-actions-alert">
128 <?php esc_html_e('No AI connection is active. Please enable AI integration.', 'chatbot'); ?>
129 </div>
130 <?php endif; ?>
131 <h3 class="qcld-wpbot-main-tabs-title"><?php esc_html_e('Choose a Template', 'chatbot'); ?></h3>
132 <p><?php esc_html_e('Select a template below to create a new AI Action. You can customize it on the next screen.', 'chatbot'); ?></p>
133
134 <div class="qcld-ai-template-grid">
135 <!-- Blank -->
136 <div class="ai-template-card" data-title="" data-prompt="" >
137 <div class="ai-template-card-icon"><span class="dashicons dashicons-plus-alt2" ></span></div>
138 <h4>Blank Prompt</h4>
139 <p>Start from scratch and build your own custom AI action.</p>
140 </div>
141
142 <!-- 1. Web Agency Quote -->
143 <div class="ai-template-card" data-title="Web Agency Quote" data-prompt="You are a project discovery assistant for a web development agency.
144 Ask the user the following questions conversationally, one at a time:
145
146 1. What type of project are they planning (e.g., WordPress plugin, custom web app, WooCommerce store)?
147 2. What are the core features or problems they need solved?
148 3. What is their estimated budget range and target launch timeline?
149 4. What is their full name, work email, and preferred contact method?
150
151 " >
152 <div class="ai-template-card-icon"><span class="dashicons dashicons-desktop" ></span></div>
153 <h4>Web Agency Quote</h4>
154 <p>Software, agency, and freelance service inquiries.</p>
155 </div>
156
157 <!-- 2. Real Estate Inquiry -->
158 <div class="ai-template-card" data-title="Real Estate Inquiry" data-prompt="You are a real estate assistant helping visitors find their ideal property.
159 Collect these details step-by-step:
160
161 1. Are they looking to Buy, Rent, or Sell?
162 2. What property type and location/neighborhood are they interested in?
163 3. How many bedrooms and bathrooms do they require?
164 4. What is their target price or monthly budget range?
165 5. What is their full name, phone number, and email address to schedule a viewing?
166
167 " >
168 <div class="ai-template-card-icon"><span class="dashicons dashicons-building" ></span></div>
169 <h4>Real Estate Inquiry</h4>
170 <p>Qualifying buyers and renters for property showings.</p>
171 </div>
172
173 <!-- 3. Priority Support -->
174 <div class="ai-template-card" data-title="Priority Support" data-prompt="You are a technical support intake agent.
175 Guide the customer through collecting diagnostic details:
176
177 1. What plugin, product, or service is experiencing the issue?
178 2. Can they briefly describe the error or unexpected behavior?
179 3. What is the website URL where this occurs, and their environment specs (e.g., WP/PHP versions) if known?
180 4. What is the urgency level (Low, Medium, or Critical / Site Down)?
181 5. What is their full name and account email address?
182
183 Acknowledge issues empathetically.
184 " >
185 <div class="ai-template-card-icon"><span class="dashicons dashicons-sos" ></span></div>
186 <h4>Priority Support</h4>
187 <p>Bug triage and diagnostic data gathering for helpdesks.</p>
188 </div>
189
190 <!-- 4. SaaS Demo Booking -->
191 <div class="ai-template-card" data-title="SaaS Demo Booking" data-prompt="You are an onboarding specialist for a SaaS platform.
192 Qualify visitors requesting a product demo by asking:
193
194 1. What company do they represent, and what is their current team or company size?
195 2. What is the primary bottleneck or workflow they want our software to automate?
196 3. What CRM or marketing tools are in their current tech stack?
197 4. What is their full name, business email, and preferred day/time for a 15-minute demo?
198
199 " >
200 <div class="ai-template-card-icon"><span class="dashicons dashicons-chart-pie" ></span></div>
201 <h4>SaaS Demo Booking</h4>
202 <p>Lead qualification and sales routing for software platforms.</p>
203 </div>
204
205 <!-- 5. E-Commerce Wholesale -->
206 <div class="ai-template-card" data-title="E-Commerce Wholesale" data-prompt="You are a sales assistant helping wholesale and bulk-order customers.
207 Gather order specifications:
208
209 1. What product SKU or item category are they interested in?
210 2. What estimated quantity or unit count do they plan to purchase?
211 3. Do they require custom branding/labels or standard packaging?
212 4. What is their target delivery deadline and destination country/postal code?
213 5. What is their company name, contact person, and billing email?
214
215 " >
216 <div class="ai-template-card-icon"><span class="dashicons dashicons-cart" ></span></div>
217 <h4>E-Commerce Wholesale</h4>
218 <p>B2B wholesale pricing and custom merchandise for WooCommerce.</p>
219 </div>
220
221 <!-- 6. Legal Case Intake -->
222 <div class="ai-template-card" data-title="Legal Case Intake" data-prompt="You are a legal intake assistant for a law firm.
223 State clearly that this chat does not establish an attorney-client relationship, then collect:
224
225 1. What area of law do they need assistance with (e.g., Personal Injury, Family Law, Business Dispute, Estate Planning)?
226 2. A brief summary of the situation and approximately when it occurred.
227 3. Are there any upcoming deadlines, court dates, or active lawsuits already filed?
228 4. What is their full name, phone number, and email address?
229
230 " >
231 <div class="ai-template-card-icon"><span class="dashicons dashicons-portfolio" ></span></div>
232 <h4>Legal Case Intake</h4>
233 <p>Pre-screening legal leads for practice area viability and deadlines.</p>
234 </div>
235
236 <!-- 7. Healthcare Booking -->
237 <div class="ai-template-card" data-title="Healthcare Booking" data-prompt="You are a patient coordinator assistant for a dental and medical clinic.
238 Collect scheduling details without providing medical advice:
239
240 1. Are they a new or existing patient, and what is the primary reason for their visit?
241 2. Do they have medical/dental insurance, and if so, who is the provider?
242 3. What days of the week and times of day work best for their appointment?
243 4. What is their full name, date of birth, phone number, and email address?
244
245 " >
246 <div class="ai-template-card-icon"><span class="dashicons dashicons-heart" ></span></div>
247 <h4>Healthcare Booking</h4>
248 <p>Clinic patient scheduling, primary symptoms, and insurance check.</p>
249 </div>
250
251 <!-- 8. Event Planning -->
252 <div class="ai-template-card" data-title="Event Planning" data-prompt="You are an event specialist assisting clients with catering and planning inquiries.
253 Guide them through these questions:
254
255 1. What type of event are they planning (e.g., Wedding, Corporate Gala, Birthday)?
256 2. What is the estimated event date, venue location, and expected guest count?
257 3. What dining/service style do they prefer (e.g., Plated Multi-Course, Buffet, Cocktail/Hors d'oeuvres)?
258 4. What is their approximate overall budget?
259 5. What is their contact name, organization (if applicable), phone number, and email?
260
261 " >
262 <div class="ai-template-card-icon"><span class="dashicons dashicons-calendar-alt" ></span></div>
263 <h4>Event Planning</h4>
264 <p>Event venue, banquet, and catering inquiries.</p>
265 </div>
266
267 <!-- 9. Auto Dealership -->
268 <div class="ai-template-card" data-title="Auto Dealership" data-prompt="You are a sales concierge for an automotive dealership.
269 Collect test drive details:
270
271 1. Which vehicle model, trim, or year are they interested in test-driving?
272 2. Do they have a trade-in vehicle? If yes, ask for the Year, Make, Model, and approximate mileage.
273 3. What is their preferred payment path (Financing, Leasing, or Cash purchase)?
274 4. What date and time would they like to schedule their test drive?
275 5. What is their full name, mobile number, and email address?
276
277 " >
278 <div class="ai-template-card-icon"><span class="dashicons dashicons-car" ></span></div>
279 <h4>Auto Dealership</h4>
280 <p>Test-drive bookings and vehicle trade-in estimates.</p>
281 </div>
282
283 <!-- 10. Education Admissions -->
284 <div class="ai-template-card" data-title="Education Admissions" data-prompt="You are an admissions advisor for an educational training academy.
285 Ask the prospective student:
286
287 1. Which program or certification do they want to enroll in?
288 2. What is their current background or experience level (Beginner, Intermediate, Advanced)?
289 3. Are they looking for Full-Time (Immersive) or Part-Time study?
290 4. What is their target cohort start date?
291 5. What is their full name, WhatsApp/phone number, and email address?
292
293 " >
294 <div class="ai-template-card-icon"><span class="dashicons dashicons-welcome-learn-more" ></span></div>
295 <h4>Education Admissions</h4>
296 <p>Online course and bootcamp enrollment qualification.</p>
297 </div>
298
299 <!-- 11. Senior PHP Programmer Assessment -->
300 <div class="ai-template-card" data-title="Senior PHP Programmer Assessment" data-prompt="You are an expert technical interviewer screening candidates for an in-house Senior PHP Developer position specializing in Laravel and WordPress core architecture.
301
302 Role Prerequisites:
303 - Degree: Must hold a Bachelor's degree in Computer Science (CSC) or Computer Information Systems (CIS).
304 - Experience: Minimum 2 years of professional PHP development with hands-on Laravel and WordPress plugin engineering.
305
306 CRITICAL EXECUTION RULES:
307 - Ask exactly ONE question per turn.
308 - NEVER combine multiple questions, items, or prompts into a single message.
309 - Await the candidate's answer before moving to the next item.
310 - Do not provide code solutions, hints, or technical corrections during the interview.
311
312 Sequential Interview Steps (Strict 1-by-1 Flow):
313 Step 1: &quot;To get started, what is your full name?&quot;
314 Step 2: &quot;What is your primary email address?&quot;
315 Step 3: &quot;What is the best phone number to reach you?&quot;
316 Step 4: &quot;Could you share the link to your GitHub, GitLab, or portfolio profile?&quot;
317 Step 5: &quot;What is your exact degree title, major, and graduating university?&quot;
318 Step 6: &quot;How many total years of professional PHP development experience do you have?&quot;
319 Step 7: &quot;What commercial projects have you built using Laravel and custom WordPress plugins?&quot;
320 Step 8: &quot;Technical Q1 (Laravel Architecture): How do Service Providers, the Service Container, and Middleware interact during Laravel's request lifecycle? How do you implement and register a custom deferred service provider?&quot;
321 Step 9: &quot;Technical Q2 (WordPress Core Internals): Explain how the WordPress Action and Filter hook system works internally under the WP_Hook class. When architecting scalable plugins, how do you manage nonces, custom database tables vs Custom Post Types, and transients for cache invalidation?&quot;
322 Step 10: &quot;Technical Q3 (Security &amp; Performance): How do you prevent race conditions, memory exhaustion (e.g., Eloquent chunking vs PHP Generators), and SQL injection when executing bulk database operations across Laravel and WordPress environments?&quot;
323
324 " >
325 <div class="ai-template-card-icon"><span class="dashicons dashicons-businessman" ></span></div>
326 <h4>Senior PHP Programmer Assessment</h4>
327 <p>Screening candidates for a Senior PHP Developer position.</p>
328 </div>
329 </div>
330 </div>
331
332 <!-- SAVED ACTIONS TABS (Generated) -->
333 <div id="ai-saved-actions-container">
334 <?php
335 $counter = 1;
336 if ( ! empty( $saved_forms ) ) :
337 foreach ( $saved_forms as $form ) :
338 $tab_id = 'ai-action-tab-' . $counter;
339 $chk_interactive_id = 'ai_interactive_' . $counter;
340 $chk_email_id = 'ai_email_' . $counter;
341 ?>
342 <div id="<?php echo esc_attr($tab_id); ?>" class="ai-content-pane ai-form-item saved-ai-action" style="display: none;">
343
344 <div class="qcld-ai-action-edit-head">
345 <h3 class="qcld-wpbot-main-tabs-title"><?php esc_html_e('Edit Action', 'chatbot'); ?></h3>
346 <div class="qcld-ai-action-edit-actions">
347 <button type="button" class="qcld-btn-primary qcld-ai-goto-new-action"><?php esc_html_e('Add New Action', 'chatbot'); ?></button>
348 <button type="button" class="button remove-ai-form"><?php esc_html_e( 'Delete Action', 'chatbot' ); ?></button>
349 </div>
350 </div>
351
352 <h2 class="nav-tab-wrapper wpbot-ai-inner-tabs">
353 <a href="#ai-inner-settings-<?php echo esc_attr($counter); ?>" class="nav-tab nav-tab-active"><?php esc_html_e('Settings', 'chatbot'); ?></a>
354 <a href="#" class="nav-tab qcld-ai-history-pro-tab"><?php esc_html_e('History', 'chatbot'); ?> <span class="qc_wpbot_pro">PRO</span></a>
355 </h2>
356
357 <div id="ai-inner-settings-<?php echo esc_attr($counter); ?>" class="ai-inner-tab-content">
358 <div class="form-group">
359 <label><?php esc_html_e('Action Title', 'chatbot'); ?></label>
360 <input type="text" name="ai_form_title[]" class="form-control ai-form-title-input" placeholder="<?php esc_attr_e('e.g., Hotel Booking', 'chatbot'); ?>" value="<?php echo esc_attr( $form['title'] ); ?>" />
361 </div>
362 <div class="form-group">
363 <label><?php esc_html_e('AI Prompt', 'chatbot'); ?></label>
364 <textarea name="ai_form_prompt[]" class="form-control" rows="15" placeholder="<?php esc_attr_e('Enter your prompt here...', 'chatbot'); ?>"><?php echo esc_textarea( $form['prompt'] ); ?></textarea>
365 </div>
366
367 <div class="cxsc-settings-blocks">
368 <div class="form-group qcld-ai-email-toggle">
369 <input type="hidden" name="ai_form_email[]" class="ai-email-val" value="<?php echo esc_attr( isset($form['email']) ? $form['email'] : 1 ); ?>">
370 <input type="checkbox" id="<?php echo esc_attr( $chk_email_id ); ?>" <?php echo ( !isset($form['email']) || $form['email'] == 1 ) ? 'checked' : ''; ?> onchange="jQuery(this).prev('.ai-email-val').val(this.checked ? 1 : 0);">
371 <label for="<?php echo esc_attr( $chk_email_id ); ?>"><?php esc_html_e('Email the data', 'chatbot'); ?></label>
372 </div>
373 <div class="qcld-ai-email-field">
374 <label><?php esc_html_e('Send to Email(s)', 'chatbot'); ?></label>
375 <input type="text" name="ai_form_email_addresses[]" class="form-control" placeholder="<?php echo esc_attr( get_option('qlcd_wp_chatbot_admin_email', get_option('admin_email')) ); ?>" value="<?php echo esc_attr( isset($form['email_addresses']) ? $form['email_addresses'] : '' ); ?>">
376 <p class="qcld-ai-field-hint"><?php esc_html_e('Comma-separated. Leave blank to use the default admin email.', 'chatbot'); ?></p>
377 </div>
378 </div>
379 </div>
380
381 <div id="ai-inner-history-<?php echo esc_attr($counter); ?>" class="ai-inner-tab-content" style="display: none;">
382 <div id="ai-inner-history-content-<?php echo esc_attr($counter); ?>">
383 <p class="qcld-ai-muted"><?php esc_html_e('Loading history...', 'chatbot'); ?></p>
384 </div>
385 </div>
386 </div>
387 <?php
388 $counter++;
389 endforeach;
390 endif;
391 ?>
392 </div>
393
394 <div id="ai-save-wrapper" class="wp-chatbot-admin-footer qcld-ai-save-footer">
395 <div class="cxsc-settings-blocks-notic">
396 <p><?php esc_html_e("Don't forget to save your changes!", 'chatbot'); ?></p>
397 <p><strong><?php esc_html_e('Create powerful AI Actions with Prompt to collect information and send to your email.', 'chatbot'); ?></strong></p>
398 <p><strong><?php esc_html_e('After creating an AI Action, you can add it to the Active Start Menu from', 'chatbot'); ?> <a href="<?php echo esc_url( admin_url( 'admin.php?page=wpbot&tab=startmenu' ) ); ?>"><?php esc_html_e('Settings -> Start Menu', 'chatbot'); ?></a></strong></p>
399 </div>
400 <input type="submit" name="submit" class="qcld-btn-primary" value="<?php esc_attr_e( 'Save Settings', 'chatbot' ); ?>" />
401 </div>
402 </form>
403 </div>
404
405 <?php
406 $default_provider = 'openai';
407 if ( get_option( 'qcld_gemini_enabled' ) == 1 ) {
408 $default_provider = 'gemini';
409 } elseif ( get_option( 'qcld_claude_enabled' ) == 1 ) {
410 $default_provider = 'claude';
411 } elseif ( get_option( 'qcld_grok_enabled' ) == 1 ) {
412 $default_provider = 'grok';
413 } elseif ( get_option( 'qcld_openrouter_enabled' ) == 1 ) {
414 $default_provider = 'openrouter';
415 }
416
417 if ( get_option( 'wp_chatbot_icon' ) == 'custom.png' ) {
418 $wp_chatbot_custom_icon_path = ( ! empty( get_option( 'wp_chatbot_custom_icon_path' ) ) ) ? get_option( 'wp_chatbot_custom_icon_path' ) : QCLD_wpCHATBOT_IMG_URL . 'icon-1.png';
419 } elseif ( get_option( 'wp_chatbot_icon' ) ) {
420 $wp_chatbot_custom_icon_path = QCLD_wpCHATBOT_IMG_URL . get_option( 'wp_chatbot_icon' );
421 } else {
422 $wp_chatbot_custom_icon_path = QCLD_wpCHATBOT_IMG_URL . 'icon-1.png';
423 }
424 ?>
425 <aside class="wp-chatbot-admin-upgrade-pro-sidebar qcld-ai-actions-playground">
426 <div class="qcld-ai-playground">
427 <div class="qcld-ai-playground-header">
428 <span><?php esc_html_e('Live AI Playground', 'chatbot'); ?></span>
429 <button type="button" id="ai-playground-refresh" title="<?php esc_attr_e('Refresh Chat', 'chatbot'); ?>">
430 <span class="dashicons dashicons-update-alt"></span>
431 </button>
432 </div>
433 <div id="ai-actions-playground-container">
434 <div id="ai-actions-playground-messages">
435 <div class="qcld-ai-pg-bot-row">
436 <div class="qcld-ai-pg-avatar" style="background-image: url('<?php echo esc_url( $wp_chatbot_custom_icon_path ); ?>');"></div>
437 <div class="qcld-ai-pg-bubble">
438 <p><?php esc_html_e('Hello! I am here to find what you need. What are you looking for?', 'chatbot'); ?></p>
439 <div id="ai-actions-live-preview"></div>
440 </div>
441 </div>
442 </div>
443 </div>
444 <div class="qcld-ai-playground-footer">
445 <input type="text" id="playground-input" placeholder="<?php esc_attr_e('Send a message...', 'chatbot'); ?>">
446 <button type="button" id="playground-send-btn">
447 <span class="dashicons dashicons-arrow-up-alt"></span>
448 </button>
449 </div>
450 </div>
451 </aside>
452
453 </div>
454 </section>
455 </div>
456 </div>
457
458 <script>
459 jQuery(document).ready(function($) {
460 // --- SIDEBAR TAB SWITCHING LOGIC ---
461 function switchTab(targetId, linkObj) {
462 $('.ai-content-pane').hide();
463 $('.ai-sidebar-link').removeClass('active');
464 $('.qcld-ai-actions-layout nav > ul > li').removeClass('tab-current');
465 $('.ai-saved-actions-submenu li').removeClass('tab-current');
466
467 $('#' + targetId).show();
468 if (linkObj) {
469 linkObj.addClass('active');
470 } else {
471 linkObj = $('.ai-sidebar-link[href="#' + targetId + '"]');
472 linkObj.addClass('active');
473 }
474 if (linkObj && linkObj.length) {
475 linkObj.closest('li').addClass('tab-current');
476 if (linkObj.hasClass('ai-sidebar-saved-link')) {
477 $('.qcld-ai-saved-parent').addClass('is-open');
478 }
479 }
480
481 // Hide Save button if history tab (if we still had it globally, but we don't)
482 $('#ai-save-wrapper').show();
483
484 // Save to sessionStorage so it stays open after reload
485 sessionStorage.setItem('qcld_ai_active_tab', targetId);
486 }
487
488 // Restore active tab on page load
489 var savedTab = sessionStorage.getItem('qcld_ai_active_tab');
490 if (savedTab) {
491 var linkToOpen = null;
492 var tabToOpen = null;
493
494 if ($('#' + savedTab).length) {
495 tabToOpen = savedTab;
496 linkToOpen = $('.ai-sidebar-link[href="#' + savedTab + '"]');
497 } else if (savedTab.indexOf('ai-action-tab-') === 0) {
498 // Was a newly generated tab. After saving, it becomes the last saved action.
499 var lastSavedLink = $('.ai-sidebar-saved-link').last();
500 if (lastSavedLink.length) {
501 tabToOpen = lastSavedLink.attr('href').substring(1);
502 linkToOpen = lastSavedLink;
503 // Update session storage to the new real ID
504 sessionStorage.setItem('qcld_ai_active_tab', tabToOpen);
505 }
506 }
507
508 if (tabToOpen) {
509 switchTab(tabToOpen, null);
510 if (linkToOpen && linkToOpen.closest('.ai-saved-actions-submenu').length) {
511 $('.ai-saved-actions-submenu').show();
512 $('.qcld-ai-saved-parent').addClass('is-open');
513 $('.qcld-ai-saved-toggle').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
514 }
515 }
516 }
517
518 $(document).on('click', '.qcld-ai-goto-new-action', function(e) {
519 e.preventDefault();
520 switchTab('ai-new-action-tab', $('.ai-sidebar-link[href="#ai-new-action-tab"]'));
521 });
522
523 $(document).on('click', '.ai-sidebar-link', function(e) {
524 e.preventDefault();
525 var href = $(this).attr('href') || '';
526 if (href.indexOf('#') === -1) {
527 return;
528 }
529 var target = href.substring(href.indexOf('#') + 1);
530 if (!target) {
531 return;
532 }
533 switchTab(target, $(this));
534 });
535
536 // --- SAVED ACTIONS SUBMENU TOGGLE ---
537 $('.ai-sidebar-parent-link').on('click', function(e) {
538 e.preventDefault();
539 var submenu = $(this).next('.ai-saved-actions-submenu');
540 var icon = $(this).find('.qcld-ai-saved-toggle');
541 $(this).closest('li').toggleClass('is-open');
542
543 submenu.slideToggle(200);
544 if (icon.hasClass('dashicons-arrow-down-alt2')) {
545 icon.removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
546 } else {
547 icon.removeClass('dashicons-arrow-up-alt2').addClass('dashicons-arrow-down-alt2');
548 }
549 });
550
551 // --- INNER TABS (SETTINGS/HISTORY) ---
552 $(document).on('click', '.wpbot-ai-inner-tabs .nav-tab', function(e) {
553 e.preventDefault();
554
555 if ($(this).attr('href') === '#') return false;
556
557 var pane = $(this).closest('.ai-content-pane');
558 var targetId = $(this).attr('href').substring(1);
559
560 // Tab styling
561 pane.find('.wpbot-ai-inner-tabs .nav-tab').removeClass('nav-tab-active');
562 $(this).addClass('nav-tab-active');
563
564 // Tab content
565 pane.find('.ai-inner-tab-content').hide();
566 pane.find('#' + targetId).fadeIn(200);
567
568 // Handle History AJAX loading
569 if ($(this).hasClass('ai-load-history-btn')) {
570 var contentTarget = $(this).data('target');
571 var formTitle = pane.find('.ai-form-title-input').val();
572
573 var targetContainer = $('#' + contentTarget);
574 targetContainer.html('<p style="color: #666; font-style: italic;"><?php esc_html_e('Loading history...', 'chatbot'); ?></p>');
575
576 if (!formTitle || formTitle.trim() === '') {
577 targetContainer.html('<p style="color: #a00;"><?php esc_html_e('Please save the form with a title first to preview entries.', 'chatbot'); ?></p>');
578 return;
579 }
580
581 var data = {
582 action: 'qcld_get_ai_form_entries',
583 form_title: formTitle,
584 nonce: '<?php echo esc_js( wp_create_nonce( 'wp_chatbot_ai_actions' ) ); ?>'
585 };
586
587 $.post(ajaxurl, data, function(response) {
588 if (response.success) {
589 targetContainer.html(response.data.html);
590 } else {
591 targetContainer.html('<p style="color: #a00;"><?php esc_html_e('Error loading entries.', 'chatbot'); ?></p>');
592 }
593 }).fail(function() {
594 targetContainer.html('<p style="color: #a00;"><?php esc_html_e('Error connecting to server.', 'chatbot'); ?></p>');
595 });
596 }
597 });
598
599 // --- DELETE HISTORY ENTRY ---
600 $(document).on('click', '.qcld-delete-ai-entry', function(e) {
601 e.preventDefault();
602 var btn = $(this);
603 var entryId = btn.data('id');
604
605 if (!confirm('<?php esc_html_e('Are you sure you want to delete this history entry?', 'chatbot'); ?>')) {
606 return;
607 }
608
609 btn.prop('disabled', true).text('Deleting...');
610
611 var data = {
612 action: 'qcld_delete_ai_form_entry',
613 entry_id: entryId,
614 nonce: '<?php echo esc_js( wp_create_nonce( 'wp_chatbot_ai_actions' ) ); ?>'
615 };
616
617 $.post(ajaxurl, data, function(response) {
618 if (response.success) {
619 btn.closest('tr').fadeOut(300, function() { $(this).remove(); });
620 } else {
621 alert('Error: ' + response.data);
622 btn.prop('disabled', false).text('Delete');
623 }
624 }).fail(function() {
625 alert('Error connecting to server.');
626 btn.prop('disabled', false).text('Delete');
627 });
628 });
629
630 // --- CREATE NEW ACTION FROM TEMPLATE ---
631 $('.ai-template-card').on('click', function() {
632 var title = $(this).data('title');
633 var prompt = $(this).data('prompt');
634
635 var uniqueId = 'ai_form_' + Math.floor(Math.random() * 1000000);
636 var tabId = 'ai-action-tab-' + uniqueId;
637 var chk_interactive_id = 'ai_interactive_' + uniqueId;
638 var chk_email_id = 'ai_email_' + uniqueId;
639 var displayTitle = title ? title : 'New Blank Action';
640
641 // Remove "No saved actions" if exists
642 $('.ai-no-saved-actions').remove();
643
644 // 1. Add Sidebar Link
645 var linkHtml = '<li><a href="#' + tabId + '" class="ai-sidebar-link ai-sidebar-saved-link" data-id="' + tabId + '">' + displayTitle + '</a></li>';
646 $('.ai-saved-actions-submenu').append(linkHtml);
647
648 // Ensure submenu is open
649 $('.ai-saved-actions-submenu').slideDown(200);
650 $('.qcld-ai-saved-parent').addClass('is-open');
651 $('.qcld-ai-saved-toggle').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
652
653 // 2. Add Form Pane
654 var template = `
655 <div id="` + tabId + `" class="ai-content-pane ai-form-item" style="display: none;">
656 <div class="qcld-ai-action-edit-head">
657 <h3 class="qcld-wpbot-main-tabs-title"><?php esc_html_e('Edit Action', 'chatbot'); ?></h3>
658 <div class="qcld-ai-action-edit-actions">
659 <button type="button" class="qcld-btn-primary qcld-ai-goto-new-action"><?php esc_html_e('Add New Action', 'chatbot'); ?></button>
660 <button type="button" class="button remove-ai-form"><?php esc_html_e( 'Delete Action', 'chatbot' ); ?></button>
661 </div>
662 </div>
663
664 <h2 class="nav-tab-wrapper wpbot-ai-inner-tabs">
665 <a href="#ai-inner-settings-` + uniqueId + `" class="nav-tab nav-tab-active"><?php esc_html_e('Settings', 'chatbot'); ?></a>
666 <a href="#" class="nav-tab qcld-ai-history-pro-tab"><?php esc_html_e('History', 'chatbot'); ?> <span class="qc_wpbot_pro">PRO</span></a>
667 </h2>
668
669 <div id="ai-inner-settings-` + uniqueId + `" class="ai-inner-tab-content">
670 <div class="form-group">
671 <label><?php esc_html_e('Action Title', 'chatbot'); ?></label>
672 <input type="text" name="ai_form_title[]" class="form-control ai-form-title-input" placeholder="<?php esc_attr_e('e.g., Hotel Booking', 'chatbot'); ?>" value="` + title + `" />
673 </div>
674 <div class="form-group">
675 <label><?php esc_html_e('AI Prompt', 'chatbot'); ?></label>
676 <textarea name="ai_form_prompt[]" class="form-control" rows="8" placeholder="<?php esc_attr_e('Enter your prompt here...', 'chatbot'); ?>">` + prompt + `</textarea>
677 </div>
678
679 <div class="cxsc-settings-blocks">
680 <div class="form-group qcld-ai-email-toggle">
681 <input type="hidden" name="ai_form_email[]" class="ai-email-val" value="1">
682 <input type="checkbox" id="` + chk_email_id + `" checked onchange="jQuery(this).prev(\'.ai-email-val\').val(this.checked ? 1 : 0);">
683 <label for="` + chk_email_id + `"><?php esc_html_e('Email the data', 'chatbot'); ?></label>
684 </div>
685 <div class="qcld-ai-email-field">
686 <label><?php esc_html_e('Send to Email(s)', 'chatbot'); ?></label>
687 <input type="text" name="ai_form_email_addresses[]" class="form-control" placeholder="<?php echo esc_attr( get_option('qlcd_wp_chatbot_admin_email', get_option('admin_email')) ); ?>" value="">
688 <p class="qcld-ai-field-hint"><?php esc_html_e('Comma-separated. Leave blank to use the default admin email.', 'chatbot'); ?></p>
689 </div>
690 </div>
691 </div>
692
693 <div id="ai-inner-history-` + uniqueId + `" class="ai-inner-tab-content" style="display: none;">
694 <div id="ai-inner-history-content-` + uniqueId + `">
695 <p class="qcld-ai-muted"><?php esc_html_e('Loading history...', 'chatbot'); ?></p>
696 </div>
697 </div>
698 </div>
699 `;
700 $('#ai-saved-actions-container').append(template);
701
702 // 3. Switch to it immediately
703 switchTab(tabId, $('.ai-sidebar-link[href="#' + tabId + '"]'));
704
705 // 4. Update preview playground
706 updateAiActionsPreview();
707 });
708
709 // --- REMOVE FORM ITEM ---
710 $(document).on('click', '.remove-ai-form', function(e) {
711 e.preventDefault();
712 var pane = $(this).closest('.ai-content-pane');
713 var tabId = pane.attr('id');
714
715 // Remove pane
716 pane.remove();
717
718 // Remove sidebar link
719 $('.ai-sidebar-link[href="#' + tabId + '"]').parent().remove();
720
721 // Check if submenu is empty
722 if ($('.ai-saved-actions-submenu li').length === 0) {
723 $('.ai-saved-actions-submenu').html('<li class="ai-no-saved-actions"><?php esc_html_e('No saved actions', 'chatbot'); ?></li>');
724 }
725
726 // Switch back to Add New Action tab
727 switchTab('ai-new-action-tab', $('.ai-sidebar-link[href="#ai-new-action-tab"]'));
728
729 updateAiActionsPreview();
730 });
731
732 // --- UPDATE HEADER DYNAMICALLY ---
733 $(document).on('keyup', '.ai-form-title-input', function() {
734 var newTitle = $(this).val();
735 var paneId = $(this).closest('.ai-content-pane').attr('id');
736 var sidebarLink = $('.ai-sidebar-link[href="#' + paneId + '"]');
737
738 if (newTitle.trim() === '') {
739 newTitle = '<?php esc_html_e('Untitled Action', 'chatbot'); ?>';
740 }
741 sidebarLink.text(newTitle);
742 updateAiActionsPreview();
743 });
744
745 // --- PREVIEW UPDATING FUNCTION ---
746 function updateAiActionsPreview() {
747 var previewContainer = $('#ai-actions-live-preview');
748 previewContainer.empty();
749
750 var titles = [];
751 $('.saved-ai-action .ai-form-title-input').each(function() {
752 var val = $(this).val().trim();
753 if(val) {
754 titles.push(val);
755 }
756 });
757
758 if(titles.length === 0) {
759 previewContainer.append('<span class="playground-ai-action-btn is-empty"><?php esc_html_e('No Actions Created Yet', 'chatbot'); ?></span>');
760 } else {
761 $.each(titles, function(index, title) {
762 previewContainer.append('<span class="playground-ai-action-btn">' + title + '</span>');
763 });
764 }
765 }
766
767 // --- PLAYGROUND INTERACTIVE LOGIC ---
768 var aiContext = [];
769
770 var playgroundIcon = '<?php echo esc_url( $wp_chatbot_custom_icon_path ); ?>';
771
772 function appendUserMessage(text) {
773 var msgHtml = '<div class="qcld-ai-pg-user-row">' +
774 '<div class="qcld-ai-pg-user-bubble">' + text + '</div>' +
775 '</div>';
776 $('#ai-actions-playground-messages').append(msgHtml);
777 scrollToBottom();
778 }
779
780 function appendBotMessage(text) {
781 var msgHtml = '<div class="qcld-ai-pg-bot-row">' +
782 '<div class="qcld-ai-pg-avatar" style="background-image: url(\'' + playgroundIcon + '\');"></div>' +
783 '<div class="qcld-ai-pg-bubble">' + text + '</div>' +
784 '</div>';
785 $('#ai-actions-playground-messages').append(msgHtml);
786 scrollToBottom();
787 }
788
789 function appendLoader() {
790 var msgHtml = '<div id="playground-loader" class="qcld-ai-pg-bot-row">' +
791 '<div class="qcld-ai-pg-avatar" style="background-image: url(\'' + playgroundIcon + '\');"></div>' +
792 '<div class="qcld-ai-pg-bubble is-loading"><i>Thinking...</i></div>' +
793 '</div>';
794 $('#ai-actions-playground-messages').append(msgHtml);
795 scrollToBottom();
796 }
797
798 function scrollToBottom() {
799 var container = $('#ai-actions-playground-container');
800 container.scrollTop(container[0].scrollHeight);
801 }
802
803 function formatBotResponse(text) {
804 // Remove internal tracking flag
805 text = text.replace(/__AI_FORM_IN_PROGRESS__/g, '');
806
807 // Extract and format AI_FORM_DATA block
808 // This regex optionally matches surrounding HTML tags to ensure they are replaced too, preventing broken tags.
809 var regex = /(?:<[^>]+>)*\s*AI_FORM_DATA[\s\S]*?__AI_FORM_DATA_END__\s*(?:<\/[^>]+>)*/g;
810 text = text.replace(regex, function(match) {
811 try {
812 // Extract just the JSON part from the match (from the first '{' to the last '}')
813 var jsonMatch = match.match(/\{[\s\S]*\}/);
814 if (!jsonMatch) {
815 return match;
816 }
817 var jsonStr = jsonMatch[0];
818 var data = JSON.parse(jsonStr.trim());
819 var html = '<div class="qcld-ai-pg-form-data">';
820 if (data.form_title) {
821 html += '<strong>' + data.form_title + '</strong>';
822 }
823 if (data.data) {
824 html += '<ul>';
825 for (var key in data.data) {
826 html += '<li style="margin-bottom: 3px;"><strong>' + key + ':</strong> ' + data.data[key] + '</li>';
827 }
828 html += '</ul>';
829 }
830 html += '</div>';
831 return html;
832 } catch (e) {
833 return match; // Return original if parsing fails
834 }
835 });
836
837 var cleanResponse = text.replace(/(\w+)\n/g,'$1 ');
838 cleanResponse = cleanResponse.replace(/```(.*?)```/gs, '<pre style="background: #f4f4f4; padding: 8px; border-radius: 5px; overflow-x: auto; font-size: 12px;">$1</pre>');
839 cleanResponse = cleanResponse.replace(/`(.*?)`/g, '<code style="background: #f4f4f4; padding: 2px 4px; border-radius: 3px;">$1</code>');
840 cleanResponse = cleanResponse.replace(/\n/g, '<br>');
841 return cleanResponse;
842 }
843
844 function sendToAI(text, actionPrompt) {
845 appendUserMessage(text);
846 appendLoader();
847
848 aiContext.push({role: 'user', content: text});
849 if (aiContext.length > 10) {
850 aiContext.shift();
851 }
852
853 var activeProvider = '<?php echo esc_js($default_provider); ?>';
854 var actionMap = {
855 'openai': 'qcld_openai_response',
856 'gemini': 'qcld_gemini_response',
857 'claude': 'claude_response',
858 'grok': 'qcld_grok_response',
859 'openrouter': 'openrouter_response'
860 };
861 var ajaxAction = actionMap[activeProvider] || 'qcld_openai_response';
862
863 var data = {
864 action: ajaxAction,
865 keyword: text,
866 ai_history: JSON.stringify(aiContext),
867 is_ai_actions_playground: 1,
868 action_prompt: actionPrompt || '',
869 nonce: '<?php echo esc_js( wp_create_nonce( 'wp_chatbot' ) ); ?>'
870 };
871
872 $.post(ajaxurl, data, function(res) {
873 $('#playground-loader').remove();
874
875 var json = res;
876 if (typeof res === 'string') {
877 try {
878 json = $.parseJSON(res);
879 } catch(e) {}
880 }
881
882 if (json && json.status === 'success') {
883 var reply = json.message;
884 aiContext.push({role: 'assistant', content: reply});
885 if (aiContext.length > 10) {
886 aiContext.shift();
887 }
888 appendBotMessage(formatBotResponse(reply));
889 } else {
890 appendBotMessage('<?php esc_html_e('Sorry, there was an error processing your request.', 'chatbot'); ?>');
891 }
892 }).fail(function() {
893 $('#playground-loader').remove();
894 appendBotMessage('<?php esc_html_e('Error connecting to AI service.', 'chatbot'); ?>');
895 });
896 }
897
898 $(document).on('click', '.playground-ai-action-btn', function() {
899 if ($(this).hasClass('is-empty')) {
900 return;
901 }
902 var text = $(this).text().trim();
903
904 var matchedPrompt = '';
905 $('.ai-form-title-input').each(function() {
906 if ($(this).val().trim().toLowerCase() === text.toLowerCase()) {
907 matchedPrompt = $(this).closest('.ai-content-pane').find('textarea[name="ai_form_prompt[]"]').val() || '';
908 }
909 });
910
911 aiContext = [];
912 sendToAI(text, matchedPrompt);
913 });
914
915 $('#playground-input').on('keypress', function(e) {
916 if(e.which === 13) {
917 var text = $(this).val().trim();
918 if(text) {
919 $(this).val('');
920 sendToAI(text);
921 }
922 }
923 });
924
925 $('#playground-send-btn').on('click', function() {
926 var text = $('#playground-input').val().trim();
927 if(text) {
928 $('#playground-input').val('');
929 sendToAI(text);
930 }
931 });
932
933 $('#ai-playground-refresh').on('click', function() {
934 var $messages = $('#ai-actions-playground-messages');
935 $messages.children(':not(:first)').remove();
936 updateAiActionsPreview();
937 });
938
939 $(document).on('click', '.qcld-ai-history-pro-tab', function(e) {
940 e.preventDefault();
941 return false;
942 });
943
944 // --- INITIALIZATION ---
945 updateAiActionsPreview();
946
947 // Make sure initial state shows first tab if history or saved tab isn't already active (fallback)
948 if ($('.ai-sidebar-link.active').length === 0) {
949 $('.ai-sidebar-link[href="#ai-new-action-tab"]').addClass('active');
950 $('#ai-new-action-tab').show();
951 }
952 });
953 </script>
954