oriceon/laravel-analytics

在 Laravel 中创建和运行 Google Analytics Data API 查询

dev-main 2024-06-13 05:03 UTC

This package is auto-updated.

Last update: 2024-09-13 05:29:43 UTC


README

Latest Version on Packagist Total Downloads Tests

轻松在 Laravel 中构建 Google Analytics Data API 查询!

当前方法返回 Gtmassey\LaravelAnalytics\ResponseData 的实例,其中包含维度和指标标题,以及 rows 中的结果。

目录

安装

通过 Composer

composer require gtmassey/laravel-analytics

设置

要使用此包,您必须拥有 Google Cloud 服务帐户凭据。

如果您尚未在 Google Cloud Platform 上设置项目,请访问 console.cloud.google.com/projectcreate 以创建一个新项目。

一旦您有一个项目,请确保您已选中控制台左上角的该项目。

Screen Shot 2022-11-30 at 2 22 35 PM

从仪表板的快速访问卡中选择“API和服务”。

Screen Shot 2022-11-30 at 2 22 54 PM

确保您已启用 Google Analytics Data API。注意:这不是 Google Analytics API。Data API 是此包所需的 API。如果您尚未启用 Google Analytics Data API,您可以通过点击“启用 API和服务”将其添加到您的 Cloud Console 帐户。

Screen Shot 2022-11-30 at 2 23 25 PM

您可以通过 Google API 库搜索 Google Analytics Data API 并启用它。

Screen Shot 2022-11-30 at 2 24 09 PM

Screen Shot 2022-11-30 at 2 24 21 PM

启用后,从 API 列表中选择 Google Analytics Data API,并单击凭据选项卡。

Screen Shot 2022-11-30 at 2 24 48 PM

如果您已经设置了此 API 的服务帐户,您可以跳过下一步。

单击创建凭据按钮,并选择服务帐户。

Screen Shot 2022-11-30 at 2 26 24 PM

选择您想分配给服务帐户的角色。对于此包,最低角色是查看者角色。

您的服务帐户创建后,单击该帐户进入 Google Cloud Console 的 IAM & Admin 部分。

在 IAM & Admin 页面的服务帐户部分中,选择适当的服务帐户,并为该帐户创建一个新的 JSON 密钥。

Screen Shot 2022-11-30 at 2 27 01 PM

Screen Shot 2022-11-30 at 2 27 14 PM

创建密钥后,下载 JSON 文件并将其保存在安全的地方。您将需要此文件来使用此包。如果您丢失此文件,您将必须创建一个新的服务帐户。Google 不允许重新发行密钥。

您可以使用这些凭据的几种方式

作为 ENV 值(默认)

如果您只为您的应用程序使用一个服务帐户,这是一个理想的设置。

在您的 .env 文件中指定 JSON 文件的路径

GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json

作为单独的 JSON 文件

如果您有多个服务帐户,您可以指示此包使用特定的一个

ANALYTICS_CREDENTIALS_USE_ENV=false
ANALYTICS_CREDENTIALS_FILE=/path/to/credentials.json

作为 JSON 字符串

如果您不想将凭据存储在文件中,您可以直接在 .env 文件中指定 JSON 字符串

ANALYTICS_CREDENTIALS_USE_ENV=false
ANALYTICS_CREDENTIALS_JSON="{type: service_account, project_id: ...}"

作为单独的值

您还可以在 .env 文件中指定作为单独值的凭据

ANALYTICS_CREDENTIALS_USE_ENV=false
ANALYTICS_CREDENTIALS_TYPE=service_account
ANALYTICS_CREDENTIALS_PROJECT_ID=...
ANALYTICS_CREDENTIALS_PRIVATE_KEY_ID=...
ANALYTICS_CREDENTIALS_PRIVATE_KEY=...
ANALYTICS_CREDENTIALS_CLIENT_EMAIL=...
ANALYTICS_CREDENTIALS_CLIENT_ID=...
ANALYTICS_CREDENTIALS_AUTH_URI=...
ANALYTICS_CREDENTIALS_TOKEN_URI=...
ANALYTICS_CREDENTIALS_AUTH_PROVIDER_X509_CERT_URL=...
ANALYTICS_CREDENTIALS_CLIENT_X509_CERT_URL=...

警告 包将始终优先考虑 GOOGLE_APPLICATION_CREDENTIALS 环境值,而不是其他选项。如果您想使用单独的服务帐户,请确保设置 ANALYTICS_CREDENTIALS_USE_ENV=false

