ไลบรารี PHP นี้มี
นอกจากนี้ยังมีตัวอย่าง/คลาสบางส่วนที่ใช้กระบวนการซิงโครไนซ์ข้อมูลผู้ติดต่อจากระบบต้นทางไปยังฐานข้อมูลผู้ติดต่อ/ลูกค้าเป้าหมายของ Sharpspring ซึ่งใช้งานได้กับแคชภายในเครื่องของ Sharpspring Lead เพื่อลดการโทรอัปเดตไปยัง Sharpspring REST API
คลาสไคลเอนต์สามารถใช้แบบสแตนด์อโลนได้ แม้ว่าไลบรารีนี้จะไม่ได้เขียนขึ้นเพื่อสิ่งนั้นก็ตาม หากคุณต้องการดูแลการสร้างพารามิเตอร์ของคุณเองและถอดรหัสผลลัพธ์ด้วยตัวเอง: ดำเนินการต่อ ยกตัวอย่าง; เรียกเมธอด call() คุณไม่จำเป็นต้องมีส่วนที่เหลือของห้องสมุด
จุดมุ่งหมายของคลาส Connection คือ ช่วยให้คุณไม่สับสนเกี่ยว กับการสื่อสารกับ REST API ของ Sharpspring มันพยายามช่วยในเรื่องนี้ด้วยวิธีต่อไปนี้:
(คลาส 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 เป็นอาร์กิวเมนต์ที่สองไปยังตัวสร้างการเชื่อมต่อ
ใน 'วัตถุ' (อาร์เรย์) ของ Sharpspring REST API ฟิลด์ที่กำหนดเองจะถูกอ้างอิงโดยชื่อระบบ ซึ่งเปลี่ยนแปลงต่อบัญชี หากต้องการเปิดใช้งานการเขียนโค้ดทั่วไปมากขึ้น วัตถุการเชื่อมต่อมีการแมปจากคุณสมบัติแบบกำหนดเองไปยังชื่อระบบฟิลด์ เมื่อตั้งค่าการแมปนี้ (ด้วยชื่อคุณสมบัติที่คุณเลือกเอง) พารามิเตอร์ 'ออบเจ็กต์' ใดๆ ในการเรียก REST API จะมีชื่อคุณสมบัติที่กำหนดเองแปลเป็นชื่อระบบฟิลด์ที่เกี่ยวข้องโดยอัตโนมัติ
สมมติว่าคุณมีโอกาสในการขายสำหรับร้านขายรองเท้าของคุณ โดยมีฟิลด์ที่กำหนดเองสำหรับขนาดรองเท้าที่คุณสร้างผ่าน Sharpspring UI ซึ่งมีชื่อระบบออกมาเป็น shoe_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 ซึ่งใช้ฟิลด์ที่รู้จักทั้งหมด (พร้อมความคิดเห็นเกี่ยวกับตำแหน่งที่เอกสาร API ของ Sharpspring ล้าสมัย)
ตัวอย่างต่อไปนี้เท่ากับด้านบน:
/**
* 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 ไม่ทราบสิ่งใดเกี่ยวกับการแมปคุณสมบัติกับชื่อระบบฟิลด์ วัตถุการเชื่อมต่อจะจัดการสิ่งนี้สำหรับการดำเนินการสร้าง/อัปเดต และหลังจากการดำเนินการ 'รับ' คุณจะต้องแปลงกลับเป็นชื่อคุณสมบัติที่กำหนดเองอย่างชัดเจนก่อนที่จะสร้างวัตถุ
นอกจากนี้ยังมีวิธีอื่น: คุณสามารถตั้งค่าการแมปใน ValueObject แทนการเชื่อมต่อ
$ 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 );
ดังนั้น: สำหรับ ValueObjects ที่มีฟิลด์ที่กำหนดเอง จะมีตัวเลือกในการตั้งค่าการแมปการเชื่อมต่อ หรือตั้งค่าใน 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 จะละทิ้งการอัปเดตอย่างเงียบ ๆ แต่ยังคงรายงานความสำเร็จ นี่เป็นปัญหาที่อาจเกิดขึ้นหากคุณกำลังจำลองฐานข้อมูลผู้ติดต่อที่มีอยู่ซึ่งที่อยู่อีเมลไม่จำเป็นต้องซ้ำกันใน Sharpspring คุณจะต้องตรวจสอบการอัปเดตของคุณอีกครั้งเพื่อดูว่าอัปเดตสำเร็จหรือไม่ (ตัวอย่างหนึ่งของโค้ดดังกล่าวอยู่ใน SharpspringSyncJob::finish().)
(ฉันยินดีเป็นอย่างยิ่งที่ได้รับรายงานเกี่ยวกับข้อบกพร่องเหล่านี้ที่ได้รับการแก้ไขแล้ว โปรดดูที่ 'คำเตือน')
เห็นได้ชัดว่า Sharpspring บางครั้งเปลี่ยนพฤติกรรมของ API โดยไม่มีการประกาศหรือเอกสารประกอบ / บันทึกการเปลี่ยนแปลง (ซึ่งพวกเขาไม่ได้ทำเลยตามความรู้ของฉัน) และแม้จะไม่เพิ่มเวอร์ชัน API ที่กล่าวถึงในเอกสาร API ออนไลน์ที่สามารถพบได้หลังการเข้าสู่ระบบ เว็บไซต์ลูกค้าของพวกเขา
ดูเหมือนว่าสิ่งที่จะได้รับจากสิ่งนี้ก็คือในฐานะนักพัฒนาแอปพลิเคชัน คุณควรทดสอบแอปพลิเคชันของคุณอย่างต่อเนื่อง เพราะคุณไม่สามารถไว้วางใจ Sharpspring ที่จะไม่ละเมิด 'สัญญาโดยนัย' กับคุณ เนื่องจาก Sharpspring เห็นได้ชัดว่าไม่รู้สึกว่าพวกเขามี 'สัญญาโดยนัย' กับผู้พัฒนาแอปพลิเคชัน
(ฉันมีความรู้สึกน่าสงสัยเกี่ยวกับเรื่องนี้ในขณะที่ฉันกำลังพัฒนาไลบรารีนี้ตลอดระยะเวลาครึ่งปี แต่สิ่งที่ฉันยึดถือคือการเปลี่ยนแปลงพฤติกรรมของการเรียก getLeadsDateRange (โดยตั้งค่าพารามิเตอร์ 'การประทับเวลา' เป็น "อัปเดต") - ซึ่งเปลี่ยนทั้งรูปแบบของวันที่ในพารามิเตอร์และเอาต์พุต และเนื้อหาของเอาต์พุต ซึ่งนำไปสู่ผลกระทบทันที - รายงานข้อผิดพลาด - ในระบบที่ใช้งานจริงซึ่งใช้ SharpspringSyncJob ซึ่งจะต้องมีการแพตช์ฉุกเฉิน เวอร์ชัน API ที่เผยแพร่ยังคงเป็น 1.117 และนับตั้งแต่อย่างน้อยเดือนพฤศจิกายน 2559
การเปลี่ยนแปลงพฤติกรรมอาจเกิดจากความไม่สอดคล้องกันที่ฉันรายงาน (ฉันมีการแลกเปลี่ยนอีเมลสั้นๆ ซึ่งจบลงด้วยการที่ฉันส่งรายการปัญหาที่พบกับ API ของพวกเขา) และฉันดีใจที่พวกเขากำลังแก้ไขความไม่สอดคล้องกัน แต่ขาด ของการตอบกลับ บันทึกการเปลี่ยนแปลง หรือการเปลี่ยนแปลงเวอร์ชันของ API ยังคงนำไปสู่ประเด็นข้างต้น ฉันหวังว่าสิ่งนี้จะมีการเปลี่ยนแปลงในอนาคต และคำเตือนนี้อาจถูกลบออกไปแล้ว แต่ดูเหมือนว่าจะเกี่ยวข้องจริงๆ ในตอนนี้)
โอ้ดูสิ! https://help.sharpspring.com/hc/en-us/articles/115001069228-Open-API-Overview ตอนนี้กล่าวถึงว่าพวกเขามี API 'v1' และ API 'v1.2'! ประการที่สองยอมรับการป้อนข้อมูลวันที่เป็น UTC (ซึ่งเป็นสิ่งที่ API v1 ของพวกเขาทำจนถึงประมาณปี 2017 วันที่ 26 กรกฎาคม) ไม่มีการเอ่ยถึงรูปแบบของวันที่ส่งออก (ซึ่งมีการเปลี่ยนแปลงในเวอร์ชัน 1 ด้วย) ดังนั้นจึงจำเป็นต้องมีการทดสอบ ปัจจุบันไลบรารีนี้ใช้งานเฉพาะ API v1 และควรขยาย ไม่อยู่ในรายการโปรดของฉัน ดังนั้นจึงยินดีรับ PR (หรืองานที่ได้รับค่าตอบแทน ;))
รหัสนี้ได้รับการทดสอบกับ Leads และ ListMembers มีการเรียก API มากขึ้น แต่ไม่ใช่ทั้งหมดที่ได้รับการทดสอบอย่างกว้างขวาง และบางส่วนยังขาดหายไป หวังว่าการเพิ่มการโทรใหม่จะไม่ใช่งานมากนัก ยินดีรับคำขอดึง
เพียงส่งประชาสัมพันธ์หรือติดต่อฉัน
'กระบวนการสร้าง' (ดูไอคอนที่ด้านบน ข้อความที่ผ่าน/ล้มเหลวที่คล้ายกันจะปรากฏบน PR) กำลังตรวจสอบมาตรฐานการเข้ารหัสกับ PHP5.6 / PSR2 เท่านั้น ยังไม่มีการทดสอบหน่วยเนื่องจากนี่เป็นเพียงชั้นโค้ดบาง ๆ ที่พันรอบ Sharpspring บอกฉันหากคุณคิดว่าควรมีการทดสอบและอะไร / เพราะเหตุใด (คงจะดีไม่น้อยถ้ามีชุดการทดสอบเต็มรูปแบบกับ Sharpspring API แบบสด แต่ฉันเดาว่านั่นเป็นปัญหาที่แตกต่างออกไปและ/หรืออย่างน้อยก็ต้องมีการประสานงานเพิ่มเติมกับพวกเขา...)
ฉันชอบแบ่งปันซอฟต์แวร์โอเพ่นซอร์สให้กับโลก และฉันชอบเปิดระบบที่ไม่มีเอกสารกึ่งปิด แจ้งให้ฉันทราบหากสิ่งนี้มีประโยชน์หรือหากคุณมีส่วนร่วม ติดต่อฉันหากคุณต้องการงานบูรณาการให้เสร็จสิ้น (ฉันมีประสบการณ์กับระบบอื่น ๆ มากมาย)
ไลบรารีนี้ได้รับอนุญาตภายใต้ใบอนุญาต MIT - ดูรายละเอียดในไฟล์ LICENSE.md