PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.5.4
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.5.4
3.5.4 3.5.3 3.5.2 3.5.1 3.4.9 3.5.0 3.4.8 3.4.7 trunk 2.3.1 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6
supportcandy / includes / admin / ai-chatbot / includes / class-wpsc-acb-cron.php

class-wpsc-acb-cron.php in SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent 3.5.4, at includes/admin/ai-chatbot/includes/class-wpsc-acb-cron.php

278 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly!
4 }
5
6 if ( ! class_exists( 'WPSC_ACB_Cron' ) ) :
7
8 final class WPSC_ACB_Cron {
9
10 /**
11 * Initialize this class
12 *
13 * @return void
14 */
15 public static function init() {
16
17 // Register custom cron schedules.
18 add_filter( 'cron_schedules', array( __CLASS__, 'register_cron_schedules' ) );
19
20 // Chatbot session check cron jobs.
21 add_action( 'init', array( __CLASS__, 'schedule_events' ) );
22
23 // Check chatbot sessions and inactive session if necessary.
24 add_action( 'wpsc_acb_session_check', array( __CLASS__, 'acb_session_check' ) );
25
26 // Delete chatbot logs cron job.
27 add_action( 'wpsc_delete_acb_logs', array( __CLASS__, 'delete_acb_logs' ) );
28 }
29
30 /**
31 * Register custom cron schedules.
32 *
33 * @param array $schedules Existing schedules.
34 * @return array
35 */
36 public static function register_cron_schedules( $schedules ) {
37
38 if ( ! isset( $schedules['wpsc_every_fifteen_minutes'] ) ) {
39 $schedules['wpsc_every_fifteen_minutes'] = array(
40 'interval' => 15 * MINUTE_IN_SECONDS,
41 'display' => __( 'Every 15 Minutes', 'supportcandy' ),
42 );
43 }
44
45 return $schedules;
46 }
47
48 /**
49 * Check chatbot sessions and inactive session if necessary.
50 *
51 * @return void
52 */
53 public static function schedule_events() {
54 $session_check_hook = 'wpsc_acb_session_check';
55 $session_check_recurrence = 'wpsc_every_fifteen_minutes';
56 $next_session_check = wp_next_scheduled( $session_check_hook );
57
58 // Ensure this hook uses intended recurrence.
59 if ( ! $next_session_check ) {
60 wp_schedule_event( time(), $session_check_recurrence, $session_check_hook );
61 } elseif ( wp_get_schedule( $session_check_hook ) !== $session_check_recurrence ) {
62 wp_clear_scheduled_hook( $session_check_hook );
63 wp_schedule_event( time(), $session_check_recurrence, $session_check_hook );
64 }
65
66 $acb_settings = get_option( 'wpsc-ps-acb-chatbot-settings', array() );
67
68 $auto_delete_acb_logs_time = isset( $acb_settings['delete-acb-session-time'] ) ? intval( $acb_settings['delete-acb-session-time'] ) : 0;
69 if ( $auto_delete_acb_logs_time > 0 && ! wp_next_scheduled( 'wpsc_delete_acb_logs' ) ) {
70 wp_schedule_single_event( time(), 'wpsc_delete_acb_logs' );
71 }
72 }
73
74 /**
75 * Check chatbot sessions and inactive session if necessary.
76 *
77 * @return void
78 */
79 public static function acb_session_check() {
80
81 $acb_settings = get_option( 'wpsc-ps-acb-chatbot-settings', array() );
82 if ( empty( $acb_settings['status'] ) || '1' !== $acb_settings['status'] ) {
83 return;
84 }
85
86 $now = new DateTime( 'now' );
87 $inactive_cutoff = $now->modify( '-1 hour' )->format( 'Y-m-d H:i:s' );
88
89 // Get all active sessions.
90 $sessions = WPSC_ACB_Sessions::find(
91 array(
92 'items_per_page' => 50,
93 'orderby' => 'last_activity',
94 'order' => 'ASC',
95 'meta_query' => array(
96 'relation' => 'AND',
97 array(
98 'slug' => 'status',
99 'compare' => '=',
100 'val' => WPSC_ACB_Status::ACTIVE,
101 ),
102 array(
103 'slug' => 'last_activity',
104 'compare' => '<=',
105 'val' => $inactive_cutoff,
106 ),
107 ),
108 ),
109 );
110 $active_sessions = $sessions['results'] ?? array();
111
112 // No active sessions found. Cache this result for 1 hour.
113 if ( empty( $active_sessions ) ) {
114 return;
115 }
116
117 // Mark sessions as inactive if last activity was more than 1 hour ago.
118 foreach ( $active_sessions as $session ) {
119
120 $data = self::analyze_chat_conversation( $session->id );
121 if ( ! empty( $data['subject'] ) ) {
122 $session->subject = $data['subject'];
123 }
124 $status = $data['status'] ?? WPSC_ACB_Status::INACTIVE;
125
126 if ( is_string( $status ) ) {
127 $status = WPSC_ACB_Status::get_value_by_key( $status );
128 }
129
130 if ( ! is_int( $status ) || ! WPSC_ACB_Status::is_valid( $status ) ) {
131 $status = WPSC_ACB_Status::INACTIVE;
132 }
133
134 $session->status = $status;
135 $session->save();
136 }
137 }
138
139
140 /**
141 * Analyze chat conversation and determine subject and status.
142 *
143 * @param int $session_id Session ID.
144 * @return array Analysis result with success, subject, status, and message.
145 */
146 public static function analyze_chat_conversation( $session_id ) {
147
148 $ai_settings = get_option( 'wpsc-ps-ai-assistant-settings', array() );
149 if ( empty( $ai_settings['is-active'] ) ) {
150 return array(
151 'subject' => __( 'AI assistant is inactive.', 'supportcandy' ),
152 'status' => WPSC_ACB_Status::INACTIVE,
153 );
154 }
155
156 $system_prompt = self::system_prompt();
157 $conversation_text = WPSC_ACB_Chats::get_conversation_text( 'text', $session_id );
158 $provider = WPSC_AIBOT_Provider_Factory::get_current_provider( $ai_settings['provider'] );
159 return $provider->wpsc_analyze_conversation_subject_status( $ai_settings, $system_prompt, $conversation_text );
160 }
161
162 /**
163 * Delete AI ChatBot logs
164 *
165 * @return void
166 */
167 public static function delete_acb_logs() {
168
169 $acb_settings = get_option( 'wpsc-ps-acb-chatbot-settings', array() );
170 if ( empty( $acb_settings['status'] ) || '1' !== $acb_settings['status'] ) {
171 return;
172 }
173
174 $tz = wp_timezone();
175 $today = new DateTime( 'now', $tz );
176
177 // Get auto delete time and unit from setting.
178 $unit = isset( $acb_settings['delete-acb-session-unit'] ) ? $acb_settings['delete-acb-session-unit'] : 'year';
179 $time = isset( $acb_settings['delete-acb-session-time'] ) ? $acb_settings['delete-acb-session-time'] : 0;
180 if ( $time === 0 ) {
181 return;
182 }
183
184 // Find the date after which tickets should be archived.
185 $age = clone $today;
186 switch ( $unit ) {
187 case 'days':
188 $age->sub( new DateInterval( 'P' . $time . 'D' ) );
189 break;
190
191 case 'month':
192 $age->sub( new DateInterval( 'P' . $time . 'M' ) );
193 break;
194
195 case 'year':
196 $age->sub( new DateInterval( 'P' . $time . 'Y' ) );
197 break;
198 }
199
200 $logs = WPSC_ACB_Sessions::find(
201 array(
202 'items_per_page' => 50,
203 'orderby' => 'last_activity',
204 'order' => 'ASC',
205 'meta_query' => array(
206 'relation' => 'AND',
207 array(
208 'slug' => 'last_activity',
209 'compare' => '<',
210 'val' => $age->format( 'Y-m-d' ),
211 ),
212 ),
213 )
214 );
215
216 if ( $logs['total_items'] > 0 ) {
217 foreach ( $logs['results'] as $log ) {
218 WPSC_ACB_Sessions::destroy( $log );
219 }
220 }
221
222 if ( $logs['has_next_page'] ) {
223 wp_schedule_single_event( time(), 'wpsc_delete_acb_logs' );
224 } else {
225 wp_schedule_single_event( time() + DAY_IN_SECONDS, 'wpsc_delete_acb_logs' );
226 }
227 }
228
229 /**
230 * System prompt for chatbot.
231 *
232 * @return string
233 */
234 private static function system_prompt() {
235
236 return '
237 You are a support conversation analyzer.
238 Analyze the provided conversation and determine:
239 1. A concise support ticket subject.
240 2. The conversation status.
241
242 Status Rules:
243 resolved
244 - The assistant provided an answer, solution, or the requested information for the user\'s issue, even if the user never replied again or left the conversation afterward (e.g. closed the chat/tab without further response).
245 - The user confirms success, satisfaction, understanding, or thanks.
246 - No further action appears required from the assistant.
247
248 abandoned
249 - The assistant asked the user a clarifying question or requested more information, and the user left without responding.
250 - The conversation ended before the assistant could provide any answer, solution, or requested information.
251 - The user\'s issue remains clearly incomplete or unanswered at the point the conversation stopped.
252 - If uncertain, classify as resolved when the assistant\'s last message already addressed the user\'s issue; otherwise classify as abandoned.
253
254 Subject Rules:
255 - Generate a concise support ticket subject between 3 and 8 words.
256 - Focus on the user\'s primary issue or request.
257 - Use professional support desk language.
258 - Do not use quotation marks.
259 - Do not use prefixes such as Subject:, Title:, or Issue:.
260 - If no clear subject exists, use General Inquiry.
261
262 Output Rules:
263 Return ONLY valid JSON.
264 Example:
265 {
266 "subject": "Unable to Login",
267 "status": "resolved"
268 }
269 Do not include explanations.
270 Do not include markdown.
271 Do not include any text outside the JSON object.
272 ';
273 }
274 }
275
276 endif;
277 WPSC_ACB_Cron::init();
278