最后,打开 Google Analytics,并复制您要查询的属性的属性 ID。您需要此 ID 来使用此软件包。

Screen Shot 2022-11-30 at 2 40 42 PM

在您的 .env 文件中设置属性 ID。

ANALYTICS_PROPERTY_ID="XXXXXXXXX"

现在您已经准备好开始使用了!

用法

安装完成后,您可以在应用程序中运行 Google Analytics 数据 API 查询。

所有 Google Analytics 数据 API 查询都需要一个运行日期范围。使用 Period 类来生成查询的时间范围。

查询构建器

use Gtmassey\LaravelAnalytics\Request\Dimensions;
use Gtmassey\LaravelAnalytics\Request\Metrics;
use Gtmassey\LaravelAnalytics\Analytics;
use Gtmassey\Period\Period;
use Carbon\Carbon;

$report = Analytics::query()
    ->setMetrics(fn(Metrics $metrics) => $metrics
        ->active1DayUsers()
        ->active7DayUsers()
        ->active28DayUsers()
    )
    ->forPeriod(Period::defaultPeriod())
    ->run();

$report2 = Analytics::query()
    ->setMetrics(fn(Metrics $metrics) => $metrics->sessions())
    ->setDimensions(fn(Dimensions $dimensions) => $dimensions->pageTitle())
    ->forPeriod(Period::create(Carbon::now()->subDays(30), Carbon::now()))
    ->run();

过滤

过滤功能遵循 Google Analytics 数据 API 文档,但考虑到便利性和流畅的界面。您可以使用 dimensionFilter()metricFilter() 方法来过滤查询。这些方法接受一个回调,该回调接收 Gtmassey\LaravelAnalytics\Request\Filters\FilterExpression 类的实例。该类提供了一组方法来构建您的过滤器

  • filter() - 接受维度或度量名称和 filter callback 的通用过滤器方法
  • filterDimension() - 接受通过回调提供的维度对象和 filter callback 的过滤器方法
  • filterMetric() - 接受通过回调提供的度量对象和 filter callback 的过滤器方法
  • not() - 取消过滤
  • andGroup() - 创建一个使用 AND 操作符组合的过滤器组
  • orGroup() - 创建一个使用 OR 操作符组合的过滤器组

您可以在 Gtmassey\LaravelAnalytics\Request\Filters\Filter 中查看可用的 filter callback 方法列表。

示例

filter() 方法
use Gtmassey\LaravelAnalytics\Request\Dimensions;
use Gtmassey\LaravelAnalytics\Request\Filters\Filter;
use Gtmassey\LaravelAnalytics\Request\Filters\FilterExpression;
use Gtmassey\LaravelAnalytics\Request\Metrics;
use Gtmassey\LaravelAnalytics\Analytics;
use Gtmassey\Period\Period;

$report = Analytics::query()
    ->setMetrics(fn(Metrics $metrics) => $metrics->sessions())
    ->setDimensions(fn(Dimensions $dimensions) => $dimensions->pageTitle())
    ->forPeriod(Period::defaultPeriod())
    ->dimensionFilter(fn(FilterExpression $filterExpression) => $filterExpression
        ->filter('pageTitle', fn(Filter $filter) => $filter->exact('Home'))
    )
    ->run();
filterDimension() 方法

使用此方法,您可以使用 Dimensions 类流畅地构建过滤器,而无需知道 API 中使用的确切维度名称。

use Gtmassey\LaravelAnalytics\Request\Dimensions;
use Gtmassey\LaravelAnalytics\Request\Filters\Filter;
use Gtmassey\LaravelAnalytics\Request\Filters\FilterExpression;
use Gtmassey\LaravelAnalytics\Request\Metrics;
use Gtmassey\LaravelAnalytics\Analytics;
use Gtmassey\Period\Period;

$report = Analytics::query()
    ->setMetrics(fn(Metrics $metrics) => $metrics->sessions())
    ->setDimensions(fn(Dimensions $dimensions) => $dimensions->pageTitle())
    ->forPeriod(Period::defaultPeriod())
    ->dimensionFilter(fn(FilterExpression $filterExpression) => $filterExpression
        ->filterDimension(
            dimensionsCallback: fn(Dimensions $dimensions) => $dimensions->pageTitle(),
            filter: fn(Filter $filter) => $filter->exact('Home')
        )
    )
    ->run();
filterMetric() 方法

类似于 filterDimension() 方法,您可以使用此方法并利用 Metrics 类流畅地构建过滤器,而无需知道 API 中使用的确切度量名称。

