esign / laravel-conversions-api
Facebook Conversions API 的 Laravel 封装包
Requires
- php: ^8.0
- facebook/php-business-sdk: ^19.0
- illuminate/http: ^8.0|^9.0|^10.0|^11.0
- illuminate/support: ^8.0|^9.0|^10.0|^11.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.3
- orchestra/testbench: ^6.0|^7.0|^8.0|^9.0
- phpunit/phpunit: ^9.0|^10.0
README
此包允许您轻松与Facebook Conversions API交互。
安装
您可以通过 composer 安装此包
composer require esign/laravel-conversions-api
接下来,您可以发布配置文件
php artisan vendor:publish --provider="Esign\ConversionsApi\ConversionsApiServiceProvider" --tag="config"
配置文件将发布为 config/conversions-api.php,内容如下
return [ /** * The access token used by the Conversions API. */ 'access_token' => env('CONVERSIONS_API_ACCESS_TOKEN'), /** * The pixel ID used by the Conversions API. */ 'pixel_id' => env('CONVERSIONS_API_PIXEL_ID'), /** * The Google Tag Manager container ID used in case you're deduplicating * events through Google Tag Manager instead of Facebook Pixel directly. * Should look something like "GTM-XXXXXX". */ 'gtm_id' => env('GOOGLE_TAG_MANAGER_ID'), /** * The Conversions API comes with a nice way to test your events. * You may use this config variable to set your test code. */ 'test_code' => env('CONVERSIONS_API_TEST_CODE'), ];
如果您想自定义视图组件,也可以发布视图
php artisan vendor:publish --provider="Esign\ConversionsApi\ConversionsApiServiceProvider" --tag="views"
转换 API
事件
要向转换 API 添加事件,您可以使用 addEvent
、addEvents
或 setEvents
方法。检索或清除事件可以使用 getEvents
和 clearEvents
方法
use Esign\ConversionsApi\Facades\ConversionsApi; use FacebookAds\Object\ServerSide\UserData; use FacebookAds\Object\ServerSide\Event; ConversionsApi::addEvent( (new Event())->setEventName('PageView')->setEventId('abc') ); ConversionsApi::setEvents([ (new Event())->setEventName('PageView')->setEventId('abc'), (new Event())->setEventName('Purchase')->setEventId('xyz'), ]); ConversionsApi::getEvents(); ConversionsApi::clearEvents();
添加事件不会导致它们被发送到转换 API。要实际发送事件,必须调用 sendEvents
方法
use Esign\ConversionsApi\Facades\ConversionsApi; ConversionsApi::sendEvents();
创建事件类
为了使事情更清晰,您可以扩展 Facebook 的默认事件类
use Esign\ConversionsApi\Facades\ConversionsApi; use FacebookAds\Object\ServerSide\ActionSource; use FacebookAds\Object\ServerSide\Event; class PurchaseEvent extends Event { public static function create(): static { return (new static()) ->setActionSource(ActionSource::WEBSITE) ->setEventName('Purchase') ->setEventTime(time()) ->setEventSourceUrl(request()->fullUrl()) ->setEventId((string) Str::uuid()) ->setUserData(ConversionsApi::getUserData()); } }
ConversionsApi::addEvent( PurchaseEvent::create() );
用户数据
此包还提供了一种定义当前请求用户默认用户数据的方式。您可以通过调用 setUserData
方法来实现。您可以通过创建自定义中间件(如下所示)来为每个传入请求设置用户数据
namespace App\Http\Middleware; use Esign\ConversionsApi\Facades\ConversionsApi; use Esign\ConversionsApi\Objects\DefaultUserData; class InitializeFacebookUserData { public function handle(Request $request, Closure $next): Response { ConversionsApi::setUserData( DefaultUserData::create() ->setEmail($request->user()?->email) ); return $next($request); } }
您现在可以在 App\Http\Kernel
中将其用作全局中间件或路由中间件。
您现在可以将用户数据与事件一起传递
use Esign\ConversionsApi\Facades\ConversionsApi; use FacebookAds\Object\ServerSide\Event; ConversionsApi::addEvent( (new Event())->setUserData(ConversionsApi::getUserData()) );
事件去重
此包提供了一些帮助您去重浏览器和服务器事件的方法。这可以通过 Facebook Pixel 直接完成,也可以通过 Google Tag Manager 的数据层完成。
Facebook Pixel
在尝试通过 Facebook Pixel 发送事件之前,请确保加载像素脚本
<x-conversions-api-facebook-pixel-script />
这将渲染以下 HTML
<script> !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n; n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0; t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window, document,'script','https://#/en_US/fbevents.js'); fbq('init', 'your-configured-pixel-id', {}); </script>
此包将尝试使用 ConversionsApi
中的用户数据提供尽可能多的高级匹配数据。例如,当设置电子邮件地址时,它将自动提供给 init 方法
ConversionsApi::setUserData( (new UserData())->setEmail('john@example.com') );
fbq('init', 'your-configured-pixel-id', {"em": "john@example.com"});
现在您的像素已正确初始化,是时候发送一些事件了。不幸的是,转换 API 和 Facebook Pixel 之间的参数并不相同,因此它们必须映射到正确的格式。一种简单的方法是扩展 FacebookAds\Object\ServerSide\Event
类并在其上实现 Esign\ConversionsApi\Contracts\MapsToFacebookPixel
接口
use Esign\ConversionsApi\Contracts\MapsToFacebookPixel; use Esign\ConversionsApi\Facades\ConversionsApi; use FacebookAds\Object\ServerSide\ActionSource; use FacebookAds\Object\ServerSide\Event; class PurchaseEvent extends Event implements MapsToFacebookPixel { public static function create(): static { return (new static()) ->setActionSource(ActionSource::WEBSITE) ->setEventName('Purchase') ->setEventTime(time()) ->setEventSourceUrl(request()->fullUrl()) ->setEventId((string) Str::uuid()) ->setUserData(ConversionsApi::getUserData()); } public function getFacebookPixelEventType(): string { return 'track'; } public function getFacebookPixelEventName(): string { return $this->getEventName(); } public function getFacebookPixelCustomData(): array { $customData = $this->getCustomData(); return array_filter([ 'currency' => $customData?->getCurrency(), 'value' => $customData?->getValue(), ]); } public function getFacebookPixelEventData(): array { return array_filter(['eventID' => $this->getEventId()]); } }
您现在可以将实现 MapsToFacebookPixel
接口的任何类传递给负责跟踪 Facebook Pixel 事件的视图组件
use FacebookAds\Object\ServerSide\CustomData; use Illuminate\Support\Str; $event = PurchaseEvent::create()->setCustomData( (new CustomData())->setCurrency('EUR')->setValue(10) );
<x-conversions-api-facebook-pixel-tracking-event :event="$event" />
这将渲染以下脚本标签
<script> fbq('track', 'Purchase', {"currency": "EUR", "value": 10}, {"eventID": "ccf928e1-56fd-4376-bee3-dda0d7dbe136"}); </script>
要检索实现 MapsToFacebookPixel
接口的全部事件列表,您可以调用 filterFacebookPixelEvents
方法
@foreach(ConversionsApi::getEvents()->filterFacebookPixelEvents() as $event) <x-conversions-api-facebook-pixel-tracking-event :event="$event" /> @endforeach
如果您想对渲染的内容有更多控制,您始终可以使用匿名组件
<x-conversions-api::facebook-pixel-tracking-event eventType="track" eventName="Purchase" :customData="[]" :eventData="[]" />
Google Tag Manager
在尝试通过 GTM 去重事件之前,请确保配置您的 GTM 容器 ID 并包含必要的脚本
GOOGLE_TAG_MANAGER_ID=GTM-XXXXXX
<html> <head> <x-conversions-api-google-tag-manager-head /> {{-- ... --}} </head> <body> <x-conversions-api-google-tag-manager-body /> {{-- ... --}} </body> </html>
此包提供了一个视图组件,将所有来自 ConversionsApi
的用户数据映射到 dataLayer 变量
<x-conversions-api-data-layer-user-variable />
例如,当设置电子邮件地址时,它将被自动映射到dataLayer变量。查看视图组件的源代码以查看所有可能的变量列表。
ConversionsApi::setUserData( (new UserData())->setEmail('john@example.com') );
window.dataLayer.push({"conversionsApiUserEmail": "john@example.com"});
现在,您的Pixel通过GTM已正确初始化,是时候发送一些事件了。一个简单的方法是通过扩展FacebookAds\Object\ServerSide\Event
类并在其上实现Esign\ConversionsApi\Contracts\MapsToDataLayer
接口
use Esign\ConversionsApi\Contracts\MapsToDataLayer; use Esign\ConversionsApi\Facades\ConversionsApi; use FacebookAds\Object\ServerSide\ActionSource; use FacebookAds\Object\ServerSide\Event; class PurchaseEvent extends Event implements MapsToDataLayer { public static function create(): static { return (new static()) ->setActionSource(ActionSource::WEBSITE) ->setEventName('Purchase') ->setEventTime(time()) ->setEventSourceUrl(request()->fullUrl()) ->setEventId((string) Str::uuid()) ->setUserData(ConversionsApi::getUserData()); } public function getDataLayerArguments(): array { $customData = $this->getCustomData(); return [ 'event' => 'conversionsApiPurchase', 'conversionsApiPurchaseEventId' => $this->getEventId(), 'conversionsApiPurchaseCurrency' => $customData?->getCurrency(), 'conversionsApiPurchaseValue' => $customData?->getValue(), ]; } }
您现在可以将实现MapsToDataLayer
接口的任何类传递给负责跟踪Facebook Pixel事件的视图组件
use FacebookAds\Object\ServerSide\CustomData; use Illuminate\Support\Str; $event = PurchaseEvent::create()->setCustomData( (new CustomData())->setCurrency('EUR')->setValue(10) );
<x-conversions-api-data-layer-variable :event="$event" />
这将渲染以下脚本标签
<script> window.dataLayer.push({ "event": "conversionsApiPurchase", "conversionsApiPurchaseEventId": "e2481afc-5af4-4483-bc4b-33f08e195e3a", "conversionsApiPurchaseCurrency": "EUR", "conversionsApiPurchaseValue": 120 }); </script>
要获取实现MapsToDataLayer
接口的所有事件的列表,您可以调用filterDataLayerEvents
方法
@foreach(ConversionsApi::getEvents()->filterDataLayerEvents() as $event) <x-conversions-api-data-layer-variable :event="$event" /> @endforeach
如果您想对渲染的内容有更多控制,您始终可以使用匿名组件
<x-conversions-api::data-layer-variable :arguments="[]" />
页面视图事件
该包附带一些帮助器,用于自动发送Conversions API和Facebook Pixel事件,并提供事件去重。
注意 确保在包含这些视图组件之前,您已经遍历了ConversionsApi上定义的任何其他事件。包含这些视图组件将清除现有的事件。
如果您直接使用Facebook Pixel
<x-conversions-api-facebook-pixel-page-view />
或使用Google Tag Manager。用于事件去重的data-layer变量称为conversionsApiPageViewEventId
。
<x-conversions-api-data-layer-page-view />
故障排除
页面视图事件在测试事件仪表板中没有显示为去重
由于事件名称和事件ID参数已提供,页面视图事件的去重应该默认正常。然而,当在本地运行应用程序时,Laravel的request()->ip()
返回的IP地址将是127.0.0.1
。这与通过Facebook Pixel发送的IP地址不同,导致Conversions API和Facebook Pixel事件没有去重。一旦应用程序在生产环境中运行,此问题应该会自行解决。
Laravel中白名单Cookies
当在\App\Http\Kernel::class
中使用\App\Http\Middleware\EncryptCookies::class
时,请确保将_fbp和_fbc cookies列入白名单,以防止在加载DefaultUserData::create()
时出现null值。如下所示更新EncryptCookies中间件的$except属性
<?php namespace App\Http\Middleware; use Illuminate\Cookie\Middleware\EncryptCookies as Middleware; class EncryptCookies extends Middleware { /** * The names of the cookies that should not be encrypted. * * @var array */ protected $except = [ '_fbp', '_fbc' ]; }
测试
composer test
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。