6.5

XML Connector

Změny verze 6.0

Úvod

InTouch CRM umožňuje přijímat a zpracovávat data z jiných informačních systémů. Typickým příkladem je požadavek na vytvoření záznamu v InTouch CRM na základě údajů získaných prostřednictvím webového formuláře.

Nejběžnější scénář komunikace mezi webem a InTouch CRM může vypadat takto: zákazník vyplní na webu objednávku, web zašle požadavek na registraci zákazníka do InTouch CRM a v odpovědi dostane přidělený kód zákazníka - web zašle data objednávky do InTouch CRM a dostane zpět kód vytvořené objednávky - web oba kódy zobrazí zákazníkovi s oznámením o potvrzení objednávky.

Jak napovídá název kapitoly, veškerá komunikace mezi druhým informačním systémem a InTouch CRM probíhá pomocí XML zpráv. Pro přenos těchto zpráv je použit protokol HTTP(S), metoda POST. Modul, který komunikaci zajišťuje, se jmenuje XML Connector a je standardní součástí InTouch CRM.

Z předchozího odstavce vyplývá, že pro správnou funkčnost XML Connectoru je třeba mít na firewallu povolenou komunikaci mezi serverem s InTouch CRM a serverem s druhým informačním systémem. Standardní port HTTPS je 443. Pokud jste při instalaci zvolili jiný port, musíte příslušně změnit nastavení firewallu.

URL pro komunikaci s XML Connectorem

Předpokládajme, že máte k dispozici nainstalovaný a běžící InTouch CRM na adrese https://my.server.com/intouch. URL adresa pro komunikaci s XML Connectorem je vždy ve tvaru <ADRESA_CRM>/connector.do. XML Connector bude mít v tomto případě adresu https://my.server.com/intouch/connector.do. V případě CRM Online verze, musíte do URL adresy zadat i Váš kód ONLINE verze. Např.https://my.server.com/intouch/connector.do?crmID=KOD123 (neplatí od verze 6.0 při použití CRM na vlastní doméně *.itcrm.cz/.sk/.app)

Jinými slovy, na výše uvedené URL bude třeba posílat XML zprávy protokolem HTTP, aby byla navázána žádaná komunikace.

Požadavky lze zasílat v kódování windows-1250, nebo v UTF-8. Aplikace toto kódování respektuje z definice hlavičky XML (např. encoding="UTF-8"). Ovšem odpovědi aplikace na dotazy jsou standartně v kódování UTF-8.

Způsob předání XML zprávy

XML zpráva se connectoru předává metodou POST na výše popsané URL jedním ze dvou možných způsobů:

  1. Přímým POSTem, tj. data jsou standardně v těle požadavku (Content-Type: text/xml).
  2. Jako parametr s názvem data, který jde v požadavku typu application/x-www-form-urlencoded (tímto způsobem se odesílají data formuláře metodou POST)

Příklad navázání komunikace (Java)

Na příkladu níže je vidět ukázka Java kódu pro navázání komunikace s XML Connectorem (první způsob předání).

// Pripravit HTTP klienta
HttpClient client = HttpClient.newBuilder()
	.version(HttpClient.Version.HTTP_1_1)
	.followRedirects(HttpClient.Redirect.NORMAL)
	.connectTimeout(Duration.ofSeconds(5))
	.build();
...
String xmlData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> ...";
String auth = "basic " + Base64.getEncoder().encodeToString((login+":"+password).getBytes(StandardCharsets.ISO_8859_1)); // pouzijte login a password

HttpRequest request = HttpRequest.newBuilder()
	.uri(URI.create("https://my.server.com/connector.do"))
	.timeout(Duration.ofSeconds(15))
	.header("Content-Type", "text/xml")
	.header("Authorization", auth)
	.POST(HttpRequest.BodyPublishers.ofString(xmlData, Charset.forName("UTF-8")))
	.build();

var response = client.send(request, HttpResponse.BodyHandlers.ofString());
Document doc = parseXml(response.body());

Ukázka přenášených dat

Na příkladu níže je vidět jak může vypadá dotaz na XML Connector. Jedná se o vytvoření kontaktu v adresáři s hodnotami jméno=John a příjmení=Brown.