use Gtmassey\LaravelAnalytics\Request\Dimensions;
use Gtmassey\LaravelAnalytics\Request\Filters\Filter;
use Gtmassey\LaravelAnalytics\Request\Filters\FilterExpression;
use Gtmassey\LaravelAnalytics\Request\Metrics;
use Gtmassey\LaravelAnalytics\Analytics;
use Gtmassey\Period\Period;

$report = Analytics::query()
    ->setMetrics(fn(Metrics $metrics) => $metrics->sessions())
    ->setDimensions(fn(Dimensions $dimensions) => $dimensions->pageTitle())
    ->forPeriod(Period::defaultPeriod())
    ->metricFilter(fn(FilterExpression $filterExpression) => $filterExpression
        ->filterMetric(
            metricsCallback: fn(Metrics $metrics) => $metrics->sessions(),
            filter: fn(Filter $filter) => $filter->greaterThanInt(100)
        )
    )
    ->run();
not() 方法
use Gtmassey\LaravelAnalytics\Request\Dimensions;
use Gtmassey\LaravelAnalytics\Request\Filters\Filter;
use Gtmassey\LaravelAnalytics\Request\Filters\FilterExpression;
use Gtmassey\LaravelAnalytics\Request\Metrics;
use Gtmassey\LaravelAnalytics\Analytics;
use Gtmassey\Period\Period;

$report = Analytics::query()
    ->setMetrics(fn(Metrics $metrics) => $metrics->sessions())
    ->setDimensions(fn(Dimensions $dimensions) => $dimensions->pageTitle())
    ->forPeriod(Period::defaultPeriod())
    ->dimensionFilter(fn(FilterExpression $filterExpression) => $filterExpression
        ->not(fn(FilterExpression $filterExpression) => $filterExpression
            ->filter('pageTitle', fn(Filter $filter) => $filter
                 ->exact('Home')
            )
        )
    )
    ->run();
andGroup() 方法
use Gtmassey\LaravelAnalytics\Request\Dimensions;
use Gtmassey\LaravelAnalytics\Request\Filters\Filter;
use Gtmassey\LaravelAnalytics\Request\Filters\FilterExpression;
use Gtmassey\LaravelAnalytics\Request\Filters\FilterExpressionList;
use Gtmassey\LaravelAnalytics\Request\Metrics;
use Gtmassey\LaravelAnalytics\Analytics;
use Gtmassey\Period\Period;

$report = Analytics::query()
    ->setMetrics(fn(Metrics $metrics) => $metrics->sessions())
    ->setDimensions(fn(Dimensions $dimensions) => $dimensions->deviceCategory()->browser())
    ->forPeriod(Period::defaultPeriod())
    ->dimensionFilter(fn(FilterExpression $filterExpression) => $filterExpression
        ->andGroup(fn(FilterExpressionList $filterExpressionList) => $filterExpressionList
            ->filter('deviceCategory', fn(Filter $filter) => $filter
                ->exact('Mobile')
			)
            ->filter('browser', fn(Filter $filter) => $filter
                ->exact('Chrome')
            )
        )
    )
    ->run();
orGroup() 方法
use Gtmassey\LaravelAnalytics\Request\Dimensions;
use Gtmassey\LaravelAnalytics\Request\Filters\Filter;
use Gtmassey\LaravelAnalytics\Request\Filters\FilterExpression;
use Gtmassey\LaravelAnalytics\Request\Filters\FilterExpressionList;
use Gtmassey\LaravelAnalytics\Request\Metrics;
use Gtmassey\LaravelAnalytics\Analytics;
use Gtmassey\Period\Period;

$report = Analytics::query()
    ->setMetrics(fn(Metrics $metrics) => $metrics->sessions())
    ->setDimensions(fn(Dimensions $dimensions) => $dimensions->browser())
    ->forPeriod(Period::defaultPeriod())
    ->dimensionFilter(fn(FilterExpression $filterExpression) => $filterExpression
        ->orGroup(fn(FilterExpressionList $filterExpressionList) => $filterExpressionList
            ->filter('browser', fn(Filter $filter) => $filter
                ->exact('Firefox')
            )
            ->filter('browser', fn(Filter $filter) => $filter
                ->exact('Chrome')
            )
        )
    )
    ->run();
高级示例

您可以将所有上述方法混合起来构建复杂的过滤器表达式。

