نمای کلی

Google Analytics Data API v1 به شما امکان می‌دهد گزارش‌های قیف تولید کنید. داده‌کاوی قیفی به شما امکان می‌دهد مراحل انجام‌شده توسط کاربران برای تکمیل یک تکلیف را تجسم کنید و به‌سرعت ببینید که آن‌ها در هر مرحله چقدر موفق یا ناموفق هستند.

ویژگی‌های مشترک با گزارش‌های اصلی

درخواست‌های گزارش قیف برای بسیاری از ویژگی‌های مشترک، معناشناسی یکسانی با درخواست‌های گزارش «اصلی» دارند. برای مثال، صفحه‌بندی، فیلترهای بُعد، و ویژگی‌های کاربر در «گزارش‌های قیفی» مانند «گزارش‌های اصلی» رفتار می‌کنند. این راهنما بر ویژگی‌های گزارش قیف تمرکز دارد. برای آشنایی با عملکرد «گزارش‌دهی اصلی» Data API v1، راهنمای اصول گزارش‌دهی و همچنین راهنمای موارد استفاده پیشرفته را بخوانید.

روش گزارش قیفی

Data API v1 از قابلیت‌های گزارش‌دهی قیفی در روش runFunnelReport پشتیبانی می‌کند. این روش گزارش قیف سفارشی‌شده‌ای از داده‌های رویداد Google Analytics شما برمی‌گرداند.

انتخاب نهاد گزارش‌دهنده

همه روش‌های Data API v1 نیاز دارند که شناسه دارایی Google Analytics در داخل مسیر درخواست نشانی وب به‌صورت properties/GA_PROPERTY_ID مشخص شود، مانند:

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

گزارش حاصل براساس داده‌های رویداد Google Analytics که در دارایی Google Analytics مشخص‌شده جمع‌آوری شده است، تولید خواهد شد.

اگر از یکی از کتابخانه‌های کارخواه Data API استفاده می‌کنید، نیازی به دستکاری دستی مسیر نشانی وب درخواست نیست. اکثر کارخواه‌های میانای برنامه‌سازی کاربردی پارامتر property را ارائه می‌دهند که انتظار رشته‌ای به‌شکل properties/GA_PROPERTY_ID دارد. برای نمونه‌های استفاده از کتابخانه‌های مشتری، راهنمای شروع سریع را ببینید.

درخواست گزارش قیفی

برای درخواست گزارش قیف، می‌توانید شیء RunFunnelReportRequest بسازید. توصیه می‌کنیم با این پارامترهای درخواست شروع کنید:

  • ورودی معتبر در فیلد dateRanges.

  • مشخصات قیف معتبر در فیلد funnel.

مشخصات قیف

مشخصات قیف در فیلد funnel شیء RunFunnelReportRequest مسیر کاربر را که می‌خواهید اندازه‌گیری کنید با توصیف steps این قیف تعریف می‌کند.

مراحل قیف شامل یک یا چند شرط است که کاربران شما باید آن‌ها را برآورده کنند تا در آن مرحله از سفر قیف قرار گیرند. شرایط گنجاندن در هر مرحله را می‌توان در فیلد filterExpression هر مرحله شرح داد.

هر عبارت فیلتر قیف ترکیبی از دو نوع فیلتر است:

  • funnelFieldFilter فیلتری برای بُعد یا سنجه ایجاد می‌کند.

  • funnelEventFilter فیلتری ایجاد می‌کند که با رویدادهای یک نام رویداد مطابقت دارد. اگر فیلد اختیاری funnelParameterFilterExpression مشخص شده باشد، فقط زیرمجموعه رویدادهایی که هم با نام رویداد تکی و هم با عبارت‌های فیلتر پارامتر مطابقت دارند با این فیلتر رویداد مطابقت خواهند داشت.

فیلترها را می‌توان بااستفاده از گروه‌های AND، OR ترکیب کرد، و همچنین بااستفاده از NOT عبارت منفی کرد.

نتایج گزارش برای هر مرحله قیف براساس بُعد تفکیک می‌شود و در فیلد funnelBreakdown مشخص می‌شود.

نمونه گزارش قیفی

مثال زیر از Google Analytics Data API v1 برای بازتولید گزارش قیفی پیش‌فرض ارائه‌شده در الگوی داده‌کاوی قیفی میانای وب Google Analytics استفاده می‌کند:

میانای کاربر گزارش قیفی نمونه

