Genel bakış

Google Analytics Data API v1, dönüşüm hunisi raporları oluşturmanıza olanak tanır. Dönüşüm hunisi keşfi, kullanıcılarınızın bir görevi tamamlamak için uyguladığı adımları görselleştirmenize ve her adımda ne kadar başarılı ya da başarısız olduklarını hızlı bir şekilde görmenize olanak tanır.

Temel Raporlarla Paylaşılan Özellikler

Dönüşüm hunisi raporlama istekleri, birçok paylaşılan özellik için Temel rapor istekleriyle aynı anlamlara sahiptir. Örneğin, sayfalara ayırma, Boyut Filtreleri ve Kullanıcı Özellikleri, Dönüşüm Hunisi Raporlarında Temel Raporlar ile aynı şekilde davranır. Bu kılavuz, dönüşüm hunisi raporlama özelliklerine odaklanmaktadır. Data API v1'in Temel Raporlama işlevi hakkında bilgi edinmek için raporlamayla ilgili temel bilgiler kılavuzunu ve gelişmiş kullanım alanları kılavuzunu okuyun.

Dönüşüm hunisi raporlama yöntemi

Data API v1, runFunnelReport yöntemindeki dönüşüm hunisi raporlama işlevini destekler. Bu yöntem, Google Analytics etkinlik verilerinizin özelleştirilmiş bir dönüşüm hunisi raporunu döndürür.

Rapor Eden Varlık Seçme

Tüm Data API v1 yöntemleri, Google Analytics 4 mülk tanımlayıcısının bir URL istek yolunda properties/GA4_PROPERTY_ID biçiminde belirtilmesini gerektirir. Örneğin:

  POST  https://analyticsdata.googleapis.com/v1alpha/properties/GA4_PROPERTY_ID:runFunnelReport

Elde edilen rapor, belirtilen Google Analytics 4 mülkünde toplanan Google Analytics etkinlik verilerine göre oluşturulur.

Data API istemci kitaplıklarından birini kullanıyorsanız istek URL yolunu manuel olarak değiştirmenize gerek yoktur. Çoğu API istemcisi, properties/GA4_PROPERTY_ID biçiminde bir dize bekleyen property parametresi sağlar. İstemci kitaplıklarını kullanmaya ilişkin örnekler için Hızlı başlangıç kılavuzuna bakın.

Dönüşüm Hunisi Raporu İsteği

Dönüşüm hunisi raporu istemek için RunFunnelReportRequest nesnesi oluşturabilirsiniz. Şu istek parametreleriyle başlamanızı öneririz:

  • dateRanges alanında geçerli bir giriş.

  • funnel alanında geçerli bir dönüşüm hunisi spesifikasyonu.

Dönüşüm Hunisi Özellikleri

Bir RunFunnelReportRequest nesnesinin funnel alanındaki dönüşüm hunisi spesifikasyonu, bu dönüşüm hunisini steps tanımlayarak ölçmek istediğiniz kullanıcı yolculuğunu tanımlar.

Dönüşüm hunisi adımları, kullanıcılarınızın dönüşüm hunisi yolculuğunun ilgili adımına dahil edilmek için karşılaması gereken bir veya daha fazla koşul içerir. Her bir adıma dahil edilme koşulları, her adımın filterExpression alanında açıklanabilir.

Her dönüşüm hunisi filtre ifadesi, iki filtre türünün bir birleşimidir:

  • funnelFieldFilter bir boyut veya metrik için filtre oluşturur.

  • funnelEventFilter tek bir etkinlik adındaki etkinliklerle eşleşen bir filtre oluşturur. İsteğe bağlı bir funnelParameterFilterExpression alanı belirtilirse yalnızca hem tek etkinlik adı hem de parametre filtre ifadeleriyle eşleşen etkinliklerin alt kümesi bu etkinlik filtresiyle eşleşir.