<?xml version="1.0" encoding="UTF-8"?>
<touch>
	<actions>
		<import entity="party">
			<fields>
			<field name="type">INDIVIDUAL</field>
			<field name="firstname">John</field>
			<field name="surname">Brown</field>
			</fields>
		</import>
	</actions>
</touch>

Podstatná je část uvnitř tagu <actions>. Je to seznam akcí, které je možné od InTouch CRM požadovat k provedení. V tomto případě se jedná o vytvoření kontaktu, a proto je zasílána jedna akce <import>.

Příslušná odpověď by pak mohla vypadat takto:

<?xml version="1.0" encoding="UTF-8"?>
<ok primaryKey="235"></ok>

Její význam je, že se podařilo úspěšně založit nový kontakt v adresáři (nebo aktualizovat nalezený) a jeho přidělený kód je 235.

Popis XML formátu

Podporované akce

Jak je vidět z DTD, klientský program může po InTouch CRM požadovat provedení tzv. akcí, které jsou obsaženy v elementu <actions>. Stávající implementaci connectoru podporuje těchto pět akcí.

AkcePopis
createVytvoření nového záznamu v databázi
updateAktualizace stávajícího záznamu
importZajistí zápis záznamu do databáze (buďto vytvoří nový, nebo aktualizuje nalezený)
lookupNalezení exitujícího záznamu
getIdZískání kódů existujících záznamů podle požadavku
listZískání informací o více záznamech současně (např. kompletní ceník produktů)
factsheetZískání faktů ke kontaktu s určitým kódem
getSqlZískání dat pomocí libovolného SQL SELECT dotazu

Každá z uvedených akcí (kromě factsheet) musí obsahovat povinný atribut entity, který určuje, na jakém typu záznamů se operace provádí (kontakt, komunikace, produkt, apod.).

Tag field

Akce musí obsahovat seznam polí, jejichž hodnoty určují, co se vytváří, hledá a nebo aktualizuje. Všechny podstatné informace jsou obsaženy v elementu <field>.

<field name="XXX" type="string">...</field>

Atribut name určuje název pole (platný seznam názvů je uveden níže), type určuje typ dat (např. řetězec=string) a obsah elementu jsou vlastní data.

Od verze 6.0 je type nepovinný - pokud se nejedná o pole bytů (např. pro content u obrázků), tak není nutné type uvádět. Stačí tedy:

<field name="XXX">...</field>

Pro zápis číselných, nebo datumových hodnot (které se stejně parsují z textového zápisu) se teké používá type="string", tudíž ani zde není nutné typ uvádět.

Tag xfield

Některé objekty v CRM mají tzv. atributy (např. atributy kontaktu, atributy nabídky, atd - neplést s atributy XML souboru). Tyto atributy jsou uloženy v jiných databázových tabulkách a pro jejich zápis je nutné je nějakým způsobem oddělit od standartních polí. K tomu slouží právě tag <xfield>.

<xfield name="XXX">...</xfield>

Zjednodušeně řečeno je xfield to samé, co field s tím rozdílem, že xfield je používán pro nestandardní, uživatelsky definovaná, pole v CRM.

Podporované entity

Aby bylo možné posílat požadavky na akce systému InTouch CRM, je třeba znát seznam entit, se kterými je možné pracovat.

NázevVýznam
partyKontakt, osoba či pobočka v adresáři
membershipVztah mezi "kontakty"
opportunityPříležitost
orderObjednávka
orderitemPoložka objednávky
invoiceVydaná faktura
communicationKomunikace (telefon, fax, apod.)
taskÚkol
eventUdálost
fileSoubor nebo dokument
documentSoubor nebo dokument
productProdukt
pcategoryKategorie produktu
imageObrázek, který je připojen k produktu
contentZáznam ze správce obsahu (viz. Znalosti)
commentPoznámky
storeSklady
storeitemPoložky na skladě
problemProblém
problemcommentKomentář k problému
factFakt (informace) ke kontaktu
customerKontakt (zpětně kompatibilní)
personOsoba (zpětně kompatibilní)
branchAdresa (zpětně kompatibilní)

Entita file (document)

