kimaai_chatbot_blocked Hook #
The kimaai_chatbot_blocked action fires whenever a chatbot request is blocked by the gate (i.e., when kimaai_chatbot_gate does not return true). It’s designed for logging, analytics, security monitoring, and user-facing diagnostics.
This hook is triggered before the REST API returns a 403 response to the frontend.
When it fires #
A request is considered “blocked” when the kimaai_chatbot_gate filter returns anything other than true, for example:
- a string (used as the error message shown to the user)
- a
WP_Error(its message is shown to the user) - any other non-
truevalue (falls back to a generic message)
When blocked, the plugin:
- builds the error message
- calls
do_action( 'kimaai_chatbot_blocked', ... ) - logs a warning
- returns
WP_REST_Response([ 'error' => $message ], 403)
Hook signature #
/**
* Action fired when a request is blocked by the gate.
*
* @param string $reason Message returned to the client.
* @param array $payload Normalized payload.
* @param array $data Raw request data.
* @param WP_REST_Request $request Request.
*/
do_action('kimaai_chatbot_blocked', $error_message, $payload, $data, $request);
Parameters #
1) $reason (string) #
The message that will be returned to the client (frontend) as:
{ "error": "..." }
It comes from:
$allowed->get_error_message()if the gate returnedWP_Error- the returned string if the gate returned a string
- otherwise a default translated message
2) $payload (array) #
A normalized payload assembled by the chatbot handler. At minimum includes:
prompt(string) — the normalized prompt afterkimaai_chatbot_promptpostId(int)selectedTools(string[])- later in the request lifecycle it may include more, but at the time of blocking it usually contains the above
3) $data (array) #
The raw JSON body from the request, e.g.:
messagepostId
4) $request (WP_REST_Request) #
The REST request object (headers, route, IP-related context if you derive it elsewhere, etc.).
Basic usage: log blocked prompts #
add_action('kimaai_chatbot_blocked', function ($reason, $payload, $data, $request) {
error_log('[KimaAI Chatbot Blocked] ' . $reason);
error_log('Prompt: ' . ($payload['prompt'] ?? ''));
error_log('Post ID: ' . (int) ($payload['postId'] ?? 0));
}, 10, 4);
Example: track blocked events in analytics (non-invasive) #
add_action('kimaai_chatbot_blocked', function ($reason, $payload) {
// Pseudocode: replace with your analytics integration.
if (function_exists('my_analytics_track')) {
my_analytics_track('kimaai_chatbot_blocked', [
'reason' => $reason,
'postId' => (int) ($payload['postId'] ?? 0),
'hasToolsSelected' => !empty($payload['selectedTools']),
]);
}
}, 10, 4);
Example: notify admins when certain blocks spike #
You can increment a transient counter and email admins when it exceeds a threshold.
add_action('kimaai_chatbot_blocked', function ($reason) {
$key = 'kimaai_blocked_count_' . gmdate('YmdH'); // per hour
$count = (int) get_transient($key);
$count++;
set_transient($key, $count, HOUR_IN_SECONDS);
if ($count === 25) {
wp_mail(
get_option('admin_email'),
'KimaAI Chatbot: high block rate',
"Blocked requests reached 25 this hour.\nLatest reason: {$reason}"
);
}
}, 10, 4);
Example: capture context safely (privacy-aware) #
If you need to store diagnostics, avoid raw prompts and store a hash instead.
add_action('kimaai_chatbot_blocked', function ($reason, $payload, $data, $request) {
$prompt = (string) ($payload['prompt'] ?? '');
$prompt_hash = $prompt !== '' ? hash('sha256', $prompt) : '';
$entry = [
'time' => time(),
'reason' => $reason,
'prompt_hash' => $prompt_hash,
'postId' => (int) ($payload['postId'] ?? 0),
'route' => method_exists($request, 'get_route') ? $request->get_route() : '',
];
// Store however you want (options table, custom table, external logger, etc.)
error_log('[KimaAI Blocked] ' . wp_json_encode($entry));
}, 10, 4);
Related hooks you’ll often use with it #
Gate: kimaai_chatbot_gate (blocks/permits) #
You typically pair your blocking logic with logging via kimaai_chatbot_blocked.
add_filter('kimaai_chatbot_gate', function ($allowed, $prompt, $payload) {
// Block empty-ish messages
if (trim($prompt) === '') {
return __('Please enter a message.', 'your-textdomain');
}
// Block specific terms
if (stripos($prompt, 'refund my card') !== false) {
return new WP_Error('kimaai_blocked_sensitive', __('Please contact support for billing requests.', 'your-textdomain'));
}
return true;
}, 10, 3);
Prompt normalization: kimaai_chatbot_prompt #
Runs before the gate, useful for trimming, removing repeated whitespace, etc.
Rate limit action: kimaai_chatbot_rate_limited #
Separate from gate-blocks (fires when the daily message limit is hit).
Notes and best practices #
- Don’t echo output inside the hook. This runs during a REST request and can corrupt JSON responses.
- Treat
$payload/$dataas user input (sanitize before storing/logging). - If you store anything, consider privacy and avoid logging full prompts unless you truly need them.
- Use the hook for telemetry, alerts, auditing, and debugging—not for modifying the response (the decision to block has already been made).