Skip to main content

Comment Management

Overview

WP-CLI provides powerful commands to manage WordPress comments—approve, spam, trash, delete, and moderate comments at scale. Essential for comment moderation, spam cleanup, and site maintenance.

Understanding WordPress Comments​

WordPress comments are user-generated content attached to posts. Comments can be in different states:

  • Approved - Visible on the site
  • Pending - Awaiting moderation
  • Spam - Marked as spam
  • Trash - Moved to trash
  • Deleted - Permanently removed

Listing Comments​

Basic Listing​

# List all comments
wp comment list

# List with specific fields
wp comment list --fields=comment_ID,comment_author,comment_date,comment_approved

# List in table format
wp comment list --format=table

Filter by Status​

# List approved comments
wp comment list --status=approve

# List pending comments
wp comment list --status=hold

# List spam comments
wp comment list --status=spam

# List trashed comments
wp comment list --status=trash

# Count comments by status
wp comment list --status=approve --format=count
wp comment list --status=spam --format=count

Filter by Post​

# List comments for specific post
wp comment list --post_id=123

# List comments for multiple posts
wp comment list --post_id=123,456,789

# Count comments on post
wp comment list --post_id=123 --format=count

Advanced Filtering​

# List comments by author email
wp comment list --author_email=user@example.com

# List comments by author name
wp comment list --author=John

# List recent comments
wp comment list --number=10 --orderby=comment_date --order=DESC

# List comments with specific keyword
wp comment list --search="keyword"

# Get just IDs
wp comment list --status=spam --field=comment_ID

Creating Comments​

Create Basic Comment​

# Create comment on post
wp comment create --comment_post_ID=123 \
--comment_content="Great article!" \
--comment_author="John Doe" \
--comment_author_email="john@example.com"

# Create and approve immediately
wp comment create --comment_post_ID=123 \
--comment_content="Excellent post!" \
--comment_author="Jane Smith" \
--comment_author_email="jane@example.com" \
--comment_approved=1

Create Comment with Full Options​

# Create detailed comment
wp comment create \
--comment_post_ID=123 \
--comment_content="This is a detailed comment with lots of information." \
--comment_author="John Doe" \
--comment_author_email="john@example.com" \
--comment_author_url="https://johndoe.com" \
--comment_author_IP="192.168.1.1" \
--user_id=5 \
--comment_approved=1 \
--comment_parent=0

Create Reply to Comment​

# Reply to existing comment
wp comment create \
--comment_post_ID=123 \
--comment_parent=456 \
--comment_content="Thanks for your comment!" \
--comment_author="Admin" \
--comment_author_email="admin@example.com" \
--comment_approved=1

Approving Comments​

Approve Single Comment​

# Approve comment
wp comment approve 123

# Approve multiple comments
wp comment approve 123 456 789

Bulk Approve Comments​

# Approve all pending comments
wp comment approve $(wp comment list --status=hold --field=comment_ID)

# Approve comments from specific author
wp comment approve $(wp comment list --author_email=trusted@example.com --status=hold --field=comment_ID)

# Approve comments on specific post
wp comment approve $(wp comment list --post_id=123 --status=hold --field=comment_ID)

Unapproving Comments​

Unapprove Comments​

# Unapprove comment (set to pending)
wp comment unapprove 123

# Unapprove multiple comments
wp comment unapprove 123 456 789

# Unapprove all comments from user
wp comment unapprove $(wp comment list --author_email=suspicious@example.com --status=approve --field=comment_ID)

Marking as Spam​

Mark Single Comment as Spam​

# Mark as spam
wp comment spam 123

# Mark multiple as spam
wp comment spam 123 456 789

Bulk Spam Operations​

# Mark all pending comments as spam
wp comment spam $(wp comment list --status=hold --field=comment_ID)

# Mark comments from specific email as spam
wp comment spam $(wp comment list --author_email=spammer@example.com --field=comment_ID)

# Mark comments with specific keyword as spam
wp comment spam $(wp comment list --search="viagra" --field=comment_ID)

Trashing Comments​

Move to Trash​

# Trash comment
wp comment trash 123

# Trash multiple comments
wp comment trash 123 456 789

# Trash all spam comments
wp comment trash $(wp comment list --status=spam --field=comment_ID)

Deleting Comments​

Delete Permanently​

# Delete comment permanently
wp comment delete 123 --force

# Delete multiple comments
wp comment delete 123 456 789 --force

# Delete all spam comments permanently
wp comment delete $(wp comment list --status=spam --field=comment_ID) --force

# Delete all trashed comments
wp comment delete $(wp comment list --status=trash --field=comment_ID) --force

Getting Comment Information​

Get Comment Details​

# Get all comment data
wp comment get 123

# Get specific field
wp comment get 123 --field=comment_content
wp comment get 123 --field=comment_author
wp comment get 123 --field=comment_author_email
wp comment get 123 --field=comment_approved