Filtreler AND ve OR grupları kullanılarak birleştirilebilir veya NOT ifadesi kullanılarak geçersiz kılınabilir.

Her dönüşüm hunisi adımı için rapor sonuçları, boyuta göre ayrılır ve funnelBreakdown alanında belirtilir.

Dönüşüm Hunisi Raporu Örneği

Google Analytics kullanıcı arayüzünün Dönüşüm hunisi keşfi şablonunda sağlanan varsayılan dönüşüm hunisi raporunu yeniden oluşturmak için Google Analytics Data API v1'i kullanalım:

Örnek dönüşüm hunisi raporu kullanıcı arayüzü

Dönüşüm Hunisi Adımları

Yukarıda gösterilen dönüşüm hunisi yapılandırması aşağıdaki adımları içerir:

# Adım adı Koşul
1 İlk açılışı/ziyareti gerçekleştirenler Etkinlik adı: first_open veya first_visit.
2 Organik ziyaretçiler firstUserMedium boyutu "organik" terimini içeriyor.
3 Oturum başlatma Etkinlik adı: session_start.
4 Ekran/Sayfa görüntüleyenler Etkinlik adı: screen_view veya page_view.
5 Satın al Etkinlik adı: purchase veya in_app_purchase.

Dönüşüm hunisinin 1. Adımı (İlk açılış/ziyaret), bir web sitesi veya uygulamayla ilk etkileşimden sonraki tüm kullanıcıları, yani first_open veya first_visit etkinliklerini tetikleyen kullanıcıları içerir.

Bu davranışı uygulamak için aşağıdaki snippet, filterExpression alanına sahip bir FunnelStep nesnesi belirtir. Filtre ifadesi alanı, iki FunnelEventFilter öğesinin bir VEYA grubu kullanılarak birleştirilmesiyle oluşturulan bir FunnelFilterExpression nesnesidir.

  {
    "name": "Purchase",
    "filterExpression": {
      "orGroup": {
        "expressions": [
          {
            "funnelEventFilter": {
              "eventName": "first_open"
            }
          },
          {
            "funnelEventFilter": {
              "eventName": "first_visit"
            }
          }
        ]
      }
    }
  }

Dönüşüm hunisinin 2. Adımı (Organik ziyaretçiler), ilk aracısı "organik" terimini içeren kullanıcıları içerir. Aşağıdaki snippet'te FunnelFieldFilter öğesinin fieldName alanı, filtrenin firstUserMedium boyutuyla eşleşmesini sağlar. stringFilter alanı, yalnızca "organik" terimini içeren boyutun değerlerini dahil edecek bir koşul içerir.

  {
    "name": "Organic visitors",
    "filterExpression": {
      "funnelFieldFilter": {
        "fieldName": "firstUserMedium",
        "stringFilter": {
          "matchType": "CONTAINS",
          "caseSensitive": false,
          "value": "organic"
        }
      }
    }
  }

Geri kalan dönüşüm hunisi adımları benzer bir şekilde belirtilebilir.

Döküm Boyutu

İsteğe bağlı bir döküm boyutu (bu örnekte deviceCategory), bir FunnelBreakdown nesnesi kullanılarak belirtilebilir:

  "funnelBreakdown": {
    "breakdownDimension": {
      "name": "deviceCategory"
    }
  }

Varsayılan olarak, döküm boyutunun yalnızca ilk 5 farklı değeri rapora dahil edilir. Bu davranışı geçersiz kılmak için FunnelBreakdown nesnesinin limit alanını kullanabilirsiniz.

Dönüşüm Hunisi Raporu Sorgusunu Tamamlama

Aşağıda, yukarıda açıklanan tüm adımları kullanarak dönüşüm hunisi raporu oluşturan eksiksiz bir sorgu verilmiştir:

HTTP