مراحل قیف

پیکربندی قیف قبلی شامل مراحل زیر است:

# نام مرحله شرایط
1 اولین باز کردن/مراجعه نام رویداد first_open یا first_visit است.
2 بازدیدکنندگان طبیعی بُعد firstUserMedium حاوی عبارت «طبیعی» است.
3 شروع جلسه نام رویداد session_start است.
4 بازدید از صفحه برنامه/ صفحه وب نام رویداد screen_view یا page_view است.
5 خرید نام رویداد purchase یا in_app_purchase است.

مرحله ۱ (اولین باز کردن/بازدید) قیف شامل همه کاربران پس‌از اولین تعاملشان با وب‌سایت یا برنامه است، مثل کاربرانی که رویدادهای first_open یا first_visit را راه‌اندازی کرده‌اند.

برای پیاده‌سازی این رفتار، قطعه زیر یک شیء FunnelStep را با یک فیلد filterExpression مشخص می‌کند.

فیلد عبارت فیلتر یک شیء FunnelFilterExpression است که با ترکیب دو موجودیت FunnelEventFilter بااستفاده از یک گروه OR ساخته شده است.

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

مرحله ۲ (بازدیدکنندگان طبیعی) قیف شامل کاربرانی است که اولین رسانه آن‌ها شامل عبارت «طبیعی» است. در قطعه کد زیر، فیلد fieldName از FunnelFieldFilter به فیلتر دستور می‌دهد تا با بُعد firstUserMedium مطابقت داشته باشد. فیلد stringFilter حاوی شرطی است که فقط مقادیر بُعدی را که حاوی عبارت «organic» است دربرمی‌گیرد.

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

مراحل باقی‌مانده قیف را می‌توان به روشی مشابه مشخص کرد.

بُعد تفکیک

یک بعد تفکیک اختیاری (deviceCategory در این مثال) می‌تواند بااستفاده از یک شیء FunnelBreakdown مشخص شود:

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

به‌طور پیش‌فرض، فقط ۵ مقدار متمایز اول بُعد تفکیک در گزارش گنجانده می‌شود. می‌توانید از فیلد limit شیء FunnelBreakdown برای لغو این رفتار استفاده کنید.

تکمیل پُرسمان گزارش قیفی

در اینجا پُرسمان کاملی وجود دارد که گزارش قیف را تولید می‌کند:

HTTP

POST https://analyticsdata.googleapis.com/v1alpha/properties/GA_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"
                }
              }
            ]
          }
        }
      }
    ]
  }
}

گزارش کردن پاسخ

پاسخ گزارش قیفی درخواست API گزارش قیفی از دو بخش اصلی تشکیل شده است که هر دو به‌عنوان شیء FunnelSubReport برگردانده می‌شوند: مصورسازی قیفی و جدول قیفی.

دیداری‌سازی قیف

«نمای قیفی» که در فیلد funnelVisualization پاسخ گزارش قیفی برگردانده می‌شود، حاوی نمای کلی سطح بالایی از گزارش قیفی است. همان‌طور که از نامش پیداست، این گزینه برای تجسم سریع گزارش قیف تولیدشده مفید است.

هر ردیف از جدول تجسم قیفی شامل برخی یا همه فیلدهای زیر است:

  • نام مرحله قیف (بُعد funnelStepName).

  • تعداد کاربران فعال (سنجه activeUsers).

  • بخش (بُعد segment). فقط درصورتی وجود دارد که Segment در پُرسمان قیف مشخص شده باشد.

  • تاریخ (بُعد date). فقط درصورتی وجود دارد که نوع تجسم TRENDED_FUNNEL در پُرسمان مشخص شده باشد.

  • بُعد کنش بعدی (بُعد funnelStepNextAction). فقط درصورتی وجود دارد که FunnelNextAction در پُرسمان قیف مشخص شده باشد.

در اینجا نحوه نمایش بخش تجسم قیف گزارش نمونه این راهنما توسط میانای وب Google Analytics آورده شده است:

سرایندهای گزارش قیفی: نمونه

جدول قیفی

