這個 PHP 函式庫包含
它還包含幾個範例/部分類,用於實現聯絡人資料從來源系統到 Sharpspring 的聯絡人/線索資料庫的同步過程。這與 Sharpspring 線索的本機快取配合使用,以最大限度地減少對 Sharpspring REST API 的更新呼叫。
客戶端類別可以獨立使用,儘管這個函式庫不是為此編寫的。如果您想自行建立參數並自行解碼結果:請繼續。實例化它;呼叫 call() 方法。您不需要圖書館的其餘部分。
Connection 類別的目的是幫助您在與 Sharpspring 的 REST API 通訊時不會感到困惑。它試圖透過以下方式幫助解決這個問題:
(這裡不討論 LocalLeadCache 類別。)
use SharpSpring RestApi Connection ;
use SharpSpring RestApi CurlClient ;
// One thing this library does not make super easy: starting. Separation of
// concerns is considered more important, so (since the actual API call was
// abstracted into CurlClient) creating a new connection takes 2 lines instead
// of 1:
$ client = new CurlClient ([ ' account_id ' => . . . , ' secret_key ' => . . . ]);
$ api = new Connection ( $ client );
// Get all leads updated after a certain time (notation in 'local' timezone,
// though there is no formal definition of what 'local' entails).
$ leads = $ api -> getLeadsDateRange ( ' 2017-01-15 10:00:00 ' );
該程式碼會針對遇到的任何奇怪情況拋出異常...除了一件事:除了您正在呼叫的特定API/連接方法所期望的數組值之外,它還會在回應中看到額外的屬性。預設情況下這些會被忽略;預計永遠不會遇到他們。如果您希望記錄這些內容,請將 PSR-3 相容記錄器物件作為第二個參數傳遞給 Connection 建構子。
在 Sharpspring REST API「物件」(陣列)中,自訂欄位透過其係統名稱來引用,該系統名稱會根據帳戶而變更。為了能夠編寫更通用的程式碼,Connection 物件具有從自訂屬性到欄位系統名稱的對應。設定此對應後(使用您自己選擇的屬性名稱),REST API 呼叫中的任何「物件」參數都會將其自訂屬性名稱自動轉換為對應的欄位系統名稱。
假設您有鞋店的銷售線索,其中包含透過 Sharpspring UI 創建的鞋碼自訂字段,其係統名稱為 Shoes_size_384c1e3eacbb3。以下兩個範例是等效的:
$ api -> createLead ([
' firstName ' => ' Roderik ' ,
' emailAddress ' => ' [email protected] ' ,
' shoe_size_384c1e3eacbb3 ' => 12 ,
]);
$ api -> setCustomProperties ( ' lead ' , [ ' shoeSize ' => ' shoe_size_384c1e3eacbb3 ' ]);
$ api -> createLead ([
' firstName ' => ' Roderik ' ,
' emailAddress ' => ' [email protected] ' ,
' shoeSize ' => 12 ,
]);
// Note that system names will still be OK; after setCustomProperties is called,
// you can still send in [...,'shoe_size_384c1e3eacbb3' => 12, ...]. Just don't
// set values for _both_ the field name _and_ its property alias, because then
// the library does not guarantee which of the two will be used.
自動轉換僅針對 API 呼叫參數中的「物件」進行。 API 呼叫傳回的結果不會被竄改。如果您希望將 API 結果中的自訂欄位系統名稱轉換回自訂屬性名稱,則需要明確執行此操作:
$ api -> setCustomProperties ( ' lead ' , [ ' shoeSize ' => ' shoe_size_384c1e3eacbb3 ' ]);
$ leads = $ api -> getLeads ([ ' emailAddress ' => ' [email protected] ' ]);
$ lead = reset ( $ leads );
$ my_lead = $ api -> convertSystemNames ( ' lead ' , $ lead );
使用陣列來表示 API「物件」就可以了。但您可能更喜歡為它們使用物件/類別。 (它為您提供了 IDE 自動完成功能,這也最大限度地減少了 REST API 無法處理的屬性名稱大寫錯誤的可能性)。
基底類別是 ValueObject,目前有一個 Lead 類別,它實作了所有已知欄位(帶有關於 Sharpspring 的 API 文件過時的地方的註解)。
以下範例與上面相同:
/**
* If you have custom fields, you will want to define your own subclass:
*/
class ShoeStoreLead extends Lead
{
// Define your own properties:
public $ shoeSize ;
}
$ api -> setCustomProperties ( ' lead ' , [ ' shoeSize ' => ' shoe_size_384c1e3eacbb3 ' ]);
// This is the create call from above. Note createLead() accepts ValueObjects as
// well as arrays.
$ lead = new ShoeStoreLead ();
$ lead -> firstName = ' Roderik ' ;
$ lead -> emailAddress = [email protected]';
$ lead -> shoeSize = 12 ;
$ api -> createLead ( $ lead );
// And this is the 'get' call which puts the result into a new object:
$ leads = $ api -> getLeads ([ ' emailAddress ' => ' [email protected] ' ]);
$ lead = reset ( $ leads );
$ my_lead = $ api -> convertSystemNames ( ' lead ' , $ lead );
$ my_lead_obj = new ShoeStoreLead ( $ my_lead );
顯然,如果您沒有任何自訂字段,那麼此範例會變得更加簡單(因為您不需要子類化 Lead 或使用 setCustomProperties() / ConvertSystemNames())。
在上面的範例中,ValueObject 不知道有關其屬性到欄位系統名稱的對應的任何資訊; Connection 物件為建立/更新作業處理此問題,在「取得」操作之後,您需要在建構物件之前將它們明確轉換回自訂屬性名稱。
還有另一種方法:您可以在 ValueObject 而不是 Connection 中設定映射。
$ mapping = [ ' shoeSize ' => ' shoe_size_384c1e3eacbb3 ' ];
// $api->setCustomProperties('lead', $mapping) is not called here.
// For create:
$ lead = new ShoeStoreLead ([], $ mapping );
$ lead -> firstName = ' Roderik ' ;
$ lead -> emailAddress = [email protected]';
$ lead -> shoeSize = 12 ;
$ api -> createLead ( $ lead );
// Note you could also add all the properties in the first argument of the
// constructor, instead of setting them individually - although that more or
// less defeats the purpose of using a ValueObject in the first place. Setting
// 'shoeSize' works just as well as 'shoe_size_384c1e3eacbb3', in that first
// argument. Just don't set values for _both_ the field name _and_ its property
// alias, because then the library does not guarantee which of the two will be
// used.
// For 'get':
$ leads = $ api -> getLeads ([ ' emailAddress ' => ' [email protected] ' ]);
$ lead = reset ( $ leads );
$ my_lead_obj = new ShoeStoreLead ( $ my_lead , $ mapping );
因此:對於具有自訂欄位的 ValueObject,可以選擇設定連接映射,或在 ValueObject 中設定。後者的優點是從 REST API 檢索的資料會在建構函式中自動轉換,但缺點是每次建構物件時都需要設定映射。
還有另一種方法:要麼對物件內部的映射進行硬編碼,例如:
// Override the parent's (empty) property mapping variable:
protected $_customProperties = ['shoeSize' => 'shoe_size_384c1e3eacbb3'];
……或讓您的自訂 ValueObject 子類別的建構子設定它(或從某個地方派生它)。這可能是針對您自己情況的程式碼。
選擇您自己喜歡的方法。
Sharpspring REST API 的大多數奇怪行為已被該庫記錄或部分緩解/隱藏。但是,如果您打算基於 API 進行認真的工作,那麼您至少應該了解一些事情,並決定是否需要考慮這些事情。
具有非標準字元的值(大致:將由 htmlspecialchars() 編碼的字元)在 Sharpspring 中的儲存方式有所不同,具體取決於它們是透過 REST API 插入還是透過 UI 輸入。 (對於 UI,標準欄位和自訂欄位之間的情況也有所不同。)「<」甚至更奇怪:它有時以雙重編碼儲存。血淋淋的細節在encoding.md。該程式庫能夠減輕這種行為的唯一方法是讓 CurlClient 始終對任何欄位進行 HTML 解碼,無論是否有必要。由於 HTML 解碼是透明進行的,因此您可能不會看到此行為,但認真的應用程式仍應考慮這是否是一個問題。
updateLead 呼叫可以透過提交(至少)現有的「id」值以及更改後的電子郵件地址來更改現有潛在客戶的電子郵件地址。但是,如果更改後的電子郵件碰巧已在另一個現有潛在客戶中使用,則 API 將默默地放棄更新,但仍會報告 success 。如果您將現有的聯絡人資料庫(其中電子郵件地址不一定是唯一的)鏡像到 Sharpspring 中,則這是一個潛在的問題。您需要仔細檢查更新以查看它們是否成功。 (此類程式碼的範例位於 SharpspringSyncJob::finish() 中。)
(我歡迎任何有關這些錯誤已修復的報告。它們可能;請參閱“警告”。)
Sharpspring 顯然有時會在沒有公告或文件/更改日誌的情況下更改其API 的行為(據我所知,他們根本沒有這樣做),甚至沒有增加在線API 文件中提到的API 版本,該文檔可以在登入後找到他們的客戶網站。
由此看來,作為應用程式開發人員,您應該不斷測試您的應用程序,因為您不能相信 Sharpspring 不會違反他們與您的「隱性合約」。因為 Sharpspring 顯然並不認為他們與應用程式開發人員有「隱性合約」。
(在半年的時間裡我開發這個庫時,我對此有一些可疑的感覺,但我的基礎是他們對 getLeadsDateRange 調用行為的改變(將“timestamp”參數設置為“更新”) - 它更改了參數和輸出中的日期格式以及輸出的內容,這會在使用SharpspringSyncJob 類別的生產系統中立即產生影響- 報告錯誤。
行為改變可能是由我報告的不一致引起的(我進行了一次簡短的電子郵件交流,最終我發送了他們的 API 遇到的問題清單),我很高興他們正在修復不一致的問題,但缺乏回應、變更日誌或API 版本變更仍然會導致上述結論。我當然希望這將來會改變,並且這個警告可能會被刪除,但現在看起來確實很相關。
哦,看! https://help.sharpspring.com/hc/en-us/articles/115001069228-Open-API-Overview 現在提到他們有一個「v1」API 和一個「v1.2」API!第二個顯然接受 UTC 日期輸入(這是他們的 v1 API 直到 2017 年 7 月 26 日左右所做的)。沒有提及輸出日期的格式(在 v1 中也發生了更改),因此需要測試。該庫目前僅支援 API v1,應該進行擴充。它不在我的候選名單上,因此歡迎 PR(或付費作業;))。
此程式碼已經過 Leads 和 ListMembers 的測試。有更多 API 調用,但並非所有調用都經過廣泛測試,有些仍缺失。新增的呼叫希望不是很多工作;歡迎拉取請求。
只需提交 PR 或以其他方式聯繫我。
「建置過程」(請參閱頂部的圖示;類似的通過/失敗訊息將出現在 PR 上)僅根據 PHP5.6 / PSR2 檢查編碼標準。目前還沒有單元測試,因為這只是 Sharpspring 周圍的一層薄薄的程式碼。告訴我您是否認為應該進行測試以及哪些/為什麼。 (顯然,對即時 Sharpspring API進行全套測試會很好,但我想這是一個不同的問題和/或至少需要與他們進一步協調...)
我喜歡向世界貢獻開源軟體,也喜歡開放半封閉、文件不足的系統。如果這有用或您有貢獻,請大聲告訴我。如果您需要完成整合工作,請與我聯絡。 (我有使用其他幾個系統的經驗。)
該庫已根據 MIT 許可證獲得許可 - 有關詳細信息,請參閱 LICENSE.md 文件。