POST https://analyticsdata.googleapis.com/v1alpha/properties/GA4_PROPERTY_ID:runFunnelReport
{
  "dateRanges": [
    {
      "startDate": "30daysAgo",
      "endDate": "today"
    }
  ],
  "funnelBreakdown": {
    "breakdownDimension": {
      "name": "deviceCategory"
    }
  },
  "funnel": {
    "steps": [
      {
        "name": "First open/visit",
        "filterExpression": {
          "orGroup": {
            "expressions": [
              {
                "funnelEventFilter": {
                  "eventName": "first_open"
                }
              },
              {
                "funnelEventFilter": {
                  "eventName": "first_visit"
                }
              }
            ]
          }
        }
      },
      {
        "name": "Organic visitors",
        "filterExpression": {
          "funnelFieldFilter": {
            "fieldName": "firstUserMedium",
            "stringFilter": {
              "matchType": "CONTAINS",
              "caseSensitive": false,
              "value": "organic"
            }
          }
        }
      },
      {
        "name": "Session start",
        "filterExpression": {
          "funnelEventFilter": {
            "eventName": "session_start"
          }
        }
      },
      {
        "name": "Screen/Page view",
        "filterExpression": {
          "orGroup": {
            "expressions": [
              {
                "funnelEventFilter": {
                  "eventName": "screen_view"
                }
              },
              {
                "funnelEventFilter": {
                  "eventName": "page_view"
                }
              }
            ]
          }
        }
      },
      {
        "name": "Purchase",
        "filterExpression": {
          "orGroup": {
            "expressions": [
              {
                "funnelEventFilter": {
                  "eventName": "purchase"
                }
              },
              {
                "funnelEventFilter": {
                  "eventName": "in_app_purchase"
                }
              }
            ]
          }
        }
      }
    ]
  }
}

Yanıtı bildir

Dönüşüm hunisi raporu API isteğinin Dönüşüm Hunisi Rapor Yanıtı, her ikisi de FunnelSubReport nesnesi olarak döndürülen iki ana bölümden oluşur: Dönüşüm Hunisi Görselleştirme ve Dönüşüm Hunisi Tablosu.

Dönüşüm Hunisi Görselleştirme

Dönüşüm Hunisi Rapor Yanıtı'nın funnelVisualization alanında döndürülen Dönüşüm Hunisi Görselleştirme, dönüşüm hunisi raporuna üst düzey bir genel bakış içerir. Bu, adından da anlaşılacağı gibi, oluşturulan dönüşüm hunisi raporunu hızlıca görselleştirmek açısından yararlıdır.

Dönüşüm hunisi görselleştirme tablosunun her satırı aşağıdaki alanların bir kısmını veya tamamını içerir:

  • Dönüşüm hunisi adımı adı (funnelStepName boyut).

  • Etkin kullanıcı sayısı (activeUsers metrik).

  • Segment (segment boyut). Yalnızca dönüşüm hunisi sorgusunda Segment belirtilmişse sunulur.

  • Tarih (date boyut). Yalnızca sorguda TRENDED_FUNNEL görselleştirme türü belirtilmişse mevcuttur.

  • Sonraki işlem boyutu (funnelStepNextAction boyut). Yalnızca dönüşüm hunisi sorgusunda FunnelNextAction belirtilmişse sunulur.

Aşağıda açıklanan örnek raporun Dönüşüm hunisi görselleştirme bölümünü Google Analytics kullanıcı arayüzünde şu şekilde görüntüleyebilirsiniz:

Dönüşüm hunisi rapor başlıkları: örnek

Dönüşüm Hunisi Tablosu

Dönüşüm Hunisi Rapor Yanıtının funnelTable alanında döndürülen Dönüşüm Hunisi Tablosu, raporun ana bölümünü temsil eder. Tablonun her satırı aşağıdaki alanların bir kısmını veya tamamını içerir:

  • Dönüşüm hunisi adımı adı (funnelStepName boyut).

  • Döküm boyutu.

  • Etkin kullanıcı sayısı (activeUsers metrik).

  • Adım tamamlama oranı (funnelStepCompletionRate metrik).

  • Adım vazgeçme sayısı (funnelStepAbandonments metrik).

  • Adım vazgeçme oranı (funnelStepAbandonmentRate metrik).

  • Segment adı (segment boyut). Yalnızca dönüşüm hunisi sorgusunda Segment belirtilmişse sunulur.

