claude-plugin-wordpress-manager 2.6.0 → 2.9.1
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/CHANGELOG.md +61 -0
- package/agents/wp-monitoring-agent.md +44 -0
- package/agents/wp-site-manager.md +19 -0
- package/docs/GUIDE.md +145 -14
- 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 +10 -3
- 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/index.js +15 -0
- 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/slack.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/slack.js +129 -0
- 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 +18 -0
- package/servers/wp-rest-bridge/build/wordpress.js +139 -0
- package/skills/wordpress-router/SKILL.md +1 -1
- package/skills/wordpress-router/references/decision-tree.md +8 -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-attribution/SKILL.md +1 -0
- package/skills/wp-content-optimization/SKILL.md +1 -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 +2 -0
- package/skills/wp-search-console/SKILL.md +1 -0
- package/skills/wp-social-email/SKILL.md +1 -0
- package/skills/wp-webhooks/SKILL.md +1 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Traffic Attribution
|
|
2
|
+
|
|
3
|
+
## UTM Parameter Standards
|
|
4
|
+
|
|
5
|
+
UTM (Urchin Tracking Module) parameters tag URLs to track marketing campaign performance.
|
|
6
|
+
|
|
7
|
+
### Required Parameters
|
|
8
|
+
| Parameter | Purpose | Example |
|
|
9
|
+
|-----------|---------|---------|
|
|
10
|
+
| `utm_source` | Traffic origin | `google`, `facebook`, `newsletter` |
|
|
11
|
+
| `utm_medium` | Marketing channel | `cpc`, `email`, `social`, `referral` |
|
|
12
|
+
| `utm_campaign` | Campaign name | `spring-sale-2024`, `black-friday` |
|
|
13
|
+
|
|
14
|
+
### Optional Parameters
|
|
15
|
+
| Parameter | Purpose | Example |
|
|
16
|
+
|-----------|---------|---------|
|
|
17
|
+
| `utm_term` | Paid search keyword | `running+shoes` |
|
|
18
|
+
| `utm_content` | Ad variation / CTA | `cta-button-red`, `hero-banner` |
|
|
19
|
+
|
|
20
|
+
### URL Format
|
|
21
|
+
```
|
|
22
|
+
https://example.com/page?utm_source=google&utm_medium=cpc&utm_campaign=spring-sale
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Source/Medium Mapping
|
|
26
|
+
|
|
27
|
+
### Standard Mappings in GA4
|
|
28
|
+
| Source/Medium | Description |
|
|
29
|
+
|---------------|-------------|
|
|
30
|
+
| `google / organic` | Google organic search |
|
|
31
|
+
| `google / cpc` | Google Ads paid search |
|
|
32
|
+
| `facebook / social` | Facebook organic posts |
|
|
33
|
+
| `facebook / cpc` | Facebook paid ads |
|
|
34
|
+
| `newsletter / email` | Email marketing campaigns |
|
|
35
|
+
| `(direct) / (none)` | Direct traffic or untagged |
|
|
36
|
+
| `referral / referral` | Incoming links from other sites |
|
|
37
|
+
|
|
38
|
+
### Plausible Source Mapping
|
|
39
|
+
Plausible uses `visit:source` which maps to the referrer or `utm_source`:
|
|
40
|
+
- Organic search: `Google`, `Bing`, `DuckDuckGo`
|
|
41
|
+
- Social: `Facebook`, `Twitter`, `LinkedIn`
|
|
42
|
+
- UTM-tagged: uses the `utm_source` value directly
|
|
43
|
+
|
|
44
|
+
## Combining GA4 Traffic with WooCommerce Conversions
|
|
45
|
+
|
|
46
|
+
### Data Flow
|
|
47
|
+
1. **GA4** tracks the user journey: source, medium, pages visited, events
|
|
48
|
+
2. **WooCommerce** records the transaction: products, revenue, order ID
|
|
49
|
+
3. **Attribution** connects which traffic source led to which purchase
|
|
50
|
+
|
|
51
|
+
### Attribution Models
|
|
52
|
+
| Model | Logic | Best For |
|
|
53
|
+
|-------|-------|----------|
|
|
54
|
+
| Last click | Credits the last touchpoint before conversion | Simple campaigns |
|
|
55
|
+
| First click | Credits the first touchpoint in the journey | Brand awareness |
|
|
56
|
+
| Linear | Equal credit to all touchpoints | Multi-touch evaluation |
|
|
57
|
+
| Data-driven | ML-based credit distribution (GA4 default) | Complex funnels |
|
|
58
|
+
|
|
59
|
+
### Implementation Steps
|
|
60
|
+
1. Ensure GA4 enhanced e-commerce tracking is active (via Site Kit or GTM)
|
|
61
|
+
2. Map WooCommerce order IDs to GA4 transaction events
|
|
62
|
+
3. Use `ga4_conversions` tool with `purchase` event to get revenue by source
|
|
63
|
+
4. Cross-reference with WooCommerce order data for product-level attribution
|
|
64
|
+
|
|
65
|
+
## Cross-Platform Discrepancy Analysis
|
|
66
|
+
|
|
67
|
+
### Common Causes of Data Differences
|
|
68
|
+
| Issue | GA4 Impact | Plausible Impact |
|
|
69
|
+
|-------|-----------|-----------------|
|
|
70
|
+
| Ad blockers | Under-reports (blocked) | Under-reports (blocked) |
|
|
71
|
+
| Cookie consent | Under-reports if declined | No impact (cookieless) |
|
|
72
|
+
| Bot traffic | Filtered (mostly) | Filtered |
|
|
73
|
+
| SPA navigation | May miss if not configured | Tracks via History API |
|
|
74
|
+
| Caching | CDN may cache tracking | Same |
|
|
75
|
+
| Sampling | Large datasets sampled | No sampling |
|
|
76
|
+
|
|
77
|
+
### Reconciliation Steps
|
|
78
|
+
1. Compare total sessions (GA4) vs visits (Plausible) for the same period
|
|
79
|
+
2. Calculate the gap percentage: typically 10-30% difference is normal
|
|
80
|
+
3. Check source-level: organic search should be closest between platforms
|
|
81
|
+
4. Investigate large discrepancies in specific sources or pages
|
|
82
|
+
5. Use CWV data as an independent third reference for page-level traffic
|
|
83
|
+
|
|
84
|
+
## Campaign Tracking Best Practices
|
|
85
|
+
|
|
86
|
+
- **Always tag** paid campaign URLs with UTM parameters
|
|
87
|
+
- **Use consistent naming** conventions (lowercase, hyphens, no spaces)
|
|
88
|
+
- **Document all campaigns** in a shared spreadsheet or naming convention guide
|
|
89
|
+
- **Test tagged URLs** before launching campaigns
|
|
90
|
+
- **Monitor `(not set)`** values in GA4 — indicates untagged traffic
|
|
91
|
+
- **Review referral exclusions** in GA4 to prevent self-referrals
|
|
92
|
+
- **Set up conversion goals** in both GA4 and WooCommerce for accurate ROI
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* analytics_inspect.mjs — Detect analytics configuration readiness.
|
|
3
|
+
*
|
|
4
|
+
* Checks WP_SITES_CONFIG for GA4, Plausible, and Google API key credentials.
|
|
5
|
+
* Scans for analytics plugins and tracking code.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* node analytics_inspect.mjs [--cwd=/path/to/project]
|
|
9
|
+
*
|
|
10
|
+
* Exit codes:
|
|
11
|
+
* 0 — analytics configuration found
|
|
12
|
+
* 1 — no analytics configuration found
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { readFileSync, existsSync, readdirSync } from 'node:fs';
|
|
16
|
+
import { join, resolve } from 'node:path';
|
|
17
|
+
import { argv, stdout, exit } from 'node:process';
|
|
18
|
+
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Helpers
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
function readFileSafe(filePath) {
|
|
24
|
+
try { return readFileSync(filePath, 'utf-8'); } catch { return null; }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function existsSafe(filePath) {
|
|
28
|
+
try { return existsSync(filePath); } catch { return false; }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function globDir(dirPath) {
|
|
32
|
+
try { return readdirSync(dirPath); } catch { return []; }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Detectors
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
function detectGA4Config() {
|
|
40
|
+
const ga4 = { configured: false, indicators: [] };
|
|
41
|
+
const raw = process.env.WP_SITES_CONFIG;
|
|
42
|
+
if (!raw) return ga4;
|
|
43
|
+
|
|
44
|
+
let sites;
|
|
45
|
+
try { sites = JSON.parse(raw); } catch { return ga4; }
|
|
46
|
+
if (!Array.isArray(sites)) return ga4;
|
|
47
|
+
|
|
48
|
+
for (const site of sites) {
|
|
49
|
+
const label = site.id || site.url || 'unknown';
|
|
50
|
+
if (site.ga4_property_id) {
|
|
51
|
+
ga4.configured = true;
|
|
52
|
+
ga4.indicators.push(`ga4_property_id configured for ${label}`);
|
|
53
|
+
}
|
|
54
|
+
if (site.ga4_service_account_key) {
|
|
55
|
+
ga4.indicators.push(`ga4_service_account_key configured for ${label}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return ga4;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function detectPlausibleConfig() {
|
|
62
|
+
const pl = { configured: false, indicators: [] };
|
|
63
|
+
const raw = process.env.WP_SITES_CONFIG;
|
|
64
|
+
if (!raw) return pl;
|
|
65
|
+
|
|
66
|
+
let sites;
|
|
67
|
+
try { sites = JSON.parse(raw); } catch { return pl; }
|
|
68
|
+
if (!Array.isArray(sites)) return pl;
|
|
69
|
+
|
|
70
|
+
for (const site of sites) {
|
|
71
|
+
const label = site.id || site.url || 'unknown';
|
|
72
|
+
if (site.plausible_api_key) {
|
|
73
|
+
pl.configured = true;
|
|
74
|
+
pl.indicators.push(`plausible_api_key configured for ${label}`);
|
|
75
|
+
}
|
|
76
|
+
if (site.plausible_base_url) {
|
|
77
|
+
pl.indicators.push(`plausible_base_url: ${site.plausible_base_url}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return pl;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function detectGoogleApiKey() {
|
|
84
|
+
const cwv = { configured: false, indicators: [] };
|
|
85
|
+
const raw = process.env.WP_SITES_CONFIG;
|
|
86
|
+
if (!raw) return cwv;
|
|
87
|
+
|
|
88
|
+
let sites;
|
|
89
|
+
try { sites = JSON.parse(raw); } catch { return cwv; }
|
|
90
|
+
if (!Array.isArray(sites)) return cwv;
|
|
91
|
+
|
|
92
|
+
for (const site of sites) {
|
|
93
|
+
const label = site.id || site.url || 'unknown';
|
|
94
|
+
if (site.google_api_key) {
|
|
95
|
+
cwv.configured = true;
|
|
96
|
+
cwv.indicators.push(`google_api_key configured for ${label}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return cwv;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function detectAnalyticsPlugins(cwd) {
|
|
103
|
+
const indicators = [];
|
|
104
|
+
const pluginsDir = join(cwd, 'wp-content', 'plugins');
|
|
105
|
+
const plugins = globDir(pluginsDir);
|
|
106
|
+
|
|
107
|
+
const analyticsPlugins = [
|
|
108
|
+
'google-analytics-for-wordpress',
|
|
109
|
+
'google-site-kit',
|
|
110
|
+
'wp-google-analytics-events',
|
|
111
|
+
'plausible-analytics',
|
|
112
|
+
'koko-analytics',
|
|
113
|
+
'matomo',
|
|
114
|
+
'independent-analytics',
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
for (const plugin of analyticsPlugins) {
|
|
118
|
+
if (plugins.includes(plugin)) {
|
|
119
|
+
indicators.push(`plugin: ${plugin}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return { found: indicators.length > 0, indicators };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
// Main
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
function main() {
|
|
130
|
+
const cwdArg = argv.find(a => a.startsWith('--cwd='));
|
|
131
|
+
const cwd = cwdArg ? resolve(cwdArg.split('=')[1]) : process.cwd();
|
|
132
|
+
|
|
133
|
+
const ga4 = detectGA4Config();
|
|
134
|
+
const plausible = detectPlausibleConfig();
|
|
135
|
+
const googleApiKey = detectGoogleApiKey();
|
|
136
|
+
const plugins = detectAnalyticsPlugins(cwd);
|
|
137
|
+
|
|
138
|
+
const anyConfigured = ga4.configured || plausible.configured || googleApiKey.configured || plugins.found;
|
|
139
|
+
|
|
140
|
+
const report = {
|
|
141
|
+
analytics_configured: anyConfigured,
|
|
142
|
+
ga4: ga4,
|
|
143
|
+
plausible: plausible,
|
|
144
|
+
google_api_key: googleApiKey,
|
|
145
|
+
analytics_plugins: plugins,
|
|
146
|
+
cwd,
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
stdout.write(JSON.stringify(report, null, 2) + '\n');
|
|
150
|
+
exit(anyConfigured ? 0 : 1);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
main();
|
|
@@ -97,3 +97,4 @@ The script checks WooCommerce presence, analytics plugins, UTM tracking setup, c
|
|
|
97
97
|
- `wp-content-repurposing` — transform high-ROI content into multi-channel formats
|
|
98
98
|
- `wp-search-console` — correlate GSC keyword data with WooCommerce conversions for content-commerce attribution
|
|
99
99
|
- `wp-content-optimization` — prioritize optimization of high-revenue content using attribution data
|
|
100
|
+
- Per correlazione contenuto→conversione completa, combina `wp-analytics` + `wp-content-attribution`
|
|
@@ -170,3 +170,4 @@ Use the **`wp-content-strategist`** agent for content optimization workflows tha
|
|
|
170
170
|
- **`wp-content-attribution`** — track content sources and attribute traffic
|
|
171
171
|
- **`wp-programmatic-seo`** — generate SEO-optimized content at scale
|
|
172
172
|
- **`wp-social-email`** — distribute optimized content across channels
|
|
173
|
+
- Per prioritizzare ottimizzazione con dati CWV, combina `wp-analytics` + `wp-content-optimization`
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wp-content-workflows
|
|
3
|
+
description: This skill should be used when the user asks about "workflow automation",
|
|
4
|
+
"triggers", "scheduled tasks", "WP-Cron", "content publishing triggers",
|
|
5
|
+
"hook-based actions", "post status transitions", "automated notifications",
|
|
6
|
+
"workflow triggers", "event-driven actions", "content lifecycle hooks",
|
|
7
|
+
"multi-channel actions", "trigger management", or mentions setting up
|
|
8
|
+
automated workflows that fire on WordPress events or schedules.
|
|
9
|
+
version: 1.0.0
|
|
10
|
+
tags: [workflows, triggers, cron, automation, hooks, scheduling]
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# WordPress Content Workflows Skill
|
|
14
|
+
|
|
15
|
+
## Overview
|
|
16
|
+
|
|
17
|
+
Event-driven workflow automation system for WordPress. Combines WP-Cron scheduling, content lifecycle hooks, and WordPress action/filter hooks to trigger multi-channel actions (Slack, email, webhook). Provides trigger creation, management, testing (dry-run), and audit logging. This skill connects WordPress events to notification and action channels, enabling automated responses to content changes, user actions, and scheduled tasks.
|
|
18
|
+
|
|
19
|
+
## When to Use
|
|
20
|
+
|
|
21
|
+
- User wants to create automated triggers for WordPress events
|
|
22
|
+
- User needs scheduled tasks (cron-based publishing, periodic reports)
|
|
23
|
+
- User asks about post status transitions (draft to published, trash, etc.)
|
|
24
|
+
- User wants to hook into WordPress actions (user_register, comment_post, etc.)
|
|
25
|
+
- User needs multi-channel action routing (Slack + email + webhook on same event)
|
|
26
|
+
- User asks about trigger management (list, test, enable/disable, delete)
|
|
27
|
+
- User wants to set up WooCommerce order-based workflows
|
|
28
|
+
- User needs to audit or troubleshoot existing workflow triggers
|
|
29
|
+
|
|
30
|
+
## Decision Tree
|
|
31
|
+
|
|
32
|
+
1. **What type of trigger?**
|
|
33
|
+
- "cron" / "scheduled" / "periodic" → Schedule-Based Triggers (Procedure 1)
|
|
34
|
+
- "on publish" / "post status" / "content change" → Content Lifecycle Hooks (Procedure 2)
|
|
35
|
+
- "on login" / "user register" / "comment" / "plugin" → WP Action/Filter Hooks (Procedure 3)
|
|
36
|
+
- "notify Slack and email" / "multi-channel" → Multi-Channel Action Configuration (Procedure 4)
|
|
37
|
+
- "list triggers" / "test" / "disable" / "delete" → Trigger Management (Procedure 5)
|
|
38
|
+
|
|
39
|
+
2. **Run detection first:**
|
|
40
|
+
```bash
|
|
41
|
+
node skills/wp-content-workflows/scripts/workflow_inspect.mjs [--cwd=/path/to/project]
|
|
42
|
+
```
|
|
43
|
+
This identifies configured action channels, automation plugins, WP-Cron status, and webhook setup.
|
|
44
|
+
|
|
45
|
+
## Procedures
|
|
46
|
+
|
|
47
|
+
### Procedure 1: Schedule-Based Triggers
|
|
48
|
+
|
|
49
|
+
See `references/schedule-triggers.md`
|
|
50
|
+
- Configure WP-Cron intervals (hourly, twicedaily, daily, weekly, custom)
|
|
51
|
+
- Set up scheduled content publishing triggers
|
|
52
|
+
- Create recurring health check and report triggers
|
|
53
|
+
- External cron setup (server cron vs WP-Cron)
|
|
54
|
+
- Test scheduled trigger with `wf_create_trigger` using cron schedule type
|
|
55
|
+
|
|
56
|
+
### Procedure 2: Content Lifecycle Hooks
|
|
57
|
+
|
|
58
|
+
See `references/content-lifecycle-hooks.md`
|
|
59
|
+
- Hook into post status transitions (draft→published, published→trash)
|
|
60
|
+
- Support custom post types (products, portfolios, events)
|
|
61
|
+
- Monitor taxonomy and term changes
|
|
62
|
+
- Track media upload events
|
|
63
|
+
- Create trigger with `wf_create_trigger` using content lifecycle event type
|
|
64
|
+
|
|
65
|
+
### Procedure 3: WP Action/Filter Hooks
|
|
66
|
+
|
|
67
|
+
See `references/wp-action-hooks.md`
|
|
68
|
+
- Hook into core WordPress actions (user_register, wp_login, comment_post)
|
|
69
|
+
- WooCommerce hooks (woocommerce_new_order, woocommerce_order_status_changed)
|
|
70
|
+
- Plugin activation/deactivation hooks
|
|
71
|
+
- Filter hooks for content transformation workflows
|
|
72
|
+
- Create trigger with `wf_create_trigger` using action hook event type
|
|
73
|
+
|
|
74
|
+
### Procedure 4: Multi-Channel Action Configuration
|
|
75
|
+
|
|
76
|
+
See `references/multi-channel-actions.md`
|
|
77
|
+
- Map triggers to one or more action channels (Slack, email, webhook)
|
|
78
|
+
- Configure template variables ({{post_title}}, {{user_name}}, {{order_total}})
|
|
79
|
+
- Channel-specific formatting (Block Kit for Slack, HTML for email, JSON for webhook)
|
|
80
|
+
- Rate limiting per channel to prevent flooding
|
|
81
|
+
- Update trigger actions with `wf_update_trigger`
|
|
82
|
+
|
|
83
|
+
### Procedure 5: Trigger Management
|
|
84
|
+
|
|
85
|
+
See `references/trigger-management.md`
|
|
86
|
+
- List and filter triggers with `wf_list_triggers`
|
|
87
|
+
- Activate/deactivate triggers without deleting (via `wf_update_trigger`)
|
|
88
|
+
- Test triggers in dry-run mode
|
|
89
|
+
- Review trigger audit log
|
|
90
|
+
- Bulk operations (enable/disable all, export/import)
|
|
91
|
+
- Delete stale triggers with `wf_delete_trigger`
|
|
92
|
+
|
|
93
|
+
## MCP Tools Reference
|
|
94
|
+
|
|
95
|
+
| Tool | Description |
|
|
96
|
+
|------|-------------|
|
|
97
|
+
| `wf_list_triggers` | List all workflow triggers with optional status/type filters |
|
|
98
|
+
| `wf_create_trigger` | Create a new workflow trigger (cron, lifecycle, action hook) |
|
|
99
|
+
| `wf_update_trigger` | Update trigger config, actions, or status (active/inactive) |
|
|
100
|
+
| `wf_delete_trigger` | Delete a workflow trigger (with safety confirmation) |
|
|
101
|
+
|
|
102
|
+
## Reference Files
|
|
103
|
+
|
|
104
|
+
| File | Content |
|
|
105
|
+
|------|---------|
|
|
106
|
+
| `references/schedule-triggers.md` | WP-Cron patterns, custom intervals, external cron setup |
|
|
107
|
+
| `references/content-lifecycle-hooks.md` | Post status transitions, CPT support, taxonomy changes, media events |
|
|
108
|
+
| `references/wp-action-hooks.md` | Core WP actions, WooCommerce hooks, plugin hooks, filter hooks |
|
|
109
|
+
| `references/multi-channel-actions.md` | Channel config, template variables, formatting, rate limiting |
|
|
110
|
+
| `references/trigger-management.md` | Listing, activate/deactivate, dry-run testing, audit log, bulk ops |
|
|
111
|
+
|
|
112
|
+
## Recommended Agent
|
|
113
|
+
|
|
114
|
+
Use the **`wp-site-manager`** for automated workflow orchestration that combines trigger creation, multi-channel action routing, and lifecycle management.
|
|
115
|
+
|
|
116
|
+
## Related Skills
|
|
117
|
+
|
|
118
|
+
- **`wp-alerting`** — shares Slack and SendGrid channels for notification delivery
|
|
119
|
+
- **`wp-monitoring`** — source of health/performance data that may trigger workflows
|
|
120
|
+
- **`wp-webhooks`** — outbound/inbound webhook infrastructure for webhook action channel
|
|
121
|
+
- **`wp-social-email`** — shares SendGrid and Mailchimp config for email actions
|
|
122
|
+
|
|
123
|
+
## Cross-references
|
|
124
|
+
|
|
125
|
+
- Workflow triggers pair with `wp-alerting` for severity-based notification routing
|
|
126
|
+
- Scheduled triggers depend on WP-Cron config detectable via `wp-monitoring`
|
|
127
|
+
- Webhook actions use `wp-webhooks` infrastructure for outbound delivery
|
|
128
|
+
- Email actions share SendGrid/Mailchimp config with `wp-social-email`
|
|
129
|
+
- WooCommerce hooks connect to `wp-woocommerce` for order-based workflows
|
|
130
|
+
|
|
131
|
+
## Troubleshooting
|
|
132
|
+
|
|
133
|
+
| Issue | Cause | Resolution |
|
|
134
|
+
|-------|-------|------------|
|
|
135
|
+
| Cron trigger not firing | DISABLE_WP_CRON is true and no server cron configured | Set up server cron job: `*/5 * * * * wget -qO- https://example.com/wp-cron.php` |
|
|
136
|
+
| Content hook missed | Post updated via direct DB query (bypasses hooks) | Ensure content changes go through `wp_update_post()` or REST API |
|
|
137
|
+
| Slack action fails | slack_webhook_url or slack_bot_token not configured | Add Slack credentials to WP_SITES_CONFIG |
|
|
138
|
+
| Email action 403 | SendGrid API key lacks Mail Send permission | Regenerate key with "Mail Send" access in SendGrid dashboard |
|
|
139
|
+
| Duplicate triggers firing | Multiple hooks registered for same event | Review triggers with `wf_list_triggers` and deduplicate |
|
|
140
|
+
| Trigger test fails | Action channel unreachable or credentials expired | Run `workflow_inspect.mjs` to verify channel configuration |
|
|
141
|
+
| WooCommerce hooks silent | WooCommerce not active or hooks not registered | Verify WooCommerce is active; hooks fire only after `woocommerce_init` |
|
|
142
|
+
| Detection script exit 1 | No workflow config found | Add action channel credentials to WP_SITES_CONFIG and install wp-crontrol |
|
|
@@ -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
|
+
```
|