# Get in JSON format
wp comment get 123 --format=json

Updating Comments​

Update Comment Content​

# Update comment content
wp comment update 123 --comment_content="Updated comment text"

# Update author name
wp comment update 123 --comment_author="New Author Name"

# Update author email
wp comment update 123 --comment_author_email="newemail@example.com"

# Update multiple fields
wp comment update 123 \
--comment_content="Updated content" \
--comment_author="Updated Author"

Real-World Scenarios​

Scenario 1: Daily Comment Moderation​

#!/bin/bash
# daily-comment-moderation.sh

echo "=== Daily Comment Moderation Report ==="
echo "Date: $(date)"
echo ""

# Count pending comments
PENDING=$(wp comment list --status=hold --format=count)
echo "Pending comments: $PENDING"

# Count spam comments
SPAM=$(wp comment list --status=spam --format=count)
echo "Spam comments: $SPAM"

# Show recent pending comments
if [ "$PENDING" -gt 0 ]; then
echo ""
echo "Recent pending comments:"
wp comment list --status=hold --number=10 --fields=comment_ID,comment_author,comment_content --format=table
fi

# Auto-delete old spam
OLD_SPAM=$(wp comment list --status=spam --before="30 days ago" --field=comment_ID)
if [ -n "$OLD_SPAM" ]; then
echo ""
echo "Deleting spam older than 30 days..."
wp comment delete $OLD_SPAM --force
echo "Deleted $(echo $OLD_SPAM | wc -w) spam comments"
fi

Scenario 2: Spam Cleanup​

#!/bin/bash
# spam-cleanup.sh

echo "Starting spam cleanup..."

# Count spam
SPAM_COUNT=$(wp comment list --status=spam --format=count)
echo "Found $SPAM_COUNT spam comments"

if [ "$SPAM_COUNT" -gt 0 ]; then
read -p "Delete all spam comments? (y/n) " -n 1 -r
echo

if [[ $REPLY =~ ^[Yy]$ ]]; then
wp comment delete $(wp comment list --status=spam --field=comment_ID) --force
echo "All spam comments deleted!"
fi
fi

# Check for potential spam patterns
echo ""
echo "Checking for potential spam patterns..."

# Comments with suspicious keywords
SUSPICIOUS=$(wp comment list --search="viagra" --status=approve --format=count)
if [ "$SUSPICIOUS" -gt 0 ]; then
echo "⚠ Warning: $SUSPICIOUS approved comments contain 'viagra'"
fi

Scenario 3: Comment Migration​

#!/bin/bash
# export-comments.sh

POST_ID=$1

if [ -z "$POST_ID" ]; then
echo "Usage: $0 <post_id>"
exit 1
fi

echo "Exporting comments for post $POST_ID..."

# Export to JSON
wp comment list --post_id=$POST_ID --format=json > comments-post-$POST_ID.json

# Export to CSV
wp comment list --post_id=$POST_ID --format=csv > comments-post-$POST_ID.csv

echo "Export complete!"
echo "Files created:"
echo " - comments-post-$POST_ID.json"
echo " - comments-post-$POST_ID.csv"

Scenario 4: Bulk Comment Approval​

#!/bin/bash
# approve-trusted-commenters.sh

# List of trusted email addresses
TRUSTED_EMAILS=(
"john@example.com"
"jane@example.com"
"admin@example.com"
)

echo "Auto-approving comments from trusted users..."

for email in "${TRUSTED_EMAILS[@]}"; do
PENDING=$(wp comment list --author_email=$email --status=hold --field=comment_ID)

if [ -n "$PENDING" ]; then
COUNT=$(echo $PENDING | wc -w)
echo "Approving $COUNT comments from $email"
wp comment approve $PENDING
fi
done

echo "Auto-approval complete!"

Scenario 5: Comment Statistics​

#!/bin/bash
# comment-statistics.sh

echo "=== Comment Statistics ==="
echo "Date: $(date)"
echo ""

# Total comments
echo "Total comments: $(wp comment list --format=count)"
echo "Approved: $(wp comment list --status=approve --format=count)"
echo "Pending: $(wp comment list --status=hold --format=count)"
echo "Spam: $(wp comment list --status=spam --format=count)"
echo "Trash: $(wp comment list --status=trash --format=count)"
echo ""

# Comments by post
echo "Top 10 Posts by Comment Count:"
wp db query "
SELECT
p.ID,
p.post_title,
COUNT(c.comment_ID) as comment_count
FROM wp_posts p
LEFT JOIN wp_comments c ON p.ID = c.comment_post_ID
WHERE p.post_status = 'publish' AND c.comment_approved = '1'
GROUP BY p.ID
ORDER BY comment_count DESC
LIMIT 10;
"

echo ""

# Recent commenters
echo "Recent Commenters:"
wp comment list --status=approve --number=10 --fields=comment_author,comment_author_email,comment_date --format=table