Entita file reprezentuje v CRM soubor (sekce Dokumenty). Přes tuto entitu nelze vytvářet adresář. Obsah souboru se přenáší v tagu content a je interpretován jako bytové pole, zakódované do datového formátu pomocí Base64.

Příklad vytvoření firmy (akce create)

Požadavek na vytvoření kontaktu je níže. V seznamu polí musí být při vytváření záznamu ty pole, které jsou povinné. Informaci o tom, které pole je povinné zjistíte z přehledu polí pro jednotlivé entity (uvedeno níže).

<?xml version="1.0" encoding="UTF-8"?>
<touch>
<actions>
	<import entity="party">
		<fields>
			<field name="type">ORGANIZATION</field>
			<field name="company">Hurnbach s.r.o.</field>
			<field name="email">info@hurnbach.cz</field>
			<field name="enteredFrom">webf</field><!-- Kontakt pochází z webového formuláře -->
			<field name="ico">12345678</field>
			<field name="dic">CZ12345678</field>
			<field name="language">cs</field>
			<field name="comment">Zaregistroval se na webu</field>
		</fields>
	</import>
</actions>
</touch>

Odpověď při úspěšném provedení:

<?xml version="1.0" encoding="UTF-8"?>
<ok primaryKey="17" version="2.0"/>

Uvedená odpověď znamená, že byl vytvořen (nebo aktualizován) záznam s kódem 17 (primární klíč).

Použitá akce import zajistí zápis importovaných dat do databáze a vrátí kód záznamu. Při importu mohou nastat dvě situace:

To, jestli systém vyhodnotí importovaná data jako duplicitu, nebo nový záznam, se provádí vyhledáním duplicity podle následujících polí:

Samozřejmě je možné, že podle importovaných dat se může najít duplicit víc a v tom případě algoritmus nijak nedefinuje, který z nich pro aktualizaci použije. Pokud tedy víte, že ve Vaší databázi je mnoho duplicit, a chcete mít pod kontrolou to, jaký konkrétní záznam se použije pro aktualizaci, tak musíte použít vlastní sekvenci dotazů (akce list, či getId) pro ověření, zda kontakt už v databázi není a případně nalezený použít pro akci update.

Chcete-li mít čistou databázi kontaktů, je vhodnější a především jednodušší používat akci import.

Příklad vyhledání firmy (akce lookup)

Požadavek je opět uveden níže. Pro vyhledání kontaktu použijeme akci s názvem lookup a entitu party. Pokud chceme vyhledat záznam, musíme uvést pole, podle kterých chceme vyhledávat v databázi. V tomto případě hledáme záznam, který má kód (primární klíč) roven číslu 17.

<?xml version="1.0" encoding="UTF-8"?>
<touch>
<actions>
	<lookup entity="party">
		<fields>
			<field name="id">17</field>
		</fields>
	</lookup>
</actions>
</touch>

Odpověď bude vypadat takto:

<?xml version="1.0" encoding="UTF-8"?>
<ok primaryKey="17">
<fields>
	<field name="id">17</field>
	<field name="type">ORGANIZATION</field>
	<field name="company">Hurnbach s.r.o.</field>
	<!-- (výpis zjednodušen vynecháním polí) -->
	<field name="enteredFrom">webf</field>
	<field name="ico">12345678</field>
	<field name="dic">CZ12345678</field>
	<field name="language">cs</field>
	<field name="comment">Zaregistroval se na webu</field>
	<field name="email" priority="1">info@hurnbach.cz</field>
</fields>
</ok>

Některé tagy <field> mohou obsahovat atribut junk="true", který znamená, že údaj je neplatný a nepůjde jej zapsat zpět. Většinou se to týká kontaktních údajů, ale i u ostatních kontrolovaných hodnot (rodné číslo, příjmení, IČO, ...). Ve výstupu to může vypadat následovně:

<field name="surname" junk="true">Samec1980</field>
<field name="ico" junk="true">2222</field>

V příkladu je vidět neplatné příjmení osoby (obsahuje číslice) a neplatné IČO (špatný počet číslic, neplatný formát). Pokud z CRM přijdou údaje označené jako junk je ideální nejdříve požádat uživatele o opravu (např. webový profil).