use Gtmassey\LaravelAnalytics\Request\Dimensions;
use Gtmassey\LaravelAnalytics\Request\Filters\Filter;
use Gtmassey\LaravelAnalytics\Request\Filters\FilterExpression;
use Gtmassey\LaravelAnalytics\Request\Filters\FilterExpressionList;
use Gtmassey\LaravelAnalytics\Request\Metrics;
use Gtmassey\LaravelAnalytics\Analytics;
use Gtmassey\Period\Period;

$report = Analytics::query()
    ->setMetrics(fn(Metrics $metrics) => $metrics->sessions()->screenPageViews())
    ->setDimensions(fn(Dimensions $dimensions) => $dimensions->browser()->deviceCategory())
    ->forPeriod(Period::defaultPeriod())
    ->dimensionFilter(fn(FilterExpression $filterExpression) => $filterExpression
        ->andGroup(fn(FilterExpressionList $filterExpressionList) => $filterExpressionList
            ->filter('browser', fn(Filter $filter) => $filter
                ->contains('safari')
            )
            ->not(fn(FilterExpression $filterExpression) => $filterExpression
                ->filterDimension(
                    dimensionsCallback: fn(Dimensions $dimensions) => $dimensions->deviceCategory(),
                    filter: fn(Filter $filter) => $filter->contains('mobile')
                )
            )
        )
    )
    ->metricFilter(fn(FilterExpression $filterExpression) => $filterExpression
        ->orGroup(fn(FilterExpressionList $filterExpressionList) => $filterExpressionList
            ->filter('sessions', fn(Filter $filter) => $filter
                ->greaterThanInt(200)
            )
            ->filterMetric(
                metricsCallback: fn(Metrics $metrics) => $metrics->sessions(),
                filter: fn(Filter $filter) => $filter->lessThanInt(100)
            )
        )
    )
    ->run();

默认报告

getTopEvents()

$report = Analytics::getTopEvents();

此方法返回给定时间段内的顶级事件。它接受一个可选的 Gtmassey\Period\Period 对象。

如果没有传递 Gtmassey\Period\Period 对象,它将使用 Gtmassey\Period\Period::defaultPeriod() 中设置的默认时间段。

该方法将返回一个 Gtmassey\LaravelAnalytics\Response\ResponseData 实例,其中包含 DimensionHeadersMetricHeadersRows 和其他元数据。

示例输出

Gtmassey\LaravelAnalytics\Response\ResponseData {
  +dimensionHeaders: Spatie\LaravelData\DataCollection {
    +items: array:1 [
      0 => Gtmassey\LaravelAnalytics\Response\DimensionHeader {
        +name: "eventName"
      }
    ]
  }
  +metricHeaders: Spatie\LaravelData\DataCollection {
    +items: array:1 [
      0 => Gtmassey\LaravelAnalytics\Response\MetricHeader {
        +name: "eventCount"
        +type: "TYPE_INTEGER"
      }
    ]
  }
  +rows: Spatie\LaravelData\DataCollection {
    +items: array:6 [
      0 => Gtmassey\LaravelAnalytics\Response\Row {
        +dimensionValues: Spatie\LaravelData\DataCollection {
          +items: array:1 [
            0 => Gtmassey\LaravelAnalytics\Response\DimensionValue {
              +value: "page_view"
            }
          ]
        }
        +metricValues: Spatie\LaravelData\DataCollection {
          +items: array:1 [
            0 => Gtmassey\LaravelAnalytics\Response\MetricValue {
              +value: "1510"
            }
          ]
        }
      }
      1 => Gtmassey\LaravelAnalytics\Response\Row {}
      2 => Gtmassey\LaravelAnalytics\Response\Row {}
      3 => Gtmassey\LaravelAnalytics\Response\Row {}
      4 => Gtmassey\LaravelAnalytics\Response\Row {}
      5 => Gtmassey\LaravelAnalytics\Response\Row {}
    ]
  }
  +totals: null
  +rowCount: 6
  +metadata: Gtmassey\LaravelAnalytics\Response\Metadata {}
  +propertyQuota: null
  +kind: "analyticsData#runReport"
}

getTopPages()

$report = Analytics::getTopPages();

此方法返回给定时间段内的顶级页面。它接受一个可选的 Gtmassey\Period\Period 对象。

页面及其会话列在响应的 Rows 属性中。

getUserAcquisitionOverview()

$report = Analytics::getUserAcquisitionOverview();

此方法返回给定时间段内的用户获取概览。它接受一个可选的 Gtmassey\Period\Period 对象。

