PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.5.6
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.5.6
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / includes / REST / AIFaq.php

AIFaq.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.5.6, at includes/REST/AIFaq.php

127 lines 4.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPDeveloper\BetterDocs\REST;
4
5 use WP_REST_Request;
6 use WPDeveloper\BetterDocs\Core\BaseAPI;
7 use WPDeveloper\BetterDocs\Utils\AIUsage;
8
9 /**
10 * Server-side proxy for the "Write FAQ with BetterDocs AI" feature.
11 *
12 * The FAQ builder used to call OpenAI directly from the browser with the secret API key —
13 * this endpoint moves that call server-side so the key never leaves the site. Uses the
14 * same dynamic model/token settings as Write with AI (write_with_ai_model).
15 */
16 class AIFaq extends BaseAPI {
17
18 const MAX_QUESTION_LENGTH = 500;
19 const MAX_KEYWORDS_LENGTH = 300;
20
21 public function register() {
22 $this->post(
23 '/ai-faq',
24 array( $this, 'generate' ),
25 array(
26 'question' => array(
27 'type' => 'string',
28 'required' => true
29 ),
30 'keywords' => array(
31 'type' => 'string',
32 'required' => false,
33 'default' => ''
34 )
35 )
36 );
37 }
38
39 public function permission_check() {
40 return current_user_can( 'edit_others_posts' );
41 }
42
43 public function generate( WP_REST_Request $request ) {
44 $settings = betterdocs()->settings;
45
46 if ( ! $settings->get( 'enable_faq_write_with_ai', true ) ) {
47 return $this->error(
48 'ai_disabled',
49 __( 'Write FAQ with AI is disabled. Enable it from BetterDocs settings.', 'betterdocs' ),
50 400
51 );
52 }
53
54 $write_ai = betterdocs()->ai_autowrtie;
55 if ( empty( $write_ai ) || empty( $write_ai->get_api_key() ) ) {
56 return $this->error(
57 'ai_no_key',
58 __( 'OpenAI API key is missing. Add one in BetterDocs settings.', 'betterdocs' ),
59 400
60 );
61 }
62
63 $question = trim( wp_strip_all_tags( (string) $request->get_param( 'question' ) ) );
64 $keywords = trim( wp_strip_all_tags( (string) $request->get_param( 'keywords' ) ) );
65
66 if ( $question === '' ) {
67 return $this->error(
68 'ai_empty_question',
69 __( 'Please provide a question for the AI.', 'betterdocs' ),
70 400
71 );
72 }
73
74 if ( strlen( $question ) > self::MAX_QUESTION_LENGTH ) {
75 $question = substr( $question, 0, self::MAX_QUESTION_LENGTH );
76 }
77 if ( strlen( $keywords ) > self::MAX_KEYWORDS_LENGTH ) {
78 $keywords = substr( $keywords, 0, self::MAX_KEYWORDS_LENGTH );
79 }
80
81 $prompt = sprintf(
82 'Generate an FAQ answer for the question related to %s. The question: %s',
83 $keywords,
84 $question
85 );
86 $system = __( 'You are a helpful assistant that writes clear, concise FAQ answers.', 'betterdocs' );
87
88 $result = $write_ai->generate_text( $prompt, $system );
89
90 if ( empty( $result['success'] ) ) {
91 $message = isset( $result['error'] ) ? (string) $result['error'] : __( 'Unknown AI error.', 'betterdocs' );
92 return $this->error( 'ai_upstream', $message, 502 );
93 }
94
95 $answer = $this->clean_response( (string) $result['content'] );
96
97 if ( $answer === '' ) {
98 return $this->error(
99 'ai_empty_response',
100 __( 'The AI returned no answer. Try again or rephrase your question.', 'betterdocs' ),
101 502
102 );
103 }
104
105 // FAQ answers are generated before the FAQ post exists — no reliable post id.
106 AIUsage::record( 'faq_write_with_ai' );
107
108 return $this->success(
109 array(
110 'answer' => $answer,
111 'model' => isset( $result['model'] ) ? $result['model'] : null
112 )
113 );
114 }
115
116 /**
117 * Strip the leading "Answer:" label / stray leading "?" the browser-side code removed.
118 */
119 protected function clean_response( $text ) {
120 $text = trim( $text );
121 $text = preg_replace( '/^\s*answer\s*:\s*/i', '', $text );
122 $text = preg_replace( '/^\s*\?/', '', $text );
123
124 return trim( $text );
125 }
126 }
127