Refactor SEO automation into unified CLI application
Major refactoring to create a clean, integrated CLI application: ### New Features: - Unified CLI executable (./seo) with simple command structure - All commands accept optional CSV file arguments - Auto-detection of latest files when no arguments provided - Simplified output directory structure (output/ instead of output/reports/) - Cleaner export filename format (all_posts_YYYY-MM-DD.csv) ### Commands: - export: Export all posts from WordPress sites - analyze [csv]: Analyze posts with AI (optional CSV input) - recategorize [csv]: Recategorize posts with AI - seo_check: Check SEO quality - categories: Manage categories across sites - approve [files]: Review and approve recommendations - full_pipeline: Run complete workflow - analytics, gaps, opportunities, report, status ### Changes: - Moved all scripts to scripts/ directory - Created config.yaml for configuration - Updated all scripts to use output/ directory - Deprecated old seo-cli.py in favor of new ./seo - Added AGENTS.md and CHANGELOG.md documentation - Consolidated README.md with updated usage ### Technical: - Added PyYAML dependency - Removed hardcoded configuration values - All scripts now properly integrated - Better error handling and user feedback Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
152
wordpress-plugins/rank-math-api-manager/docs/README.md
Normal file
152
wordpress-plugins/rank-math-api-manager/docs/README.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# Documentation - Rank Math API Manager Plugin
|
||||
|
||||
## 📚 Documentation Overview
|
||||
|
||||
Welcome to the comprehensive documentation for the Rank Math API Manager plugin. This documentation is organized to help you get started quickly and find the information you need.
|
||||
|
||||
## 📖 Available Guides
|
||||
|
||||
### 🚀 Getting Started
|
||||
|
||||
- **[Installation Guide](installation.md)** - Complete installation and setup instructions
|
||||
- **[API Documentation](api-documentation.md)** - Complete technical API reference
|
||||
- **[Example Use Cases](example-use-cases.md)** - Practical examples and scenarios
|
||||
|
||||
### 🔧 Integration & Development
|
||||
|
||||
- **[Integration Guide](integration-guide.md)** - Step-by-step integration with n8n, Zapier, Make, and custom applications
|
||||
- **[Troubleshooting Guide](troubleshooting.md)** - Common issues and solutions
|
||||
- **[Security Guide](security.md)** - Security best practices and configuration
|
||||
|
||||
### 📋 Reference
|
||||
|
||||
- **[Changelog](../CHANGELOG.md)** - Version history and changes
|
||||
- **[Security Policy](../SECURITY.md)** - Security policy and vulnerability reporting
|
||||
- **[Code of Conduct](../CODE_OF_CONDUCT.md)** - Community guidelines
|
||||
|
||||
## 🎯 Quick Start
|
||||
|
||||
### 1. Installation
|
||||
|
||||
1. Follow the [Installation Guide](installation.md) to set up the plugin
|
||||
2. Configure WordPress Application Passwords
|
||||
3. Test the API endpoint
|
||||
|
||||
### 2. Basic Usage
|
||||
|
||||
```bash
|
||||
# Update SEO metadata for a post
|
||||
curl -X POST "https://your-site.com/wp-json/rank-math-api/v1/update-meta" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-H "Authorization: Basic [your-credentials]" \
|
||||
-d "post_id=123&rank_math_title=Your SEO Title&rank_math_description=Your meta description"
|
||||
```
|
||||
|
||||
### 3. Integration
|
||||
|
||||
- **n8n**: See [Integration Guide](integration-guide.md#n8n-integration)
|
||||
- **Zapier**: See [Integration Guide](integration-guide.md#zapier-integration)
|
||||
- **Python**: See [Integration Guide](integration-guide.md#python-integration)
|
||||
|
||||
## 🔍 Finding What You Need
|
||||
|
||||
### By Task
|
||||
|
||||
| Task | Documentation |
|
||||
| ------------------------ | ------------------------------------------- |
|
||||
| **Install the plugin** | [Installation Guide](installation.md) |
|
||||
| **Understand the API** | [API Documentation](api-documentation.md) |
|
||||
| **See examples** | [Example Use Cases](example-use-cases.md) |
|
||||
| **Integrate with tools** | [Integration Guide](integration-guide.md) |
|
||||
| **Fix problems** | [Troubleshooting Guide](troubleshooting.md) |
|
||||
| **Secure your setup** | [Security Guide](security.md) |
|
||||
|
||||
### By Experience Level
|
||||
|
||||
#### Beginner
|
||||
|
||||
1. [Installation Guide](installation.md) - Start here
|
||||
2. [Example Use Cases](example-use-cases.md) - See what's possible
|
||||
3. [API Documentation](api-documentation.md) - Learn the basics
|
||||
|
||||
#### Intermediate
|
||||
|
||||
1. [Integration Guide](integration-guide.md) - Connect with your tools
|
||||
2. [Troubleshooting Guide](troubleshooting.md) - Solve common issues
|
||||
3. [Security Guide](security.md) - Secure your implementation
|
||||
|
||||
#### Advanced
|
||||
|
||||
1. [API Documentation](api-documentation.md) - Complete reference
|
||||
2. [Security Guide](security.md) - Advanced security configuration
|
||||
3. [Integration Guide](integration-guide.md) - Custom integrations
|
||||
|
||||
## 🆘 Getting Help
|
||||
|
||||
### Documentation Issues
|
||||
|
||||
If you find errors or missing information in the documentation:
|
||||
|
||||
- [Create a GitHub issue](https://github.com/devora-as/rank-math-api-manager/issues)
|
||||
- Include the specific documentation page and section
|
||||
|
||||
### Plugin Issues
|
||||
|
||||
For plugin bugs or problems:
|
||||
|
||||
- [Create a GitHub issue](https://github.com/devora-as/rank-math-api-manager/issues)
|
||||
- Include error messages and steps to reproduce
|
||||
|
||||
### Security Issues
|
||||
|
||||
For security vulnerabilities:
|
||||
|
||||
- **Email**: security@devora.no
|
||||
- **Do not** create public GitHub issues for security problems
|
||||
|
||||
## 📝 Contributing to Documentation
|
||||
|
||||
We welcome contributions to improve the documentation:
|
||||
|
||||
1. **Fork the repository**
|
||||
2. **Create a feature branch**
|
||||
3. **Make your changes**
|
||||
4. **Submit a pull request**
|
||||
|
||||
### Documentation Standards
|
||||
|
||||
- Use clear, concise language
|
||||
- Include code examples where helpful
|
||||
- Follow the existing format and structure
|
||||
- Test all code examples before submitting
|
||||
|
||||
## 🔄 Documentation Updates
|
||||
|
||||
This documentation is updated with each plugin release. Check the [Changelog](../CHANGELOG.md) for the latest changes.
|
||||
|
||||
### Version Information
|
||||
|
||||
- **Current Version**: 1.0.6
|
||||
- **Last Updated**: July 2025
|
||||
- **WordPress Compatibility**: 5.0+
|
||||
- **PHP Compatibility**: 7.4+
|
||||
|
||||
## 📞 Support
|
||||
|
||||
- **Documentation**: This documentation
|
||||
- **GitHub Issues**: [Create an issue](https://github.com/devora-as/rank-math-api-manager/issues)
|
||||
- **Email Support**: [devora.no](https://devora.no)
|
||||
- **Security**: security@devora.no
|
||||
|
||||
---
|
||||
|
||||
**Related Links**:
|
||||
|
||||
- [Main README](../README.md)
|
||||
- [Norwegian Documentation](../README-NORWEGIAN.md)
|
||||
- [GitHub Repository](https://github.com/devora-as/rank-math-api-manager)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: July 2025
|
||||
**Version**: 1.0.6
|
||||
@@ -0,0 +1,126 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
We actively maintain and provide security updates for the following versions:
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 1.0.6 | :white_check_mark: |
|
||||
| 1.0.5 | :white_check_mark: |
|
||||
| 1.0.0 | :white_check_mark: |
|
||||
| < 1.0.0 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
We take security vulnerabilities seriously. If you discover a security vulnerability in the Rank Math API Manager plugin, please follow these steps:
|
||||
|
||||
### 1. **DO NOT** create a public GitHub issue
|
||||
|
||||
Security vulnerabilities should be reported privately to prevent potential exploitation.
|
||||
|
||||
### 2. **DO** report via email
|
||||
|
||||
Send your security report to: **security@devora.no**
|
||||
|
||||
### 3. Include the following information in your report:
|
||||
|
||||
- **Description**: A clear description of the vulnerability
|
||||
- **Steps to reproduce**: Detailed steps to reproduce the issue
|
||||
- **Impact**: Potential impact of the vulnerability
|
||||
- **Environment**: WordPress version, plugin version, and other relevant details
|
||||
- **Proof of concept**: If possible, include a proof of concept (without exploiting it publicly)
|
||||
|
||||
### 4. What to expect:
|
||||
|
||||
- **Response time**: We aim to respond within 48 hours
|
||||
- **Assessment**: We will assess the reported vulnerability
|
||||
- **Updates**: We will keep you informed of our progress
|
||||
- **Fix timeline**: Critical vulnerabilities will be addressed within 7 days
|
||||
- **Credit**: We will credit you in our security advisories (unless you prefer to remain anonymous)
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
### For Users:
|
||||
|
||||
1. **Keep WordPress updated**: Always use the latest WordPress version
|
||||
2. **Update plugins**: Keep all plugins, including this one, updated
|
||||
3. **Use strong authentication**: Implement strong passwords and two-factor authentication
|
||||
4. **Limit API access**: Only grant API access to trusted applications
|
||||
5. **Monitor logs**: Regularly check WordPress and server logs for suspicious activity
|
||||
6. **Use HTTPS**: Always use HTTPS for API communications
|
||||
|
||||
### For Developers:
|
||||
|
||||
1. **Input validation**: Always validate and sanitize all input data
|
||||
2. **Authentication**: Implement proper authentication for all API endpoints
|
||||
3. **Rate limiting**: Consider implementing rate limiting for API endpoints
|
||||
4. **Logging**: Log security-relevant events
|
||||
5. **Error handling**: Don't expose sensitive information in error messages
|
||||
|
||||
## Security Features
|
||||
|
||||
This plugin implements several security measures:
|
||||
|
||||
### Authentication & Authorization:
|
||||
|
||||
- WordPress Application Password authentication
|
||||
- User capability checks (`edit_posts`)
|
||||
- Proper permission validation for all endpoints
|
||||
|
||||
### Input Validation:
|
||||
|
||||
- All input parameters are sanitized
|
||||
- URL validation for canonical URLs
|
||||
- Text field sanitization using WordPress functions
|
||||
- Post ID validation
|
||||
|
||||
### Data Protection:
|
||||
|
||||
- No sensitive data is logged
|
||||
- Secure transmission via HTTPS
|
||||
- Proper WordPress nonce validation (where applicable)
|
||||
|
||||
## Known Security Considerations
|
||||
|
||||
### API Rate Limiting:
|
||||
|
||||
Currently, the plugin relies on WordPress's built-in rate limiting. For high-traffic sites, consider implementing additional rate limiting.
|
||||
|
||||
### CORS:
|
||||
|
||||
The plugin uses WordPress's default CORS settings. For enhanced security, consider implementing custom CORS policies.
|
||||
|
||||
### Logging:
|
||||
|
||||
The plugin doesn't log sensitive data, but ensure your WordPress installation has appropriate logging configured.
|
||||
|
||||
## Security Updates
|
||||
|
||||
We regularly:
|
||||
|
||||
- Review and update dependencies
|
||||
- Conduct security audits
|
||||
- Monitor WordPress security advisories
|
||||
- Test against common vulnerabilities
|
||||
- Update security best practices
|
||||
|
||||
## Responsible Disclosure
|
||||
|
||||
We follow responsible disclosure practices:
|
||||
|
||||
- We will not publicly disclose vulnerabilities until a fix is available
|
||||
- We will work with security researchers to understand and fix issues
|
||||
- We will credit security researchers in our advisories
|
||||
- We will provide reasonable time for users to update before public disclosure
|
||||
|
||||
## Contact Information
|
||||
|
||||
- **Security Email**: security@devora.no
|
||||
- **Company**: Devora AS
|
||||
- **Website**: https://devora.no
|
||||
- **GitHub**: https://github.com/devora-as/rank-math-api-manager
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: July 2025
|
||||
584
wordpress-plugins/rank-math-api-manager/docs/SECURITY.md
Normal file
584
wordpress-plugins/rank-math-api-manager/docs/SECURITY.md
Normal file
@@ -0,0 +1,584 @@
|
||||
# Security Guide - Rank Math API Manager Plugin
|
||||
|
||||
## 📋 Overview
|
||||
|
||||
This guide covers security best practices, configuration recommendations, and security features for the Rank Math API Manager plugin. Follow these guidelines to ensure your WordPress site and API endpoints remain secure.
|
||||
|
||||
## 🛡️ Security Features
|
||||
|
||||
### Built-in Security Measures
|
||||
|
||||
The Rank Math API Manager plugin implements several security measures:
|
||||
|
||||
#### 1. Authentication & Authorization
|
||||
|
||||
- **WordPress Application Passwords**: Secure authentication method
|
||||
- **User Capability Checks**: Validates `edit_posts` permissions
|
||||
- **Permission Validation**: Ensures users can modify content
|
||||
|
||||
#### 2. Input Validation & Sanitization
|
||||
|
||||
- **Text Field Sanitization**: Uses `sanitize_text_field()`
|
||||
- **URL Validation**: Uses `esc_url_raw()` for canonical URLs
|
||||
- **Post ID Validation**: Ensures posts exist before updates
|
||||
- **Parameter Validation**: Validates all input parameters
|
||||
|
||||
#### 3. Data Protection
|
||||
|
||||
- **No Sensitive Data Logging**: API credentials are never logged
|
||||
- **Secure Transmission**: Requires HTTPS for production use
|
||||
- **WordPress Nonce Validation**: Where applicable
|
||||
|
||||
## 🔐 Authentication Best Practices
|
||||
|
||||
### WordPress Application Passwords
|
||||
|
||||
#### Setting Up Secure Application Passwords
|
||||
|
||||
1. **Create Dedicated User Account**
|
||||
|
||||
```bash
|
||||
# Create a dedicated API user with limited permissions
|
||||
# Go to Users → Add New
|
||||
# Username: api-user
|
||||
# Role: Author (has edit_posts capability)
|
||||
# Email: api@your-domain.com
|
||||
```
|
||||
|
||||
2. **Generate Application Password**
|
||||
|
||||
```bash
|
||||
# Go to Users → Profile → Application Passwords
|
||||
# Name: "Rank Math API Access"
|
||||
# Click "Add New Application Password"
|
||||
# Copy the generated password immediately
|
||||
```
|
||||
|
||||
3. **Store Credentials Securely**
|
||||
```bash
|
||||
# Never store credentials in plain text
|
||||
# Use environment variables or secure configuration
|
||||
export WORDPRESS_API_USERNAME="api-user"
|
||||
export WORDPRESS_API_PASSWORD="your-application-password"
|
||||
```
|
||||
|
||||
#### Credential Management
|
||||
|
||||
```bash
|
||||
# Example: Secure credential storage
|
||||
# .env file (add to .gitignore)
|
||||
WORDPRESS_API_USERNAME=api-user
|
||||
WORDPRESS_API_PASSWORD=your-application-password
|
||||
WORDPRESS_SITE_URL=https://your-site.com
|
||||
|
||||
# Load in your application
|
||||
source .env
|
||||
```
|
||||
|
||||
### API Key Management (Future Feature)
|
||||
|
||||
```php
|
||||
// Future implementation for API key authentication
|
||||
add_action('rest_api_init', function() {
|
||||
register_rest_route('rank-math-api/v1', '/generate-api-key', [
|
||||
'methods' => 'POST',
|
||||
'callback' => 'generate_api_key',
|
||||
'permission_callback' => function() {
|
||||
return current_user_can('manage_options');
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
function generate_api_key() {
|
||||
$api_key = wp_generate_password(64, false);
|
||||
$user_id = get_current_user_id();
|
||||
|
||||
update_user_meta($user_id, 'rank_math_api_key', $api_key);
|
||||
|
||||
return [
|
||||
'api_key' => $api_key,
|
||||
'created_at' => current_time('mysql')
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## 🔒 Network Security
|
||||
|
||||
### HTTPS Configuration
|
||||
|
||||
#### Force HTTPS for API Endpoints
|
||||
|
||||
```php
|
||||
// Add to wp-config.php or theme functions.php
|
||||
add_action('rest_api_init', function() {
|
||||
if (!is_ssl() && !is_admin()) {
|
||||
add_filter('rest_authentication_errors', function($result) {
|
||||
return new WP_Error('https_required', 'HTTPS is required for API access', ['status' => 403]);
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### SSL Certificate Validation
|
||||
|
||||
```bash
|
||||
# Test SSL configuration
|
||||
curl -I https://your-site.com/wp-json/rank-math-api/v1/update-meta
|
||||
|
||||
# Check SSL certificate
|
||||
openssl s_client -connect your-site.com:443 -servername your-site.com
|
||||
```
|
||||
|
||||
### CORS Configuration
|
||||
|
||||
#### Default WordPress CORS
|
||||
|
||||
The plugin uses WordPress's default CORS settings. For enhanced security:
|
||||
|
||||
```php
|
||||
// Custom CORS configuration
|
||||
add_action('rest_api_init', function() {
|
||||
add_filter('rest_pre_serve_request', function($served, $result, $request, $server) {
|
||||
// Allow only specific origins
|
||||
$allowed_origins = [
|
||||
'https://your-frontend-app.com',
|
||||
'https://your-n8n-instance.com'
|
||||
];
|
||||
|
||||
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
|
||||
|
||||
if (in_array($origin, $allowed_origins)) {
|
||||
header('Access-Control-Allow-Origin: ' . $origin);
|
||||
header('Access-Control-Allow-Methods: POST, OPTIONS');
|
||||
header('Access-Control-Allow-Headers: Content-Type, Authorization');
|
||||
header('Access-Control-Allow-Credentials: true');
|
||||
}
|
||||
|
||||
return $served;
|
||||
}, 10, 4);
|
||||
});
|
||||
```
|
||||
|
||||
## 🚫 Rate Limiting
|
||||
|
||||
### Basic Rate Limiting Implementation
|
||||
|
||||
```php
|
||||
// Add rate limiting to API endpoints
|
||||
add_action('rest_api_init', function() {
|
||||
add_filter('rest_pre_dispatch', function($result, $server, $request) {
|
||||
if (strpos($request->get_route(), 'rank-math-api') !== false) {
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$user_id = get_current_user_id();
|
||||
$key = "rate_limit_{$user_id}_{$ip}";
|
||||
|
||||
$count = get_transient($key);
|
||||
$limit = 100; // requests per hour
|
||||
$window = 3600; // 1 hour
|
||||
|
||||
if ($count && $count >= $limit) {
|
||||
return new WP_Error(
|
||||
'rate_limit_exceeded',
|
||||
'Rate limit exceeded. Please try again later.',
|
||||
['status' => 429]
|
||||
);
|
||||
}
|
||||
|
||||
set_transient($key, ($count ? $count + 1 : 1), $window);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}, 10, 3);
|
||||
});
|
||||
```
|
||||
|
||||
### Advanced Rate Limiting
|
||||
|
||||
```php
|
||||
// Advanced rate limiting with different tiers
|
||||
class RankMathAPIRateLimiter {
|
||||
private $limits = [
|
||||
'default' => ['requests' => 100, 'window' => 3600],
|
||||
'premium' => ['requests' => 1000, 'window' => 3600],
|
||||
'admin' => ['requests' => 10000, 'window' => 3600]
|
||||
];
|
||||
|
||||
public function check_rate_limit($user_id, $ip) {
|
||||
$user_tier = $this->get_user_tier($user_id);
|
||||
$limit = $this->limits[$user_tier];
|
||||
|
||||
$key = "rate_limit_{$user_tier}_{$user_id}_{$ip}";
|
||||
$count = get_transient($key);
|
||||
|
||||
if ($count && $count >= $limit['requests']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
set_transient($key, ($count ? $count + 1 : 1), $limit['window']);
|
||||
return true;
|
||||
}
|
||||
|
||||
private function get_user_tier($user_id) {
|
||||
if (user_can($user_id, 'manage_options')) {
|
||||
return 'admin';
|
||||
}
|
||||
|
||||
// Check for premium user status
|
||||
if (get_user_meta($user_id, 'premium_user', true)) {
|
||||
return 'premium';
|
||||
}
|
||||
|
||||
return 'default';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔍 Input Validation & Sanitization
|
||||
|
||||
### Enhanced Input Validation
|
||||
|
||||
```php
|
||||
// Enhanced validation for API parameters
|
||||
add_action('rest_api_init', function() {
|
||||
add_filter('rest_pre_dispatch', function($result, $server, $request) {
|
||||
if (strpos($request->get_route(), 'rank-math-api') !== false) {
|
||||
$params = $request->get_params();
|
||||
|
||||
// Validate post_id
|
||||
if (isset($params['post_id'])) {
|
||||
if (!is_numeric($params['post_id']) || $params['post_id'] <= 0) {
|
||||
return new WP_Error('invalid_post_id', 'Invalid post ID', ['status' => 400]);
|
||||
}
|
||||
|
||||
$post = get_post($params['post_id']);
|
||||
if (!$post || !in_array($post->post_type, ['post', 'product'])) {
|
||||
return new WP_Error('post_not_found', 'Post not found or invalid type', ['status' => 404]);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate SEO title length
|
||||
if (isset($params['rank_math_title'])) {
|
||||
if (strlen($params['rank_math_title']) > 60) {
|
||||
return new WP_Error('title_too_long', 'SEO title exceeds 60 characters', ['status' => 400]);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate SEO description length
|
||||
if (isset($params['rank_math_description'])) {
|
||||
if (strlen($params['rank_math_description']) > 160) {
|
||||
return new WP_Error('description_too_long', 'SEO description exceeds 160 characters', ['status' => 400]);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate canonical URL
|
||||
if (isset($params['rank_math_canonical_url'])) {
|
||||
if (!filter_var($params['rank_math_canonical_url'], FILTER_VALIDATE_URL)) {
|
||||
return new WP_Error('invalid_url', 'Invalid canonical URL', ['status' => 400]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}, 10, 3);
|
||||
});
|
||||
```
|
||||
|
||||
### Content Security
|
||||
|
||||
```php
|
||||
// Prevent XSS and injection attacks
|
||||
function sanitize_seo_data($data) {
|
||||
$sanitized = [];
|
||||
|
||||
if (isset($data['rank_math_title'])) {
|
||||
$sanitized['rank_math_title'] = sanitize_text_field($data['rank_math_title']);
|
||||
}
|
||||
|
||||
if (isset($data['rank_math_description'])) {
|
||||
$sanitized['rank_math_description'] = sanitize_textarea_field($data['rank_math_description']);
|
||||
}
|
||||
|
||||
if (isset($data['rank_math_canonical_url'])) {
|
||||
$sanitized['rank_math_canonical_url'] = esc_url_raw($data['rank_math_canonical_url']);
|
||||
}
|
||||
|
||||
if (isset($data['rank_math_focus_keyword'])) {
|
||||
$sanitized['rank_math_focus_keyword'] = sanitize_text_field($data['rank_math_focus_keyword']);
|
||||
}
|
||||
|
||||
return $sanitized;
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 Security Monitoring
|
||||
|
||||
### API Access Logging
|
||||
|
||||
```php
|
||||
// Log API access for security monitoring
|
||||
add_action('rest_api_init', function() {
|
||||
add_filter('rest_post_dispatch', function($response, $handler, $request) {
|
||||
if (strpos($request->get_route(), 'rank-math-api') !== false) {
|
||||
$log_entry = [
|
||||
'timestamp' => current_time('mysql'),
|
||||
'ip' => $_SERVER['REMOTE_ADDR'],
|
||||
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
|
||||
'user_id' => get_current_user_id(),
|
||||
'route' => $request->get_route(),
|
||||
'method' => $request->get_method(),
|
||||
'status' => $response->get_status(),
|
||||
'params' => array_keys($request->get_params())
|
||||
];
|
||||
|
||||
// Log to WordPress debug log
|
||||
error_log('Rank Math API Access: ' . json_encode($log_entry));
|
||||
|
||||
// Store in database for analysis
|
||||
$logs = get_option('rank_math_api_logs', []);
|
||||
$logs[] = $log_entry;
|
||||
|
||||
// Keep only last 1000 entries
|
||||
if (count($logs) > 1000) {
|
||||
$logs = array_slice($logs, -1000);
|
||||
}
|
||||
|
||||
update_option('rank_math_api_logs', $logs);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}, 10, 3);
|
||||
});
|
||||
```
|
||||
|
||||
### Security Event Monitoring
|
||||
|
||||
```php
|
||||
// Monitor for suspicious activity
|
||||
add_action('rest_api_init', function() {
|
||||
add_filter('rest_authentication_errors', function($result) {
|
||||
if ($result !== null) {
|
||||
// Log failed authentication attempts
|
||||
$log_entry = [
|
||||
'timestamp' => current_time('mysql'),
|
||||
'ip' => $_SERVER['REMOTE_ADDR'],
|
||||
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
|
||||
'route' => $_SERVER['REQUEST_URI'] ?? '',
|
||||
'error' => 'Authentication failed'
|
||||
];
|
||||
|
||||
error_log('Rank Math API Security Event: ' . json_encode($log_entry));
|
||||
|
||||
// Alert on multiple failed attempts
|
||||
$failed_attempts = get_transient('failed_auth_' . $_SERVER['REMOTE_ADDR']);
|
||||
if ($failed_attempts && $failed_attempts > 10) {
|
||||
// Send alert email
|
||||
wp_mail(
|
||||
get_option('admin_email'),
|
||||
'Security Alert: Multiple Failed API Authentication Attempts',
|
||||
'Multiple failed authentication attempts detected from IP: ' . $_SERVER['REMOTE_ADDR']
|
||||
);
|
||||
}
|
||||
|
||||
set_transient('failed_auth_' . $_SERVER['REMOTE_ADDR'], ($failed_attempts ? $failed_attempts + 1 : 1), 3600);
|
||||
}
|
||||
|
||||
return $result;
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## 🔧 Security Configuration
|
||||
|
||||
### WordPress Security Settings
|
||||
|
||||
#### Essential Security Plugins
|
||||
|
||||
```php
|
||||
// Recommended security plugins
|
||||
// 1. Wordfence Security
|
||||
// 2. Sucuri Security
|
||||
// 3. iThemes Security
|
||||
// 4. All In One WP Security & Firewall
|
||||
```
|
||||
|
||||
#### wp-config.php Security
|
||||
|
||||
```php
|
||||
// Add to wp-config.php
|
||||
// Disable file editing
|
||||
define('DISALLOW_FILE_EDIT', true);
|
||||
|
||||
// Increase memory limit
|
||||
define('WP_MEMORY_LIMIT', '256M');
|
||||
|
||||
// Enable debug logging
|
||||
define('WP_DEBUG', true);
|
||||
define('WP_DEBUG_LOG', true);
|
||||
define('WP_DEBUG_DISPLAY', false);
|
||||
|
||||
// Secure database
|
||||
define('DB_CHARSET', 'utf8mb4');
|
||||
define('DB_COLLATE', 'utf8mb4_unicode_ci');
|
||||
|
||||
// Force SSL for admin
|
||||
define('FORCE_SSL_ADMIN', true);
|
||||
```
|
||||
|
||||
### Server Security
|
||||
|
||||
#### Apache Security Headers
|
||||
|
||||
```apache
|
||||
# Add to .htaccess
|
||||
<IfModule mod_headers.c>
|
||||
Header always set X-Content-Type-Options nosniff
|
||||
Header always set X-Frame-Options DENY
|
||||
Header always set X-XSS-Protection "1; mode=block"
|
||||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||||
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';"
|
||||
</IfModule>
|
||||
|
||||
# Block access to sensitive files
|
||||
<Files "wp-config.php">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</Files>
|
||||
|
||||
<Files ".htaccess">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</Files>
|
||||
```
|
||||
|
||||
#### Nginx Security Headers
|
||||
|
||||
```nginx
|
||||
# Add to nginx.conf
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin";
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';";
|
||||
|
||||
# Block access to sensitive files
|
||||
location ~ /(wp-config\.php|\.htaccess) {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
|
||||
## 🚨 Incident Response
|
||||
|
||||
### Security Incident Checklist
|
||||
|
||||
1. **Immediate Response**
|
||||
|
||||
- Disable API access if compromised
|
||||
- Change all Application Passwords
|
||||
- Review server logs for intrusion
|
||||
- Check for unauthorized changes
|
||||
|
||||
2. **Investigation**
|
||||
|
||||
- Analyze access logs
|
||||
- Review API usage patterns
|
||||
- Check for data breaches
|
||||
- Identify attack vectors
|
||||
|
||||
3. **Recovery**
|
||||
- Restore from clean backup
|
||||
- Update all credentials
|
||||
- Implement additional security measures
|
||||
- Monitor for further attacks
|
||||
|
||||
### Security Contact Information
|
||||
|
||||
```php
|
||||
// Add security contact information
|
||||
add_action('admin_menu', function() {
|
||||
add_options_page(
|
||||
'Security Settings',
|
||||
'Security',
|
||||
'manage_options',
|
||||
'security-settings',
|
||||
function() {
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1>Security Settings</h1>
|
||||
<h2>Emergency Contacts</h2>
|
||||
<p><strong>Security Email:</strong> security@devora.no</p>
|
||||
<p><strong>Emergency Phone:</strong> [Your emergency number]</p>
|
||||
<h2>Security Checklist</h2>
|
||||
<ul>
|
||||
<li>✅ HTTPS enabled</li>
|
||||
<li>✅ Application Passwords configured</li>
|
||||
<li>✅ Rate limiting enabled</li>
|
||||
<li>✅ Input validation active</li>
|
||||
<li>✅ Security monitoring active</li>
|
||||
</ul>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
## 📋 Security Checklist
|
||||
|
||||
### Pre-Deployment Checklist
|
||||
|
||||
- [ ] **HTTPS enabled** for all API communications
|
||||
- [ ] **Application Passwords** configured for API access
|
||||
- [ ] **User permissions** properly set (edit_posts capability)
|
||||
- [ ] **Input validation** and sanitization active
|
||||
- [ ] **Rate limiting** implemented
|
||||
- [ ] **Security headers** configured
|
||||
- [ ] **Error logging** enabled
|
||||
- [ ] **Backup strategy** in place
|
||||
- [ ] **Monitoring** and alerting configured
|
||||
- [ ] **Incident response plan** documented
|
||||
|
||||
### Regular Security Audits
|
||||
|
||||
- [ ] **Review access logs** monthly
|
||||
- [ ] **Update Application Passwords** quarterly
|
||||
- [ ] **Check for plugin updates** weekly
|
||||
- [ ] **Review user permissions** monthly
|
||||
- [ ] **Test security measures** quarterly
|
||||
- [ ] **Update security documentation** as needed
|
||||
|
||||
## 📞 Security Support
|
||||
|
||||
### Reporting Security Issues
|
||||
|
||||
**Important**: Do not report security issues via GitHub Issues. Send them to **security@devora.no** instead.
|
||||
|
||||
### Required Information for Security Reports
|
||||
|
||||
```
|
||||
Subject: Security Issue - Rank Math API Manager
|
||||
|
||||
Details:
|
||||
- Description of the vulnerability
|
||||
- Steps to reproduce
|
||||
- Potential impact
|
||||
- Environment details
|
||||
- Proof of concept (if applicable)
|
||||
|
||||
Contact Information:
|
||||
- Your name and email
|
||||
- Preferred contact method
|
||||
- Disclosure timeline preference
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Related Documentation**:
|
||||
|
||||
- [Installation Guide](installation.md)
|
||||
- [API Documentation](api-documentation.md)
|
||||
- [Troubleshooting Guide](troubleshooting.md)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: July 2025
|
||||
**Version**: 1.0.6
|
||||
@@ -0,0 +1,498 @@
|
||||
# Example Use Cases - Rank Math API Manager Plugin
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
This guide provides practical examples of how to use the Rank Math API Manager plugin in various real-world scenarios. Each example includes complete code snippets and step-by-step instructions.
|
||||
|
||||
## 📝 Content Syndication
|
||||
|
||||
### Scenario: Automatically Update SEO When Content is Syndicated
|
||||
|
||||
When content is published on multiple platforms, you need to ensure consistent SEO metadata across all sites.
|
||||
|
||||
#### Example: Cross-Site SEO Synchronization
|
||||
|
||||
```bash
|
||||
# Update SEO metadata when content is syndicated
|
||||
curl -X POST "https://primary-site.com/wp-json/rank-math-api/v1/update-meta" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-H "Authorization: Basic [base64-encoded-credentials]" \
|
||||
-d "post_id=123&rank_math_title=How to Optimize WordPress SEO&rank_math_description=Learn the best practices for optimizing your WordPress site for search engines&rank_math_focus_keyword=WordPress SEO optimization"
|
||||
```
|
||||
|
||||
#### n8n Workflow Example
|
||||
|
||||
```json
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"name": "Content Published",
|
||||
"type": "trigger",
|
||||
"parameters": {
|
||||
"event": "content_published"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Generate SEO Metadata",
|
||||
"type": "ai_generate",
|
||||
"parameters": {
|
||||
"prompt": "Generate SEO title, description, and focus keyword for: {{ $('Content Published').first().json.content }}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Update Primary Site",
|
||||
"type": "http_request",
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "https://primary-site.com/wp-json/rank-math-api/v1/update-meta",
|
||||
"headers": {
|
||||
"Authorization": "Basic [credentials]"
|
||||
},
|
||||
"bodyParameters": {
|
||||
"post_id": "={{ $('Content Published').first().json.post_id }}",
|
||||
"rank_math_title": "={{ $('Generate SEO Metadata').first().json.title }}",
|
||||
"rank_math_description": "={{ $('Generate SEO Metadata').first().json.description }}",
|
||||
"rank_math_focus_keyword": "={{ $('Generate SEO Metadata').first().json.keyword }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 AI-Driven SEO Optimization
|
||||
|
||||
### Scenario: Automatic SEO Generation Based on Content
|
||||
|
||||
Use AI to analyze content and generate optimized SEO metadata automatically.
|
||||
|
||||
#### Example: AI-Powered SEO Generation
|
||||
|
||||
```python
|
||||
import requests
|
||||
import json
|
||||
|
||||
def generate_seo_metadata(content):
|
||||
"""Generate SEO metadata using AI"""
|
||||
# This would integrate with your AI service
|
||||
ai_response = ai_service.analyze(content)
|
||||
|
||||
return {
|
||||
'title': ai_response['seo_title'],
|
||||
'description': ai_response['seo_description'],
|
||||
'keyword': ai_response['focus_keyword']
|
||||
}
|
||||
|
||||
def update_wordpress_seo(post_id, seo_data):
|
||||
"""Update WordPress SEO metadata via API"""
|
||||
url = "https://your-site.com/wp-json/rank-math-api/v1/update-meta"
|
||||
|
||||
headers = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Authorization': 'Basic [base64-encoded-credentials]'
|
||||
}
|
||||
|
||||
data = {
|
||||
'post_id': post_id,
|
||||
'rank_math_title': seo_data['title'],
|
||||
'rank_math_description': seo_data['description'],
|
||||
'rank_math_focus_keyword': seo_data['keyword']
|
||||
}
|
||||
|
||||
response = requests.post(url, headers=headers, data=data)
|
||||
return response.json()
|
||||
|
||||
# Usage example
|
||||
content = "Your article content here..."
|
||||
post_id = 123
|
||||
|
||||
seo_data = generate_seo_metadata(content)
|
||||
result = update_wordpress_seo(post_id, seo_data)
|
||||
print(f"SEO updated: {result}")
|
||||
```
|
||||
|
||||
#### n8n Workflow: AI Content Analysis
|
||||
|
||||
```json
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"name": "New Content",
|
||||
"type": "trigger"
|
||||
},
|
||||
{
|
||||
"name": "Analyze Content",
|
||||
"type": "openai",
|
||||
"parameters": {
|
||||
"prompt": "Analyze this content and generate SEO metadata:\n\n{{ $('New Content').first().json.content }}\n\nProvide:\n1. SEO title (max 60 characters)\n2. Meta description (max 160 characters)\n3. Primary focus keyword"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Parse AI Response",
|
||||
"type": "code",
|
||||
"parameters": {
|
||||
"code": "const response = $('Analyze Content').first().json.text;\nconst lines = response.split('\\n');\n\nreturn {\n title: lines[0].replace('1. ', ''),\n description: lines[1].replace('2. ', ''),\n keyword: lines[2].replace('3. ', '')\n};"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Update SEO",
|
||||
"type": "http_request",
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "https://your-site.com/wp-json/rank-math-api/v1/update-meta",
|
||||
"bodyParameters": {
|
||||
"post_id": "={{ $('New Content').first().json.post_id }}",
|
||||
"rank_math_title": "={{ $('Parse AI Response').first().json.title }}",
|
||||
"rank_math_description": "={{ $('Parse AI Response').first().json.description }}",
|
||||
"rank_math_focus_keyword": "={{ $('Parse AI Response').first().json.keyword }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 🛒 E-commerce SEO Automation
|
||||
|
||||
### Scenario: Product Catalog Optimization
|
||||
|
||||
Automatically update SEO metadata for WooCommerce products based on inventory, categories, or seasonal campaigns.
|
||||
|
||||
#### Example: Seasonal Product SEO Updates
|
||||
|
||||
```bash
|
||||
# Update product SEO for seasonal campaign
|
||||
curl -X POST "https://ecommerce-site.com/wp-json/rank-math-api/v1/update-meta" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-H "Authorization: Basic [base64-encoded-credentials]" \
|
||||
-d "post_id=456&rank_math_title=Christmas Sale - Premium Wireless Headphones&rank_math_description=Get 30% off premium wireless headphones this Christmas. Free shipping and 2-year warranty included.&rank_math_focus_keyword=wireless headphones christmas sale"
|
||||
```
|
||||
|
||||
#### PHP Script: Bulk Product SEO Update
|
||||
|
||||
```php
|
||||
<?php
|
||||
// Bulk update product SEO metadata
|
||||
function update_product_seo_bulk($products) {
|
||||
$api_url = 'https://your-site.com/wp-json/rank-math-api/v1/update-meta';
|
||||
$credentials = base64_encode('username:application_password');
|
||||
|
||||
foreach ($products as $product) {
|
||||
$data = [
|
||||
'post_id' => $product['id'],
|
||||
'rank_math_title' => $product['seo_title'],
|
||||
'rank_math_description' => $product['seo_description'],
|
||||
'rank_math_focus_keyword' => $product['focus_keyword']
|
||||
];
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $api_url);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/x-www-form-urlencoded',
|
||||
'Authorization: Basic ' . $credentials
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
echo "Updated product {$product['id']}: " . $response . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Example usage
|
||||
$products = [
|
||||
[
|
||||
'id' => 123,
|
||||
'seo_title' => 'Premium Wireless Headphones - Best Sound Quality',
|
||||
'seo_description' => 'Experience crystal clear sound with our premium wireless headphones. Perfect for music lovers and professionals.',
|
||||
'focus_keyword' => 'premium wireless headphones'
|
||||
],
|
||||
[
|
||||
'id' => 124,
|
||||
'seo_title' => 'Bluetooth Speaker - Portable and Waterproof',
|
||||
'seo_description' => 'Take your music anywhere with our portable and waterproof Bluetooth speaker. Perfect for outdoor adventures.',
|
||||
'focus_keyword' => 'portable bluetooth speaker'
|
||||
]
|
||||
];
|
||||
|
||||
update_product_seo_bulk($products);
|
||||
?>
|
||||
```
|
||||
|
||||
## 📊 Bulk SEO Administration
|
||||
|
||||
### Scenario: Mass SEO Updates for Multiple Posts
|
||||
|
||||
Update SEO metadata for multiple posts at once, useful for site-wide SEO improvements.
|
||||
|
||||
#### Example: Category-Based SEO Updates
|
||||
|
||||
```javascript
|
||||
// JavaScript/Node.js example for bulk updates
|
||||
const axios = require("axios");
|
||||
|
||||
async function updateCategorySEO(categoryId, seoTemplate) {
|
||||
// First, get all posts in the category
|
||||
const postsResponse = await axios.get(
|
||||
`https://your-site.com/wp-json/wp/v2/posts?categories=${categoryId}`
|
||||
);
|
||||
|
||||
const posts = postsResponse.data;
|
||||
const results = [];
|
||||
|
||||
for (const post of posts) {
|
||||
try {
|
||||
// Generate SEO data based on template and post content
|
||||
const seoData = generateSEOFromTemplate(seoTemplate, post);
|
||||
|
||||
// Update via API
|
||||
const response = await axios.post(
|
||||
"https://your-site.com/wp-json/rank-math-api/v1/update-meta",
|
||||
{
|
||||
post_id: post.id,
|
||||
rank_math_title: seoData.title,
|
||||
rank_math_description: seoData.description,
|
||||
rank_math_focus_keyword: seoData.keyword,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Authorization: "Basic [base64-encoded-credentials]",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
results.push({
|
||||
post_id: post.id,
|
||||
status: "success",
|
||||
response: response.data,
|
||||
});
|
||||
} catch (error) {
|
||||
results.push({
|
||||
post_id: post.id,
|
||||
status: "error",
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
function generateSEOFromTemplate(template, post) {
|
||||
return {
|
||||
title: template.title.replace("{post_title}", post.title.rendered),
|
||||
description: template.description.replace(
|
||||
"{post_excerpt}",
|
||||
post.excerpt.rendered
|
||||
),
|
||||
keyword: template.keyword,
|
||||
};
|
||||
}
|
||||
|
||||
// Usage
|
||||
const seoTemplate = {
|
||||
title: "{post_title} - Your Brand Name",
|
||||
description: "{post_excerpt} Read more about this topic on our website.",
|
||||
keyword: "your category keyword",
|
||||
};
|
||||
|
||||
updateCategorySEO(5, seoTemplate)
|
||||
.then((results) => console.log("Bulk update results:", results))
|
||||
.catch((error) => console.error("Error:", error));
|
||||
```
|
||||
|
||||
## 🔄 Automated Content Workflows
|
||||
|
||||
### Scenario: Content Publishing Pipeline
|
||||
|
||||
Integrate SEO updates into your content publishing workflow.
|
||||
|
||||
#### Example: WordPress + n8n + AI Workflow
|
||||
|
||||
```json
|
||||
{
|
||||
"workflow": {
|
||||
"name": "Content Publishing with SEO",
|
||||
"nodes": [
|
||||
{
|
||||
"name": "New Post Created",
|
||||
"type": "webhook",
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "new-post"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Extract Content",
|
||||
"type": "code",
|
||||
"parameters": {
|
||||
"code": "const post = $('New Post Created').first().json;\nreturn {\n post_id: post.ID,\n title: post.post_title,\n content: post.post_content,\n excerpt: post.post_excerpt\n};"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Generate SEO",
|
||||
"type": "openai",
|
||||
"parameters": {
|
||||
"prompt": "Generate SEO metadata for this WordPress post:\n\nTitle: {{ $('Extract Content').first().json.title }}\nContent: {{ $('Extract Content').first().json.content }}\n\nProvide:\n- SEO title (max 60 chars)\n- Meta description (max 160 chars)\n- Primary keyword"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Update SEO Metadata",
|
||||
"type": "http_request",
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "https://your-site.com/wp-json/rank-math-api/v1/update-meta",
|
||||
"headers": {
|
||||
"Authorization": "Basic [credentials]"
|
||||
},
|
||||
"bodyParameters": {
|
||||
"post_id": "={{ $('Extract Content').first().json.post_id }}",
|
||||
"rank_math_title": "={{ $('Generate SEO').first().json.title }}",
|
||||
"rank_math_description": "={{ $('Generate SEO').first().json.description }}",
|
||||
"rank_math_focus_keyword": "={{ $('Generate SEO').first().json.keyword }}"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Send Notification",
|
||||
"type": "email",
|
||||
"parameters": {
|
||||
"to": "admin@your-site.com",
|
||||
"subject": "SEO Updated for Post {{ $('Extract Content').first().json.post_id }}",
|
||||
"text": "SEO metadata has been automatically updated for the new post."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📈 Competitor Analysis Integration
|
||||
|
||||
### Scenario: SEO Optimization Based on Competitor Analysis
|
||||
|
||||
Use competitor analysis tools to generate optimized SEO metadata.
|
||||
|
||||
#### Example: Competitor-Based SEO Generation
|
||||
|
||||
```python
|
||||
import requests
|
||||
import json
|
||||
|
||||
def analyze_competitors(keyword):
|
||||
"""Analyze competitor content for a keyword"""
|
||||
# This would integrate with your competitor analysis tool
|
||||
competitor_data = competitor_tool.analyze(keyword)
|
||||
|
||||
return {
|
||||
'avg_title_length': competitor_data['avg_title_length'],
|
||||
'common_keywords': competitor_data['common_keywords'],
|
||||
'title_patterns': competitor_data['title_patterns']
|
||||
}
|
||||
|
||||
def generate_optimized_seo(content, keyword, competitor_data):
|
||||
"""Generate SEO based on competitor analysis"""
|
||||
# Use competitor insights to optimize SEO
|
||||
optimized_title = create_title_with_patterns(content, competitor_data['title_patterns'])
|
||||
optimized_description = create_description_with_keywords(content, competitor_data['common_keywords'])
|
||||
|
||||
return {
|
||||
'title': optimized_title,
|
||||
'description': optimized_description,
|
||||
'keyword': keyword
|
||||
}
|
||||
|
||||
def update_wordpress_seo(post_id, seo_data):
|
||||
"""Update WordPress SEO via API"""
|
||||
url = "https://your-site.com/wp-json/rank-math-api/v1/update-meta"
|
||||
|
||||
headers = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Authorization': 'Basic [base64-encoded-credentials]'
|
||||
}
|
||||
|
||||
data = {
|
||||
'post_id': post_id,
|
||||
'rank_math_title': seo_data['title'],
|
||||
'rank_math_description': seo_data['description'],
|
||||
'rank_math_focus_keyword': seo_data['keyword']
|
||||
}
|
||||
|
||||
response = requests.post(url, headers=headers, data=data)
|
||||
return response.json()
|
||||
|
||||
# Usage
|
||||
keyword = "WordPress SEO optimization"
|
||||
content = "Your article content..."
|
||||
post_id = 123
|
||||
|
||||
competitor_data = analyze_competitors(keyword)
|
||||
seo_data = generate_optimized_seo(content, keyword, competitor_data)
|
||||
result = update_wordpress_seo(post_id, seo_data)
|
||||
```
|
||||
|
||||
## 🎯 Best Practices
|
||||
|
||||
### 1. Error Handling
|
||||
|
||||
Always implement proper error handling in your API calls:
|
||||
|
||||
```javascript
|
||||
try {
|
||||
const response = await updateSEO(postId, seoData);
|
||||
console.log("SEO updated successfully:", response);
|
||||
} catch (error) {
|
||||
console.error("Failed to update SEO:", error.response?.data || error.message);
|
||||
// Implement retry logic or fallback
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Rate Limiting
|
||||
|
||||
Respect API rate limits and implement delays between requests:
|
||||
|
||||
```javascript
|
||||
async function bulkUpdateWithRateLimit(posts, delayMs = 1000) {
|
||||
for (const post of posts) {
|
||||
await updateSEO(post.id, post.seoData);
|
||||
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Validation
|
||||
|
||||
Always validate your data before sending to the API:
|
||||
|
||||
```javascript
|
||||
function validateSEOData(seoData) {
|
||||
const errors = [];
|
||||
|
||||
if (!seoData.title || seoData.title.length > 60) {
|
||||
errors.push("Title must be between 1-60 characters");
|
||||
}
|
||||
|
||||
if (!seoData.description || seoData.description.length > 160) {
|
||||
errors.push("Description must be between 1-160 characters");
|
||||
}
|
||||
|
||||
if (!seoData.keyword) {
|
||||
errors.push("Focus keyword is required");
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Next Steps**: See the [API Documentation](api-documentation.md) for complete technical details.
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: July 2025
|
||||
**Version**: 1.0.6
|
||||
244
wordpress-plugins/rank-math-api-manager/docs/installation.md
Normal file
244
wordpress-plugins/rank-math-api-manager/docs/installation.md
Normal file
@@ -0,0 +1,244 @@
|
||||
# Installation Guide - Rank Math API Manager Plugin
|
||||
|
||||
## 📋 Prerequisites
|
||||
|
||||
Before installing the Rank Math API Manager plugin, ensure you have:
|
||||
|
||||
- **WordPress 5.0 or newer**
|
||||
- **PHP 7.4 or newer**
|
||||
- **Rank Math SEO plugin** (installed and activated)
|
||||
- **Administrator access** to your WordPress site
|
||||
|
||||
## 🚀 Installation Methods
|
||||
|
||||
### Method 1: Manual Installation (Recommended)
|
||||
|
||||
#### Step 1: Download the Plugin
|
||||
|
||||
1. Visit the [GitHub repository](https://github.com/devora-as/rank-math-api-manager)
|
||||
2. Click the green "Code" button
|
||||
3. Select "Download ZIP"
|
||||
4. Extract the ZIP file to your local computer
|
||||
|
||||
#### Step 2: Upload to WordPress
|
||||
|
||||
1. **Log in to your WordPress admin panel**
|
||||
2. **Navigate to Plugins → Add New**
|
||||
3. **Click "Upload Plugin"** at the top of the page
|
||||
4. **Choose File** and select the extracted plugin folder
|
||||
5. **Click "Install Now"**
|
||||
6. **Activate the plugin** when prompted
|
||||
|
||||

|
||||
|
||||
### Method 2: FTP Installation
|
||||
|
||||
#### Step 1: Prepare the Files
|
||||
|
||||
1. Download the plugin from GitHub
|
||||
2. Extract the ZIP file
|
||||
3. Upload the `rank-math-api-manager` folder to `/wp-content/plugins/`
|
||||
|
||||
#### Step 2: Activate the Plugin
|
||||
|
||||
1. Log in to WordPress admin
|
||||
2. Go to **Plugins → Installed Plugins**
|
||||
3. Find "Rank Math API Manager"
|
||||
4. Click **"Activate"**
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
### Step 1: Verify Installation
|
||||
|
||||
After activation, you should see:
|
||||
|
||||
- ✅ Plugin appears in the plugins list
|
||||
- ✅ No error messages in WordPress admin
|
||||
- ✅ REST API endpoints are available
|
||||
|
||||
### Step 2: Test API Endpoints
|
||||
|
||||
#### Using cURL (Command Line)
|
||||
|
||||
```bash
|
||||
# Test the API endpoint
|
||||
curl -X POST "https://your-site.com/wp-json/rank-math-api/v1/update-meta" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-H "Authorization: Basic [base64-encoded-credentials]" \
|
||||
-d "post_id=1&rank_math_title=Test Title"
|
||||
```
|
||||
|
||||
#### Using Postman
|
||||
|
||||
1. **Create a new POST request**
|
||||
2. **URL**: `https://your-site.com/wp-json/rank-math-api/v1/update-meta`
|
||||
3. **Headers**:
|
||||
- `Content-Type: application/x-www-form-urlencoded`
|
||||
- `Authorization: Basic [base64-encoded-credentials]`
|
||||
4. **Body** (form-data):
|
||||
- `post_id`: `1`
|
||||
- `rank_math_title`: `Test Title`
|
||||
|
||||
### Step 3: Set Up Authentication
|
||||
|
||||
#### WordPress Application Passwords
|
||||
|
||||
1. **Go to Users → Profile**
|
||||
2. **Scroll to "Application Passwords"**
|
||||
3. **Enter a name** (e.g., "API Access")
|
||||
4. **Click "Add New Application Password"**
|
||||
5. **Copy the generated password**
|
||||
|
||||
#### Basic Auth Setup
|
||||
|
||||
```bash
|
||||
# Encode credentials
|
||||
echo -n "username:password" | base64
|
||||
```
|
||||
|
||||
## 🔧 Integration Setup
|
||||
|
||||
### n8n Workflow Integration
|
||||
|
||||
1. **Add HTTP Request node** to your n8n workflow
|
||||
2. **Configure the request**:
|
||||
- Method: `POST`
|
||||
- URL: `https://your-site.com/wp-json/rank-math-api/v1/update-meta`
|
||||
- Headers: Add authentication headers
|
||||
- Body: Configure form data
|
||||
|
||||
### Example n8n Configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"method": "POST",
|
||||
"url": "https://your-site.com/wp-json/rank-math-api/v1/update-meta",
|
||||
"contentType": "form-urlencoded",
|
||||
"headers": {
|
||||
"Authorization": "Basic [base64-encoded-credentials]"
|
||||
},
|
||||
"bodyParameters": {
|
||||
"post_id": "={{ $('Post on Wordpress').first().json.id }}",
|
||||
"rank_math_title": "={{ $('Generate metatitle e metadescription').first().json.output.metatitle }}",
|
||||
"rank_math_description": "={{ $('Generate metatitle e metadescription').first().json.output.metadescription }}",
|
||||
"rank_math_focus_keyword": "={{ $('Generate metatitle e metadescription').first().json.output.metakeywords }}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🛡️ Security Configuration
|
||||
|
||||
### 1. Enable HTTPS
|
||||
|
||||
Ensure your WordPress site uses HTTPS for secure API communications.
|
||||
|
||||
### 2. Restrict API Access
|
||||
|
||||
- Use strong application passwords
|
||||
- Limit API access to trusted applications
|
||||
- Monitor API usage logs
|
||||
|
||||
### 3. WordPress Security
|
||||
|
||||
- Keep WordPress updated
|
||||
- Use security plugins
|
||||
- Enable two-factor authentication
|
||||
|
||||
## 🔍 Verification Steps
|
||||
|
||||
### 1. Check Plugin Status
|
||||
|
||||
1. Go to **Plugins → Installed Plugins**
|
||||
2. Verify "Rank Math API Manager" is **Active**
|
||||
3. Check for any error messages
|
||||
|
||||
### 2. Test API Endpoint
|
||||
|
||||
```bash
|
||||
# Test endpoint availability
|
||||
curl -X GET "https://your-site.com/wp-json/rank-math-api/v1/update-meta"
|
||||
```
|
||||
|
||||
Expected response: `{"code":"rest_no_route","message":"No route was found matching the URL and request method","data":{"status":404}}`
|
||||
|
||||
This confirms the endpoint exists but requires POST method.
|
||||
|
||||
### 3. Verify Permissions
|
||||
|
||||
1. Create a test post
|
||||
2. Use the API to update its SEO metadata
|
||||
3. Verify the changes appear in Rank Math
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Issue: "Plugin could not be activated"
|
||||
|
||||
**Solution:**
|
||||
|
||||
- Check PHP version (requires 7.4+)
|
||||
- Verify WordPress version (requires 5.0+)
|
||||
- Check for plugin conflicts
|
||||
|
||||
#### Issue: "401 Unauthorized" API errors
|
||||
|
||||
**Solution:**
|
||||
|
||||
- Verify application password is correct
|
||||
- Check user permissions (`edit_posts`)
|
||||
- Ensure authentication headers are properly formatted
|
||||
|
||||
#### Issue: "404 Not Found" API errors
|
||||
|
||||
**Solution:**
|
||||
|
||||
- Verify plugin is activated
|
||||
- Check WordPress REST API is enabled
|
||||
- Ensure URL is correct
|
||||
|
||||
#### Issue: "400 Bad Request" API errors
|
||||
|
||||
**Solution:**
|
||||
|
||||
- Verify `post_id` exists
|
||||
- Check parameter formatting
|
||||
- Ensure all required fields are provided
|
||||
|
||||
### Debug Mode
|
||||
|
||||
Enable WordPress debug mode for detailed error messages:
|
||||
|
||||
```php
|
||||
// Add to wp-config.php
|
||||
define('WP_DEBUG', true);
|
||||
define('WP_DEBUG_LOG', true);
|
||||
define('WP_DEBUG_DISPLAY', false);
|
||||
```
|
||||
|
||||
## 📞 Support
|
||||
|
||||
If you encounter issues during installation:
|
||||
|
||||
1. **Check the troubleshooting section above**
|
||||
2. **Review WordPress error logs**
|
||||
3. **Create a GitHub issue** with detailed information
|
||||
4. **Contact support** at [devora.no](https://devora.no)
|
||||
|
||||
### Required Information for Support
|
||||
|
||||
- WordPress version
|
||||
- PHP version
|
||||
- Plugin version
|
||||
- Error messages
|
||||
- Steps to reproduce the issue
|
||||
- Screenshots (if applicable)
|
||||
|
||||
---
|
||||
|
||||
**Next Steps**: After installation, see the [API Documentation](api-documentation.md) for detailed usage instructions.
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: July 2025
|
||||
**Version**: 1.0.6
|
||||
@@ -0,0 +1,766 @@
|
||||
# Integration Guide - Rank Math API Manager Plugin
|
||||
|
||||
## 📋 Overview
|
||||
|
||||
This guide provides step-by-step instructions for integrating the Rank Math API Manager plugin with various automation tools and platforms. Learn how to connect the plugin with n8n, Zapier, Make (Integromat), and custom applications.
|
||||
|
||||
## 🔧 Prerequisites
|
||||
|
||||
Before starting integration:
|
||||
|
||||
- ✅ **Plugin installed and activated** (see [Installation Guide](installation.md))
|
||||
- ✅ **WordPress Application Password** configured
|
||||
- ✅ **Test post or product** created for testing
|
||||
- ✅ **API endpoint tested** and working
|
||||
|
||||
## 🚀 n8n Integration
|
||||
|
||||
### Step 1: Set Up n8n
|
||||
|
||||
1. **Install n8n** (if not already installed)
|
||||
2. **Create a new workflow**
|
||||
3. **Add an HTTP Request node**
|
||||
|
||||
### Step 2: Configure HTTP Request Node
|
||||
|
||||
#### Basic Configuration
|
||||
|
||||
1. **Method**: `POST`
|
||||
2. **URL**: `https://your-site.com/wp-json/rank-math-api/v1/update-meta`
|
||||
3. **Content Type**: `form-urlencoded`
|
||||
|
||||
#### Authentication Setup
|
||||
|
||||
1. **Click on "Add Credential"**
|
||||
2. **Select "HTTP Basic Auth"**
|
||||
3. **Enter your WordPress username**
|
||||
4. **Enter your Application Password**
|
||||
5. **Save the credential**
|
||||
|
||||
#### Body Parameters
|
||||
|
||||
Configure the following parameters:
|
||||
|
||||
| Parameter | Value | Description |
|
||||
| ------------------------- | -------------------------------------------------------- | -------------------------- |
|
||||
| `post_id` | `={{ $('Previous Node').first().json.post_id }}` | Post ID from previous node |
|
||||
| `rank_math_title` | `={{ $('Previous Node').first().json.seo_title }}` | SEO title |
|
||||
| `rank_math_description` | `={{ $('Previous Node').first().json.seo_description }}` | SEO description |
|
||||
| `rank_math_focus_keyword` | `={{ $('Previous Node').first().json.focus_keyword }}` | Focus keyword |
|
||||
|
||||
### Step 3: Complete n8n Workflow Example
|
||||
|
||||
#### AI Content Generation + SEO Update
|
||||
|
||||
```json
|
||||
{
|
||||
"workflow": {
|
||||
"name": "AI Content + SEO Update",
|
||||
"nodes": [
|
||||
{
|
||||
"name": "Webhook Trigger",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "new-content",
|
||||
"responseMode": "responseNode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Generate SEO with AI",
|
||||
"type": "n8n-nodes-base.openAi",
|
||||
"parameters": {
|
||||
"operation": "completion",
|
||||
"model": "gpt-3.5-turbo",
|
||||
"prompt": "Generate SEO metadata for this content:\n\nTitle: {{ $('Webhook Trigger').first().json.title }}\nContent: {{ $('Webhook Trigger').first().json.content }}\n\nProvide in JSON format:\n{\n \"seo_title\": \"SEO title (max 60 chars)\",\n \"seo_description\": \"Meta description (max 160 chars)\",\n \"focus_keyword\": \"Primary keyword\"\n}",
|
||||
"options": {
|
||||
"temperature": 0.7,
|
||||
"maxTokens": 200
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Parse AI Response",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"parameters": {
|
||||
"code": "const aiResponse = $('Generate SEO with AI').first().json.text;\nconst seoData = JSON.parse(aiResponse);\n\nreturn {\n post_id: $('Webhook Trigger').first().json.post_id,\n seo_title: seoData.seo_title,\n seo_description: seoData.seo_description,\n focus_keyword: seoData.focus_keyword\n};"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Update WordPress SEO",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "https://your-site.com/wp-json/rank-math-api/v1/update-meta",
|
||||
"contentType": "form-urlencoded",
|
||||
"authentication": "httpBasicAuth",
|
||||
"options": {
|
||||
"bodyParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "post_id",
|
||||
"value": "={{ $('Parse AI Response').first().json.post_id }}"
|
||||
},
|
||||
{
|
||||
"name": "rank_math_title",
|
||||
"value": "={{ $('Parse AI Response').first().json.seo_title }}"
|
||||
},
|
||||
{
|
||||
"name": "rank_math_description",
|
||||
"value": "={{ $('Parse AI Response').first().json.seo_description }}"
|
||||
},
|
||||
{
|
||||
"name": "rank_math_focus_keyword",
|
||||
"value": "={{ $('Parse AI Response').first().json.focus_keyword }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Send Success Response",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "{\n \"success\": true,\n \"message\": \"SEO updated successfully\",\n \"data\": {{ $('Update WordPress SEO').first().json }}\n}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### WordPress + n8n Integration
|
||||
|
||||
```json
|
||||
{
|
||||
"workflow": {
|
||||
"name": "WordPress Post + SEO Update",
|
||||
"nodes": [
|
||||
{
|
||||
"name": "WordPress Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "wordpress-post",
|
||||
"responseMode": "responseNode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Extract Post Data",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"parameters": {
|
||||
"code": "const post = $('WordPress Webhook').first().json;\n\nreturn {\n post_id: post.ID,\n title: post.post_title,\n content: post.post_content,\n excerpt: post.post_excerpt\n};"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Generate SEO",
|
||||
"type": "n8n-nodes-base.openAi",
|
||||
"parameters": {
|
||||
"operation": "completion",
|
||||
"model": "gpt-3.5-turbo",
|
||||
"prompt": "Generate SEO metadata for this WordPress post:\n\nTitle: {{ $('Extract Post Data').first().json.title }}\nContent: {{ $('Extract Post Data').first().json.content }}\n\nProvide:\n1. SEO title (max 60 characters)\n2. Meta description (max 160 characters)\n3. Primary focus keyword",
|
||||
"options": {
|
||||
"temperature": 0.7,
|
||||
"maxTokens": 150
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Parse SEO Response",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"parameters": {
|
||||
"code": "const response = $('Generate SEO').first().json.text;\nconst lines = response.split('\\n');\n\nreturn {\n post_id: $('Extract Post Data').first().json.post_id,\n seo_title: lines[0].replace(/^\\d+\\.\\s*/, ''),\n seo_description: lines[1].replace(/^\\d+\\.\\s*/, ''),\n focus_keyword: lines[2].replace(/^\\d+\\.\\s*/, '')\n};"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Update SEO",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "https://your-site.com/wp-json/rank-math-api/v1/update-meta",
|
||||
"contentType": "form-urlencoded",
|
||||
"authentication": "httpBasicAuth",
|
||||
"options": {
|
||||
"bodyParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "post_id",
|
||||
"value": "={{ $('Parse SEO Response').first().json.post_id }}"
|
||||
},
|
||||
{
|
||||
"name": "rank_math_title",
|
||||
"value": "={{ $('Parse SEO Response').first().json.seo_title }}"
|
||||
},
|
||||
{
|
||||
"name": "rank_math_description",
|
||||
"value": "={{ $('Parse SEO Response').first().json.seo_description }}"
|
||||
},
|
||||
{
|
||||
"name": "rank_math_focus_keyword",
|
||||
"value": "={{ $('Parse SEO Response').first().json.focus_keyword }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Send Notification",
|
||||
"type": "n8n-nodes-base.emailSend",
|
||||
"parameters": {
|
||||
"toEmail": "admin@your-site.com",
|
||||
"subject": "SEO Updated for Post {{ $('Parse SEO Response').first().json.post_id }}",
|
||||
"text": "SEO metadata has been automatically updated for the new post."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Testing the n8n Workflow
|
||||
|
||||
1. **Activate the workflow**
|
||||
2. **Send a test webhook** with sample data
|
||||
3. **Check the execution logs** for any errors
|
||||
4. **Verify the SEO update** in WordPress admin
|
||||
|
||||
## 🔌 Zapier Integration
|
||||
|
||||
### Step 1: Create a Zap
|
||||
|
||||
1. **Log in to Zapier**
|
||||
2. **Click "Create Zap"**
|
||||
3. **Choose a trigger** (e.g., "New Post" in WordPress)
|
||||
|
||||
### Step 2: Add Code Action
|
||||
|
||||
1. **Add a "Code by Zapier" action**
|
||||
2. **Select "Run JavaScript"**
|
||||
3. **Use the following code**:
|
||||
|
||||
```javascript
|
||||
// Zapier Code Action for SEO Update
|
||||
const postId = inputData.post_id;
|
||||
const postTitle = inputData.post_title;
|
||||
const postContent = inputData.post_content;
|
||||
|
||||
// Generate SEO data (you can customize this logic)
|
||||
const seoTitle =
|
||||
postTitle.length > 60 ? postTitle.substring(0, 57) + "..." : postTitle;
|
||||
const seoDescription =
|
||||
postContent.length > 160
|
||||
? postContent.substring(0, 157) + "..."
|
||||
: postContent;
|
||||
const focusKeyword = postTitle.split(" ").slice(0, 3).join(" ");
|
||||
|
||||
// Make API request
|
||||
const response = await fetch(
|
||||
"https://your-site.com/wp-json/rank-math-api/v1/update-meta",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Authorization: "Basic " + btoa("username:application_password"),
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
post_id: postId,
|
||||
rank_math_title: seoTitle,
|
||||
rank_math_description: seoDescription,
|
||||
rank_math_focus_keyword: focusKeyword,
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
return {
|
||||
success: response.ok,
|
||||
data: result,
|
||||
post_id: postId,
|
||||
seo_title: seoTitle,
|
||||
seo_description: seoDescription,
|
||||
focus_keyword: focusKeyword,
|
||||
};
|
||||
```
|
||||
|
||||
### Step 3: Test the Zap
|
||||
|
||||
1. **Test the trigger** with a sample post
|
||||
2. **Check the execution** in Zapier
|
||||
3. **Verify the results** in WordPress
|
||||
|
||||
## 🔗 Make (Integromat) Integration
|
||||
|
||||
### Step 1: Create a Scenario
|
||||
|
||||
1. **Log in to Make**
|
||||
2. **Create a new scenario**
|
||||
3. **Add a trigger** (e.g., WordPress webhook)
|
||||
|
||||
### Step 2: Add HTTP Module
|
||||
|
||||
1. **Add an HTTP module**
|
||||
2. **Configure the request**:
|
||||
|
||||
#### HTTP Configuration
|
||||
|
||||
- **URL**: `https://your-site.com/wp-json/rank-math-api/v1/update-meta`
|
||||
- **Method**: `POST`
|
||||
- **Headers**:
|
||||
- `Content-Type`: `application/x-www-form-urlencoded`
|
||||
- `Authorization`: `Basic [base64-encoded-credentials]`
|
||||
|
||||
#### Body Configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"post_id": "{{1.post_id}}",
|
||||
"rank_math_title": "{{1.seo_title}}",
|
||||
"rank_math_description": "{{1.seo_description}}",
|
||||
"rank_math_focus_keyword": "{{1.focus_keyword}}"
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Complete Make Scenario
|
||||
|
||||
```json
|
||||
{
|
||||
"scenario": {
|
||||
"name": "WordPress SEO Update",
|
||||
"modules": [
|
||||
{
|
||||
"name": "WordPress Webhook",
|
||||
"type": "webhook",
|
||||
"config": {
|
||||
"url": "https://hook.eu1.make.com/your-webhook-url"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Generate SEO",
|
||||
"type": "openai",
|
||||
"config": {
|
||||
"prompt": "Generate SEO metadata for: {{1.post_title}}",
|
||||
"model": "gpt-3.5-turbo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Update SEO",
|
||||
"type": "http",
|
||||
"config": {
|
||||
"url": "https://your-site.com/wp-json/rank-math-api/v1/update-meta",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"Authorization": "Basic [credentials]"
|
||||
},
|
||||
"body": {
|
||||
"post_id": "{{1.post_id}}",
|
||||
"rank_math_title": "{{2.seo_title}}",
|
||||
"rank_math_description": "{{2.seo_description}}",
|
||||
"rank_math_focus_keyword": "{{2.focus_keyword}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🐍 Python Integration
|
||||
|
||||
### Step 1: Install Required Packages
|
||||
|
||||
```bash
|
||||
pip install requests
|
||||
```
|
||||
|
||||
### Step 2: Create Integration Script
|
||||
|
||||
```python
|
||||
import requests
|
||||
import base64
|
||||
import json
|
||||
from typing import Dict, Optional
|
||||
|
||||
class RankMathAPIClient:
|
||||
def __init__(self, site_url: str, username: str, application_password: str):
|
||||
self.base_url = f"{site_url}/wp-json/rank-math-api/v1"
|
||||
self.credentials = base64.b64encode(
|
||||
f"{username}:{application_password}".encode()
|
||||
).decode()
|
||||
|
||||
def update_seo(self, post_id: int, seo_data: Dict[str, str]) -> Dict:
|
||||
"""
|
||||
Update SEO metadata for a post
|
||||
|
||||
Args:
|
||||
post_id: WordPress post ID
|
||||
seo_data: Dictionary containing SEO data
|
||||
|
||||
Returns:
|
||||
API response as dictionary
|
||||
"""
|
||||
url = f"{self.base_url}/update-meta"
|
||||
|
||||
headers = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Authorization': f'Basic {self.credentials}'
|
||||
}
|
||||
|
||||
data = {
|
||||
'post_id': post_id,
|
||||
'rank_math_title': seo_data.get('title'),
|
||||
'rank_math_description': seo_data.get('description'),
|
||||
'rank_math_canonical_url': seo_data.get('canonical_url'),
|
||||
'rank_math_focus_keyword': seo_data.get('focus_keyword')
|
||||
}
|
||||
|
||||
# Remove None values
|
||||
data = {k: v for k, v in data.items() if v is not None}
|
||||
|
||||
response = requests.post(url, headers=headers, data=data)
|
||||
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
else:
|
||||
raise Exception(f"API request failed: {response.status_code} - {response.text}")
|
||||
|
||||
def bulk_update_seo(self, updates: list) -> list:
|
||||
"""
|
||||
Update SEO metadata for multiple posts
|
||||
|
||||
Args:
|
||||
updates: List of dictionaries with post_id and seo_data
|
||||
|
||||
Returns:
|
||||
List of results for each update
|
||||
"""
|
||||
results = []
|
||||
|
||||
for update in updates:
|
||||
try:
|
||||
result = self.update_seo(update['post_id'], update['seo_data'])
|
||||
results.append({
|
||||
'post_id': update['post_id'],
|
||||
'success': True,
|
||||
'data': result
|
||||
})
|
||||
except Exception as e:
|
||||
results.append({
|
||||
'post_id': update['post_id'],
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
})
|
||||
|
||||
return results
|
||||
|
||||
# Usage example
|
||||
def main():
|
||||
# Initialize client
|
||||
client = RankMathAPIClient(
|
||||
site_url="https://your-site.com",
|
||||
username="your_username",
|
||||
application_password="your_application_password"
|
||||
)
|
||||
|
||||
# Single update
|
||||
try:
|
||||
result = client.update_seo(123, {
|
||||
'title': 'How to Optimize WordPress SEO',
|
||||
'description': 'Learn the best practices for optimizing your WordPress site for search engines',
|
||||
'focus_keyword': 'WordPress SEO optimization'
|
||||
})
|
||||
print(f"SEO updated successfully: {result}")
|
||||
except Exception as e:
|
||||
print(f"Error updating SEO: {e}")
|
||||
|
||||
# Bulk update
|
||||
updates = [
|
||||
{
|
||||
'post_id': 123,
|
||||
'seo_data': {
|
||||
'title': 'Post 1 SEO Title',
|
||||
'description': 'Post 1 SEO Description',
|
||||
'focus_keyword': 'keyword 1'
|
||||
}
|
||||
},
|
||||
{
|
||||
'post_id': 124,
|
||||
'seo_data': {
|
||||
'title': 'Post 2 SEO Title',
|
||||
'description': 'Post 2 SEO Description',
|
||||
'focus_keyword': 'keyword 2'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
results = client.bulk_update_seo(updates)
|
||||
for result in results:
|
||||
if result['success']:
|
||||
print(f"Post {result['post_id']}: Updated successfully")
|
||||
else:
|
||||
print(f"Post {result['post_id']}: Failed - {result['error']}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
## 🔧 Custom WordPress Integration
|
||||
|
||||
### Step 1: WordPress Plugin Integration
|
||||
|
||||
```php
|
||||
<?php
|
||||
/**
|
||||
* Custom WordPress plugin integration example
|
||||
*/
|
||||
|
||||
// Add action to update SEO when post is published
|
||||
add_action('publish_post', 'auto_update_seo_on_publish', 10, 2);
|
||||
|
||||
function auto_update_seo_on_publish($post_id, $post) {
|
||||
// Skip revisions and autosaves
|
||||
if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate SEO data based on post content
|
||||
$seo_data = generate_seo_from_content($post);
|
||||
|
||||
// Update via API
|
||||
$result = update_seo_via_api($post_id, $seo_data);
|
||||
|
||||
// Log the result
|
||||
if ($result['success']) {
|
||||
error_log("SEO updated successfully for post {$post_id}");
|
||||
} else {
|
||||
error_log("Failed to update SEO for post {$post_id}: " . $result['error']);
|
||||
}
|
||||
}
|
||||
|
||||
function generate_seo_from_content($post) {
|
||||
// Simple SEO generation logic
|
||||
$title = wp_trim_words($post->post_title, 8, '');
|
||||
$description = wp_trim_words(wp_strip_all_tags($post->post_content), 25, '...');
|
||||
$keyword = implode(' ', array_slice(explode(' ', $post->post_title), 0, 3));
|
||||
|
||||
return [
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'focus_keyword' => $keyword
|
||||
];
|
||||
}
|
||||
|
||||
function update_seo_via_api($post_id, $seo_data) {
|
||||
$url = home_url('/wp-json/rank-math-api/v1/update-meta');
|
||||
|
||||
// Get application password (you should store this securely)
|
||||
$app_password = get_option('rank_math_api_app_password');
|
||||
$username = get_option('rank_math_api_username');
|
||||
|
||||
if (!$app_password || !$username) {
|
||||
return ['success' => false, 'error' => 'API credentials not configured'];
|
||||
}
|
||||
|
||||
$credentials = base64_encode("{$username}:{$app_password}");
|
||||
|
||||
$response = wp_remote_post($url, [
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
'Authorization' => "Basic {$credentials}"
|
||||
],
|
||||
'body' => [
|
||||
'post_id' => $post_id,
|
||||
'rank_math_title' => $seo_data['title'],
|
||||
'rank_math_description' => $seo_data['description'],
|
||||
'rank_math_focus_keyword' => $seo_data['focus_keyword']
|
||||
],
|
||||
'timeout' => 30
|
||||
]);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
return ['success' => false, 'error' => $response->get_error_message()];
|
||||
}
|
||||
|
||||
$status_code = wp_remote_retrieve_response_code($response);
|
||||
$body = wp_remote_retrieve_body($response);
|
||||
|
||||
if ($status_code === 200) {
|
||||
return ['success' => true, 'data' => json_decode($body, true)];
|
||||
} else {
|
||||
return ['success' => false, 'error' => "HTTP {$status_code}: {$body}"];
|
||||
}
|
||||
}
|
||||
|
||||
// Add admin settings page
|
||||
add_action('admin_menu', 'add_rank_math_api_settings_page');
|
||||
|
||||
function add_rank_math_api_settings_page() {
|
||||
add_options_page(
|
||||
'Rank Math API Settings',
|
||||
'Rank Math API',
|
||||
'manage_options',
|
||||
'rank-math-api-settings',
|
||||
'rank_math_api_settings_page'
|
||||
);
|
||||
}
|
||||
|
||||
function rank_math_api_settings_page() {
|
||||
if (isset($_POST['submit'])) {
|
||||
update_option('rank_math_api_username', sanitize_text_field($_POST['username']));
|
||||
update_option('rank_math_api_app_password', sanitize_text_field($_POST['app_password']));
|
||||
echo '<div class="notice notice-success"><p>Settings saved!</p></div>';
|
||||
}
|
||||
|
||||
$username = get_option('rank_math_api_username');
|
||||
$app_password = get_option('rank_math_api_app_password');
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1>Rank Math API Settings</h1>
|
||||
<form method="post">
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">Username</th>
|
||||
<td><input type="text" name="username" value="<?php echo esc_attr($username); ?>" class="regular-text" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Application Password</th>
|
||||
<td><input type="password" name="app_password" value="<?php echo esc_attr($app_password); ?>" class="regular-text" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php submit_button(); ?>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
```
|
||||
|
||||
## 🧪 Testing Your Integration
|
||||
|
||||
### Step 1: Create Test Data
|
||||
|
||||
```bash
|
||||
# Create a test post
|
||||
curl -X POST "https://your-site.com/wp-json/wp/v2/posts" \
|
||||
-H "Authorization: Basic [credentials]" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"title": "Test Post for SEO Integration",
|
||||
"content": "This is a test post to verify the SEO integration is working correctly.",
|
||||
"status": "publish"
|
||||
}'
|
||||
```
|
||||
|
||||
### Step 2: Test SEO Update
|
||||
|
||||
```bash
|
||||
# Test the SEO update
|
||||
curl -X POST "https://your-site.com/wp-json/rank-math-api/v1/update-meta" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-H "Authorization: Basic [credentials]" \
|
||||
-d "post_id=123&rank_math_title=Test SEO Title&rank_math_description=Test SEO description for integration testing&rank_math_focus_keyword=test integration"
|
||||
```
|
||||
|
||||
### Step 3: Verify Results
|
||||
|
||||
1. **Check WordPress admin** for updated SEO metadata
|
||||
2. **View the post** to see the changes
|
||||
3. **Check Rank Math SEO** settings for the post
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Common Integration Issues
|
||||
|
||||
#### Issue: Authentication Errors
|
||||
|
||||
**Symptoms**: 401 Unauthorized errors
|
||||
**Solutions**:
|
||||
|
||||
- Verify Application Password is correct
|
||||
- Check username spelling
|
||||
- Ensure credentials are properly encoded
|
||||
|
||||
#### Issue: Post Not Found
|
||||
|
||||
**Symptoms**: 404 errors
|
||||
**Solutions**:
|
||||
|
||||
- Verify post ID exists
|
||||
- Check post status (published vs draft)
|
||||
- Ensure post type is supported
|
||||
|
||||
#### Issue: Invalid Data
|
||||
|
||||
**Symptoms**: 400 Bad Request errors
|
||||
**Solutions**:
|
||||
|
||||
- Check parameter names and values
|
||||
- Verify data types
|
||||
- Ensure required fields are provided
|
||||
|
||||
### Debug Mode
|
||||
|
||||
Enable WordPress debug mode for detailed error messages:
|
||||
|
||||
```php
|
||||
// Add to wp-config.php
|
||||
define('WP_DEBUG', true);
|
||||
define('WP_DEBUG_LOG', true);
|
||||
define('WP_DEBUG_DISPLAY', false);
|
||||
```
|
||||
|
||||
### Logging
|
||||
|
||||
Add logging to your integration:
|
||||
|
||||
```javascript
|
||||
// JavaScript logging
|
||||
console.log("API Request:", {
|
||||
url: apiUrl,
|
||||
data: requestData,
|
||||
headers: requestHeaders,
|
||||
});
|
||||
|
||||
console.log("API Response:", response);
|
||||
```
|
||||
|
||||
```php
|
||||
// PHP logging
|
||||
error_log('Rank Math API Request: ' . json_encode($request_data));
|
||||
error_log('Rank Math API Response: ' . json_encode($response));
|
||||
```
|
||||
|
||||
## 📞 Support
|
||||
|
||||
For integration issues:
|
||||
|
||||
1. **Check this documentation**
|
||||
2. **Review error messages**
|
||||
3. **Test with provided examples**
|
||||
4. **Create a GitHub issue** with details
|
||||
5. **Contact support** at [devora.no](https://devora.no)
|
||||
|
||||
### Required Information for Support
|
||||
|
||||
- Integration platform (n8n, Zapier, etc.)
|
||||
- Complete error messages
|
||||
- Request/response data
|
||||
- Steps to reproduce the issue
|
||||
- WordPress and plugin versions
|
||||
|
||||
---
|
||||
|
||||
**Related Documentation**:
|
||||
|
||||
- [Installation Guide](installation.md)
|
||||
- [API Documentation](api-documentation.md)
|
||||
- [Example Use Cases](example-use-cases.md)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: July 2025
|
||||
**Version**: 1.0.6
|
||||
607
wordpress-plugins/rank-math-api-manager/docs/troubleshooting.md
Normal file
607
wordpress-plugins/rank-math-api-manager/docs/troubleshooting.md
Normal file
@@ -0,0 +1,607 @@
|
||||
# Troubleshooting Guide - Rank Math API Manager Plugin
|
||||
|
||||
## 📋 Overview
|
||||
|
||||
This guide helps you identify and resolve common issues with the Rank Math API Manager plugin. Follow the troubleshooting steps to diagnose and fix problems quickly.
|
||||
|
||||
## 🔍 Quick Diagnostic Checklist
|
||||
|
||||
Before diving into specific issues, run through this checklist:
|
||||
|
||||
- ✅ **Plugin is activated** in WordPress admin
|
||||
- ✅ **Rank Math SEO plugin** is installed and active
|
||||
- ✅ **WordPress REST API** is accessible
|
||||
- ✅ **Application Password** is correctly configured
|
||||
- ✅ **User has `edit_posts` permissions**
|
||||
- ✅ **Post ID exists** and is published
|
||||
- ✅ **HTTPS is enabled** (recommended for security)
|
||||
|
||||
## 🚨 Common Error Codes
|
||||
|
||||
### 401 Unauthorized
|
||||
|
||||
**Error Message**: `"Sorry, you are not allowed to do that."`
|
||||
|
||||
#### Possible Causes:
|
||||
|
||||
1. **Invalid credentials**
|
||||
2. **Missing Application Password**
|
||||
3. **Incorrect username**
|
||||
4. **User lacks permissions**
|
||||
|
||||
#### Solutions:
|
||||
|
||||
**Step 1: Verify Application Password**
|
||||
|
||||
```bash
|
||||
# Test with cURL
|
||||
curl -X POST "https://your-site.com/wp-json/rank-math-api/v1/update-meta" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-H "Authorization: Basic [your-base64-credentials]" \
|
||||
-d "post_id=123&rank_math_title=Test"
|
||||
```
|
||||
|
||||
**Step 2: Check User Permissions**
|
||||
|
||||
1. Go to **Users → All Users**
|
||||
2. Find your user account
|
||||
3. Verify role has `edit_posts` capability
|
||||
4. Check if user is active
|
||||
|
||||
**Step 3: Regenerate Application Password**
|
||||
|
||||
1. Go to **Users → Profile**
|
||||
2. Scroll to "Application Passwords"
|
||||
3. Delete existing password
|
||||
4. Create new Application Password
|
||||
5. Update your integration
|
||||
|
||||
**Step 4: Verify Base64 Encoding**
|
||||
|
||||
```bash
|
||||
# Test encoding
|
||||
echo -n "username:application_password" | base64
|
||||
```
|
||||
|
||||
### 404 Not Found
|
||||
|
||||
**Error Message**: `"No route was found matching the URL and request method"`
|
||||
|
||||
#### Possible Causes:
|
||||
|
||||
1. **Plugin not activated**
|
||||
2. **WordPress REST API disabled**
|
||||
3. **Incorrect endpoint URL**
|
||||
4. **Permalink structure issues**
|
||||
|
||||
#### Solutions:
|
||||
|
||||
**Step 1: Check Plugin Status**
|
||||
|
||||
1. Go to **Plugins → Installed Plugins**
|
||||
2. Verify "Rank Math API Manager" is **Active**
|
||||
3. Check for any error messages
|
||||
|
||||
**Step 2: Test REST API**
|
||||
|
||||
```bash
|
||||
# Test WordPress REST API
|
||||
curl -X GET "https://your-site.com/wp-json/wp/v2/posts"
|
||||
```
|
||||
|
||||
**Step 3: Check Permalinks**
|
||||
|
||||
1. Go to **Settings → Permalinks**
|
||||
2. Select any option other than "Plain"
|
||||
3. Save changes
|
||||
|
||||
**Step 4: Verify Endpoint URL**
|
||||
|
||||
```bash
|
||||
# Test endpoint availability
|
||||
curl -X GET "https://your-site.com/wp-json/rank-math-api/v1/update-meta"
|
||||
```
|
||||
|
||||
Expected response: 404 (confirms endpoint exists but requires POST)
|
||||
|
||||
### 400 Bad Request
|
||||
|
||||
**Error Message**: `"No metadata was updated"`
|
||||
|
||||
#### Possible Causes:
|
||||
|
||||
1. **Missing `post_id`**
|
||||
2. **Invalid post ID**
|
||||
3. **No SEO fields provided**
|
||||
4. **Invalid data format**
|
||||
|
||||
#### Solutions:
|
||||
|
||||
**Step 1: Verify Post ID**
|
||||
|
||||
```bash
|
||||
# Check if post exists
|
||||
curl -X GET "https://your-site.com/wp-json/wp/v2/posts/123"
|
||||
```
|
||||
|
||||
**Step 2: Check Request Format**
|
||||
|
||||
```bash
|
||||
# Ensure proper form data
|
||||
curl -X POST "https://your-site.com/wp-json/rank-math-api/v1/update-meta" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-H "Authorization: Basic [credentials]" \
|
||||
-d "post_id=123&rank_math_title=Test Title"
|
||||
```
|
||||
|
||||
**Step 3: Verify Post Status**
|
||||
|
||||
1. Go to **Posts → All Posts**
|
||||
2. Find the post by ID
|
||||
3. Ensure status is "Published"
|
||||
|
||||
### 500 Internal Server Error
|
||||
|
||||
**Error Message**: Various server error messages
|
||||
|
||||
#### Possible Causes:
|
||||
|
||||
1. **PHP memory limit exceeded**
|
||||
2. **Plugin conflicts**
|
||||
3. **Server configuration issues**
|
||||
4. **Database connection problems**
|
||||
|
||||
#### Solutions:
|
||||
|
||||
**Step 1: Enable Debug Mode**
|
||||
|
||||
```php
|
||||
// Add to wp-config.php
|
||||
define('WP_DEBUG', true);
|
||||
define('WP_DEBUG_LOG', true);
|
||||
define('WP_DEBUG_DISPLAY', false);
|
||||
```
|
||||
|
||||
**Step 2: Check Error Logs**
|
||||
|
||||
```bash
|
||||
# Check WordPress debug log
|
||||
tail -f wp-content/debug.log
|
||||
|
||||
# Check server error logs
|
||||
tail -f /var/log/apache2/error.log
|
||||
# or
|
||||
tail -f /var/log/nginx/error.log
|
||||
```
|
||||
|
||||
**Step 3: Increase Memory Limit**
|
||||
|
||||
```php
|
||||
// Add to wp-config.php
|
||||
define('WP_MEMORY_LIMIT', '256M');
|
||||
```
|
||||
|
||||
**Step 4: Test Plugin Conflicts**
|
||||
|
||||
1. Deactivate all plugins except Rank Math SEO and Rank Math API Manager
|
||||
2. Test the API endpoint
|
||||
3. Reactivate plugins one by one to identify conflicts
|
||||
|
||||
## 🔧 Integration-Specific Issues
|
||||
|
||||
### n8n Integration Problems
|
||||
|
||||
#### Issue: Authentication Fails in n8n
|
||||
|
||||
**Symptoms**: 401 errors in n8n workflow
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. **Check Credential Configuration**
|
||||
|
||||
- Verify username and Application Password
|
||||
- Ensure no extra spaces or characters
|
||||
- Test credentials manually first
|
||||
|
||||
2. **Update n8n Node Configuration**
|
||||
|
||||
```json
|
||||
{
|
||||
"authentication": "httpBasicAuth",
|
||||
"username": "your_username",
|
||||
"password": "your_application_password"
|
||||
}
|
||||
```
|
||||
|
||||
3. **Test with Simple Request**
|
||||
|
||||
```json
|
||||
{
|
||||
"method": "POST",
|
||||
"url": "https://your-site.com/wp-json/rank-math-api/v1/update-meta",
|
||||
"contentType": "form-urlencoded",
|
||||
"bodyParameters": {
|
||||
"post_id": "123",
|
||||
"rank_math_title": "Test Title"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Issue: Data Mapping Errors
|
||||
|
||||
**Symptoms**: Missing or incorrect data in API calls
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. **Add Data Validation Node**
|
||||
|
||||
```javascript
|
||||
// Add Code node before HTTP Request
|
||||
const postId = $("Previous Node").first().json.post_id;
|
||||
const seoTitle = $("Previous Node").first().json.seo_title;
|
||||
|
||||
if (!postId || !seoTitle) {
|
||||
throw new Error("Missing required data");
|
||||
}
|
||||
|
||||
return {
|
||||
post_id: postId,
|
||||
rank_math_title: seoTitle,
|
||||
rank_math_description: $("Previous Node").first().json.seo_description || "",
|
||||
rank_math_focus_keyword: $("Previous Node").first().json.focus_keyword || "",
|
||||
};
|
||||
```
|
||||
|
||||
2. **Add Error Handling**
|
||||
|
||||
```javascript
|
||||
// Add Code node after HTTP Request
|
||||
const response = $("HTTP Request").first().json;
|
||||
|
||||
if (response.error) {
|
||||
throw new Error(`API Error: ${response.error}`);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: response,
|
||||
};
|
||||
```
|
||||
|
||||
### Zapier Integration Problems
|
||||
|
||||
#### Issue: Code Action Fails
|
||||
|
||||
**Symptoms**: JavaScript errors in Zapier
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. **Add Error Handling**
|
||||
|
||||
```javascript
|
||||
try {
|
||||
const response = await fetch(
|
||||
"https://your-site.com/wp-json/rank-math-api/v1/update-meta",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Authorization: "Basic " + btoa("username:application_password"),
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
post_id: inputData.post_id,
|
||||
rank_math_title: inputData.seo_title,
|
||||
rank_math_description: inputData.seo_description,
|
||||
rank_math_focus_keyword: inputData.focus_keyword,
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`HTTP ${response.status}: ${result.message || "Unknown error"}`
|
||||
);
|
||||
}
|
||||
|
||||
return { success: true, data: result };
|
||||
} catch (error) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
```
|
||||
|
||||
2. **Validate Input Data**
|
||||
|
||||
```javascript
|
||||
// Validate required fields
|
||||
if (!inputData.post_id) {
|
||||
throw new Error("Post ID is required");
|
||||
}
|
||||
|
||||
if (!inputData.seo_title) {
|
||||
throw new Error("SEO title is required");
|
||||
}
|
||||
```
|
||||
|
||||
### Python Integration Problems
|
||||
|
||||
#### Issue: SSL Certificate Errors
|
||||
|
||||
**Symptoms**: SSL verification failures
|
||||
|
||||
**Solutions**:
|
||||
|
||||
```python
|
||||
import requests
|
||||
import urllib3
|
||||
|
||||
# Disable SSL warnings (not recommended for production)
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
# Make request with SSL verification disabled
|
||||
response = requests.post(url, headers=headers, data=data, verify=False)
|
||||
```
|
||||
|
||||
#### Issue: Connection Timeouts
|
||||
|
||||
**Symptoms**: Request timeouts
|
||||
|
||||
**Solutions**:
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
# Set timeout
|
||||
response = requests.post(url, headers=headers, data=data, timeout=30)
|
||||
|
||||
# Retry logic
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests.packages.urllib3.util.retry import Retry
|
||||
|
||||
session = requests.Session()
|
||||
retry = Retry(connect=3, backoff_factor=0.5)
|
||||
adapter = HTTPAdapter(max_retries=retry)
|
||||
session.mount('http://', adapter)
|
||||
session.mount('https://', adapter)
|
||||
|
||||
response = session.post(url, headers=headers, data=data)
|
||||
```
|
||||
|
||||
## 🛠️ Advanced Troubleshooting
|
||||
|
||||
### Debug Mode Setup
|
||||
|
||||
**Step 1: Enable WordPress Debug**
|
||||
|
||||
```php
|
||||
// Add to wp-config.php
|
||||
define('WP_DEBUG', true);
|
||||
define('WP_DEBUG_LOG', true);
|
||||
define('WP_DEBUG_DISPLAY', false);
|
||||
define('WP_DEBUG_DISPLAY', false);
|
||||
define('SCRIPT_DEBUG', true);
|
||||
```
|
||||
|
||||
**Step 2: Add Plugin Debug Logging**
|
||||
|
||||
```php
|
||||
// Add to your theme's functions.php or a custom plugin
|
||||
add_action('rest_api_init', function() {
|
||||
error_log('REST API initialized');
|
||||
});
|
||||
|
||||
add_action('wp_rest_server_class', function($class) {
|
||||
error_log('REST server class: ' . $class);
|
||||
});
|
||||
```
|
||||
|
||||
**Step 3: Monitor API Requests**
|
||||
|
||||
```php
|
||||
// Add to your theme's functions.php
|
||||
add_action('rest_api_init', function() {
|
||||
add_filter('rest_pre_dispatch', function($result, $server, $request) {
|
||||
error_log('API Request: ' . $request->get_route());
|
||||
error_log('API Method: ' . $request->get_method());
|
||||
error_log('API Params: ' . json_encode($request->get_params()));
|
||||
return $result;
|
||||
}, 10, 3);
|
||||
});
|
||||
```
|
||||
|
||||
### Performance Issues
|
||||
|
||||
#### Issue: Slow API Responses
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. **Optimize Database Queries**
|
||||
|
||||
```php
|
||||
// Add to wp-config.php
|
||||
define('SAVEQUERIES', true);
|
||||
```
|
||||
|
||||
2. **Check Server Resources**
|
||||
|
||||
```bash
|
||||
# Monitor server resources
|
||||
htop
|
||||
free -h
|
||||
df -h
|
||||
```
|
||||
|
||||
3. **Enable Caching**
|
||||
|
||||
```php
|
||||
// Add caching headers
|
||||
add_action('rest_api_init', function() {
|
||||
add_filter('rest_post_dispatch', function($response, $handler, $request) {
|
||||
$response->header('Cache-Control', 'public, max-age=300');
|
||||
return $response;
|
||||
}, 10, 3);
|
||||
});
|
||||
```
|
||||
|
||||
### Security Issues
|
||||
|
||||
#### Issue: Unauthorized Access Attempts
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. **Implement Rate Limiting**
|
||||
|
||||
```php
|
||||
// Add rate limiting
|
||||
add_action('rest_api_init', function() {
|
||||
add_filter('rest_pre_dispatch', function($result, $server, $request) {
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$key = 'api_rate_limit_' . $ip;
|
||||
$count = get_transient($key);
|
||||
|
||||
if ($count && $count > 100) {
|
||||
return new WP_Error('rate_limit_exceeded', 'Rate limit exceeded', ['status' => 429]);
|
||||
}
|
||||
|
||||
set_transient($key, ($count ? $count + 1 : 1), 3600);
|
||||
return $result;
|
||||
}, 10, 3);
|
||||
});
|
||||
```
|
||||
|
||||
2. **Log Security Events**
|
||||
|
||||
```php
|
||||
// Log failed authentication attempts
|
||||
add_action('rest_authentication_errors', function($result) {
|
||||
if ($result !== null) {
|
||||
error_log('Failed API authentication attempt from IP: ' . $_SERVER['REMOTE_ADDR']);
|
||||
}
|
||||
return $result;
|
||||
});
|
||||
```
|
||||
|
||||
## 📊 Monitoring and Logging
|
||||
|
||||
### Set Up Monitoring
|
||||
|
||||
**Step 1: Create Health Check Endpoint**
|
||||
|
||||
```php
|
||||
// Add to your plugin
|
||||
add_action('rest_api_init', function() {
|
||||
register_rest_route('rank-math-api/v1', '/health', [
|
||||
'methods' => 'GET',
|
||||
'callback' => function() {
|
||||
return [
|
||||
'status' => 'healthy',
|
||||
'timestamp' => current_time('mysql'),
|
||||
'version' => '1.0.6'
|
||||
];
|
||||
},
|
||||
'permission_callback' => '__return_true'
|
||||
]);
|
||||
});
|
||||
```
|
||||
|
||||
**Step 2: Monitor API Usage**
|
||||
|
||||
```php
|
||||
// Track API usage
|
||||
add_action('rest_api_init', function() {
|
||||
add_filter('rest_post_dispatch', function($response, $handler, $request) {
|
||||
if (strpos($request->get_route(), 'rank-math-api') !== false) {
|
||||
$usage = get_option('rank_math_api_usage', []);
|
||||
$date = date('Y-m-d');
|
||||
$usage[$date] = ($usage[$date] ?? 0) + 1;
|
||||
update_option('rank_math_api_usage', $usage);
|
||||
}
|
||||
return $response;
|
||||
}, 10, 3);
|
||||
});
|
||||
```
|
||||
|
||||
### Log Analysis
|
||||
|
||||
**Step 1: Parse WordPress Debug Log**
|
||||
|
||||
```bash
|
||||
# Find API-related errors
|
||||
grep "rank-math-api" wp-content/debug.log
|
||||
|
||||
# Find authentication errors
|
||||
grep "authentication" wp-content/debug.log
|
||||
|
||||
# Find recent errors
|
||||
tail -n 100 wp-content/debug.log | grep "ERROR"
|
||||
```
|
||||
|
||||
**Step 2: Monitor Server Logs**
|
||||
|
||||
```bash
|
||||
# Apache error logs
|
||||
tail -f /var/log/apache2/error.log | grep "your-domain.com"
|
||||
|
||||
# Nginx error logs
|
||||
tail -f /var/log/nginx/error.log | grep "your-domain.com"
|
||||
```
|
||||
|
||||
## 🆘 Getting Help
|
||||
|
||||
### Before Contacting Support
|
||||
|
||||
1. **Collect Information**:
|
||||
|
||||
- WordPress version
|
||||
- Plugin version
|
||||
- PHP version
|
||||
- Server environment
|
||||
- Complete error messages
|
||||
- Request/response data
|
||||
|
||||
2. **Test with Minimal Setup**:
|
||||
|
||||
- Deactivate other plugins
|
||||
- Switch to default theme
|
||||
- Test with basic cURL request
|
||||
|
||||
3. **Check Known Issues**:
|
||||
- Review GitHub issues
|
||||
- Check documentation
|
||||
- Search community forums
|
||||
|
||||
### Contact Information
|
||||
|
||||
- **GitHub Issues**: [Create an issue](https://github.com/devora-as/rank-math-api-manager/issues)
|
||||
- **Email Support**: [devora.no](https://devora.no)
|
||||
- **Documentation**: [docs/](docs/)
|
||||
|
||||
### Required Information for Support
|
||||
|
||||
When contacting support, include:
|
||||
|
||||
```
|
||||
WordPress Version: X.X.X
|
||||
Plugin Version: X.X.X
|
||||
PHP Version: X.X.X
|
||||
Server: Apache/Nginx
|
||||
Error Message: [Complete error message]
|
||||
Request Data: [API request details]
|
||||
Response Data: [API response details]
|
||||
Steps to Reproduce: [Detailed steps]
|
||||
Environment: [Local/Staging/Production]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Related Documentation**:
|
||||
|
||||
- [Installation Guide](installation.md)
|
||||
- [API Documentation](api-documentation.md)
|
||||
- [Integration Guide](integration-guide.md)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: July 2025
|
||||
**Version**: 1.0.6
|
||||
Reference in New Issue
Block a user