Temel Raporlama işlevine benzer şekilde, toplam değerler döküm boyut değeri olarak RESERVED_TOTAL değerine sahip ayrı bir satırda döndürülür.

Aşağıda, Google Analytics kullanıcı arayüzünde görüntülenen Dönüşüm Hunisi Tablosunun bir örneğini görebilirsiniz: Dönüşüm hunisi rapor tablosu: örnek

İşlenmemiş yanıt

Aşağıdaki snippet, runFunnelReport sorgusuna yanıt olarak döndürülen ham verilerin bir örneğini gösterir.

Mülkünüz tarafından toplanan verilere bağlı olarak, yukarıdaki örnek rapor her bir dönüşüm hunisi adımına dahil edilen etkin kullanıcı sayısını gösteren aşağıdaki raporu döndürür.

{
  "funnelTable": {
    "dimensionHeaders": [
      {
        "name": "funnelStepName"
      },
      {
        "name": "deviceCategory"
      }
    ],
    "metricHeaders": [
      {
        "name": "activeUsers",
        "type": "TYPE_INTEGER"
      },
      {
        "name": "funnelStepCompletionRate",
        "type": "TYPE_INTEGER"
      },
      {
        "name": "funnelStepAbandonments",
        "type": "TYPE_INTEGER"
      },
      {
        "name": "funnelStepAbandonmentRate",
        "type": "TYPE_INTEGER"
      }
    ],
    "rows": [
      {
        "dimensionValues": [
          {
            "value": "1. First open/visit"
          },
          {
            "value": "RESERVED_TOTAL"
          }
        ],
        "metricValues": [
          {
            "value": "4621565"
          },
          {
            "value": "0.27780178359495106"
          },
          {
            "value": "3337686"
          },
          {
            "value": "0.72219821640504889"
          }
        ]
      },
      {
        "dimensionValues": [
          {
            "value": "1. First open/visit"
          },
          {
            "value": "desktop"
          }
        ],
        "metricValues": [
          {
            "value": "4015959"
          },
          {
            "value": "0.27425279989163237"
          },
          {
            "value": "2914571"
          },
          {
            "value": "0.72574720010836768"
          }
        ]
      },
      {
        "dimensionValues": [
          {
            "value": "1. First open/visit"
          },
          {
            "value": "mobile"
          }
        ],
        "metricValues": [
          {
            "value": "595760"
          },
          {
            "value": "0.29156035987646034"
          },
          {
            "value": "422060"
          },
          {
            "value": "0.70843964012353966"
          }
        ]
      },
      {
        "dimensionValues": [
          {
            "value": "1. First open/visit"
          },
          {
            "value": "tablet"
          }
        ],
        "metricValues": [
          {
            "value": "33638"
          },
          {
            "value": "0.205571080325822"
          },
          {
            "value": "26723"
          },
          {
            "value": "0.79442891967417806"
          }
        ]
      },

...

    ],
    "metadata": {
      "samplingMetadatas": [
        {
          "samplesReadCount": "9917254",
          "samplingSpaceSize": "1162365416"
        }
      ]
    }
  },

  "funnelVisualization": {
    "dimensionHeaders": [
      {
        "name": "funnelStepName"
      }
    ],
    "metricHeaders": [
      {
        "name": "activeUsers",
        "type": "TYPE_INTEGER"
      }
    ],
    "rows": [
      {
        "dimensionValues": [
          {
            "value": "1. First open/visit"
          }
        ],
        "metricValues": [
          {
            "value": "4621565"
          }
        ]
      },

...

    ],
    "metadata": {
      "samplingMetadatas": [
        {
          "samplesReadCount": "9917254",
          "samplingSpaceSize": "1162365416"
        }
      ]
    }
  },
  "kind": "analyticsData#runFunnelReport"
}

