A Laravel package for seamless integration with HubSpot CRM. Provides automatic synchronization of Laravel models with HubSpot contacts and companies, with support for queued operations.
composer require tapp/laravel-hubspot
php artisan vendor:publish --tag="laravel-hubspot-config"
php artisan vendor:publish --tag="hubspot-migrations"
php artisan migrate
Add your HubSpot API key to your .env
file:
HUBSPOT_ID=your_hubspot_id
HUBSPOT_TOKEN=your_api_key
HUBSPOT_DISABLED=false
HUBSPOT_LOG_REQUESTS=false
HUBSPOT_PROPERTY_GROUP=app_user_profile
HUBSPOT_PROPERTY_GROUP_LABEL=App User Profile
Add the trait to your User model, implement the required interface, and define the HubSpot property mapping:
use Tapp\LaravelHubspot\Models\HubspotContact;
use Tapp\LaravelHubspot\Contracts\HubspotModelInterface;
class User extends Authenticatable implements HubspotModelInterface
{
use HubspotContact;
public array $hubspotMap = [
'email' => 'email',
'first_name' => 'first_name',
'last_name' => 'last_name',
'user_type' => 'type.name', // Supports dot notation for relations
];
}
Important: Models must implement HubspotModelInterface
to enable automatic synchronization. This interface ensures your models have the required methods for HubSpot integration:
getHubspotMap()
- Returns the property mapping arraygetHubspotUpdateMap()
- Returns update-specific property mappinggetHubspotCompanyRelation()
- Returns the company relationship namegetHubspotProperties()
- Returns dynamic propertiesgetHubspotId()
/setHubspotId()
- Manages the HubSpot ID
The traits (HubspotContact
, HubspotCompany
) provide the implementation for these methods, so you only need to implement the interface and define your $hubspotMap
array.
For company models, use the HubspotCompany
trait:
use Tapp\LaravelHubspot\Models\HubspotCompany;
use Tapp\LaravelHubspot\Contracts\HubspotModelInterface;
class Company extends Model implements HubspotModelInterface
{
use HubspotCompany;
public array $hubspotMap = [
'name' => 'name',
'domain' => 'domain',
'industry' => 'industry',
];
}
Override the hubspotProperties
method for computed values using trait aliasing:
use Tapp\LaravelHubspot\Models\HubspotContact {
hubspotProperties as traitHubspotProperties;
}
class User extends Authenticatable implements HubspotModelInterface
{
use HubspotContact;
public function hubspotProperties(array $map): array
{
// Get the base properties from the trait
$properties = $this->traitHubspotProperties($map);
// Add computed properties
$properties['full_name'] = $this->first_name . ' ' . $this->last_name;
$properties['display_name'] = $this->getDisplayName();
$properties['account_age_days'] = $this->created_at->diffInDays(now());
return $properties;
}
}
Important: Observers are required for automatic synchronization. Register observers in your AppServiceProvider
to enable automatic sync when models are created/updated:
use App\Models\User;
use App\Models\Company;
use Tapp\LaravelHubspot\Observers\HubspotContactObserver;
use Tapp\LaravelHubspot\Observers\HubspotCompanyObserver;
public function boot(): void
{
User::observe(HubspotContactObserver::class);
Company::observe(HubspotCompanyObserver::class);
}
If you prefer manual control over when syncing occurs, you can use the provided commands instead of observers:
# Sync all contacts from a specific model
php artisan hubspot:sync-contacts App\Models\User
# Sync with options
php artisan hubspot:sync-contacts App\Models\User --delay=1 --limit=100
Note: Without observers, models will only sync when you explicitly run these commands.
Create the property group and properties in HubSpot:
php artisan hubspot:sync-properties
The package supports queued operations for better performance. Configure in your .env
:
HUBSPOT_QUEUE_ENABLED=true
HUBSPOT_QUEUE_CONNECTION=default
HUBSPOT_QUEUE_NAME=hubspot
HUBSPOT_QUEUE_RETRY_ATTEMPTS=3
HUBSPOT_QUEUE_RETRY_DELAY=60
Run queue workers:
php artisan queue:work --queue=hubspot
# Run all tests
composer test
# Run only unit tests (fast, no API calls)
composer test-unit
# Run only integration tests (requires HubSpot API key)
composer test-integration
# Run with coverage report
composer test-coverage
- Create
.env.testing
:
HUBSPOT_TEST_API_KEY=your_test_api_key_here
HUBSPOT_DISABLED=false
HUBSPOT_LOG_REQUESTS=true
HUBSPOT_PROPERTY_GROUP=test_property_group
HUBSPOT_QUEUE_ENABLED=false
-
Get HubSpot test API key with scopes:
crm.objects.contacts.read
crm.objects.contacts.write
crm.objects.companies.read
crm.objects.companies.write
-
Sync test properties:
export HUBSPOT_TEST_API_KEY=your_test_api_key_here
php artisan hubspot:sync-properties
Switch between mocked and real API calls:
# Run with mocks (fast, no API calls)
HUBSPOT_DISABLED=true composer test
# Run with real API calls (requires API key)
HUBSPOT_DISABLED=false composer test
- Quick Start Guide - Fast testing checklist
- Comprehensive Testing Guide - Detailed testing strategy
Please 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.
- [TappNetwork](https://github.com/Scott Grayson)
- All Contributors
The MIT License (MIT). Please see License File for more information.