Příklad aktualizace firmy (akce update)

V následujícím příkladu chceme zaslat do InTouch CRM změněná pole, tj. aktualizovat existující záznam. Je důležité vědět, že v seznamu polí se musí vyskytovat primární klíč záznamu, což je pro kontakt pole id. Požadavek bude vypadat takto:

<?xml version="1.0" encoding="UTF-8"?>
<touch>
<actions>
	<update entity="party">
		<fields>
			<field name="id">17</field> <!-- určuje, co se aktualizuje -->
			<field name="company">Hurnbach s.r.o.</field>
			<field name="email">zakaznicke_centrum@hurnbach.cz</field>
			<field name="street">Koníčková 16</field>
			<field name="city">Sekačkovice</field>
			<field name="zip">11150</field>
			<field name="country">CZ</field>
		</fields>
	</update>
</actions>
</touch>

Odpověď:

<?xml version="1.0" encoding="UTF-8"?>
<ok primaryKey="17" version="2.0"></ok>

Přepsání celého záznamu (pouze pro adresář)

Pokud nechcete u záznamů v adresáři CRM aktualizovat jen některá pole, ale chcete celý záznam kompletně přepsat novými údaji, můžete do tagu <update> přidat atribut mode="replace". Pole, pro která nebyl v dávce korespondující tag <field>, budou po aktualizaci prázdná.

Vynechání validace (pouze pro adresář)

Díky postupnému zpřísnění kontroly platnosti zapisovaných dat může nastat situace, že v databázi CRM jsou neplatné údaje kontaktu (čísla v příjmení, špatná telefonní čísla, apod.). Takové záznamy je možné aktualizovat jen tehdy, pokud aktualizujete pouze vybraná pole uvedená níže. Při pokusu o aktualizaci jiného pole, než která zde uvádíme, je prováděna plná kontrola zapisovaných dat a <update> může skončit chybou.

Pole, u kterých není prováděna plná kontrola platnosti dat jsou: id, comment, vip, categories, password, canShopping, globalStatus (pole id je ve výčtu jen proto, že je nutné ho uvádět kvůli nalezení záznamu, který se má aktualizovat).

Příklad vyhledání kódů - primárních klíčů (akce getId)

Akci getId můžeme s úspěchem využít tehdy, když potřebujeme zjistit kódy záznamů, které vyhovují nějaké podmínce. V následujícím příkladě se dotazujeme na kódy produktů, které byly upraveny po 11.5.2016 12:34.

<?xml version="1.0" encoding="UTF-8"?>
<touch>
<actions>
	<getId entity="product">
		<fields>
			<field name="modified" operator="&gt;">2016-05-11 12:34:00</field>
		</fields>
	</getId>
</actions>
</touch>

Odpověď:

<?xml version="1.0" encoding="UTF-8"?>
<ok primaryKey="5">
<fields>
	<field name="id2">5</field>
	<field name="id1">4</field>
	<field name="id0">1</field>
</fields>
</ok>

V odpovědi je vidět seznam kódů, které systém vrátí, a které vyhovují dotazu. Jsou pojmenovány id0 - id2. Toto pojmenování však nemá žádný význam. Klientská aplikace může názvy ignorovat a používat pouze hodnoty uvnitř elementu pro další dotazy.

Příklad získání seznamu záznamů (akce list)

V následujícím příkladě se dotazujeme na seznam produktů, které byly upraveny po 11.5.2016 12:34.

<?xml version="1.0" encoding="UTF-8"?>
<touch>
<actions>
	<list entity="product">
		<fields>
			<field name="modified" operator="&gt;">2016-05-11 12:34:00</field>
		</fields>
	</list>
</actions>
</touch>

Odpověď bude vypadat takto:

<?xml version="1.0" encoding="UTF-8"?>
<ok>
	<fields primaryKey="20">
		<field name="id">20</field>
		<field name="name">Apple MacBook Pro</field>
		...údaje o produktu s kódem 20
	</fields>
	<fields primaryKey="21">
		<field name="id">21</field>
		<field name="name">Apple iPhone XS (red)</field>
		...údaje o produktu s kódem 21
	</fields>
	<!-- ... další produkty ... -->
