From 6ea33b14a6912597b109e936ed1662b93ae021d6 Mon Sep 17 00:00:00 2001 From: Tjardo <31533540+tjardoo@users.noreply.github.com> Date: Mon, 11 Dec 2023 11:32:35 +0100 Subject: [PATCH] Add Measurement Protocol (#1) --- README.md | 65 +++++++++++++- config/config.php | 23 ++++- .../measurement-protocol-client-id.blade.php | 33 +++++++ routes/web.php | 8 ++ src/Facades/MeasurementProtocol.php | 13 +++ ...eMeasurementProtocolClientIdController.php | 13 +++ src/MeasurementProtocol.php | 90 +++++++++++++++++++ src/TagManagerServiceProvider.php | 9 ++ .../MeasurementProtocolClientId.php | 21 +++++ 9 files changed, 270 insertions(+), 5 deletions(-) create mode 100644 resources/views/components/measurement-protocol-client-id.blade.php create mode 100644 routes/web.php create mode 100644 src/Facades/MeasurementProtocol.php create mode 100644 src/Http/Controllers/StoreMeasurementProtocolClientIdController.php create mode 100644 src/MeasurementProtocol.php create mode 100644 src/View/Components/MeasurementProtocolClientId.php diff --git a/README.md b/README.md index 536cdfc..03d8971 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Quality Score](https://img.shields.io/scrutinizer/g/label84/laravel-tagmanager.svg?style=flat-square)](https://scrutinizer-ci.com/g/label84/laravel-tagmanager) [![Total Downloads](https://img.shields.io/packagist/dt/label84/laravel-tagmanager.svg?style=flat-square)](https://packagist.org/packages/label84/laravel-tagmanager) -An easier way to add Google Tag Manager to your Laravel application. Including recommended GTM events support. +Easier way to add Google Tag Manager to your Laravel application. Including support for User-ID, E-commerce and Server Side Events (Measurement Protocol). - [Laravel support](#laravel-support) - [Installation](#installation) @@ -15,6 +15,9 @@ An easier way to add Google Tag Manager to your Laravel application. Including r - [Ecommerce (GA4)](#ecommerce-ga4) - [Ecommerce Item](#ecommerce-item) - [Ecommerce Events](#ecommerce-events) +- [Server Side Events](#server-side-events) + - [Measurement Protocol](#measurement-protocol) + - [Measurement Protocol Debug Mode](#measurement-protocol-debug-mode) - [Tests](#tests) - [License](#license) @@ -87,8 +90,6 @@ Go to ``https://tagmanager.google.com`` and copy the 'Container ID' of the accou ## Usage ```php -// DashboardController.php (example) - use Label84\TagManager\Facades\TagManager; TagManager::push(['foo' => 'bar']); @@ -112,7 +113,7 @@ You can find a list of recommended events on: [https://support.google.com/analyt This package also supports the User-ID feature. -To start using the User-ID feature you've to add the TagManagerUserIdMiddleware in your 'web' middleware group directly after the TagManagerMiddleware. +To start using the User-ID feature you've to add the ``TagManagerUserIdMiddleware`` in your 'web' middleware group directly after the ``TagManagerMiddleware``. ```php // app/Http/Kernel.php @@ -196,6 +197,62 @@ TagManager::purchase('00001', 'Google', 'EUR', 12.10, 2.10, 0, [ More information: [https://developers.google.com/analytics/devguides/collection/ga4/ecommerce?client_type=gtm](https://developers.google.com/analytics/devguides/collection/ga4/ecommerce?client_type=gtm) +## Server Side Events + +The Google Analytics Measurement Protocol allows developers to make HTTP requests to send raw user interaction data directly to Google Analytics servers. This allows developers to measure how users interact with their business from almost any environment. Developers can then use the Measurement Protocol to: + +- Measure user activity in new environments. +- Tie online to offline behavior. +- Send data from both the client and server. + +### Measurement Protocol + +You need complete the general installation steps first, such as adding the ``.env`` variables, adding the head and body tags to your layout file and adding the ``TagManagerMiddleware``. + +Add the following extra variables to your .env file. + +```sh +// .env + +# Found in the Google Analytics UI under Admin > Data Streams > choose your stream > Measurement ID. The measurement_id isn't your Stream ID. +GOOGLE_MEASUREMENT_ID=G-XXXXXX +# Found in the Google Analytics UI under Admin > Data Streams > choose your stream > Measurement Protocol API Secrets +GOOGLE_MEASUREMENT_PROTOCOL_API_SECRET=XXXXXX +``` + +Add the following snippet to the head of your blade layout file (below the existing ``x-tagmanager-head`` tag). + +```html + + + + + +``` + +```php +use Label84\TagManager\Facades\MeasurementProtocol; + +MeasurementProtocol::event('some_event', ['foo' => 'bar']); +``` + +The User-ID feature is set automatically if the ``TagManagerUserIdMiddleware`` is enabled. + +You can view the events directly in the Google Analytics UI under Realtime > Events. + +### Measurement Protocol Debug Mode + +You can enable the debug mode by calling the ``debug()`` method. This will return a JSON validation response instead of sending the request to Google Analytics. +If there are any errors, they will be returned in the validation messages response. If there are no errors, the validation response array will be empty. + +```php +use Label84\TagManager\Facades\MeasurementProtocol; + +dd( + MeasurementProtocol::debug()->event('some_event', ['foo' => 'bar']) +); +``` + ## Tests ```sh diff --git a/config/config.php b/config/config.php index d5e3e73..9c3bcdb 100644 --- a/config/config.php +++ b/config/config.php @@ -24,7 +24,8 @@ 'session_name' => 'tagmanager', /* - * (optional) + * User ID + * https://developers.google.com/analytics/devguides/collection/ga4/user-id * * The key of the User model that will be used for the User-ID feature. * @@ -33,4 +34,24 @@ * https://developers.google.com/analytics/devguides/collection/ga4/policy */ 'user_id_key' => env('GOOGLE_TAG_MANAGER_USER_ID_KEY', 'id'), + + /** + * Measurement Protocol + * https://developers.google.com/analytics/devguides/collection/protocol/ga4/ + * + * The measurement ID associated with a stream. + * Found in the Google Analytics UI under Admin > Data Streams > choose your stream > Measurement ID. The measurement_id isn't your Stream ID. + */ + 'measurement_id' => env('GOOGLE_MEASUREMENT_ID'), + + /** + * The API SECRET generated in the Google Analytics UI. + * Found in the Google Analytics UI under Admin > Data Streams > choose your stream > Measurement Protocol API Secrets. + */ + 'measurement_protocol_api_secret' => env('GOOGLE_MEASUREMENT_PROTOCOL_API_SECRET'), + + /** + * The session key used to store the measurement protocol client id. + */ + 'measurement_protocol_client_id_session_key' => 'measurement-protocol-client-id' ]; diff --git a/resources/views/components/measurement-protocol-client-id.blade.php b/resources/views/components/measurement-protocol-client-id.blade.php new file mode 100644 index 0000000..613e095 --- /dev/null +++ b/resources/views/components/measurement-protocol-client-id.blade.php @@ -0,0 +1,33 @@ +@if($isEnabled) + + + +@if(session(config('tagmanager.measurement_protocol_client_id_session_key')) === null) + +@endif + +@endif diff --git a/routes/web.php b/routes/web.php new file mode 100644 index 0000000..2578199 --- /dev/null +++ b/routes/web.php @@ -0,0 +1,8 @@ +middleware('web') + ->name('tagmanager.store-measurement-protocol-client-id'); diff --git a/src/Facades/MeasurementProtocol.php b/src/Facades/MeasurementProtocol.php new file mode 100644 index 0000000..0f68a94 --- /dev/null +++ b/src/Facades/MeasurementProtocol.php @@ -0,0 +1,13 @@ + request('client_id'), + ]); + } +} diff --git a/src/MeasurementProtocol.php b/src/MeasurementProtocol.php new file mode 100644 index 0000000..dcbaa4b --- /dev/null +++ b/src/MeasurementProtocol.php @@ -0,0 +1,90 @@ +clientId = session(config('tagmanager.measurement_protocol_client_id_session_key')); + } + + public function event(string $name, array $params = null): array + { + $event = [ + 'name' => $name, + ]; + + if ($params !== null) { + $event['params'] = $params; + } + + $response = Http::withHeaders([ + 'content-type' => 'application/json', + ]) + ->withQueryParameters([ + 'measurement_id' => config('tagmanager.measurement_id'), + 'api_secret' => config('tagmanager.measurement_protocol_api_secret'), + ]) + ->post($this->route(), array_merge( + [ + 'client_id' => $this->clientId, + 'events' => [$event], + ], + $this->getUserIdArray(), + )); + + if($this->isDebugEnabled) { + return $response->json(); + } + + return [ + 'status' => $response->successful() ? 'success' : 'error', + ]; + } + + public function debug(): self + { + $this->isDebugEnabled = true; + + return $this; + } + + public function user(User $user): self + { + $this->userId = "{$user->{config('tagmanager.user_id_key')}}"; + + return $this; + } + + private function route(): string + { + $url = 'www.google-analytics.com'; + + if ($this->isDebugEnabled) { + $url = 'www.google-analytics.com/debug'; + } + + return "https://{$url}/mp/collect"; + } + + private function getUserIdArray(): array + { + if ($this->userId === null) { + return []; + } + + return [ + 'user_id' => $this->userId, + ]; + } +} diff --git a/src/TagManagerServiceProvider.php b/src/TagManagerServiceProvider.php index 462ecbc..4251c45 100644 --- a/src/TagManagerServiceProvider.php +++ b/src/TagManagerServiceProvider.php @@ -5,6 +5,7 @@ use Illuminate\Support\ServiceProvider; use Label84\TagManager\View\Components\Body; use Label84\TagManager\View\Components\Head; +use Label84\TagManager\View\Components\MeasurementProtocolClientId; class TagManagerServiceProvider extends ServiceProvider { @@ -16,7 +17,12 @@ public function register(): void return new TagManager(); }); + $this->app->singleton(MeasurementProtocol::class, function ($app) { + return new MeasurementProtocol(); + }); + $this->app->alias(TagManager::class, 'tagmanager'); + $this->app->alias(MeasurementProtocol::class, 'measurement_protocol'); } public function boot(): void @@ -27,11 +33,14 @@ public function boot(): void ], 'config'); } + $this->loadRoutesFrom(__DIR__.'/../routes/web.php'); + $this->loadViewsFrom(__DIR__.'/../resources/views', 'tagmanager'); $this->loadViewComponentsAs('tagmanager', [ Head::class, Body::class, + MeasurementProtocolClientId::class, ]); } } diff --git a/src/View/Components/MeasurementProtocolClientId.php b/src/View/Components/MeasurementProtocolClientId.php new file mode 100644 index 0000000..7deebe6 --- /dev/null +++ b/src/View/Components/MeasurementProtocolClientId.php @@ -0,0 +1,21 @@ +isEnabled = config('tagmanager.enabled'); + } + + public function render(): View + { + return view('tagmanager::components.measurement-protocol-client-id'); + } +}