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 migrateAdd 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 ProfileAdd 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 getHubspotProperties() to add dynamic or computed properties. The hubspot:sync-properties command discovers property keys from your map, hubspotProperties(), and getHubspotProperties(), so you only need to override this method for your dynamic keys to be created in HubSpot.
class User extends Authenticatable implements HubspotModelInterface
{
use HubspotContact;
public function getHubspotProperties(array $map): array
{
return [
'full_name' => $this->first_name . ' ' . $this->last_name,
'display_name' => $this->getDisplayName(),
'account_age_days' => $this->created_at->diffInDays(now()),
];
}
}When the model has no id (e.g. hubspot:sync-properties uses new User() to discover keys), return the same keys with null values so the command can build the full list without running user-specific queries.
If you need to customize the full property set (e.g. computed values that replace or extend map-based properties), you can instead override hubspotProperties() using trait aliasing: alias the trait method (e.g. hubspotProperties as traitHubspotProperties), call $this->traitHubspotProperties($map), merge your properties, and return.
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=100Note: Without observers, models will only sync when you explicitly run these commands.
Create the property group and properties in HubSpot:
php artisan hubspot:sync-propertiesThe 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=60Run 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.readcrm.objects.contacts.writecrm.objects.companies.readcrm.objects.companies.write
-
Sync test properties:
export HUBSPOT_TEST_API_KEY=your_test_api_key_here
php artisan hubspot:sync-propertiesSwitch 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.