İstemci kitaplıkları

İstemci kitaplıklarının nasıl yükleneceği ve yapılandırılacağıyla ilgili bir açıklama için Hızlı başlangıç kılavuzuna bakın.

Aşağıda, dönüşüm hunisi sorgusu çalıştıran ve yanıtı yazdıran istemci kitaplıklarının kullanıldığı örnekler verilmiştir.

Java

import com.google.analytics.data.v1alpha.AlphaAnalyticsDataClient;
import com.google.analytics.data.v1alpha.DateRange;
import com.google.analytics.data.v1alpha.Dimension;
import com.google.analytics.data.v1alpha.DimensionHeader;
import com.google.analytics.data.v1alpha.FunnelBreakdown;
import com.google.analytics.data.v1alpha.FunnelEventFilter;
import com.google.analytics.data.v1alpha.FunnelFieldFilter;
import com.google.analytics.data.v1alpha.FunnelFilterExpression;
import com.google.analytics.data.v1alpha.FunnelFilterExpressionList;
import com.google.analytics.data.v1alpha.FunnelStep;
import com.google.analytics.data.v1alpha.FunnelSubReport;
import com.google.analytics.data.v1alpha.MetricHeader;
import com.google.analytics.data.v1alpha.Row;
import com.google.analytics.data.v1alpha.RunFunnelReportRequest;
import com.google.analytics.data.v1alpha.RunFunnelReportResponse;
import com.google.analytics.data.v1alpha.SamplingMetadata;
import com.google.analytics.data.v1alpha.StringFilter;
import com.google.analytics.data.v1alpha.StringFilter.MatchType;

/**
 * Google Analytics Data API sample application demonstrating the creation of a funnel report.
 *
 * <p>See
 * https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport
 * for more information.
 *
 * <p>Before you start the application, please review the comments starting with "TODO(developer)"
 * and update the code to use correct values.
 *
 * <p>To run this sample using Maven:
 *
 * <pre>{@code
 * cd google-analytics-data
 * mvn compile exec:java -Dexec.mainClass="com.google.analytics.data.samples.RunFunnelReportSample"
 * }</pre>
 */
public class RunFunnelReportSample {

  public static void main(String... args) throws Exception {
    /**
     * TODO(developer): Replace this variable with your Google Analytics 4 property ID before
     * running the sample.
     */
    String propertyId = "YOUR-GA4-PROPERTY-ID";
    sampleRunFunnelReport(propertyId);
  }

