SEO Metrics Hooks

Intermediate External SEO Integration

DVP CMS is a truth distillation system for AI-generated content. Plugins are evidence suppliers—they verify facts, pull live data, and make content more trustworthy over time. Learn more →

Build plugins that integrate external SEO data using SEOMetricsHooks.

Overview

SEO metrics hooks allow plugins to:

Data Flow:

External API → dvp_seo_metrics_received → Storage
Storage → dvp_before_pattern_extraction → Pattern Mining
Pattern Mining → dvp_pattern_discovered → Notification
Generation → dvp_learning_applied → Tracking

Quick Start

from typing import TYPE_CHECKING
from dvp_cms.plugins.base import Plugin
from dvp_cms.plugins.hookspec import SEOMetricsHooks

if TYPE_CHECKING:
    from dvp_cms.plugins.context import HookContext
    from dvp_cms.plugins.hooks.seo_metrics import (
        SEOMetricsPayload,
        DiscoveredPattern,
        AppliedLearning,
    )


class GSCIntegrationPlugin(Plugin, SEOMetricsHooks):
    """Plugin that integrates Google Search Console data."""

    name = "gsc-integration"
    version = "1.0.0"

    async def dvp_seo_metrics_received(
        self,
        ctx: "HookContext",
        payload: "SEOMetricsPayload",
    ) -> "SEOMetricsPayload":
        """Enrich incoming SEO metrics data."""
        if payload.source == "gsc":
            # Calculate CTR from raw data
            impressions = payload.data.get("impressions", 0)
            clicks = payload.data.get("clicks", 0)
            ctr = clicks / impressions if impressions > 0 else 0.0

            return payload.with_metadata({
                "ctr": ctr,
                "enriched_by": self.name,
            })
        return payload

    async def dvp_pattern_discovered(
        self,
        ctx: "HookContext",
        pattern: "DiscoveredPattern",
    ) -> None:
        """React to discovered patterns."""
        if pattern.is_high_confidence:
            self.logger.info(
                f"High-confidence pattern: {pattern.name}",
                extra={"confidence": pattern.confidence},
            )

Hooks Reference

dvp_seo_metrics_received

Called when SEO metrics data is received from external sources.

async def dvp_seo_metrics_received(
    self,
    ctx: "HookContext",
    payload: "SEOMetricsPayload",
) -> "SEOMetricsPayload":
    """
    Type: Filter hook
    Returns: Modified SEOMetricsPayload
    """
    if payload.source == "gsc":
        # Add computed metrics
        return payload.with_metadata({
            "ctr": clicks / impressions,
            "processed_by": self.name,
        })
    return payload

dvp_before_pattern_extraction

Called before pattern extraction begins on the data.

async def dvp_before_pattern_extraction(
    self,
    ctx: "HookContext",
    payload: "SEOMetricsPayload",
) -> "SEOMetricsPayload":
    """
    Type: Filter hook
    Returns: Modified SEOMetricsPayload
    """
    data = payload.data

    # Filter out low-impression keywords
    if "rankings" in data:
        filtered = [r for r in data["rankings"] if r.get("impressions", 0) > 100]
        return payload.with_data({**data, "rankings": filtered})

    return payload

dvp_pattern_discovered

Called when a pattern is discovered from SEO data.

async def dvp_pattern_discovered(
    self,
    ctx: "HookContext",
    pattern: "DiscoveredPattern",
) -> None:
    """
    Type: Action hook
    Returns: None
    """
    if pattern.is_high_confidence:
        await self._send_notification(
            f"New pattern: {pattern.name}",
            confidence=pattern.confidence,
        )

dvp_learning_applied

Called when a learning is applied during content generation.

async def dvp_learning_applied(
    self,
    ctx: "HookContext",
    learning: "AppliedLearning",
) -> None:
    """
    Type: Action hook
    Returns: None
    """
    self.logger.info(
        f"Applied {learning.pattern_count} patterns to {learning.content_id}",
    )

See Also