该方法将返回一个包含会话的会话主要获取来源数量的 ResponseData 对象。主要获取来源是“直接”、“推荐”、“有机搜索”和“有机社交”。

getUserEngagement()

$report = Analytics::getUserEngagement();

此方法返回一个没有维度的 ResponseData 对象。查询仅包含度量。将包含以下内容的 ResponseData 对象:

  • 平均会话持续时间,以秒为单位
  • 参与会话数量
  • 每个用户的会话数量
  • 会话总数

可扩展性

自定义度量值和维度

您不仅限于此软件包提供的度量值和维度。您可以使用您在 Google Analytics 中创建的任何自定义度量值和维度。

创建一个扩展自 Gtmassey\LaravelAnalytics\Request\CustomMetricGtmassey\LaravelAnalytics\Request\CustomDimension 的新类,并按照以下格式实现方法:

namespace App\Analytics;

use Google\Analytics\Data\V1beta\Metric;
use Gtmassey\LaravelAnalytics\Request\Metrics;

class CustomMetrics extends Metrics
{
    public function customMetric(): self
    {
        $this->metrics->push(new Metric(['name' => 'customEvent:parameter_name']));

        return $this;
    }
}

在您的 AppServiceProvider 中绑定该类

use Gtmassey\LaravelAnalytics\Request\Metrics;
use App\Analytics\CustomMetrics;
//use Gtmassey\LaravelAnalytics\Request\Dimensions;
//use App\Analytics\CustomDimensions;

public function boot()
{
    $this->app->bind(Metrics::class, CustomMetrics::class);
    //$this->app->bind(Dimensions::class, CustomDimensions::class);
}

现在您可以在查询中使用自定义指标

use App\Analytics\CustomMetrics;
use Gtmassey\LaravelAnalytics\Analytics;
use Gtmassey\LaravelAnalytics\Period;

$report = Analytics::query()
     ->setMetrics(fn(CustomMetrics $metrics) => $metrics
         ->customMetric()
         ->sessions()
     )
     ->forPeriod(Period::defaultPeriod())
     ->run();

可重用过滤器

您可以为查询创建可重用过滤器。创建一个扩展自 Gtmassey\LaravelAnalytics\Analytics 的新类,并按照以下格式实现方法

namespace App\Analytics;

use Gtmassey\LaravelAnalytics\Analytics;
use Gtmassey\LaravelAnalytics\Request\Filters\Filter;
use Gtmassey\LaravelAnalytics\Request\Filters\FilterExpression;
use Gtmassey\LaravelAnalytics\Request\Metrics;

class CustomAnalytics extends Analytics
{
    public function onlySessionsAbove(int $count): static
    {
        $this->metricFilter(fn(FilterExpression $filterExpression) => $filterExpression
            ->filterMetric(
                metricsCallback: fn(Metrics $metrics) => $metrics->sessions(),
                filter: fn(Filter $filter) => $filter->greaterThanInt($count),
            )
        );

        return $this;
    }
}

在您的 AppServiceProvider 中绑定该类

use Gtmassey\LaravelAnalytics\Analytics;
use App\Analytics\CustomAnalytics;

public function boot()
{
    $this->app->bind(Analytics::class, CustomAnalytics::class);
}

现在您可以在查询中使用自定义过滤器

use App\Analytics\CustomAnalytics;
use Gtmassey\LaravelAnalytics\Period;
use Gtmassey\LaravelAnalytics\Request\Dimensions;
use Gtmassey\LaravelAnalytics\Request\Metrics;

$report = CustomAnalytics::query()
    ->setMetrics(fn(Metrics $metrics) => $metrics->sessions())
    ->setDimensions(fn(Dimensions $dimensions) => $dimensions->browser())
    ->forPeriod(Period::defaultPeriod())
    ->onlySessionsAbove(100)
    ->run();

变更日志

阅读 CHANGELOG.md

测试

要运行测试,请运行

composer test

请注意,此命令还会运行代码覆盖率分析。

贡献

查看 贡献指南

安全

如果您发现任何与安全相关的问题,请通过电子邮件 contact@garrettmassey.net 而不是使用问题跟踪器联系。

鸣谢

特别感谢 Plytas 对项目的早期和重大贡献。没有他们的帮助设置一切并愿意教授我新的工具和技术,这个项目可能就已经夭折。

还要向 Spatie 团队表示衷心的感谢,他们一直为开源社区做出贡献!他们的部分工作被用于本项目,并且我已经多年将他们的软件包作为项目的基础。

许可证

MIT。有关更多信息,请参阅 许可证文件