wazza/sync-model-to-crm
辅助包,用于简化 Laravel 模型(例如 `User`、`Entity` 等)与外部 CRM 对象(例如 HubSpot/Pipedrive 的 `Contact`、`Company` 等)的数据同步
Requires
- php: ^8.1
- ext-json: *
- guzzlehttp/guzzle: ^7.4
- hubspot/api-client: ^10.1
- illuminate/support: ~10
Requires (Dev)
- fakerphp/faker: ^1.20.0
- laravel/legacy-factories: ~1
- mockery/mockery: ^1.2
- orchestra/testbench: ~8
- pestphp/pest: ^2.34
- pestphp/pest-plugin-laravel: ^2.4
This package is auto-updated.
Last update: 2024-09-06 12:01:49 UTC
README
同步模型到远程 CRM 对象
一个库,可以将任何定义的数据库表属性/关联(在模型内部)同步到外部 CRM 提供商,例如 HubSpot、Pipedrive 等。
步骤:在 Laravel 模型中添加一些属性配置,通过观察器或模型修改器配置同步触发,并监控日志以查看数据如何自动与 HubSpot 对象(如客户)同步。您还可以通过事件作业触发同步过程。
当前支持
- HubSpot
- 本地
User
与Contact
对象的同步。 - 本地
Entity
与Company
对象的同步。 Contact
和Company
记录之间的关联。- 即将推出...
Deal
&Ticket
对象。
- 本地
- 未来支持
- Pipedrive
- Salesforce
- ZohoCrm
- 等。
概述
这个库的目的是让开发者能够轻松地在每个适用的模型(如 User
、Entity
、Order
等)中定义哪些属性应该与哪个 CRM 提供商和环境同步。
在每次首次成功同步后,CRM 对象的主键将存储在映射表中,与本地表的主键相对应。这允许未来更改时更快地加载。
使用 7 个属性更新您的模型,以定义第三方 CRM 同步的规则
- @var string|array|null
$syncModelCrmEnvironment
;如果没有提供,将使用
config('sync_modeltocrm.api.environment')
。 - @var array
$syncModelCrmPropertyMapping
; *必需 - @var array
$syncModelCrmUniqueSearch
; *必需 - @var string
$syncModelCrmRelatedObject
;如果没有提供,将使用
config('sync_modeltocrm.api.providers.{provider}.object_table_mapping')
。 - @var array
$syncModelCrmDeleteRules
; *必需用于删除操作 - @var array
$syncModelCrmActiveRules
; *必需用于恢复操作 - @var array
$syncModelCrmAssociateRules
; *必需当关联为 true 时
以下是一个示例
User
模型将同步到Sandbox
和Production
HubSpot 环境($syncModelCrmEnvironment)。- 它将只同步
name
和email
属性到 HubSpot 对应的firstname
和email
字段($syncModelCrmPropertyMapping)。 - 当没有内部映射已存储时,将使用
email
属性($syncModelCrmUniqueSearch)唯一加载 CRM 记录。 - 为了让脚本知道哪个远程 CRM 对象与用户模型相关,必须将
contact
($syncModelCrmRelatedObject) 定义为远程项。 - ($syncModelCrmDeleteRules)属性用于指导 CRM 当本地记录被删除/移除时采取什么操作。例如,当本地启用 SoftDeletes 时,CRM 将使用
soft_delete
规则更新 CRM 记录,或者将记录存档在 CRM 中。 - 与上述相反,($syncModelCrmActiveRules) 将用于定义删除的记录再次激活时要采取的操作。
- 最后,非必填属性 ($syncModelCrmAssociateRules) 用于定义对象之间的关系(关联)。例如,从
user
到entity
。
<?php namespace App\Models; // use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; use App\Models\Entity; use Illuminate\Database\Eloquent\SoftDeletes; use Wazza\SyncModelToCrm\Http\Controllers\CrmProviders\HubSpotController; use Wazza\SyncModelToCrm\Traits\crmTrait; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable, SoftDeletes; // include this if you wish to use the `Mutators function` or // $this->syncToCrm() directly as appose to the observer method use crmTrait; /** * The attributes that are mass assignable. * * @var array<int, string> */ protected $fillable = [ 'name', 'email', 'password', ]; /** * The attributes that should be hidden for serialization. * * @var array<int, string> */ protected $hidden = [ 'password', 'remember_token', ]; /** * The attributes that should be cast. * * @var array<string, string> */ protected $casts = [ 'email_verified_at' => 'datetime', 'password' => 'hashed', ]; /** * Function that will be used to return the relationship data * @return type */ public function entity() { return $this->belongsTo(Entity::class)->withTrashed(); } // -------------------------------------------------------------- // Sync Model to CRM // -------------------------------------------------------------- /** * The CRM provider environment/s to use (e.g. production, sandbox, etc.) * Use an array to sync to multiple environments. * `null` (or not defined) will take the default from the config file. * * @var string|array|null */ public $syncModelCrmEnvironment = ['sandbox']; // ..or ['sandbox','production'] /** * Mapping array for local and CRM properties * This will be the primary property used to cycle through the crm providers * and properties to sync the model to the CRM. * Required - if not provided, the sync will process will be skipped (no Exceptions will be thrown) * * @var array */ public $syncModelCrmPropertyMapping = [ 'hubspot' => [ 'name' => 'firstname', 'email' => 'email', // ... add all the properties that you would like to sync ], ]; /** * Unique filters for the CRM to locate the record if there is no internal mapping available. * Not required, but strongly encouraged to be configured as to avoid any duplicate record creation in the crm * * @var array */ public $syncModelCrmUniqueSearch = [ 'hubspot' => [ 'email' => 'email', // this will ensure that the search filter is unique ], ]; /** * The CRM object to sync this model to. * This is the CRM object type (e.g. contact, company, deal, etc.) * If this is null or not provided, the `object_table_mapping` key will be used from the config file. * * @var string */ public $syncModelCrmRelatedObject = 'contact'; /** * The CRM Delete rules to follow. * i.e. if Soft-delete is applicable, what should the CRM record be updated to? * if Hard-delete is used, the record will be deleted/archived in the CRM. * * @var array */ public $syncModelCrmDeleteRules = [ 'hard_delete' => [ 'hubspot' => false, ], 'soft_delete' => [ 'hubspot' => [ 'lifecyclestage' => 'other', 'hs_lead_status' => 'DELETED', ], ] ]; /** * The CRM Active/Restore rules to follow. * These will be the rules to follow for any new entries that are not soft-deleted. * * @var array */ public $syncModelCrmActiveRules = [ 'hubspot' => [ 'lifecyclestage' => 'customer', 'hs_lead_status' => 'OPEN', ], ]; /** * The CRM Associations to sync. * This is used to associate the model with other CRM objects. * * @var array */ public $syncModelCrmAssociateRules = [ [ 'assocMethod' => 'entity', // App\Models\Entity::class 'provider' => [ 'hubspot' => [ [ 'association_category' => HubSpotController::ASSOCIATION_CATEGORY__HUBSPOT_DEFINED, 'association_type_id' => HubSpotController::ASSOCIATION_TYPE_ID__CONTACT_TO_COMPANY_PRIMARY, ], [ 'association_category' => HubSpotController::ASSOCIATION_CATEGORY__HUBSPOT_DEFINED, 'association_type_id' => HubSpotController::ASSOCIATION_TYPE_ID__CONTACT_TO_COMPANY, ], ], ], ], ]; // -------------------------------------------------------------- // Custom Methods to initiate a sync // -------------------------------------------------------------- /** * (1) Register the observer in the AppServiceProvider boot method * * public function boot(): void * { * // register the observer/s * // ...refer the the template examples in the sync-model-to-crm repo for a observer working copy * \App\Models\User::observe(\App\Observers\UserObserver::class); * } */ /** * (2) Mutators function (Laravel 5.4 or above) * * Laravel provides mutators which are methods that can be defined on a model to modify * attributes before they are saved. You can create a custom mutator named save that * first calls the original save method using parent::save() and then performs your * additional action. * * @param array $options * @return void */ public function save(array $options = []) { parent::save($options); // lets call the syncModelToCrm method to sync the model to the CRM. // refer to the trait for all the available methods // $this->syncToCrmPatch(); -- disabled as we are currently using the observer method } }
用法
您可以使用几种方法来启动模型同步。
执行 (new CrmController())->setModel($user)->execute();
-
直接在控制器操作中。
-
在模型中使用特性作为类型化函数。
-
通过观察者。例如,在 UserObserver 中触发 save() 事件之后。(见下文)
<?php namespace App\Observers; use App\Models\User; use Wazza\SyncModelToCrm\Http\Controllers\CrmController; use Illuminate\Contracts\Events\ShouldHandleEventsAfterCommit; /** * Register the observer in the AppServiceProvider boot method * * public function boot(): void * { * // register the observer/s * \App\Models\User::observe(\App\Observers\UserObserver::class); * } */ class UserObserver implements ShouldHandleEventsAfterCommit { /** * Handle the User "created" event. */ public function created(User $user): void { echo ('create...'); (new CrmController()) ->setModel($user) ->setAttemptCreate() ->execute(true); echo ('created...'); } /** * Handle the User "updated" event. */ public function updated(User $user): void { echo ('update...'); (new CrmController()) ->setModel($user) ->setAttemptUpdate() ->execute(true); echo ('updated...'); } /** * Handle the User "deleted" event. * Run when a user is soft-deleted. */ public function deleted(User $user) { echo ('delete...'); (new CrmController()) ->setModel($user) ->setAttemptDelete() ->execute(); echo ('deleted...'); } /** * Handle the User "restored" event. * Soft-delete has been reversed. */ public function restored(User $user): void { echo ('restore...'); (new CrmController()) ->setModel($user) ->setAttemptRestore() ->execute(); echo ('restored...'); } /** * Handle the User "force deleted" event. */ public function forceDeleted(User $user): void { echo ('forceDeleted...'); } /** * Handle the User "saved" event. * */ public function saved(User $user): void { echo ('saving...'); (new CrmController()) ->setModel($user) ->setAttemptAll() // open for anything... ->execute(); echo ('saved...'); } }
-
在事件作业中。这是一种将逻辑从保存事件中分离出来,并将同步放入作业队列以在记录保存后立即处理的好方法。
安装
PHP 8.1 是本项目的最低要求。
-
打开终端并要求包。
composer require wazza/sync-model-to-crm
-
导航到您的 Laravel 项目的
config
目录并打开app.php
文件。-
在
app.php
文件中查找providers
数组。 -
在
providers
数组中,添加以下行并保存:Wazza\SyncModelToCrm\Providers\SyncModelToCrmServiceProvider::class,
以下为示例'providers' => ServiceProvider::defaultProviders()->merge([ /* * Package Service Providers... */ Wazza\SyncModelToCrm\Providers\SyncModelToCrmServiceProvider::class, // <-- here Wazza\DomTranslate\Providers\DomTranslateServiceProvider::class, /* * Application Service Providers... */ App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, // App\Providers\BroadcastServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, ])->toArray(),
-
-
再次在终端中,通过运行以下命令完成设置:
php artisan vendor:publish --tag="sync-modeltocrm-config" php artisan vendor:publish --tag="sync-modeltocrm-migrations" php artisan migrate
-
以下是您可以添加到 .env 配置文件中的一些环境键。如果您需要更多关于每个项目的信息,请参阅
config/sync_modeltocrm.php
配置文件。SYNC_MODEL_TO_CRM_HASH_SALT=Ey4cw2BHvi0HmGYjyqYr SYNC_MODEL_TO_CRM_HASH_ALGO=sha256 SYNC_MODEL_TO_CRM_LOG_INDICATOR=sync-modeltocrm SYNC_MODEL_TO_CRM_LOG_LEVEL=3 SYNC_MODEL_TO_CRM_PROVIDER=hubspot SYNC_MODEL_TO_CRM_ENVIRONMENT=sandbox SYNC_MODEL_TO_CRM_PROVIDER_HUBSPOT_SANDBOX_URI=https://api.hubapi.com/crm/v4/ SYNC_MODEL_TO_CRM_PROVIDER_HUBSPOT_SANDBOX_TOKEN=xxx-xxx-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
-
在修改完 env 变量后,运行
config:cache
。php artisan config:cache
-
完成。审查您可能想要更改的任何配置文件更改。配置文件已发布到主配置文件夹。
查看日志
根据您的日志级别(参考您的配置文件设置:1:高到 3:低),您的 Laravel 日志文件将写入更少或更多的信息。
您可以通过运行 tail -f {log path}
跟踪事务,甚至可以包含带有唯一事务 8 位代码的 grep
。
测试
运行以下命令以执行测试
./vendor/bin/pest
输出示例
PASS Tests\Unit\EnvTest ✓ it should have the correct environment variables set 1.11s PASS Tests\Unit\ExampleTest ✓ it contains a successful example unit test 0.33s PASS Tests\Unit\ModelTest ✓ it can create a new SmtcExternalKeyLookup model record 0.31s ✓ it can mass assign data to the SmtcExternalKeyLookup model 0.25s ✓ it can update the SmtcExternalKeyLookup model record 0.35s PASS Tests\Feature\ExampleTest ✓ it contains a successful example feature test 0.24s Tests: 6 passed (25 assertions) Duration: 3.84s
注意:下一版本将包含更多测试。