«جدول قیفی» که در فیلد funnelTable پاسخ گزارش قیفی برگردانده می‌شود، بخش اصلی گزارش را نشان می‌دهد. هر ردیف جدول شامل برخی یا همه فیلدهای زیر است:

  • نام مرحله قیف (بُعد funnelStepName).

  • بُعد تفکیک.

  • تعداد کاربران فعال (سنجه activeUsers).

  • نرخ تکمیل مرحله (سنجه funnelStepCompletionRate).

  • تعداد رها کردن مرحله (سنجه funnelStepAbandonments).

  • نرخ رها کردن مرحله (سنجه funnelStepAbandonmentRate).

  • نام بخش (بُعد segment). فقط درصورتی وجود دارد که Segment در پُرسمان قیف مشخص شده باشد.

مقادیر کل در ردیف جداگانه‌ای برگردانده می‌شود که RESERVED_TOTAL را به‌عنوان مقدار بُعد تفکیک دارد.

در اینجا نمونه‌ای از «جدول قیف» که در میانای وب Google Analytics نمایش داده می‌شود آورده شده است:

جدول گزارش قیفی: نمونه

پاسخ خام

قطعه کد زیر نمونه‌ای از داده‌های خام را نشان می‌دهد که در پاسخ به پُرسمان runFunnelReport برگردانده شده است.

بسته به داده‌های جمع‌آوری‌شده توسط دارایی‌تان، گزارش نمونه گزارش زیر را برمی‌گرداند که تعداد کاربران فعال موجود در هر مرحله قیف را نشان می‌دهد.

{
  "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"
}

کتابخانه‌های مشتری

برای توضیح درباره نحوه نصب و پیکربندی کتابخانه‌های کارخواه، راهنمای شروع سریع را ببینید.

در اینجا نمونه‌هایی از استفاده از کتابخانه‌های کارخواه آورده شده است که یک پُرسمان قیف را اجرا می‌کنند و پاسخ را چاپ می‌کنند.

جاوا

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());
    }
  }
}

PHP

use Google\Analytics\Data\V1alpha\Client\AlphaAnalyticsDataClient;
use Google\Analytics\Data\V1alpha\DateRange;
use Google\Analytics\Data\V1alpha\Dimension;
use Google\Analytics\Data\V1alpha\FunnelBreakdown;
use Google\Analytics\Data\V1alpha\FunnelEventFilter;
use Google\Analytics\Data\V1alpha\FunnelFieldFilter;
use Google\Analytics\Data\V1alpha\FunnelFilterExpression;
use Google\Analytics\Data\V1alpha\FunnelFilterExpressionList;
use Google\Analytics\Data\V1alpha\FunnelStep;
use Google\Analytics\Data\V1alpha\Funnel;
use Google\Analytics\Data\V1alpha\FunnelSubReport;
use Google\Analytics\Data\V1alpha\RunFunnelReportRequest;
use Google\Analytics\Data\V1alpha\RunFunnelReportResponse;
use Google\Analytics\Data\V1alpha\StringFilter;
use Google\Analytics\Data\V1alpha\StringFilter\MatchType;

/**
 * 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
 *
 * @param string $propertyId Your GA-4 Property ID
 */
