This package provides:
- A Laravel Facade wrapper for the HubSpot API PHP Library.
- A customizable webhook (
/api/hubspot/webhook) to receive contact updates from HubSpot. - An event-driven sync system (
SyncHubspotContactListener) to automatically sync contacts from HubSpot to Laravel.
This package is a quick-start solution for integrating HubSpot contacts into a Laravel + Filament sales pipeline.
Install the package via Composer:
composer require visualbuilder/filament-hubspotPublish the config file:-
php artisan vendor:publish --tag="filament-hubspot-config"If you wish to use the provided lead model then run the install command to setup the migration
php artisan filament-hubspot:install- Go to HubSpot > Settings > Account Management > Integrations.
- Navigate to Connected Apps or Private Apps.
- Generate an Access Token and Client Secret.
HUBSPOT_ACCESS_TOKEN=pat-eu1-xxxxx
HUBSPOT_CLIENT_SECRET=xxxxx-xxx-xxxxxTesting the connection. The HubSpot API should now be available on the HubSpot Facade. You can test with tinker or in a console command:-
$response = HubSpot::crm()->contacts()->basicApi()->getPage();
foreach ($response->getResults() as $contact) {
dump($contact->getProperties());
}On your app, add the events that should trigger a webhook and point to yourdomain.com/api/hubspot/webhook
For local testing of webhooks use ngrok or smee to route requests to your local server
ngrok http localhost:80Which should provide a url which can be used in HubSpot:-
Forwarding https://a5ed-18-170-5-16.ngrok-free.app -> http://localhost:80Paste this URL into the Hubspot App webhooks section and define your events to trigger call. On this page you can send a test webhook.
Ngrok should output something like
05:20:45.763 GMT POST /api/hubspot/webhook 200 OKThis indicates the POST has been received and validated and the HubspotWebhookReceived Event will be triggered
The provided SyncHubspotContactListener will be called each time the Webhook is received.
Add your own custom Listeners in the config
/**
* What to do when a webhook is received
*/
'listeners' => [
Visualbuilder\FilamentHubspot\Events\HubspotWebhookReceived::class => [
Visualbuilder\FilamentHubspot\Listeners\SyncHubspotContactListener::class,
// Additional listeners can be added here...
],
],If you are getting 401 Unauthorized, check the keys and your server time. Valid requests must be within 5 minutes so clocks must be correct.
Set your model that should receive the HubSpot Contact and set which attributes to update.
/*
|--------------------------------------------------------------------------
| HubSpot Webhook Options
|--------------------------------------------------------------------------
| Enabling adds a route at /api/hubspot/webhook
| Valid requests will trigger an event HubspotWebhookReceived
|
*/
'webhook' => [
'enabled' => env('HUBSPOT_WEBHOOK_ENABLED', true),
'slug' => env('HUBSPOT_WEBHOOK_SLUG', 'api/hubspot/webhook'),
/**
* Replace this with your own Contact Model preference
*/
'local_contact_model' => \App\Models\Lead::class,
'match_on_attribute' => [
'hubspot' => 'email',
'localModel' => 'email'
], /*
|--------------------------------------------------------------------------
| HubSpot Contact to local Model mappings
|--------------------------------------------------------------------------
| Setup hubspot fields => model attribute mapping
| These fields will be requested from hubspot, the values are the model mappings
|
*/
'mappings' => [
'firstname' => ['attribute' => 'first_name'],
'lastname' => ['attribute' => 'last_name'],
'email' => ['attribute' => 'email'],
'company' => ['attribute' => 'company'],
'website' => ['attribute' => 'website'],
'jobtitle' => ['attribute' => 'job_title'],
'message' => ['attribute' => 'message'],
'lastmodifieddate' => ['attribute' => 'updated_at'],
'lifecyclestage' => ['attribute' => null],
'hs_object_id' => ['attribute' => 'hs_id'],
// Relations can be added and auto created if not existing
// in this case leadsource may contain LinkedIn, Facebook etc as a string and will populate a related model if the source is not found
'leadsource' => [
'relation' => 'leadSource',
'lookup_field' => 'name', // the column to find or create related model
'foreign_key' => 'lead_source_id', // optional, otherwise inferred automatically
'not_found_action' => 'create', // use ignore or create missing lookup relation
],
],composer testPlease see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.