  /**
   * Runs a funnel query to build a report with 5 funnel steps.
   *
   * <ol>
   *   <li>First open/visit (event name is `first_open` or `first_visit`).
   *   <li>Organic visitors (`firstUserMedium` dimension contains the term "organic").
   *   <li>Session start (event name is `session_start`).
   *   <li>Screen/Page view (event name is `screen_view` or `page_view`).
   *   <li>Purchase (event name is `purchase` or `in_app_purchase`).
   * </ol>
   *
   * The report configuration reproduces the default funnel report provided in the Funnel
   * Exploration template of the Google Analytics UI. See more at
   * https://support.google.com/analytics/answer/9327974
   */
  static void sampleRunFunnelReport(String propertyId) throws Exception {

    // Using a default constructor instructs the client to use the credentials
    // specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
    try (AlphaAnalyticsDataClient analyticsData = AlphaAnalyticsDataClient.create()) {
      RunFunnelReportRequest.Builder requestBuilder =
          RunFunnelReportRequest.newBuilder()
              .setProperty("properties/" + propertyId)
              .addDateRanges(DateRange.newBuilder().setStartDate("30daysAgo").setEndDate("today"))
              .setFunnelBreakdown(
                  FunnelBreakdown.newBuilder()
                      .setBreakdownDimension(Dimension.newBuilder().setName("deviceCategory")));

      // Adds each step of the funnel.
      requestBuilder
          .getFunnelBuilder()
          .addSteps(
              FunnelStep.newBuilder()
                  .setName("First open/visit")
                  .setFilterExpression(
                      FunnelFilterExpression.newBuilder()
                          .setOrGroup(
                              FunnelFilterExpressionList.newBuilder()
                                  .addExpressions(
                                      FunnelFilterExpression.newBuilder()
                                          .setFunnelEventFilter(
                                              FunnelEventFilter.newBuilder()
                                                  .setEventName("first_open")))
                                  .addExpressions(
                                      FunnelFilterExpression.newBuilder()
                                          .setFunnelEventFilter(
                                              FunnelEventFilter.newBuilder()
                                                  .setEventName("first_visit"))))));
      requestBuilder
          .getFunnelBuilder()
          .addSteps(
              FunnelStep.newBuilder()
                  .setName("Organic visitors")
                  .setFilterExpression(
                      FunnelFilterExpression.newBuilder()
                          .setFunnelFieldFilter(
                              FunnelFieldFilter.newBuilder()
                                  .setFieldName("firstUserMedium")
                                  .setStringFilter(
                                      StringFilter.newBuilder()
                                          .setMatchType(MatchType.CONTAINS)
                                          .setCaseSensitive(false)
                                          .setValue("organic")))));
      requestBuilder
          .getFunnelBuilder()
          .addSteps(
              FunnelStep.newBuilder()
                  .setName("Session start")
                  .setFilterExpression(
                      FunnelFilterExpression.newBuilder()
                          .setFunnelEventFilter(
                              FunnelEventFilter.newBuilder().setEventName("session_start"))));

      requestBuilder
          .getFunnelBuilder()
          .addSteps(
              FunnelStep.newBuilder()
                  .setName("Screen/Page view")
                  .setFilterExpression(
                      FunnelFilterExpression.newBuilder()
                          .setOrGroup(
                              FunnelFilterExpressionList.newBuilder()
                                  .addExpressions(
                                      FunnelFilterExpression.newBuilder()
                                          .setFunnelEventFilter(
                                              FunnelEventFilter.newBuilder()
                                                  .setEventName("screen_view")))
                                  .addExpressions(
                                      FunnelFilterExpression.newBuilder()
                                          .setFunnelEventFilter(
                                              FunnelEventFilter.newBuilder()
                                                  .setEventName("page_view"))))));
      requestBuilder
          .getFunnelBuilder()
          .addSteps(
              FunnelStep.newBuilder()
                  .setName("Purchase")
                  .setFilterExpression(
                      FunnelFilterExpression.newBuilder()
                          .setOrGroup(
                              FunnelFilterExpressionList.newBuilder()
                                  .addExpressions(
                                      FunnelFilterExpression.newBuilder()
                                          .setFunnelEventFilter(
                                              FunnelEventFilter.newBuilder()
                                                  .setEventName("purchase")))
                                  .addExpressions(
                                      FunnelFilterExpression.newBuilder()
                                          .setFunnelEventFilter(
                                              FunnelEventFilter.newBuilder()
                                                  .setEventName("in_app_purchase"))))));

      // Make the request.
      RunFunnelReportResponse response = analyticsData.runFunnelReport(requestBuilder.build());
      printRunFunnelReportResponse(response);
    }
  }

  /** Prints results of a runFunnelReport call. */
  static void printRunFunnelReportResponse(RunFunnelReportResponse response) {
    System.out.println("Report result:");
    System.out.println("=== FUNNEL VISUALIZATION ===");
    printFunnelSubReport(response.getFunnelVisualization());

    System.out.println("=== FUNNEL TABLE ===");
    printFunnelSubReport(response.getFunnelTable());
  }

