Filters
replymind_send_comment_data
Decide whether a specific comment is sent to the AI for reply generation. Returning false skips the comment.
apply_filters( 'replymind_send_comment_data', $allow, $comment );
| Argument | Type | Description |
|---|---|---|
$allow |
bool |
Default true |
$comment |
WP_Comment |
The comment being evaluated |
Examples:
// Skip all comments on a specific post.
add_filter( 'replymind_send_comment_data', function ( $allow, $comment ) {
if ( (int) $comment->comment_post_ID === 123 ) {
return false;
}
return $allow;
}, 10, 2 );
// Skip comments from a specific email domain.
add_filter( 'replymind_send_comment_data', function ( $allow, $comment ) {
if ( str_ends_with( $comment->comment_author_email, '@example.com' ) ) {
return false;
}
return $allow;
}, 10, 2 );
// Skip very short comments.
add_filter( 'replymind_send_comment_data', function ( $allow, $comment ) {
if ( str_word_count( $comment->comment_content ) < 5 ) {
return false;
}
return $allow;
}, 10, 2 );
This filter is checked in the cron handler (new comments), the per-comment Generate AI Reply admin action, and the batch process loop. All three respect the same return value.
replymind_daily_limit
Override the daily cap on AI calls.
apply_filters( 'replymind_daily_limit', $limit );
| Argument | Type | Description |
|---|---|---|
$limit |
int |
Default 100. Set to 0 to disable the cap entirely. |
Examples:
// Cap at 1000 replies per day.
add_filter( 'replymind_daily_limit', fn() => 1000 );
// Disable the cap entirely.
add_filter( 'replymind_daily_limit', fn() => 0 );
// Different cap on weekends.
add_filter( 'replymind_daily_limit', function () {
$day = (int) wp_date( 'N' );
return ( $day >= 6 ) ? 50 : 200;
} );
The counter is stored in a date-keyed transient (replymind_daily_YYYYMMDD) and resets at midnight server time. Only successful API calls increment the counter.
Cron events
| Event | Type | Triggered by |
|---|---|---|
replymind_process_comment | one-shot per comment | New approved comment (delayed by Reply Scheduling in Auto mode) |
replymind_process_wc_review | one-shot per review | New approved WooCommerce product review |
add_action( 'replymind_process_comment', function ( $comment_id ) {
// Pre-process hook — runs before ReplyMind's own callback (priority 10).
// Mainly useful for logging or external notifications.
}, 9 );
The plugin's callbacks handle all the eligibility checks (enabled, replymind_send_comment_data, AI Client available, per-post override, sentiment, rules, daily cap, comment still approved at processing time). Each comment gets one event thanks to _replymind_processed meta. A weekly interval is also registered via cron_schedules. Deactivation clears both scheduled hooks.
Comment meta keys
The plugin sets the following keys on the original visitor's comment:
| Meta key | Set when | Value |
|---|---|---|
_replymind_pending_reply |
Suggestion-mode generation succeeds | reply text (may contain HTML) |
_replymind_reply_generated |
A child reply has been posted | '1' |
_replymind_processed |
End of processing (success or error) | '1' |
_replymind_error |
Generation or post fails | error message string |
_replymind_sentiment |
Sentiment detection has run | positive / neutral / negative |
_replymind_flagged |
Sentiment or a Reply Rule flagged the comment | '1' |
The plugin also sets _replymind_reply_generated = '1' on the AI-authored child comment itself.
Querying for comments with a pending draft:
$comments = get_comments( array(
'meta_key' => '_replymind_pending_reply',
'meta_compare' => '!=',
'meta_value' => '',
'status' => 'approve',
'type' => 'comment',
) );
Cleaning up a single comment manually:
delete_comment_meta( $comment_id, '_replymind_pending_reply' );
delete_comment_meta( $comment_id, '_replymind_processed' );
delete_comment_meta( $comment_id, '_replymind_error' );
This makes the comment eligible for re-processing.
Other meta: post meta _replymind_post_overrides holds per-post enabled / tone / mode / custom_prompt overrides; user meta replymind_onboarding_dismissed records that the guided tour was dismissed.
Options
| Option | Autoload | Notes |
|---|---|---|
replymind_settings | yes | Core settings group (see below) |
replymind_pro_settings | yes | Advanced settings group (see below) |
replymind_pro_reply_rules | yes | Reply Rules list |
replymind_logs | no | Last 200 log entries |
replymind_do_activation_redirect | yes | One-shot post-activation flag |
replymind_1_1_migrated | yes | Migration marker for legacy Pro data |
replymind_api_key | yes | Legacy — unused when the AI Client is active; provider credentials live in WordPress core's Connectors |
The replymind_settings array contains:
array(
'enabled' => '0' | '1',
'mode' => 'suggestion' | 'auto',
'provider' => 'openai' | 'claude' | 'gemini',
'model' => 'gpt-5-mini' | 'claude-sonnet-4-6' | 'gemini-2.5-flash' | etc.,
'tone' => 'professional' | 'friendly' | 'casual' | 'empathetic' | 'formal' | 'concise',
'response_length' => 'short' | 'medium' | 'detailed',
'language' => 'auto' | 'en' | 'es' | 'fr' | 'de' | 'it' | 'pt' | 'hi' | 'ar' | 'ja' | 'zh',
'prompt' => string,
)
The replymind_pro_settings array contains:
array(
'email_approval_enabled' => '0' | '1',
'email_approval_recipient' => string, // default: admin_email
'sentiment_enabled' => '0' | '1',
'sentiment_negative_action' => 'flag' | 'skip' | 'empathetic',
'woocommerce_enabled' => '0' | '1',
'schedule_enabled' => '0' | '1',
'schedule_delay_hours' => int, // clamped 1–168
'multi_provider_enabled' => '0' | '1',
'category_providers' => array( array( 'taxonomy', 'term_id', 'provider', 'model' ), ... ),
'rules' => array, // mirror of replymind_pro_reply_rules
'per_post_enabled' => '0', // reserved; the meta box always renders
)
Rule rows are { title, condition, condition_value, action, action_value, enabled } with conditions always | keyword | category | word_count_min | word_count_max | author_email | post_type and actions skip | flag | tone | prompt.
The AI call itself goes through wp_ai_client_prompt() with using_provider() (openai / anthropic / google), using_model_preference(), using_system_instruction() and using_max_tokens( 300 ). Failures surface as WP_Error codes ai_client_unavailable, ai_client_error, or rate_limit. ReplyMind adds no HTTP or REST endpoints of its own.
Admin endpoints
All endpoints are nonce-protected. Capability requirements are listed below.
admin-post.php actions
| Action | HTTP | Capability | Nonce action |
|---|---|---|---|
replymind_generate_reply | GET | edit_comment | replymind_generate_reply |
replymind_publish_reply | GET | edit_comment | replymind_publish_reply |
replymind_unflag_comment | GET | edit_comment | replymind_unflag_comment_{$comment_id} |
replymind_clear_logs | POST | manage_options | replymind_clear_logs |
replymind_dismiss_onboarding | GET | manage_options | replymind_dismiss_onboarding |
replymind_remove_api_key | GET | manage_options | replymind_remove_api_key (legacy) |
replymind_pro_push_settings | POST | manage_network_options | multisite only |
The per-post meta box save is nonce-protected with replymind_pro_post_overrides_{$post_id} and requires edit_post. Email-approval links use a single-use transient token (replymind_appr_*, 48 h TTL).
AJAX endpoints
| Action | Capability | Returns |
|---|---|---|
replymind_submit_reply | edit_comment | success/failure of single draft publish |
replymind_batch_count | manage_options | { total, drafts } |
replymind_batch_process | manage_options | { processed, errors, remaining } |
replymind_batch_publish | manage_options | { published, errors, remaining } |
replymind_pro_save_rule | manage_options | { rules } |
replymind_pro_delete_rule | manage_options | { rules } |
replymind_pro_toggle_rule | manage_options | { rules } |
replymind_pro_reorder_rules | manage_options | { rules } |
All AJAX endpoints verify nonces via check_ajax_referer at the top of the handler before reading any other request data (batch actions share replymind_batch_nonce; rule actions share replymind_pro_rules_nonce).
Privacy hooks
The plugin registers itself with WordPress's privacy framework on admin_init:
| Hook | Purpose |
|---|---|
wp_add_privacy_policy_content (action) |
Adds a notice to the Privacy Policy guide |
wp_privacy_personal_data_exporters (filter) |
Registers an exporter for comment AI metadata |
wp_privacy_personal_data_erasers (filter) |
Registers an eraser for the same |
Both the exporter and eraser paginate (100 comments per page) and follow WordPress's canonical return shape.
Uninstall
When the plugin is deleted via the WordPress admin, uninstall.php runs and removes:
- All plugin options (
replymind_settings,replymind_pro_settings,replymind_pro_reply_rules,replymind_logs,replymind_do_activation_redirect,replymind_1_1_migrated, legacyreplymind_api_key). - All comment meta with keys starting
_replymind_— including sentiment and flagged meta — (uses$wpdb->preparewith$wpdb->esc_likeand theLIKEoperator).
The AI reply comments themselves are not deleted — they're regular WordPress comments and the plugin doesn't track which comments it authored beyond the meta flag.
Asset versioning
All admin CSS/JS files are enqueued with REPLYMIND_VERSION as the cache-buster. To force-refresh assets in development, define a different constant:
define( 'REPLYMIND_VERSION', '1.1.1-dev-' . time() );
(in wp-config.php before the plugin loads)
File structure
replymind-ai-comment-responder/
├── replymind-ai-comment-responder.php bootstrap, plugin headers, activation
├── README.txt wp.org listing
├── uninstall.php cleanup on delete
├── includes/
│ ├── class-replymind-loader.php privacy hooks, weekly cron interval
│ └── class-replymind-utils.php settings, prompt, AI Client call, logging
├── admin/
│ ├── class-replymind-admin.php admin UI + handlers
│ ├── tabs/class-tab-rules.php Reply Rules tab
│ ├── css/replymind-admin.css tabs, tooltips, rules, analytics
│ ├── css/replymind-menu.css sidebar menu icon
│ └── js/
│ ├── replymind-settings.js provider/model dropdown filter
│ ├── replymind-multi-provider.js taxonomy → provider row editor
│ ├── replymind-comments.js inline draft modal
│ ├── replymind-batch.js batch generate + bulk publish
│ ├── replymind-rules.js rules drag-sort + modal editor
│ ├── replymind-nav-tabs.js instant tab switcher
│ └── replymind-onboarding.js guided tour (WP Pointers)
├── pro/
│ ├── class-reply-rules.php evaluate() + AJAX handlers
│ ├── class-sentiment.php evaluate() + get_badge()
│ ├── class-scheduler.php get_delay_seconds()
│ ├── class-per-post-settings.php "ReplyMind Replies" meta box
│ ├── class-email-approval.php Approve / Reject links
│ ├── class-analytics.php Analytics tab
│ ├── class-woocommerce.php review cron worker
│ └── class-multisite.php network admin + push settings
├── public/
│ └── class-replymind-public.php comment_post listener + cron callback
├── assets/images/replymind-menu-icon.png
└── languages/
Every CSS/JS file is enqueued via wp_enqueue_*; dynamic data reaches JS through wp_localize_script. There are no inline <script> or <style> blocks, so a strict CSP (script-src 'self', style-src 'self') is compatible.
License
Released under GPL v2 or later (the same license as WordPress). You're free to fork, modify, and redistribute under that license. Contributions back to the upstream plugin are welcome via the WordPress.org support forum or a pull request to the public repo (when available).