claude-plugin-wordpress-manager 2.4.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +10 -3
- package/CHANGELOG.md +103 -0
- package/agents/wp-content-strategist.md +104 -0
- package/agents/wp-monitoring-agent.md +44 -0
- package/agents/wp-site-manager.md +19 -0
- package/docs/GUIDE.md +183 -23
- package/docs/plans/2026-03-01-tier4-5-implementation.md +1783 -0
- package/docs/plans/2026-03-01-tier4-5-observability-automation-design.md +426 -0
- package/docs/plans/2026-03-01-wcop-reassessment-v2.6.0.md +403 -0
- package/hooks/hooks.json +9 -0
- package/package.json +19 -3
- package/servers/wp-rest-bridge/build/tools/comments.d.ts +6 -6
- package/servers/wp-rest-bridge/build/tools/cwv.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/cwv.js +196 -0
- package/servers/wp-rest-bridge/build/tools/ga4.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/ga4.js +323 -0
- package/servers/wp-rest-bridge/build/tools/gsc.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/gsc.js +354 -0
- package/servers/wp-rest-bridge/build/tools/index.d.ts +38 -38
- package/servers/wp-rest-bridge/build/tools/index.js +18 -0
- package/servers/wp-rest-bridge/build/tools/media.d.ts +2 -2
- package/servers/wp-rest-bridge/build/tools/multisite-sites.d.ts +2 -2
- package/servers/wp-rest-bridge/build/tools/plausible.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/plausible.js +207 -0
- package/servers/wp-rest-bridge/build/tools/plugin-repository.d.ts +1 -1
- package/servers/wp-rest-bridge/build/tools/search.d.ts +2 -2
- package/servers/wp-rest-bridge/build/tools/slack.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/slack.js +129 -0
- package/servers/wp-rest-bridge/build/tools/unified-content.d.ts +8 -8
- package/servers/wp-rest-bridge/build/tools/unified-taxonomies.d.ts +4 -4
- package/servers/wp-rest-bridge/build/tools/users.d.ts +6 -6
- package/servers/wp-rest-bridge/build/tools/wc-coupons.d.ts +1 -1
- package/servers/wp-rest-bridge/build/tools/wc-customers.d.ts +3 -3
- package/servers/wp-rest-bridge/build/tools/wc-orders.d.ts +4 -4
- package/servers/wp-rest-bridge/build/tools/wc-products.d.ts +8 -8
- package/servers/wp-rest-bridge/build/tools/wc-webhooks.d.ts +4 -4
- package/servers/wp-rest-bridge/build/tools/wc-workflows.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/wc-workflows.js +222 -0
- package/servers/wp-rest-bridge/build/wordpress.d.ts +23 -0
- package/servers/wp-rest-bridge/build/wordpress.js +178 -0
- package/servers/wp-rest-bridge/package.json +1 -0
- package/skills/wordpress-router/SKILL.md +1 -1
- package/skills/wordpress-router/references/decision-tree.md +12 -2
- package/skills/wp-alerting/SKILL.md +142 -0
- package/skills/wp-alerting/references/alert-thresholds.md +79 -0
- package/skills/wp-alerting/references/escalation-paths.md +92 -0
- package/skills/wp-alerting/references/report-scheduling.md +142 -0
- package/skills/wp-alerting/references/slack-integration.md +109 -0
- package/skills/wp-alerting/scripts/alerting_inspect.mjs +150 -0
- package/skills/wp-analytics/SKILL.md +158 -0
- package/skills/wp-analytics/references/analytics-dashboards.md +83 -0
- package/skills/wp-analytics/references/cwv-monitoring.md +101 -0
- package/skills/wp-analytics/references/ga4-integration.md +76 -0
- package/skills/wp-analytics/references/plausible-setup.md +92 -0
- package/skills/wp-analytics/references/traffic-attribution.md +92 -0
- package/skills/wp-analytics/scripts/analytics_inspect.mjs +153 -0
- package/skills/wp-content/SKILL.md +1 -0
- package/skills/wp-content-attribution/SKILL.md +3 -0
- package/skills/wp-content-optimization/SKILL.md +173 -0
- package/skills/wp-content-optimization/references/content-freshness.md +234 -0
- package/skills/wp-content-optimization/references/headline-optimization.md +171 -0
- package/skills/wp-content-optimization/references/meta-optimization.md +243 -0
- package/skills/wp-content-optimization/references/readability-analysis.md +201 -0
- package/skills/wp-content-optimization/references/seo-content-scoring.md +245 -0
- package/skills/wp-content-optimization/scripts/content_optimization_inspect.mjs +237 -0
- package/skills/wp-content-workflows/SKILL.md +142 -0
- package/skills/wp-content-workflows/references/content-lifecycle-hooks.md +131 -0
- package/skills/wp-content-workflows/references/multi-channel-actions.md +151 -0
- package/skills/wp-content-workflows/references/schedule-triggers.md +118 -0
- package/skills/wp-content-workflows/references/trigger-management.md +159 -0
- package/skills/wp-content-workflows/references/wp-action-hooks.md +114 -0
- package/skills/wp-content-workflows/scripts/workflow_inspect.mjs +202 -0
- package/skills/wp-monitoring/SKILL.md +3 -0
- package/skills/wp-programmatic-seo/SKILL.md +2 -0
- package/skills/wp-search-console/SKILL.md +122 -0
- package/skills/wp-search-console/references/competitor-gap-analysis.md +226 -0
- package/skills/wp-search-console/references/content-seo-feedback.md +181 -0
- package/skills/wp-search-console/references/gsc-setup.md +110 -0
- package/skills/wp-search-console/references/indexing-management.md +182 -0
- package/skills/wp-search-console/references/keyword-tracking.md +181 -0
- package/skills/wp-search-console/scripts/search_console_inspect.mjs +178 -0
- package/skills/wp-social-email/SKILL.md +1 -0
- package/skills/wp-webhooks/SKILL.md +1 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Content Lifecycle Hooks
|
|
2
|
+
|
|
3
|
+
## Post Status Transitions
|
|
4
|
+
|
|
5
|
+
WordPress fires `transition_post_status` on every status change:
|
|
6
|
+
|
|
7
|
+
| Transition | From → To | Common Use |
|
|
8
|
+
|------------|-----------|------------|
|
|
9
|
+
| Publish | `draft` → `publish` | Notify team of new content |
|
|
10
|
+
| Schedule | `draft` → `future` | Confirm scheduling |
|
|
11
|
+
| Unpublish | `publish` → `draft` | Alert editors |
|
|
12
|
+
| Trash | `publish` → `trash` | Audit log entry |
|
|
13
|
+
| Restore | `trash` → `draft` | Notify original author |
|
|
14
|
+
| Pending review | `draft` → `pending` | Notify reviewers |
|
|
15
|
+
|
|
16
|
+
### Hook Signatures
|
|
17
|
+
|
|
18
|
+
```php
|
|
19
|
+
// Generic transition hook
|
|
20
|
+
add_action('transition_post_status', function ($new, $old, $post) {
|
|
21
|
+
if ($new === 'publish' && $old !== 'publish') {
|
|
22
|
+
// First-time publish — trigger workflow
|
|
23
|
+
}
|
|
24
|
+
}, 10, 3);
|
|
25
|
+
|
|
26
|
+
// Specific transition hooks (preferred for performance)
|
|
27
|
+
add_action('draft_to_publish', function ($post) {
|
|
28
|
+
// Fires only on draft → publish transition
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
add_action('pending_to_publish', function ($post) {
|
|
32
|
+
// Fires on pending → publish (after review approval)
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Trigger Config Example
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"type": "content_lifecycle",
|
|
41
|
+
"event": "draft_to_publish",
|
|
42
|
+
"post_type": "post",
|
|
43
|
+
"actions": [
|
|
44
|
+
{ "channel": "slack", "message": ":newspaper: New post published: *{{post_title}}* by {{post_author}}" }
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Custom Post Type Support
|
|
50
|
+
|
|
51
|
+
The same transition hooks work for any registered post type:
|
|
52
|
+
|
|
53
|
+
| Post Type | Slug | Example Trigger |
|
|
54
|
+
|-----------|------|-----------------|
|
|
55
|
+
| WooCommerce Product | `product` | Notify when new product goes live |
|
|
56
|
+
| Portfolio | `portfolio` | Share on social when portfolio item published |
|
|
57
|
+
| Event | `event` | Send reminder email on event publish |
|
|
58
|
+
| Landing Page | `page` | Alert marketing team on page publish |
|
|
59
|
+
|
|
60
|
+
Filter by post type in trigger config:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"event": "draft_to_publish",
|
|
65
|
+
"post_type": ["post", "product"],
|
|
66
|
+
"condition": "post_type IN (post, product)"
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Taxonomy and Term Changes
|
|
71
|
+
|
|
72
|
+
| Hook | Fires When | Parameters |
|
|
73
|
+
|------|------------|------------|
|
|
74
|
+
| `set_object_terms` | Terms assigned to a post | `$object_id`, `$terms`, `$tt_ids`, `$taxonomy` |
|
|
75
|
+
| `created_term` | New term created | `$term_id`, `$tt_id`, `$taxonomy` |
|
|
76
|
+
| `edited_term` | Term updated | `$term_id`, `$tt_id`, `$taxonomy` |
|
|
77
|
+
| `delete_term` | Term deleted | `$term_id`, `$tt_id`, `$taxonomy`, `$deleted_term` |
|
|
78
|
+
|
|
79
|
+
Example: notify when a post is tagged with "featured":
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"type": "content_lifecycle",
|
|
84
|
+
"event": "set_object_terms",
|
|
85
|
+
"condition": "taxonomy == 'post_tag' AND terms CONTAINS 'featured'",
|
|
86
|
+
"actions": [
|
|
87
|
+
{ "channel": "slack", "message": "Post tagged as featured: {{post_title}}" }
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Media Upload Events
|
|
93
|
+
|
|
94
|
+
| Hook | Fires When | Parameters |
|
|
95
|
+
|------|------------|------------|
|
|
96
|
+
| `add_attachment` | New media uploaded | `$attachment_id` |
|
|
97
|
+
| `edit_attachment` | Attachment metadata updated | `$attachment_id` |
|
|
98
|
+
| `delete_attachment` | Media file deleted | `$attachment_id` |
|
|
99
|
+
| `wp_handle_upload` | File upload processed | `$upload` array |
|
|
100
|
+
|
|
101
|
+
Example: log large file uploads:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"type": "content_lifecycle",
|
|
106
|
+
"event": "add_attachment",
|
|
107
|
+
"condition": "filesize > 5MB",
|
|
108
|
+
"actions": [
|
|
109
|
+
{ "channel": "webhook", "url": "{{audit_webhook_url}}", "payload": { "event": "large_upload", "file": "{{filename}}", "size": "{{filesize}}" } }
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Example: Notify Slack When Blog Post Published
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"name": "Blog Post Published Notification",
|
|
119
|
+
"type": "content_lifecycle",
|
|
120
|
+
"event": "draft_to_publish",
|
|
121
|
+
"post_type": "post",
|
|
122
|
+
"actions": [
|
|
123
|
+
{
|
|
124
|
+
"channel": "slack",
|
|
125
|
+
"message": ":mega: *New blog post published!*\n*Title:* {{post_title}}\n*Author:* {{post_author}}\n*URL:* {{post_url}}",
|
|
126
|
+
"channel_override": "#content-updates"
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
"status": "active"
|
|
130
|
+
}
|
|
131
|
+
```
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Multi-Channel Action Configuration
|
|
2
|
+
|
|
3
|
+
## Action Channel Types
|
|
4
|
+
|
|
5
|
+
| Channel | Identifier | Required Config | Tool |
|
|
6
|
+
|---------|-----------|-----------------|------|
|
|
7
|
+
| Slack (Webhook) | `slack` | `slack_webhook_url` in WP_SITES_CONFIG | `slack_send_webhook` |
|
|
8
|
+
| Slack (Bot) | `slack_bot` | `slack_bot_token` + `slack_channel` | `slack_send_message` |
|
|
9
|
+
| Email (SendGrid) | `email` | `sendgrid_api_key` in WP_SITES_CONFIG | `sg_send_email` |
|
|
10
|
+
| Webhook (HTTP) | `webhook` | Target URL in action config | Custom HTTP POST |
|
|
11
|
+
| Mailchimp | `mailchimp` | `mailchimp_api_key` in WP_SITES_CONFIG | Mailchimp API |
|
|
12
|
+
|
|
13
|
+
## Template Variables
|
|
14
|
+
|
|
15
|
+
Common variables available in all action templates:
|
|
16
|
+
|
|
17
|
+
| Variable | Description | Example Value |
|
|
18
|
+
|----------|-------------|---------------|
|
|
19
|
+
| `{{site_url}}` | WordPress site URL | `https://example.com` |
|
|
20
|
+
| `{{site_name}}` | Site title | `My WordPress Site` |
|
|
21
|
+
| `{{timestamp}}` | Event timestamp (ISO 8601) | `2026-03-01T14:30:00Z` |
|
|
22
|
+
| `{{trigger_name}}` | Name of the firing trigger | `Blog Post Published` |
|
|
23
|
+
| `{{post_title}}` | Post title (content events) | `Hello World` |
|
|
24
|
+
| `{{post_url}}` | Post permalink | `https://example.com/hello-world` |
|
|
25
|
+
| `{{post_author}}` | Post author display name | `John Doe` |
|
|
26
|
+
| `{{post_type}}` | Post type slug | `post` |
|
|
27
|
+
| `{{user_name}}` | User display name | `Jane Smith` |
|
|
28
|
+
| `{{user_email}}` | User email address | `jane@example.com` |
|
|
29
|
+
| `{{order_id}}` | WooCommerce order ID | `1234` |
|
|
30
|
+
| `{{order_total}}` | Order total with currency | `$99.00` |
|
|
31
|
+
| `{{order_status}}` | Current order status | `completed` |
|
|
32
|
+
|
|
33
|
+
## Channel-Specific Formatting
|
|
34
|
+
|
|
35
|
+
### Slack (Block Kit)
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"channel": "slack",
|
|
40
|
+
"format": "block_kit",
|
|
41
|
+
"blocks": [
|
|
42
|
+
{
|
|
43
|
+
"type": "header",
|
|
44
|
+
"text": { "type": "plain_text", "text": "{{trigger_name}}", "emoji": true }
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"type": "section",
|
|
48
|
+
"fields": [
|
|
49
|
+
{ "type": "mrkdwn", "text": "*Post:*\n{{post_title}}" },
|
|
50
|
+
{ "type": "mrkdwn", "text": "*Author:*\n{{post_author}}" }
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"fallback_text": "{{trigger_name}}: {{post_title}} by {{post_author}}"
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Email (HTML)
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"channel": "email",
|
|
63
|
+
"to": "team@example.com",
|
|
64
|
+
"subject": "[{{site_name}}] {{trigger_name}}",
|
|
65
|
+
"format": "html",
|
|
66
|
+
"body": "<h2>{{trigger_name}}</h2><p><strong>{{post_title}}</strong> by {{post_author}}</p><p><a href='{{post_url}}'>View Post</a></p>"
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Webhook (JSON)
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"channel": "webhook",
|
|
75
|
+
"url": "https://api.example.com/events",
|
|
76
|
+
"method": "POST",
|
|
77
|
+
"headers": { "Content-Type": "application/json", "X-Webhook-Secret": "{{webhook_secret}}" },
|
|
78
|
+
"payload": {
|
|
79
|
+
"event": "{{trigger_name}}",
|
|
80
|
+
"post": { "title": "{{post_title}}", "url": "{{post_url}}", "author": "{{post_author}}" },
|
|
81
|
+
"timestamp": "{{timestamp}}"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Rate Limiting Per Channel
|
|
87
|
+
|
|
88
|
+
| Channel | Default Limit | Burst | Cooldown |
|
|
89
|
+
|---------|---------------|-------|----------|
|
|
90
|
+
| Slack (Webhook) | 1 msg/sec | 5 msg burst | 1 second |
|
|
91
|
+
| Slack (Bot) | 1 msg/sec per channel | Tier 2 | Varies |
|
|
92
|
+
| Email (SendGrid) | 100 msg/sec (plan-dependent) | — | None |
|
|
93
|
+
| Webhook | 10 req/sec | 20 burst | 100ms |
|
|
94
|
+
|
|
95
|
+
**Rate limit strategy:**
|
|
96
|
+
- Queue actions when rate exceeded
|
|
97
|
+
- Batch low-priority events into digest messages
|
|
98
|
+
- Critical events bypass rate limits (sent immediately)
|
|
99
|
+
- Log rate limit hits for trigger tuning
|
|
100
|
+
|
|
101
|
+
## Multi-Channel Action Mapping
|
|
102
|
+
|
|
103
|
+
A single trigger can fire multiple actions across channels:
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"actions": [
|
|
108
|
+
{ "channel": "slack", "priority": "high" },
|
|
109
|
+
{ "channel": "email", "priority": "high" },
|
|
110
|
+
{ "channel": "webhook", "priority": "normal" }
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Priority levels:**
|
|
116
|
+
- `critical` — all channels fire immediately, bypass rate limits
|
|
117
|
+
- `high` — all channels fire immediately, respect rate limits
|
|
118
|
+
- `normal` — queued, batched if necessary
|
|
119
|
+
- `low` — batched into digest (hourly or daily)
|
|
120
|
+
|
|
121
|
+
## Example: Critical Order — Slack + Email + Webhook
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"name": "Critical Order Alert",
|
|
126
|
+
"type": "action_hook",
|
|
127
|
+
"event": "woocommerce_payment_complete",
|
|
128
|
+
"condition": "order_total > 500",
|
|
129
|
+
"actions": [
|
|
130
|
+
{
|
|
131
|
+
"channel": "slack",
|
|
132
|
+
"priority": "critical",
|
|
133
|
+
"message": ":moneybag: *High-value order!* #{{order_id}} — {{order_total}}"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"channel": "email",
|
|
137
|
+
"priority": "critical",
|
|
138
|
+
"to": "sales@example.com",
|
|
139
|
+
"subject": "High-value order #{{order_id}} — {{order_total}}",
|
|
140
|
+
"template": "high_value_order"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"channel": "webhook",
|
|
144
|
+
"priority": "critical",
|
|
145
|
+
"url": "https://crm.example.com/api/orders",
|
|
146
|
+
"payload": { "order_id": "{{order_id}}", "total": "{{order_total}}", "event": "high_value" }
|
|
147
|
+
}
|
|
148
|
+
],
|
|
149
|
+
"status": "active"
|
|
150
|
+
}
|
|
151
|
+
```
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Schedule-Based Triggers
|
|
2
|
+
|
|
3
|
+
## WP-Cron Built-in Intervals
|
|
4
|
+
|
|
5
|
+
| Interval | Hook Name | Frequency |
|
|
6
|
+
|----------|-----------|-----------|
|
|
7
|
+
| `hourly` | `wp_scheduled_event` | Every hour |
|
|
8
|
+
| `twicedaily` | `wp_scheduled_event` | Every 12 hours |
|
|
9
|
+
| `daily` | `wp_scheduled_event` | Every 24 hours |
|
|
10
|
+
| `weekly` | `wp_scheduled_event` | Every 7 days |
|
|
11
|
+
|
|
12
|
+
## Custom Cron Intervals
|
|
13
|
+
|
|
14
|
+
Register custom intervals via `cron_schedules` filter:
|
|
15
|
+
|
|
16
|
+
```php
|
|
17
|
+
add_filter('cron_schedules', function ($schedules) {
|
|
18
|
+
$schedules['every_15_minutes'] = [
|
|
19
|
+
'interval' => 900,
|
|
20
|
+
'display' => 'Every 15 Minutes',
|
|
21
|
+
];
|
|
22
|
+
$schedules['every_monday_9am'] = [
|
|
23
|
+
'interval' => 604800, // weekly
|
|
24
|
+
'display' => 'Weekly (Monday 9am)',
|
|
25
|
+
];
|
|
26
|
+
return $schedules;
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Schedule a recurring event:
|
|
31
|
+
|
|
32
|
+
```php
|
|
33
|
+
if (!wp_next_scheduled('wpm_weekly_report')) {
|
|
34
|
+
wp_schedule_event(
|
|
35
|
+
strtotime('next Monday 09:00'),
|
|
36
|
+
'weekly',
|
|
37
|
+
'wpm_weekly_report'
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
add_action('wpm_weekly_report', 'generate_weekly_performance_report');
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Scheduled Content Publishing
|
|
44
|
+
|
|
45
|
+
WordPress natively supports future-dated posts via `publish_future_post` hook:
|
|
46
|
+
|
|
47
|
+
- Set post status to `future` with a future `post_date`
|
|
48
|
+
- WP-Cron fires `publish_future_post` at the scheduled time
|
|
49
|
+
- Trigger workflow actions on publish (e.g., notify Slack)
|
|
50
|
+
|
|
51
|
+
Trigger config example:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"type": "schedule",
|
|
56
|
+
"event": "publish_future_post",
|
|
57
|
+
"actions": [
|
|
58
|
+
{ "channel": "slack", "message": "New post published: {{post_title}}" }
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Recurring Health Check Triggers
|
|
64
|
+
|
|
65
|
+
Common scheduled workflow patterns:
|
|
66
|
+
|
|
67
|
+
| Trigger | Interval | Purpose |
|
|
68
|
+
|---------|----------|---------|
|
|
69
|
+
| Performance report | Weekly | CWV scores, uptime stats |
|
|
70
|
+
| Plugin update check | Daily | Security and compatibility |
|
|
71
|
+
| Content freshness | Weekly | Stale draft detection |
|
|
72
|
+
| Backup verification | Daily | Confirm last backup age |
|
|
73
|
+
| SSL expiry check | Daily | Certificate renewal reminder |
|
|
74
|
+
|
|
75
|
+
## External Cron Setup (Server Cron)
|
|
76
|
+
|
|
77
|
+
When `DISABLE_WP_CRON` is `true`, use server-side cron:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# crontab entry — fire WP-Cron every 5 minutes
|
|
81
|
+
*/5 * * * * wget -qO- https://example.com/wp-cron.php > /dev/null 2>&1
|
|
82
|
+
|
|
83
|
+
# Alternative with curl
|
|
84
|
+
*/5 * * * * curl -s https://example.com/wp-cron.php > /dev/null 2>&1
|
|
85
|
+
|
|
86
|
+
# WP-CLI approach (recommended for reliability)
|
|
87
|
+
*/5 * * * * cd /var/www/html && wp cron event run --due-now > /dev/null 2>&1
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**When to use external cron:**
|
|
91
|
+
- High-traffic sites (WP-Cron adds latency to page loads)
|
|
92
|
+
- Sites behind caching layers that block `wp-cron.php`
|
|
93
|
+
- When precise timing is required (WP-Cron is visitor-triggered)
|
|
94
|
+
|
|
95
|
+
## Example: Weekly Performance Report Every Monday 9am
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"name": "Weekly Performance Report",
|
|
100
|
+
"type": "schedule",
|
|
101
|
+
"schedule": "weekly",
|
|
102
|
+
"first_run": "2026-03-02T09:00:00Z",
|
|
103
|
+
"actions": [
|
|
104
|
+
{
|
|
105
|
+
"channel": "slack",
|
|
106
|
+
"template": "weekly_report",
|
|
107
|
+
"variables": { "site": "{{site_url}}", "period": "last_7_days" }
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"channel": "email",
|
|
111
|
+
"to": "team@example.com",
|
|
112
|
+
"subject": "Weekly WP Report — {{site_url}}",
|
|
113
|
+
"template": "weekly_report_email"
|
|
114
|
+
}
|
|
115
|
+
],
|
|
116
|
+
"status": "active"
|
|
117
|
+
}
|
|
118
|
+
```
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Trigger Management
|
|
2
|
+
|
|
3
|
+
## Listing and Filtering Triggers
|
|
4
|
+
|
|
5
|
+
Use `wf_list_triggers` to retrieve all registered triggers:
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
// List all triggers
|
|
9
|
+
{ "tool": "wf_list_triggers" }
|
|
10
|
+
|
|
11
|
+
// Filter by status
|
|
12
|
+
{ "tool": "wf_list_triggers", "status": "active" }
|
|
13
|
+
{ "tool": "wf_list_triggers", "status": "inactive" }
|
|
14
|
+
|
|
15
|
+
// Filter by type
|
|
16
|
+
{ "tool": "wf_list_triggers", "type": "schedule" }
|
|
17
|
+
{ "tool": "wf_list_triggers", "type": "content_lifecycle" }
|
|
18
|
+
{ "tool": "wf_list_triggers", "type": "action_hook" }
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Trigger List Response Format
|
|
22
|
+
|
|
23
|
+
| Field | Description |
|
|
24
|
+
|-------|-------------|
|
|
25
|
+
| `id` | Unique trigger identifier |
|
|
26
|
+
| `name` | Human-readable trigger name |
|
|
27
|
+
| `type` | `schedule`, `content_lifecycle`, or `action_hook` |
|
|
28
|
+
| `event` | The WordPress event or cron schedule |
|
|
29
|
+
| `status` | `active` or `inactive` |
|
|
30
|
+
| `actions` | Array of action channel configurations |
|
|
31
|
+
| `last_fired` | Timestamp of last execution (null if never) |
|
|
32
|
+
| `fire_count` | Total number of times fired |
|
|
33
|
+
| `created_at` | Creation timestamp |
|
|
34
|
+
|
|
35
|
+
## Activate/Deactivate Without Deleting
|
|
36
|
+
|
|
37
|
+
Toggle triggers on or off without losing configuration:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
// Deactivate a trigger
|
|
41
|
+
{ "tool": "wf_update_trigger", "id": "trg_001", "status": "inactive" }
|
|
42
|
+
|
|
43
|
+
// Reactivate a trigger
|
|
44
|
+
{ "tool": "wf_update_trigger", "id": "trg_001", "status": "active" }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Use cases for deactivation:**
|
|
48
|
+
- Temporarily silence during maintenance windows
|
|
49
|
+
- Pause triggers during site migration
|
|
50
|
+
- Debug by isolating triggers one at a time
|
|
51
|
+
- Seasonal triggers (e.g., holiday sale workflows)
|
|
52
|
+
|
|
53
|
+
## Testing Triggers (Dry-Run Mode)
|
|
54
|
+
|
|
55
|
+
Test a trigger without executing real actions:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"tool": "wf_update_trigger",
|
|
60
|
+
"id": "trg_001",
|
|
61
|
+
"dry_run": true
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Dry-run behavior:
|
|
66
|
+
- Evaluates conditions against current site state
|
|
67
|
+
- Resolves all template variables with real data
|
|
68
|
+
- Logs the fully rendered action payloads
|
|
69
|
+
- Does NOT send Slack messages, emails, or webhooks
|
|
70
|
+
- Returns the rendered output for review
|
|
71
|
+
|
|
72
|
+
### Manual Test Fire
|
|
73
|
+
|
|
74
|
+
Force a trigger to execute once (real actions):
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"tool": "wf_update_trigger",
|
|
79
|
+
"id": "trg_001",
|
|
80
|
+
"test_fire": true
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Warning:** `test_fire` sends real messages. Use `dry_run` first to verify payload format.
|
|
85
|
+
|
|
86
|
+
## Trigger Audit Log
|
|
87
|
+
|
|
88
|
+
Every trigger execution is logged:
|
|
89
|
+
|
|
90
|
+
| Field | Description |
|
|
91
|
+
|-------|-------------|
|
|
92
|
+
| `trigger_id` | ID of the trigger that fired |
|
|
93
|
+
| `timestamp` | When the trigger fired |
|
|
94
|
+
| `event` | WordPress event that caused the fire |
|
|
95
|
+
| `actions_executed` | List of actions taken (channel + status) |
|
|
96
|
+
| `dry_run` | Whether this was a dry-run execution |
|
|
97
|
+
| `error` | Error message if any action failed |
|
|
98
|
+
| `duration_ms` | Total execution time in milliseconds |
|
|
99
|
+
|
|
100
|
+
Query audit logs via the WordPress admin or REST API for debugging and compliance.
|
|
101
|
+
|
|
102
|
+
## Bulk Operations
|
|
103
|
+
|
|
104
|
+
### Enable/Disable All Triggers
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
// Disable all triggers (maintenance mode)
|
|
108
|
+
{ "tool": "wf_update_trigger", "bulk": true, "status": "inactive" }
|
|
109
|
+
|
|
110
|
+
// Re-enable all triggers
|
|
111
|
+
{ "tool": "wf_update_trigger", "bulk": true, "status": "active" }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Export/Import Triggers
|
|
115
|
+
|
|
116
|
+
Export all trigger configurations as JSON for backup or migration:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
// Export triggers
|
|
120
|
+
{ "tool": "wf_list_triggers", "format": "export" }
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The export includes full trigger config without runtime data (fire_count, last_fired). Import by creating triggers from the exported JSON array.
|
|
124
|
+
|
|
125
|
+
### Bulk Delete
|
|
126
|
+
|
|
127
|
+
Remove all inactive or stale triggers:
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
// Delete a specific trigger (requires confirmation)
|
|
131
|
+
{ "tool": "wf_delete_trigger", "id": "trg_001" }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The `wf_delete_trigger` tool has a safety hook that requires explicit confirmation before deletion.
|
|
135
|
+
|
|
136
|
+
## Cleanup: Removing Stale Triggers
|
|
137
|
+
|
|
138
|
+
A trigger is considered stale if:
|
|
139
|
+
- Status is `inactive` for more than 30 days
|
|
140
|
+
- `last_fired` is null and `created_at` is older than 30 days
|
|
141
|
+
- Referenced hook or event no longer exists (e.g., plugin deactivated)
|
|
142
|
+
|
|
143
|
+
### Cleanup Workflow
|
|
144
|
+
|
|
145
|
+
1. List inactive triggers: `wf_list_triggers` with `status: "inactive"`
|
|
146
|
+
2. Review each trigger's `last_fired` and `created_at`
|
|
147
|
+
3. Identify stale triggers based on criteria above
|
|
148
|
+
4. Delete stale triggers with `wf_delete_trigger`
|
|
149
|
+
5. Verify remaining triggers are all active and functional
|
|
150
|
+
|
|
151
|
+
### Recommended Maintenance Schedule
|
|
152
|
+
|
|
153
|
+
| Task | Frequency | Tool |
|
|
154
|
+
|------|-----------|------|
|
|
155
|
+
| Review trigger list | Weekly | `wf_list_triggers` |
|
|
156
|
+
| Test critical triggers | Monthly | `wf_update_trigger` (dry_run) |
|
|
157
|
+
| Clean stale triggers | Monthly | `wf_delete_trigger` |
|
|
158
|
+
| Export trigger backup | Before updates | `wf_list_triggers` (export) |
|
|
159
|
+
| Audit log review | Weekly | WordPress admin |
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# WordPress Action/Filter Hooks for Workflows
|
|
2
|
+
|
|
3
|
+
## Core WordPress Action Hooks
|
|
4
|
+
|
|
5
|
+
### User Actions
|
|
6
|
+
|
|
7
|
+
| Hook | Fires When | Key Parameters |
|
|
8
|
+
|------|------------|----------------|
|
|
9
|
+
| `user_register` | New user created | `$user_id` |
|
|
10
|
+
| `wp_login` | User logs in | `$user_login`, `$user` |
|
|
11
|
+
| `wp_logout` | User logs out | `$user_id` |
|
|
12
|
+
| `profile_update` | Profile updated | `$user_id`, `$old_user_data` |
|
|
13
|
+
| `delete_user` | User deleted | `$user_id`, `$reassign` |
|
|
14
|
+
| `set_user_role` | Role changed | `$user_id`, `$role`, `$old_roles` |
|
|
15
|
+
|
|
16
|
+
### Comment Actions
|
|
17
|
+
|
|
18
|
+
| Hook | Fires When | Key Parameters |
|
|
19
|
+
|------|------------|----------------|
|
|
20
|
+
| `comment_post` | New comment posted | `$comment_id`, `$approved` |
|
|
21
|
+
| `edit_comment` | Comment edited | `$comment_id` |
|
|
22
|
+
| `wp_set_comment_status` | Status changed (approve/spam/trash) | `$comment_id`, `$status` |
|
|
23
|
+
| `delete_comment` | Comment deleted | `$comment_id` |
|
|
24
|
+
|
|
25
|
+
### Plugin & Theme Actions
|
|
26
|
+
|
|
27
|
+
| Hook | Fires When | Key Parameters |
|
|
28
|
+
|------|------------|----------------|
|
|
29
|
+
| `activated_plugin` | Plugin activated | `$plugin`, `$network_wide` |
|
|
30
|
+
| `deactivated_plugin` | Plugin deactivated | `$plugin` |
|
|
31
|
+
| `upgrader_process_complete` | Update completed | `$upgrader`, `$options` |
|
|
32
|
+
| `switch_theme` | Theme switched | `$new_name`, `$new_theme` |
|
|
33
|
+
|
|
34
|
+
### System Actions
|
|
35
|
+
|
|
36
|
+
| Hook | Fires When | Key Parameters |
|
|
37
|
+
|------|------------|----------------|
|
|
38
|
+
| `wp_mail_failed` | Email delivery failed | `$wp_error` |
|
|
39
|
+
| `recovery_mode_email_sent` | Recovery mode triggered | — |
|
|
40
|
+
| `wp_privacy_personal_data_export_file_created` | GDPR export ready | `$archive_pathname` |
|
|
41
|
+
|
|
42
|
+
## WooCommerce Action Hooks
|
|
43
|
+
|
|
44
|
+
| Hook | Fires When | Key Parameters |
|
|
45
|
+
|------|------------|----------------|
|
|
46
|
+
| `woocommerce_new_order` | New order placed | `$order_id` |
|
|
47
|
+
| `woocommerce_order_status_changed` | Order status transition | `$order_id`, `$old_status`, `$new_status` |
|
|
48
|
+
| `woocommerce_payment_complete` | Payment received | `$order_id` |
|
|
49
|
+
| `woocommerce_order_refunded` | Order refunded | `$order_id`, `$refund_id` |
|
|
50
|
+
| `woocommerce_low_stock` | Product low stock | `$product` |
|
|
51
|
+
| `woocommerce_no_stock` | Product out of stock | `$product` |
|
|
52
|
+
| `woocommerce_new_customer_note` | Customer note added | `$args` |
|
|
53
|
+
|
|
54
|
+
### Trigger Config Example (WooCommerce)
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"type": "action_hook",
|
|
59
|
+
"event": "woocommerce_order_status_changed",
|
|
60
|
+
"condition": "new_status == 'completed'",
|
|
61
|
+
"actions": [
|
|
62
|
+
{ "channel": "slack", "message": ":package: Order #{{order_id}} completed — {{order_total}}" },
|
|
63
|
+
{ "channel": "email", "to": "fulfillment@example.com", "subject": "Order #{{order_id}} ready for shipping" }
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Filter Hooks for Content Transformation
|
|
69
|
+
|
|
70
|
+
Filters modify data before saving or displaying. Use for content transformation workflows:
|
|
71
|
+
|
|
72
|
+
| Filter | Purpose | Parameters |
|
|
73
|
+
|--------|---------|------------|
|
|
74
|
+
| `wp_insert_post_data` | Modify post before save | `$data`, `$postarr` |
|
|
75
|
+
| `the_content` | Transform content on display | `$content` |
|
|
76
|
+
| `wp_handle_upload_prefilter` | Validate uploads before processing | `$file` |
|
|
77
|
+
| `comment_text` | Transform comment text on display | `$comment_text` |
|
|
78
|
+
|
|
79
|
+
**Note:** Filter-based triggers observe data flow but should not block it. Use filters for logging and auditing, not for heavy action dispatch.
|
|
80
|
+
|
|
81
|
+
## Hook Priority and Execution Order
|
|
82
|
+
|
|
83
|
+
```php
|
|
84
|
+
// Default priority is 10. Lower = earlier execution.
|
|
85
|
+
add_action('user_register', 'workflow_on_register', 20); // Fires after core handlers
|
|
86
|
+
add_action('user_register', 'audit_log_register', 5); // Fires before most handlers
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- Use priority `20+` for workflow triggers to ensure core WordPress operations complete first
|
|
90
|
+
- Avoid priority `1` unless the trigger must run before all other handlers
|
|
91
|
+
|
|
92
|
+
## Example: Email Admin on New User Registration
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"name": "New User Registration Alert",
|
|
97
|
+
"type": "action_hook",
|
|
98
|
+
"event": "user_register",
|
|
99
|
+
"actions": [
|
|
100
|
+
{
|
|
101
|
+
"channel": "email",
|
|
102
|
+
"to": "admin@example.com",
|
|
103
|
+
"subject": "New user registered: {{user_name}}",
|
|
104
|
+
"body": "A new user ({{user_email}}) registered on {{site_url}} at {{timestamp}}.",
|
|
105
|
+
"template": "new_user_alert"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"channel": "slack",
|
|
109
|
+
"message": ":bust_in_silhouette: New user: *{{user_name}}* ({{user_email}})"
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"status": "active"
|
|
113
|
+
}
|
|
114
|
+
```
|