get_charset_collate(); // Conversation table $conversation_sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}" . self::$conversation_table . "` ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, campaign_id BIGINT(20) UNSIGNED NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, conversation_steps JSON NOT NULL, prompt TEXT NOT NULL, PRIMARY KEY (id), INDEX campaign_id_idx (campaign_id) ) $charset_collate;"; // Message table $message_sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}" . self::$message_table . "` ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, campaign_id BIGINT(20) UNSIGNED NOT NULL, conversation_id BIGINT(20) UNSIGNED NOT NULL, scheduled_for_timestamp DATETIME NOT NULL, status ENUM('pending', 'in_progress', 'sent', 'failed') NOT NULL DEFAULT 'pending', from_email VARCHAR(255) NOT NULL, to_email TEXT NOT NULL, cc TEXT NULL, subject VARCHAR(255) NOT NULL, body TEXT NOT NULL, PRIMARY KEY (id), INDEX scheduled_idx (scheduled_for_timestamp, status), INDEX conversation_id_idx (conversation_id), INDEX campaign_id_idx (campaign_id) ) $charset_collate;"; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta($conversation_sql); dbDelta($message_sql); } /** * Insert a conversation record. */ public static function insert_conversation($campaign_id, $conversation_steps, $prompt) { global $wpdb; $wpdb->insert( "{$wpdb->prefix}" . self::$conversation_table, [ 'campaign_id' => $campaign_id, 'conversation_steps' => json_encode($conversation_steps), 'prompt' => $prompt, ], ['%d', '%s', '%s'] ); return $wpdb->insert_id; } /** * Insert a message record. */ public static function insert_message($campaign_id, $conversation_id, $scheduled_for, $from_email, $to_email, $cc, $subject, $body) { global $wpdb; $wpdb->insert( "{$wpdb->prefix}" . self::$message_table, [ 'campaign_id' => $campaign_id, 'conversation_id' => $conversation_id, 'scheduled_for_timestamp' => $scheduled_for, 'status' => 'pending', 'from_email' => $from_email, 'to_email' => $to_email, 'cc' => $cc, 'subject' => $subject, 'body' => $body, ], ['%d', '%d', '%s', '%s', '%s', '%s', '%s', '%s'] ); return $wpdb->insert_id; } /** * Fetch pending messages. */ public static function fetch_pending_messages($limit = 100) { global $wpdb; $sql = $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}" . self::$message_table . "` WHERE scheduled_for_timestamp <= %s AND status = 'pending' LIMIT %d", current_time('mysql'), $limit ); return $wpdb->get_results($sql, ARRAY_A); } }