</ok>

Z výkonnostních důvodů je odpověď limitována na max. 1000 záznamů. To znamená, že pokud máte v InTouch CRM více než 1000 záznamů, budete nuceni provést více dotazů. Akce vrací seznamy seřazené podle primárního klíče (id). Pokud tedy nejvyšší id v prvním dotazu bylo 1350, tak v následujícím dotazu provedete volání takto:

<?xml version="1.0" encoding="UTF-8"?>
<touch>
<actions>
	<list entity="product">
		<fields>
			<field name="modified" operator="&gt;">2016-05-11 12:34:00</field>
			<field name="id" operator="&gt;">1350</field>
		</fields>
	</list>
</actions>
</touch>

Atribut operator, který použijete v dotazu, může nabývat následujících hodnot: <, >, <=, >=, !=, starts, ends, contains. Nezapomeňte, že místo znaků < a > musíte uvádět entity &lt; resp. &gt;, aby zpráva vyhověla syntaxi XML.

Příklad získání seznamu faktů ke kontaktu (factsheet)

Následující dotaz vrátí seznam všech faktů ke kontaktu s kódem 123.

<?xml version="1.0" encoding="UTF-8"?>
<touch>
<actions>
	<factsheet type="customer" id="123"/>
</actions>
</touch>

Odpověď bude vypadat takto:

<?xml version="1.0" encoding="UTF-8"?>
<ok>
	<fields primaryKey="clickBanner|123">
		<field name="title">Kliknul na banner na webu</field>
		<field name="created">1336125307000</field>
		<field name="priority">70</field>
		<field name="kindGroup">clicks</field>
		<field name="value">25.3.2012</field>
		<field name="closed">false</field>
		<field name="display">3</field>
		<field name="customer">123</field>
		<field name="type">0</field>
		<field name="kind">clickBanner</field>
		<field name="modified">1336125521000</field>
		<field name="info">Přišel na web díky Google AdWords</field>
	</fields>
	<fields primaryKey="surveyForm|123">
		<field name="title">Vyplnil dotazník</field>
		...
	</fields>
	...
</ok>

Příklad získání dat (akce getSql)

Akci getSql lze použít na libovolné získání dat z CRM. Povinný je atribut table - název tabulky v SQL databázi a seznam elementů fields - seznam SQL sloupců, jejichž data chcete získat. Nepovinné jsou tagy where - SQL podmínka a limit - SQL limit vrácených výsledků.

UPOZORNĚNÍ - použití této akce příliš nedoporučujeme (pouze pokud není alternativní způsob, jak získat požadovaná data), protože řešení postavené na této funkcionalitě může přestat fungovat po aktualizaci CRM na novější verzi (změní se struktura databáze).

<?xml version="1.0"?>
<touch>
<actions>
	<getSql table="special_note">
		<where>type=1</where>
		<limit>2</limit>
		<fields>
			<field name="id" />
		</fields>
	</getSql>
</actions>
</touch>

Odpověď:

<ok>
<fields primaryKey="row1">
	<field name="id">2734</field>
</fields>
<fields primaryKey="row2">
	<field name="id">2737</field>
</fields>
</ok>

V odpovědi je vidět seznam vyhovujících záznamů v SQL databázi a zobrazeny jsou u nich pouze hodnoty definované přes element fields.

Příklad zápisu a čtení souhlasů

<?xml version="1.0" encoding="utf-8"?>
<touch>
   <actions>
       <create entity="consent">
           <fields>
               <field name="customer">1214</field>
               <field name="consentType">1</field>
               <field name="description">Souhlas poskytnut ze zákaznické zóny</field>
               <field name="value">true</field>
           </fields>
       </create>
   </actions>
</touch>

V případě, že potřeba zapsat více, než jen jeden souhlas, tak je možné zapsat všechny souhlasy najednou v jednom zapisovacím XML a nemusí se posílat jednotlivé požadavky postupně.