Advanced Operations​

Auto-Moderate Based on Rules​

#!/bin/bash
# auto-moderate.sh

# Approve comments from registered users
REGISTERED=$(wp comment list --status=hold --user_id!=0 --field=comment_ID)
if [ -n "$REGISTERED" ]; then
echo "Auto-approving comments from registered users..."
wp comment approve $REGISTERED
fi

# Mark short comments as spam (likely spam)
wp comment list --status=hold --field=comment_ID | while read comment_id; do
CONTENT=$(wp comment get $comment_id --field=comment_content)
LENGTH=${#CONTENT}

if [ "$LENGTH" -lt 10 ]; then
echo "Marking short comment $comment_id as spam"
wp comment spam $comment_id
fi
done

Disable Comments on Old Posts​

#!/bin/bash
# close-old-comments.sh

# Close comments on posts older than 1 year
OLD_POSTS=$(wp post list --before="1 year ago" --field=ID)

for post_id in $OLD_POSTS; do
wp post update $post_id --comment_status=closed
done

echo "Closed comments on old posts"

Export Comments for Analysis​

#!/bin/bash
# export-for-analysis.sh

# Export all approved comments with sentiment data
wp comment list --status=approve --format=json | \
jq -r '.[] | [.comment_ID, .comment_author, .comment_content, .comment_date] | @csv' > \
comments-analysis-$(date +%Y%m%d).csv

echo "Comments exported for analysis"

Comment Meta Management​

Add Comment Meta​

# Add custom field to comment
wp comment meta add 123 rating "5"

# Add moderation note
wp comment meta add 123 moderator_note "Approved by admin"

Get Comment Meta​

# Get specific meta
wp comment meta get 123 rating

# List all meta for comment
wp comment meta list 123

Update Comment Meta​

# Update meta value
wp comment meta update 123 rating "4"

Delete Comment Meta​

# Delete specific meta
wp comment meta delete 123 old_field

Best Practices​

1. Regular Spam Cleanup​

# Weekly spam cleanup (cron)
0 2 * * 0 wp comment delete $(wp comment list --status=spam --field=comment_ID) --force

2. Backup Before Bulk Deletion​

# Export comments before deleting
wp comment list --status=spam --format=json > spam-backup-$(date +%Y%m%d).json

# Then delete
wp comment delete $(wp comment list --status=spam --field=comment_ID) --force

3. Monitor Pending Queue​

# Daily notification of pending comments
PENDING=$(wp comment list --status=hold --format=count)
if [ "$PENDING" -gt 0 ]; then
echo "$PENDING comments pending moderation" | mail -s "Comment Moderation" admin@example.com
fi

4. Auto-Approve Trusted Users​

# Whitelist trusted commenters
wp comment approve $(wp comment list --author_email=trusted@example.com --status=hold --field=comment_ID)

5. Archive Old Comments​

# Export comments older than 2 years
wp comment list --before="2 years ago" --format=json > archived-comments-$(date +%Y%m%d).json

Quick Reference​

Essential Commands​

# List
wp comment list # All comments
wp comment list --status=approve # Approved only
wp comment list --status=hold # Pending only
wp comment list --status=spam # Spam only
wp comment list --post_id=123 # For specific post
wp comment list --format=count # Count only

# Create
wp comment create --comment_post_ID=123 --comment_content="Text" --comment_author="Name"

# Moderate
wp comment approve 123 # Approve
wp comment unapprove 123 # Unapprove
wp comment spam 123 # Mark as spam
wp comment trash 123 # Move to trash
wp comment delete 123 --force # Delete permanently

# Bulk operations
wp comment approve $(wp comment list --status=hold --field=comment_ID)
wp comment spam $(wp comment list --author_email=spam@example.com --field=comment_ID)
wp comment delete $(wp comment list --status=spam --field=comment_ID) --force

# Get info
wp comment get 123 # All data
wp comment get 123 --field=comment_content # Specific field

# Update
wp comment update 123 --comment_content="New text"

# Meta
wp comment meta add 123 key "value"
wp comment meta get 123 key
wp comment meta update 123 key "new value"
wp comment meta delete 123 key

Comparison: WP-CLI vs wp-admin​

TaskWP-CLIwp-admin
Delete 1000 Spam~5 seconds15-20 minutes
Approve 50 Comments~2 seconds5-10 minutes
Export CommentsInstantManual copy/paste
Bulk ModerationSingle commandMultiple clicks
Automation✅ Fully scriptable❌ Manual only
Read Comment Context⚠️ Limited✅ Full post view
Visual Moderation❌ Text-based✅ Visual interface
Key Takeaway

WP-CLI excels at bulk moderation, spam cleanup, and automation. Use it for large-scale comment management. Use wp-admin for individual comment moderation where you need to see the full post context.

Next Steps​