  /** Prints the contents of a FunnelSubReport object. */
  private static void printFunnelSubReport(FunnelSubReport funnelSubReport) {
    System.out.println("Dimension headers:");
    for (DimensionHeader dimensionHeader : funnelSubReport.getDimensionHeadersList()) {
      System.out.println(dimensionHeader.getName());
    }
    System.out.println();

    System.out.println("Metric headers:");
    for (MetricHeader metricHeader : funnelSubReport.getMetricHeadersList()) {
      System.out.println(metricHeader.getName());
    }
    System.out.println();

    System.out.println("Dimension and metric values for each row in the report:");
    for (int rowIndex = 0; rowIndex < funnelSubReport.getRowsCount(); rowIndex++) {
      Row row = funnelSubReport.getRows(rowIndex);
      for (int fieldIndex = 0; fieldIndex < row.getDimensionValuesCount(); fieldIndex++) {
        System.out.printf(
            "%s: '%s'%n",
            funnelSubReport.getDimensionHeaders(fieldIndex).getName(),
            row.getDimensionValues(fieldIndex).getValue());
      }
      for (int fieldIndex = 0; fieldIndex < row.getMetricValuesCount(); fieldIndex++) {
        System.out.printf(
            "%s: '%s'%n",
            funnelSubReport.getMetricHeaders(fieldIndex).getName(),
            row.getMetricValues(fieldIndex).getValue());
      }
    }
    System.out.println();

    System.out.println("Sampling metadata for each date range:");
    for (int metadataIndex = 0;
        metadataIndex < funnelSubReport.getMetadata().getSamplingMetadatasCount();
        metadataIndex++) {
      SamplingMetadata samplingMetadata =
          funnelSubReport.getMetadata().getSamplingMetadatas(metadataIndex);
      System.out.printf(
          "Sampling metadata for date range #%d: samplesReadCount=%d, samplingSpaceSize=%d%n",
          metadataIndex,
          samplingMetadata.getSamplesReadCount(),
          samplingMetadata.getSamplingSpaceSize());
    }
  }
}

Python

from google.analytics.data_v1alpha import AlphaAnalyticsDataClient
from google.analytics.data_v1alpha.types import (
    DateRange,
    Dimension,
    Funnel,
    FunnelBreakdown,
    FunnelEventFilter,
    FunnelFieldFilter,
    FunnelFilterExpression,
    FunnelFilterExpressionList,
    FunnelStep,
    RunFunnelReportRequest,
    StringFilter,
)


def run_sample():
    """Runs the sample."""
    # TODO(developer): Replace this variable with your Google Analytics 4
    #  property ID before running the sample.
    property_id = "YOUR-GA4-PROPERTY-ID"
    run_funnel_report(property_id)