<?xml version="1.0" encoding="utf-8"?>
<touch>
   <actions>
       <create entity="consent">
           <fields>
               <field name="customer">1214</field>
               <field name="consentType">1</field>
               ...
           </fields>
       </create>
       <create entity="consent">
           <fields>
               <field name="customer">1214</field>
               <field name="consentType">2</field>
               ...
           </fields>
       </create>
   </actions>
</touch>

Metoda <create> je implementována tak, že pokud je u záznamu nalezen již existující souhlas se stejnou hodnotou value a stejným popiskem description, tak se nový záznam nevytváří (neobsahuje žádnou novou „hodnotu“). V ostatních případech je souhlas zapsán jako nový záznam. Po aktualizaci/zápisu záznamu Kontaktu/Osoby vrátí XML Connector v odezvě primární klíč záznamu a ten je pak možné použít pro následující zápis souhlasů. Souhlasy je vhodné zapisovat, jen tehdy pokud je opravdu detekována změna (tj. pokud došlo ke změně daného souhlasu). V opačném případě (tj. po každém zápisu kontaktu zapisovat i jeho souhlasy) je nutné již existující souhlasy nejprve načíst (případně upravit ty, které se měnily) a poté provést zápis zpět do aplikace.

Pro čtení již existujících souhlasů je nutné použít akci <list>.

<?xml version="1.0" encoding="utf-8"?>
<touch>
   <actions>
      <list entity="consent">
         <fields>
            <field name="customer" operator="=">1214</field>
         </fields>
      </list>
   </actions>
</touch>

Příklad odpovědi může být:

<?xml version="1.0" encoding="UTF-8"?>
<ok version="2.0">
   <fields primaryKey="5">
      <field name="customer">1214</field>
      <field name="consentType">1</field>
      <field name="sourceType">3</field>
      <field name="description">Poznámka k souhlasu se zpracováním osobních údajů</field>
      <field name="entered">1524660762000</field>
      <field name="value">true</field>
   </fields>
   <fields primaryKey="8">
      <field name="customer">1214</field>
      <field name="consentType">2</field>
      <field name="sourceType">3</field>
      <field name="description">Poznámka k souhlasu s poskytnutím os. údajů třetím stranám</field>
      <field name="entered">1524662354000</field>
      <field name="value">true</field>
   </fields>
   <fields primaryKey="7">
      <field name="customer">1214</field>
      <field name="consentType">10</field>
      <field name="sourceType">3</field>
      <field name="description">Poznámka k nesouhlasu zasílání zpravodaje</field>
      <field name="entered">1524660922000</field>
      <field name="value">false</field>
   </fields>
</ok>

Význam jednotlivých polí je popsán v referenční příručce souhlasů.

Chyby zpracování požadavku

V případě, že se požadovaná akce nepodaří uskutečnit, výsledkem bude odpověď v následujícím tvaru.

<?xml version="1.0" encoding="UTF-8"?>
<errors>
	<error>Column not found,  message from server: "Unknown column 
	'type' in 'where clause'"</error>
</errors>

Chyb, které jsou obsaženy v elementu error může být v odpovědi více.

Obecná doporučení

Pokud chcete integrovat InTouch CRM s jiným systémem pomocí XML Connectoru, doporučujeme držet se následujícíh obecných zásad:

  1. Vždy používejte šifrovanou komunikaci https.
  2. Počítejte, že požadavek nemusí být vykonán a server vrátí chybu v XML odpovědi.
  3. Žádný systém nemá 100% up-time, síťová komunikace bývá přerušena, někdy probíhá aktualizace CRM. Počítejte s tím, že CRM někdy nebude běžet a nezpracované požadavky na zápis do systému ukládejte do fronty pro pozdější asynchronní zpracování.
  4. Vytvořte v CRM uživatelský účet s přístupem Pouze API a posílejte své dotazy jako tento uživatel (HTTP autorizace).
  5. Poctivě provádějte integrační testy na neprodukční verzi CRM. Snažíme se zachovávat kompatibilitu API se staršími verzemi CRM, ale někdy to nejde a co fungovalo včera nemusí fungovat po aktualizaci.

Popis jednotlivých entit

Pro každou podporovanou entitu potřebujete znát význam a pojmenování polí. Podívejte se prosím do referenční příručky datových struktur, kde naleznete požadovanou dokumentaci.