Skip to content
Development
Skill

/marketing-analytics

Marketing analytics - UTM, attribution, CAC, ROAS, conversion tracking.

From plugin
vibecosystem
534200 skills138 agents7 hooks
Install
$ npx -y skills add vibeeval/vibecosystem --skill marketing-analytics --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/marketing-analytics

Context preview

The summary Claude sees to decide when to auto-load this skill.

Marketing analytics - UTM, attribution, CAC, ROAS, conversion tracking.

SKILL.md

marketing-analytics.SKILL.md
name: marketing-analytics
description: "Marketing analytics - UTM, attribution, CAC, ROAS, conversion tracking."

Marketing Analytics

UTM Tracking Setup

UTM Parameter Standartlari

https://example.com/landing?
  utm_source=google           # Trafik kaynagi (google, facebook, newsletter)
  &utm_medium=cpc             # Kanal tipi (cpc, email, social, organic)
  &utm_campaign=spring_2026   # Kampanya adi
  &utm_term=saas+analytics    # Arama terimi (paid search)
  &utm_content=hero_banner    # Reklam varyanti (A/B test)

UTM Naming Convention

| Parameter | Format | Ornekler | |-----------|--------|---------| | source | lowercase, platform adi | google, facebook, linkedin, newsletter | | medium | lowercase, kanal tipi | cpc, cpm, email, social, organic, referral | | campaign | snake_case, tarih dahil | spring_sale_2026, product_launch_q1 | | term | + ile ayrilmis | saas+analytics, project+management | | content | snake_case, varyant | hero_banner, sidebar_cta, email_v2 |

UTM Builder (TypeScript)

interface UTMConfig {
  baseUrl: string;
  source: string;
  medium: string;
  campaign: string;
  term?: string;
  content?: string;
}

function buildUTMUrl(config: UTMConfig): string {
  const params = new URLSearchParams();
  params.set("utm_source", config.source.toLowerCase());
  params.set("utm_medium", config.medium.toLowerCase());
  params.set("utm_campaign", config.campaign.toLowerCase().replace(/\s+/g, "_"));
  if (config.term) params.set("utm_term", config.term.toLowerCase());
  if (config.content) params.set("utm_content", config.content.toLowerCase());

  const separator = config.baseUrl.includes("?") ? "&" : "?";
  return `${config.baseUrl}${separator}${params.toString()}`;
}

// UTM parametrelerini parse et ve kaydet
function captureUTM(): UTMParams | null {
  const params = new URLSearchParams(window.location.search);
  const utm: UTMParams = {
    source: params.get("utm_source") || undefined,
    medium: params.get("utm_medium") || undefined,
    campaign: params.get("utm_campaign") || undefined,
    term: params.get("utm_term") || undefined,
    content: params.get("utm_content") || undefined,
  };

  if (utm.source) {
    // First-touch ve last-touch ayri kaydet
    if (!localStorage.getItem("utm_first_touch")) {
      localStorage.setItem("utm_first_touch", JSON.stringify({ ...utm, timestamp: Date.now() }));
    }
    localStorage.setItem("utm_last_touch", JSON.stringify({ ...utm, timestamp: Date.now() }));
    return utm;
  }
  return null;
}

Attribution Modeling

Attribution Modelleri

| Model | Aciklama | Ne Zaman Kullan | |-------|----------|----------------| | First Touch | Ilk temas %100 kredi alir | Awareness kampanyalari | | Last Touch | Son temas %100 kredi alir | Direct response kampanyalari | | Linear | Tum temaslar esit kredi alir | Tum kanallari esit degerlendirme | | Time Decay | Son temaslara daha cok kredi | Uzun satis dongusu | | U-Shaped | Ilk ve son temas %40, orta %20 | Balanced B2B attribution | | W-Shaped | Ilk, lead, opportunity %30, geri kalan %10 | Full-funnel B2B | | Data-Driven | Algoritmik (Markov chain, Shapley) | Yeterli veri varsa (10K+ conversion) |

Multi-Touch Attribution Query

-- U-Shaped Attribution
WITH touchpoints AS (
  SELECT
    conversion_id,
    user_id,
    channel,
    touch_timestamp,
    ROW_NUMBER() OVER (PARTITION BY conversion_id ORDER BY touch_timestamp) AS touch_order,
    COUNT(*) OVER (PARTITION BY conversion_id) AS total_touches
  FROM marketing_touches
  WHERE conversion_id IS NOT NULL
),
attributed AS (
  SELECT
    conversion_id,
    channel,
    CASE
      WHEN total_touches = 1 THEN 1.0
      WHEN total_touches = 2 THEN 0.5
      WHEN touch_order = 1 THEN 0.4                            -- first touch
      WHEN touch_order = total_touches THEN 0.4                -- last touch
      ELSE 0.2 / (total_touches - 2)                           -- middle touches
    END AS attribution_weight
  FROM touchpoints
)
SELECT
  channel,
  ROUND(SUM(attribution_weight), 2) AS attributed_conversions,
  ROUND(SUM(attribution_weight * c.revenue), 2) AS attributed_revenue
FROM attributed a
JOIN conversions c ON a.conversion_id = c.id
GROUP BY channel
ORDER BY attributed_revenue DESC;

Markov Chain Attribution

interface TransitionMatrix {
  [fromState: string]: {
    [toState: string]: number;  // probability
  };
}

// Removal effect: Her kanalin conversion'a katki oranini hesapla
function calculateRemovalEffect(
  matrix: TransitionMatrix,
  channels: string[]
): Record<string, number> {
  const baseConversionRate = simulateConversions(matrix, channels);
  const effects: Record<string, number> = {};

  for (const channel of channels) {
    const withoutChannel = channels.filter(c => c !== channel);
    const reducedRate = simulateConversions(matrix, withoutChannel);
    effects[channel] = (baseConversionRate - reducedRate) / baseConversionRate;
  }

  // Normalize to sum to 1
  const total = Object.values(effects).reduce((a, b) => a + b, 0);
  for (const channel of channels) {
    effects[channel] = effects[channel] / total;
  }

  return effects;
}

CAC (Customer Acquisition Cost)

CAC Hesaplama

interface CACMetrics {
  totalMarketingSpend: number;        // Toplam marketing harcamasi
  totalSalesSpend: number;            // Toplam sales harcamasi (maas dahil)
  newCustomers: number;               // Kazanilan musteri sayisi
  period: string;                     // "2026-Q1"
}

function calculateCAC(metrics: CACMetrics): {
  blendedCAC: number;
  paidCAC: number;
  organicCAC: number;
} {
  const totalSpend = metrics.totalMarketingSpend + metrics.totalSalesSpend;
  return {
    blendedCAC: totalSpend / metrics.newCustomers,
    paidCAC
Read more
Ships withvibecosystem

Your AI software team. Built on Claude Code. vibecosystem turns Claude Code into a full AI software team — 138 specialized agents that plan, build, review, test, and learn from every mistake. No configuration needed — just install and code.

Get the whole plugin

Other skills on vibecosystem.