def run_funnel_report(property_id="YOUR-GA4-PROPERTY-ID"):
    """Runs a funnel query to build a report with 5 funnel steps.
      Step 1: First open/visit (event name is `first_open` or `first_visit`).
      Step 2: Organic visitors (`firstUserMedium` dimension contains the term
      "organic").
      Step 3: Session start (event name is `session_start`).
      Step 4: Screen/Page view (event name is `screen_view` or `page_view`).
      Step 5: Purchase (event name is `purchase` or `in_app_purchase`).

    The report configuration reproduces the default funnel report provided in
    the Funnel Exploration template of the Google Analytics UI.
    See more at https://support.google.com/analytics/answer/9327974
    """
    client = AlphaAnalyticsDataClient()

    request = RunFunnelReportRequest(
        property=f"properties/{property_id}",
        date_ranges=[DateRange(start_date="30daysAgo", end_date="today")],
        funnel_breakdown=FunnelBreakdown(
            breakdown_dimension=Dimension(name="deviceCategory")
        ),
        funnel=Funnel(
            steps=[
                FunnelStep(
                    name="First open/visit",
                    filter_expression=FunnelFilterExpression(
                        or_group=FunnelFilterExpressionList(
                            expressions=[
                                FunnelFilterExpression(
                                    funnel_event_filter=FunnelEventFilter(
                                        event_name="first_open"
                                    )
                                ),
                                FunnelFilterExpression(
                                    funnel_event_filter=FunnelEventFilter(
                                        event_name="first_visit"
                                    )
                                ),
                            ]
                        )
                    ),
                ),
                FunnelStep(
                    name="Organic visitors",
                    filter_expression=FunnelFilterExpression(
                        funnel_field_filter=FunnelFieldFilter(
                            field_name="firstUserMedium",
                            string_filter=StringFilter(
                                match_type=StringFilter.MatchType.CONTAINS,
                                case_sensitive=False,
                                value="organic",
                            ),
                        )
                    ),
                ),
                FunnelStep(
                    name="Session start",
                    filter_expression=FunnelFilterExpression(
                        funnel_event_filter=FunnelEventFilter(
                            event_name="session_start"
                        )
                    ),
                ),
                FunnelStep(
                    name="Screen/Page view",
                    filter_expression=FunnelFilterExpression(
                        or_group=FunnelFilterExpressionList(
                            expressions=[
                                FunnelFilterExpression(
                                    funnel_event_filter=FunnelEventFilter(
                                        event_name="screen_view"
                                    )
                                ),
                                FunnelFilterExpression(
                                    funnel_event_filter=FunnelEventFilter(
                                        event_name="page_view"
                                    )
                                ),
                            ]
                        )
                    ),
                ),
                FunnelStep(
                    name="Purchase",
                    filter_expression=FunnelFilterExpression(
                        or_group=FunnelFilterExpressionList(
                            expressions=[
                                FunnelFilterExpression(
                                    funnel_event_filter=FunnelEventFilter(
                                        event_name="purchase"
                                    )
                                ),
                                FunnelFilterExpression(
                                    funnel_event_filter=FunnelEventFilter(
                                        event_name="in_app_purchase"
                                    )
                                ),
                            ]
                        )
                    ),
                ),
            ]
        ),
    )
    response = client.run_funnel_report(request)
    print_run_funnel_report_response(response)


def print_funnel_sub_report(funnel_sub_report):
    """Prints the contents of a FunnelSubReport object."""
    print("Dimension headers:")
    for dimension_header in funnel_sub_report.dimension_headers:
        print(dimension_header.name)

    print("\nMetric headers:")
    for metric_header in funnel_sub_report.metric_headers:
        print(metric_header.name)

    print("\nDimensions and metric values for each row in the report:")
    for row_idx, row in enumerate(funnel_sub_report.rows):
        print("\nRow #{}".format(row_idx))
        for field_idx, dimension_value in enumerate(row.dimension_values):
            dimension_name = funnel_sub_report.dimension_headers[field_idx].name
            print("{}: '{}'".format(dimension_name, dimension_value.value))

        for field_idx, metric_value in enumerate(row.metric_values):
            metric_name = funnel_sub_report.metric_headers[field_idx].name
            print("{}: '{}'".format(metric_name, metric_value.value))

    print("\nSampling metadata for each date range:")
    for metadata_idx, metadata in enumerate(
        funnel_sub_report.metadata.sampling_metadatas
    ):
        print(
            "Sampling metadata for date range #{}: samplesReadCount={}, "
            "samplingSpaceSize={}".format(
                metadata_idx, metadata.samples_read_count, metadata.sampling_space_size
            )
        )


def print_run_funnel_report_response(response):
    """Prints results of a runFunnelReport call."""
    print("Report result:")
    print("=== FUNNEL VISUALIZATION ===")
    print_funnel_sub_report(response.funnel_visualization)

    print("=== FUNNEL TABLE ===")
    print_funnel_sub_report(response.funnel_table)