gtmassey / laravel-analytics
在 Laravel 中创建和运行 Google Analytics 数据 API 查询
Requires
- php: ^8.1
- google/analytics-data: ^0.9.0
- gtmassey/period: ^1.0
- illuminate/support: ^9.0|^10.0
- nesbot/carbon: ^2.63
- spatie/laravel-data: ^2.0
- spatie/laravel-package-tools: ^1.13
Requires (Dev)
- laravel/pint: ^1.6
- nunomaduro/collision: ^6.4
- nunomaduro/larastan: ^2.4.1
- orchestra/testbench: ^7.15|^8.0.3
- phpstan/extension-installer: ^1.2
- phpstan/phpstan-deprecation-rules: ^1.1.2
- phpstan/phpstan-mockery: ^1.1.1
- phpstan/phpstan-phpunit: ^1.3.7
- phpunit/phpunit: ^9.6.3
- rregeer/phpunit-coverage-check: ^0.3.1
README
轻松构建 Google Analytics 数据 API 查询!
当前的方法返回一个包含维度和度量标题的 Gtmassey\LaravelAnalytics\ResponseData
实例,以及 rows
中的结果。
目录
安装
通过 Composer
composer require gtmassey/laravel-analytics
设置
使用此包,您必须拥有 Google Cloud 服务帐户凭据。
如果您在 Google Cloud Platform 上没有设置项目,请访问 console.cloud.google.com/projectcreate 创建一个新的项目。
拥有项目后,请确保您已在该控制台左上角选择了该项目。
从仪表板上的快速访问卡中选择“API 和服务”。
确保您已启用 Google Analytics 数据 API。注意:这不同于 Google Analytics API。数据 API 是此包所需的 API。如果您尚未启用 Google Analytics 数据 API,您可以通过单击“启用 API 和服务”将其添加到您的 Cloud Console 帐户中。
您可以在 Google API 库中搜索 Google Analytics 数据 API 并通过它启用。
启用后,从 API 列表中选择 Google Analytics 数据 API,然后单击“凭据”选项卡。
如果您已经设置了具有此 API 的服务帐户,您可以跳过下一步。
单击“创建凭据”按钮,然后选择“服务帐户”。
选择要分配给服务帐户的角色。对于此包,最小角色是查看者角色。
您的服务帐户创建后,单击该帐户进入 Google Cloud Console 的 IAM & Admin 部分。
在 IAM & Admin 页面的服务帐户部分,选择合适的服务帐户,并为帐户创建一个新的 JSON 密钥。
密钥创建后,下载 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 来使用此包。
在您的 .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
实例,其中包含 DimensionHeaders
、MetricHeaders
、Rows
和其他元数据。
示例输出
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\CustomMetric
或 Gtmassey\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。有关更多信息,请参阅 许可文件。