function run_funnel_report(string $propertyId)
{
    // Create an instance of the Google Analytics Data API client library.
    $client = new AlphaAnalyticsDataClient();

    // Create the funnel report request.
    $request = (new RunFunnelReportRequest())
        ->setProperty('properties/' . $propertyId)
        ->setDateRanges([
            new DateRange([
                'start_date' => '30daysAgo',
                'end_date' => 'today',
            ]),
        ])
        ->setFunnelBreakdown(
            new FunnelBreakdown([
                'breakdown_dimension' =>
                    new Dimension([
                        'name' => 'deviceCategory'
                    ])
            ])
        )
        ->setFunnel(new Funnel());

    // Add funnel steps to the funnel.

    // 1. Add first open/visit step.
    $request->getFunnel()->getSteps()[] = new FunnelStep([
        'name' => 'First open/visit',
        'filter_expression' => new FunnelFilterExpression([
            'or_group' => new FunnelFilterExpressionList([
                'expressions' => [
                    new FunnelFilterExpression([
                        'funnel_event_filter' => new FunnelEventFilter([
                            'event_name' => 'first_open',
                        ])
                    ]),
                    new FunnelFilterExpression([
                        'funnel_event_filter' => new FunnelEventFilter([
                            'event_name' => 'first_visit'
                        ])
                    ])
                ]
            ])
        ])
    ]);

    // 2. Add organic visitors step.
    $request->getFunnel()->getSteps()[] = new FunnelStep([
        'name' => 'Organic visitors',
        'filter_expression' => new FunnelFilterExpression([
            'funnel_field_filter' => new FunnelFieldFilter([
                'field_name' => 'firstUserMedium',
                'string_filter' => new StringFilter([
                    'match_type' => MatchType::CONTAINS,
                    'case_sensitive' => false,
                    'value' => 'organic',
                ])
            ])
        ])
    ]);

    // 3. Add session start step.
    $request->getFunnel()->getSteps()[] = new FunnelStep([
        'name' => 'Session start',
        'filter_expression' => new FunnelFilterExpression([
            'funnel_event_filter' => new FunnelEventFilter([
                'event_name' => 'session_start',
            ])
        ])
    ]);

    // 4. Add screen/page view step.
    $request->getFunnel()->getSteps()[] = new FunnelStep([
        'name' => 'Screen/Page view',
        'filter_expression' => new FunnelFilterExpression([
            'or_group' => new FunnelFilterExpressionList([
                'expressions' => [
                    new FunnelFilterExpression([
                        'funnel_event_filter' => new FunnelEventFilter([
                            'event_name' => 'screen_view',
                        ])
                    ]),
                    new FunnelFilterExpression([
                        'funnel_event_filter' => new FunnelEventFilter([
                            'event_name' => 'page_view'
                        ])
                    ])
                ]
            ])
        ])
    ]);

    // 5. Add purchase step.
    $request->getFunnel()->getSteps()[] = new FunnelStep([
        'name' => 'Purchase',
        'filter_expression' => new FunnelFilterExpression([
            'or_group' => new FunnelFilterExpressionList([
                'expressions' => [
                    new FunnelFilterExpression([
                        'funnel_event_filter' => new FunnelEventFilter([
                            'event_name' => 'purchase',
                        ])
                    ]),
                    new FunnelFilterExpression([
                        'funnel_event_filter' => new FunnelEventFilter([
                            'event_name' => 'in_app_purchase'
                        ])
                    ])
                ]
            ])
        ])
    ]);

    // Make an API call.
    $response = $client->runFunnelReport($request);

    printRunFunnelReportResponse($response);
}

/**
 * Print results of a runFunnelReport call.
 * @param RunFunnelReportResponse $response
 */
function printRunFunnelReportResponse(RunFunnelReportResponse $response)
{
    print 'Report result: ' . PHP_EOL;
    print '=== FUNNEL VISUALIZATION ===' . PHP_EOL;
    printFunnelSubReport($response->getFunnelVisualization());

    print '=== FUNNEL TABLE ===' . PHP_EOL;
    printFunnelSubReport($response->getFunnelTable());
}

/**
 * Print the contents of a FunnelSubReport object.
 * @param FunnelSubReport $subReport
 */
function printFunnelSubReport(FunnelSubReport $subReport)
{
    print 'Dimension headers:' . PHP_EOL;
    foreach ($subReport->getDimensionHeaders() as $dimensionHeader) {
        print $dimensionHeader->getName() . PHP_EOL;
    }

    print PHP_EOL . 'Metric headers:' . PHP_EOL;
    foreach ($subReport->getMetricHeaders() as $metricHeader) {
        print $metricHeader->getName() . PHP_EOL;
    }

    print PHP_EOL . 'Dimension and metric values for each row in the report:';
    foreach ($subReport->getRows() as $rowIndex => $row) {
        print PHP_EOL . 'Row #' . $rowIndex . PHP_EOL;
        foreach ($row->getDimensionValues() as $dimIndex => $dimValue) {
            $dimName = $subReport->getDimensionHeaders()[$dimIndex]->getName();
            print $dimName . ": '" . $dimValue->getValue() . "'" . PHP_EOL;
        }
        foreach ($row->getMetricValues() as $metricIndex => $metricValue) {
            $metricName = $subReport->getMetricHeaders()[$metricIndex]->getName();
            print $metricName . ": '" . $metricValue->getValue() . "'" . PHP_EOL;
        }
    }

    print PHP_EOL . 'Sampling metadata for each date range:' . PHP_EOL;
    foreach ($subReport->getMetadata()->getSamplingMetadatas() as $metadataIndex => $metadata) {
        printf('Sampling metadata for date range #%d: samplesReadCount=%d' .
            'samplingSpaceSize=%d%s',
            $metadataIndex, $metadata->getSamplesReadCount(), $metadata->getSamplingSpaceSize(), PHP_EOL);
    }
}

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)