A programozói interfésszel kapcsolatos alapvető információink:
- ez nem egy klasszikus API
- nincs hozzá kimerítő részletességű dokumentáció
- nincs verziózva, és külön értesítés nélkül bármikor megváltozhat (természetesen igyekszünk értesítést küldeni a változásokról)
- A jelenlegi működés fix, tehát fejlesztési igényeket nem tudunk befogadni rá
Általános tudnivaló az interfész használatához
Az interfész HTTPS fölött JSON üzenetekben kommunikál. Alapvetően POST kéréseket használunk. A hívható végpontok a cég adott domainje alatt vannak, a https://cegnev.comnica.cc/api névtér alatt.
Payload formátum
Általánosan minden backend végpontunk a következő JSON formátumot várja:
{ "rq_sent" : "2019-10-07 09:37:49.700+0000" , /* A request elküldésének timestampje a kliens szerint */ "payload" :{} /* A tényleges kérés */ } |
A továbbiakban a requestek leírásakor csak a payload formátumára fogunk kitérni, amennyiben az üres, akkor egy üres JSON objektumot („{}”) kell küldenie a hívó félnek.
Általános válasz formátum:
{ "res_sent" : "2019-10-07 09:37:49.971653+0000" , /* A szerver szerint a válasz kiküldésének timestampje */ "rq_rcvd" : "2019-10-07 09:37:49.926506+0000" , /* A szerver ekkor kapta meg a kérést */ "payload" :{} /* A tényleges válasz */ } |
Minden sikeres kérésre adott válasz 200-as HTTP státuszkódot kap és a fenti formátumú keretbe van csomagolva.
A továbbiakban a válaszok írásakor csak a payload formátumára fogunk kitérni, amennyiben az üres, akkor a szerver egy üres JSON objektumot küld („{}”) küld.
Hibák
400 Bad Request
A válasz JSON formátumú és az általános válasz formátumnál ismeretett wrapperbe van csomagolva. A payload a következő jellegű:
{ "errors" : [ { "code" : "BAD_DATA" , "parameters" : { "username" : "Foo" }, "field_name" : null , "global" : true }, { "code" : "ALREADY_EXISTS" , "parameters" : { "thing" : "Teszt Projekt" }, "field_name" : name, "global" : false } ] } |
Az errors
tömb tartalmazza a hibák leírását. Egy konkrét hiba vonatkozhat a kérés valamelyik meghatározott mezejére (ekkor global
= false és a field_name
kulcs mutat a mezőre, amely a hibát kiváltotta), vagy lehet általános jellegű (ekkor global
= true és field_name
hiányzik). A code kulcs tartalmazza a tényleges hibakódot. A lehetséges hibakódok listája a kérés típusától függ.
401 Authentication required
A válasz kivételesen egyszerű szöveg (annyi, hogy „Authorization required”).
Érvénytelen felhasználónév vagy jelszó, valamint lejárt token esetén keletkezik ilyen válasz.
403 Permission denied
A válasz JSON, de NEM tartalmazza az általános wrappert.
Akkor keletkezik ilyen válasz, ha az usernév/jelszó vagy token érvényes, de a felhasználónak a kért művelet végrehajtásához nincs jogosultsága.
404 Resource not found
A válasz JSON, de NEM tartalmazza az általános wrappert.
Nem létező endpoint hívásakor keletkezik ilyen válasz. Fontos, hogy a kérés metódusának is stimmelnie kell, tehát ha egy POST-ként definiált endpointot GET-ként hívnak, arra is ilyen hibakód a válasz.
Bejelentkezés
Minden session indításakor kötelező egy session tokent kérni. Ehhez egy valid usernév jelszó párost kell HTTP Basic authentikációval megadni.
A token érvényességi időtartama jelenleg 4 óra, ez minden sikeres kéréssel újraindul. A lejárt tokennel küldött kérések 401-es hibakódú választ generálnak, ilyenkor új tokent kell kérni.
Kérés
/new_session
A Request payload üres.
Válasz
{ "user_id" :31, "permissions" : [ "login" , "change_password" , ... ], "session_key" : "XXXYYYZZZ" , "is_support" : false , "name" : "Some User" , "is_admin" : false , "username" : "somebody" } |
Ebből a session_key kulcs a releváns, a többit csak az admin felület frontendje használja.
Minden további requesthez a a HTTP Basic authentikációt a „_session” felhasználónévvel és az itt megkapott „session_key”-jel kell végrehajtani.
Általános lista-lekérdezés
Az endpointok egy része olyan, hogy valamilyen entitások (például: rekordok, munkaidő-bejegyzések) táblázat-szerű listáját lehet velük lekérni, paraméterezhető oszlopokkal és szűrőkkel. Az ilyen kérések formátuma azonos sémára illeszkedik, csak az engedélyezett oszlopok és szűrők listája függ a konkrét kérés céljától.
Továbbá jellemzően minden ilyen listázó endpointhoz tartozik egy exportáló endpoint, amely (néhány, alább részletezett különbségtől eltekintve) ugyanazt a kérés-formátumot használja. Az a konvenció, hogy ha a listázó endpoint neve /foo/list
, amely a választ JSON-ként adja vissza, akkor létezik egy /foo/export
is, amely ugyanazt a listát XLS vagy CSV formátumban, fájlként kínálja letöltésre.
Kérés
A payload két tömböt kell tartalmazzon, ezek neve columns
és filters
. A columns
a kért oszlopok (megjelenítendő attribútumok) listáját, a filters pedig az adatokon végrehajtandó szűréseket tartalmazza. Jellemzően minden oszlophoz tartozhat egy szűrő, de az oszlopok és szűrők listájának nem kell megegyeznie (tehát lehetséges olyan kérés, amely az X, Y, Z oszlopkat kéri le, de az A, B, C oszlopok szerint szűr).
A kérés tartalmazhat még egy opcionális kulcsot, amelynek neve limit
, értéke egy egész szám. Ha a limit N, akkor a válaszban csak az első N sor fog szerepelni. Az alapértelmezett limit 50.
Alapértelmezésben a válaszban a sorok sorrendje nem definiált, így az sem, hogy mi számit az első N sornak. Ezen úgy lehet segíteni, ha a columns
specifikáció valamelyik oszlopánál szerepel egy explicit order
kulcs, amelynek értéke asc
vagy desc
lehet, ekkor a válasz a megjelölt oszlop szerint lesz rendezve, növekvő avagy csökkenő sorrendben.
A columns
és filters
tömbökben megadható oszlopok típussal rendelkeznek, az oszlop típusa meghatározza, hogy a szűrőfeltételt milyen formátumban kell megadni. A következő típusok fordulnak elő:
„boolean”, „string”, „integer”, „number”, „date”, „datetime”, „time”, „multiselect”, „select”
Egy szűrő aktív, ha meg van adva mellé szűrőfeltétetel, azaz condition
kulcs. A szűrőfeltétel formátumai a következők
string
szűrőknél a feltétel string típusú, a backend a megadott mintára illeszkedő sorokat adja vissza.boolean
szűrőknél a feltételtrue
vagyfalse
lehet.multiselect
szűrőknél a feltétel egy számokat (numerikus ID-ket) tartalmazó tömb. Hogy minek az ID-jeire vonatkozik a szűrés, az az oszlop nevétől/céljától függ, és az alább részletezettfilterdata
mechanizmussal deríthető ki.select
szűrőknél a feltétel egy darab szám (numerikus ID).- a
date/time/datetime
szűrők egy időtartományt határoznak meg. A szűrőfeltétel egy objektum, amely atype
ésvalue
kulcsokat tartalmazza. Hatype
értékeabsolute
, akkor avalue
egy objektum kell legyen, amelyben afrom
illetveto
kulcsok határozzák meg a kívánt időtartomány elejét és végét. Ha atype
értékerelative,
akkor avalue
értéke egy string, amely egy relatív időtartományt határoz meg. A lehetséges értékek:- „today”
- „yesterday”
- „last week”
- „this week”
- „last month”
- „this month”
- „last year”
- „this year”
number/integer
szűrőknél további kötelező mezők vannak:display_format
, értékei lehetnek:time
,raw
,percentage
is_range
, booleanminimum
ésmaximum
, a megengedett számtartomány alsó ill. felső határa.- a szűrőfeltétel egy objektum, amelyben az
is_range
értékétől függően vagy avalue
(hais_range
hamis), vagy afrom
ésto
kulcsoknak kell szerepelnie (hais_range
igaz).
Példa:
{ "limit" : 5, "columns" : [ { "name" : "project" }, { "name" : "hidden" } ], "filters" : [ { "condition" : false , "name" : "hidden" , "type" : "boolean" } ] } |
Válasz
A válaszban a data
tömb tartalmazza a lekérdezés eredményét. A tömb minden eleme egy objektum, amelyben a kulcsok a lekérdezés columns
szakaszában megadott oszlopoknak felelnek meg (ezen kívül a legtöbb lekérdezés eredményében minden objektumban szerepel még egy plusz id
mező is, amely a lekérdezett entitást egyértelműen azonosítja).
Ezen felül szerepel még a válaszban egy config
objektum is, amelyben a have_more
boolean mondja meg, hogy a válasz a szűrőfeltételeknek megfelelő összes elérhető sort tartalmazza-e. Ha például a feltételeknek 70 sor felelt volna meg, de a kérésben 50-es limit szerepelt (akár implicit módon), akkor have_more
true értéket vesz fel, innen tudható, hogy az eredmény nem teljes, és vagy a szűrőfeltételeket kell módosítani, vagy a limitet növelni az összes sor lekérdezéséhez.
Példa:
{ "config" : { "have_more" : true }, "data" : [ { "hidden" : false , "project" : "Teszt Project Chavez exter-marriage" , "id" : 1 }, { "id" : 2, "hidden" : false , "project" : "Teszt Project collar-shaping junk-bottle" }, { "hidden" : false , "project" : "Teszt Project chondrosarcoma suburbanize" , "id" : 4 }, { "id" : 5, "project" : "Teszt Project borer NCCL" , "hidden" : false }, { "hidden" : false , "project" : "Teszt Project anthography hue" , "id" : 6 } ] } |
Export
A /foo/export
változat a fentiekhez képest egy plusz kötelező kulcsot tartalmaz, amelynek neve download
, és a lehetséges értékei ‘csv’ vagy ‘xls’, amely a letöltendő fájl típusát határozza meg.
A columns
és filters
tömbök kötelezőek és ugyanazokat az oszlop-specifikációkat kell, hogy tartalmazzák, mint a megfelelő /foo/list
kérés. A limit
kulcs is használható, azzal a különbséggel, hogy ha hiányzik, akkor az eredmény az összes sort tartalmazni fogja.
A válasz a kért típusú fájlként (CSV vagy XLS) töltődik le.
Filterdata
/search/filterdata
A select
és multiselect
típusú szűrőfeltételekben használható numerikus azonosítók és a hozzájuk tartozó nevek kérdezhetők le ezzel az endpointtal.
Kérés
A payload objektumban az alább felsorolt kulcsok szerepelhetnek (egy vagy több). Alapesetben a hozzájuk tartozó értékek üres objektumok, de néhány esetben további paramétereket is meg lehet adni, amelyekkel a keresés feltételeit lehet módosítani.
- „calldirection”: hívásirányok (kimenő vs. bejövő)
- „callreason_types”: hívás végének lehetséges okai
- „communication_method”: audio vs. video
- „emails”: a rendszer felhasználóinak email-címei
- opcionális paraméterek:
- all: boolean – ha true: az inaktív felhasználókat is listázza
- project_id: szám – csak az ehhez a projekthez rendelt felhasználókat listázza
- opcionális paraméterek:
- „files”: csatolmányként feltöltött fájlok
- „global_roles”: a felhasználók lehetséges jogosultsági szintjei
- „operatorstates”: operátori állapotok
- „project_roles”: a felhasználók kampányhoz kötött jogosultsági szintjei
- „projectdata_column”: adott kampányhoz tartozó rekordokban előforduló oszlopok nevei
- kötelező paraméterek:
- project_id: ennek a projektnek az oszlopait listázza
- kötelező paraméterek:
- „projects”: kampányok nevei
- opcionális paraméterek:
- all: boolean – ha true, az inaktívakat is listázza
- type: [outgoing_voice, incoming_voice, incoming_video] – csak az ilyen típusú kampányokat listázza
- opcionális paraméterek:
- „queues”: hívási sorok nevei
- opcionális paraméterek:
- all: boolean
- opcionális paraméterek:
- „robinson_lists”: Robinson-listák
- opcionális paraméterek:
- all: boolean – ha true, az inaktívakat is listázza
- opcionális paraméterek:
- „scripts”: adott kampányhoz tartozó scriptek
- kötelező paraméterek:
- project_id: ennek a projektnek az scriptjeit listázza
- opcionális paraméterek:
- all: boolean – ha true: az inaktív scripteket is listázza
- kötelező paraméterek:
- „termination_categories”: terminációs kategóriák (pl. sikeres vs. sikertelen)
- „terminations”: terminációk (lezárások)
- opcionális paraméterek:
- all: boolean – ha true: az inaktív terminációkat is listázza
- project_id: szám – csak az ehhez a projekthez rendelt terminációkat listázza
- termination_category_id: szám – csak az ilyen kategóriába tartozó terminációkat listázza
- hide_redial: a redial terminációt ne listázza ಠ_ಠ
- opcionális paraméterek:
- „usernames”: a rendszer felhasználóinak bejelentkezési nevei
- opcionális paraméterek:
- all: boolean – ha true: az inaktív felhasználókat is listázza
- project_id: szám – csak az ehhez a projekthez rendelt felhasználókat listázza
- opcionális paraméterek:
- „users”: a rendszer felhasználóinak valódi nevei
- opcionális paraméterek:
- all: boolean – ha true: az inaktív felhasználókat is listázza
- project_id: szám – csak az ehhez a projekthez rendelt felhasználókat listázza
- opcionális paraméterek:
- „video_projects”: video kampányok nevei
Példa:
{ "users" :{ "all" : true }, "projects" :{}, "operatorstates" :{}, "video_projects" :{} } |
Válasz
A válasz objektumban a kérésben megadott kulcsok szerepelnek, amelyek mindegyikéhez egy-egy tömb tartozik. A tömbök elemei az egyes entitások azonosítóját és nevét tartalmazó objektumok. Ez utóbbiak mindig tartalmazzák az id
és name
kulcsokat.
Példa:
{ "video_projects" :[ { "id" : 1 , "name" : "demo" } ] "operatorstates" : [ { "id" : 13 , "name" : "Állapotváltást kér" }, { "id" : 3 , "name" : "Beszélget" }, { "id" : 7 , "name" : "Ebédel" }, { "id" : 10 , "name" : "Előmunka" }, { "id" : 15 , "name" : "Hívási sor váltás" }, { "id" : 6 , "name" : "Kézi hívás" }, { "id" : 12 , "name" : "Ki akar lépni" }, { "id" : 16 , "name" : "My custom state" }, { "id" : 17 , "name" : "My custom state 2" }, { "id" : 8 , "name" : "Oktatáson van" }, { "id" : 14 , "name" : "Operátori beszélgetés" }, { "id" : 4 , "name" : "Regisztrál" }, { "id" : 2 , "name" : "Szünetet tart" }, { "id" : 1 , "name" : "Ügyfélre vár" }, { "id" : 5 , "name" : "Visszahívásra vár" } ], "projects" : [ { "id" : 41 , "name" : "_______" }, { "id" : 23 , "name" : "bejovo" }, { "id" : 42 , "name" : "dd f" }, { "id" : 40 , "name" : "Operátor próba" }, { "id" : 27 , "name" : "Kampány másolás" }, { "id" : 28 , "name" : "Kampány másolás 2" }, { "id" : 29 , "name" : "Nottaken" }, { "id" : 39 , "name" : "Szkriptszerkesztés" }, { "id" : 37 , "name" : "Szkriptszerkesztés3" }, { "id" : 38 , "name" : "Szkriptszerkesztés4" }, { "id" : 22 , "name" : "Telesales" }, { "id" : 34 , "name" : "Tranzakció alapú időzített E-mail küldés" }, { "id" : 33 , "name" : "Tranzakció alapú időzített SMS küldés" }, { "id" : 25 , "name" : "Try" }, { "id" : 26 , "name" : "Try2" }, { "id" : 1 , "name" : "Tudásbázis" }, { "id" : 35 , "name" : "Ügyfélszolgálat feladat II. kör" }, { "id" : 21 , "name" : "Ügyfélszolgálat feladat I. kör" }, { "id" : 30 , "name" : "webugyteszt" } ], "users" : [ { "id" : 18 , "name" : "Admin" }, { "id" : 42 , "name" : "Admin1" }, { "id" : 22 , "name" : "Operátor1" }, { "id" : 26 , "name" : "Operátor11" }, { "id" : 40 , "name" : "Operátor3" }, { "id" : 33 , "name" : "Medialetolto" }, { "id" : 44 , "name" : "Operátor" }, { "id" : 21 , "name" : "Operátor 123" }, { "id" : 23 , "name" : "Operátor 11" }, { "id" : 19 , "name" : "Operátor 12" }, { "id" : 24 , "name" : "Operátor 22" }, { "id" : 43 , "name" : "Operátor 456" }, { "id" : 41 , "name" : "Jó" } ] } |
Részletes munkaidő-statisztika
/stat/worklog_detailed/list
Ez az endpoint az operátorok által a webes kliensben eltöltött idő részletes lekérdezésére szolgál.
A szűrőfeltételek, valamint a visszaadott adatok értelmezéséhez a következőket érdemes tudni:
Az operátorok minden pillanatban, amikor a Comnica klienst használják, valamilyen operátori állapotban vannak. Ilyen állapotok például: Beszélget, Ügyfélre vár, Szüneten van. A rendszer eleve definiál néhány, a működéshez szükséges operátori állapotot, de újak is felvehetők az adminisztrátori felületen. Ezen felül az operátor a Comnica kliens használata közben be van jelentkezve egy vagy több hívási sorba, és ezek között menet közben is válthat. A rendszer minden állapotváltozást, továbbá minden hívásisor-váltást regisztrál, vagyis a rendszer használata közben keletkezik egy részletes napló, amely azt tartalmazza, hogy melyik operátor melyik hívási sorokban, milyen állapotban mettől meddig mennyi időt töltött. A részletes munkaidő-statisztika valójában ennek a naplónak a rugalmas lekérdezésére szolgál. Az eredmény sorai ennek a naplónak a bejegyzései, ha úgy tetszik, munkaidő-szeletek. A kívánt oszlopokat és a szűrőfeltételeket az „Általános lista-lekérdezés” szakaszban részletezett módon lehet megadni, és a lehetséges szűrők típusainak jelentése is ott olvasható.
Ennél a statisztikánál van egy szűrőfeltétel, amelyet kötelező megadni, ennek neve interval
és a típusa datetime
. Ezzel a szűrővel lehet a lekérdezett időtartományt megszorítani (abszolút intervallum is megadható kezdő- és végponttal, illetve relatív hivatkozás, pl. „today”).
A lehetséges további oszlopok ill. szűrők
- user_name
- Ha szerepel az oszlopok között, akkor az eredmény minden sora tartalmazni fogja a felhasználó nevét (akihez az adott bejegyzés tartozik).
- Ha szerepel a szűrők között, akkor csak a szűrőfeltételben megadott felhasználók bejegyzései jelennek meg a listában.
Multiselect
típusú szűrő, vagyis a keresett felhasználók id-jeit (és nem a nevüket) kell megadni egy tömbben a szűrőfeltételben (Lásd „users” filterdata).
- description
- Ha szerepel az oszlopok között, akkor az eredmény minden sora tartalmazni fogja az operátori állapot nevét.
- Ha szerepel a szűrők között, akkor csak a szűrőfeltételben megadott operátori állapotok jelennek meg a listában.
Multiselect
típusú szűrő, vagyis a keresett operátori állapotok id-jeit (és nem a nevüket) kell megadni egy tömbben a szűrőfeltételben (Lásd „operatorstates” filterdata).
- counts_as_work
- Ha szerepel az oszlopok között, akkor az eredmény minden sora tartalmazni fogja, hogy bejegyzés munkának számít-e (ez minden operátori állapotnál meg van határozva, hogy munkának számít-e vagy nem).
- Ha szerepel a szűrők között, akkor csak a munkának számító (vagy nem annak számító) bejegyzések jelennek meg. Boolean típusú szűrő, azaz true vagy false lehet a feltétel.
- status_begin
- Ha szerepel az oszlopok között, akkor az eredmény minden sora tartalmazni fogja az bejegyzés kezdetét.
- Ehhez az oszlophoz nem tartozik szűrőfeltétel (azonban lásd az
interval
szűrőt).
- status_end
- Ha szerepel az oszlopok között, akkor az eredmény minden sora tartalmazni fogja az bejegyzés végét.
- Ehhez az oszlophoz nem tartozik szűrőfeltétel (azonban lásd az
interval
szűrőt).
- duration
- Ha szerepel az oszlopok között, akkor az eredmény minden sora tartalmazni fogja az bejegyzés időtartamát (azaz, hogy a felhasználó mennyi időt töltött a kérdéses állapotban).
- Ha szerepel a szűrők között, akkor csak a megadott időtartam-tartományba eső bejegyzések jelennek meg az eredményben. Number típusú szűrő, azaz a
minimum
ésmaximum
kulcsokkal kell megadni a kívánt számtartományt, percben (hogy mekkoránál hosszabb és mekkoránál rövidebb időtartamú bejegyzések jelenjenek meg.)
- project_name
- Ha szerepel az oszlopok között, akkor az eredmény minden sora tartalmazni fogja azt, hogy a felhasználó az adott bejegyzésben melyik kampányokba volt bejelentkezve.
- Ha szerepel a szűrők között, akkor csak a szűrőfeltételben megadott kampányokhoz tartozó bejegyzések jelennek meg a listában.
Multiselect
típusú szűrő, vagyis a keresett kampányok id-jeit (és nem a nevüket) kell megadni egy tömbben a szűrőfeltételben (Lásd „projects” filterdata).
- queue_name
- Ha szerepel az oszlopok között, akkor az eredmény minden sora tartalmazni fogja azt, hogy a felhasználó az adott bejegyzésben melyik hívási sorokba volt bejelentkezve.
- Ha szerepel a szűrők között, akkor csak a szűrőfeltételben megadott hívási sorokhoz tartozó bejegyzések jelennek meg a listában.
Multiselect
típusú szűrő, vagyis a keresett hívási sorok id-jeit (és nem a nevüket) kell megadni egy tömbben a szűrőfeltételben (Lásd „queues” filterdata).
Kérés
Az alábbi példa az összes lehetséges oszlopot, valamint a szűrők típusát és az elvárt szűrőfeltételeket mutatja. Nem muszáj minden oszlopot ill. szűrőt megadni, és nem szükséges, hogy ugyanazokat a szűrőket és oszlopokat adjuk meg (a valóságban ennél a statisztikánál célszerű minden oszlopot megadni a teljes eredményhez).
{ "columns" : [ { "name" : "user_name" }, { "name" : "description" }, { "name" : "counts_as_work" }, { "name" : "status_begin" }, { "name" : "status_end" }, { "name" : "duration" }, { "name" : "project_name" }, { "name" : "queue_name" } ], "filters" : [ { "condition" : [ 17, 22, 25, 44, 35, 37 ], "name" : "user_name" , "type" : "multiselect" }, { "condition" : [ 13, 3, 7, 10 ], "name" : "description" , "type" : "multiselect" }, { "condition" : true , "name" : "counts_as_work" , "type" : "boolean" }, { "condition" : { "type" : "relative" , "value" : "this week" }, "name" : "interval" , "type" : "datetime" }, { "condition" : { "from" : 0, "to" : 3706 }, "display_format" : "time" , "is_range" : true , "maximum" : 7200, "minimum" : 0, "name" : "duration" , "type" : "integer" }, { "condition" : [ 35, 21, 22 ], "name" : "project_name" , "type" : "multiselect" } ], "limit" : 50 } |
Válasz
{ "config" : { "have_more" : false }, "data" : [ { "counts_as_work" : true , "description" : "Állapotváltást kér" , "duration" : 1.02511, "id" : 2656, "project_name" : "Ügyfélszolgálat feladat II. kör" , "queue_name" : "Ügyfélszolgálat feladat II. kör" , "status_begin" : "2019-10-14 11:32:11.88445+02" , "status_end" : "2019-10-14 11:32:12.90956+02" , "user_name" : "Kovács Géza" }, { "counts_as_work" : true , "description" : "Állapotváltást kér" , "duration" : 1.02598, "id" : 2659, "project_name" : "Ügyfélszolgálat feladat II. kör" , "queue_name" : "Ügyfélszolgálat feladat II. kör" , "status_begin" : "2019-10-14 13:04:12.85681+02" , "status_end" : "2019-10-14 13:04:13.88279+02" , "user_name" : "Kovács Géza" }, { "counts_as_work" : true , "description" : "Előmunka" , "duration" : 1.69876, "id" : 2661, "project_name" : "Ügyfélszolgálat feladat II. kör" , "queue_name" : "Ügyfélszolgálat feladat II. kör" , "status_begin" : "2019-10-14 13:04:22.81521+02" , "status_end" : "2019-10-14 13:04:24.51397+02" , "user_name" : "Kovács Géza" }, { "counts_as_work" : true , "description" : "Állapotváltást kér" , "duration" : 1.01377, "id" : 2662, "project_name" : "Ügyfélszolgálat feladat II. kör" , "queue_name" : "Ügyfélszolgálat feladat II. kör" , "status_begin" : "2019-10-14 13:04:24.51397+02" , "status_end" : "2019-10-14 13:04:25.52774+02" , "user_name" : "Kovács Géza" }, { "counts_as_work" : true , "description" : "Beszélget" , "duration" : 3.58388, "id" : 2664, "project_name" : "Ügyfélszolgálat feladat II. kör" , "queue_name" : "Ügyfélszolgálat feladat II. kör" , "status_begin" : "2019-10-14 13:04:32.13318+02" , "status_end" : "2019-10-14 13:04:35.71706+02" , "user_name" : "Kovács Géza" }, { "counts_as_work" : true , "description" : "Állapotváltást kér" , "duration" : 1.01884, "id" : 2674, "project_name" : "Telesales, Ügyfélszolgálat feladat II. kör, Ügyfélszolgálat feladat I. kör" , "queue_name" : "Telesales, Ügyfélszolgálat feladat II. kör, Ügyfélszolgálat feladat I. kör" , "status_begin" : "2019-10-14 14:18:30.85001+02" , "status_end" : "2019-10-14 14:18:31.86885+02" , "user_name" : "Nagy Napóleon" }, { "counts_as_work" : true , "description" : "Állapotváltást kér" , "duration" : 1.01853, "id" : 2678, "project_name" : "Telesales, Ügyfélszolgálat feladat II. kör, Ügyfélszolgálat feladat I. kör" , "queue_name" : "Telesales, Ügyfélszolgálat feladat II. kör, Ügyfélszolgálat feladat I. kör" , "status_begin" : "2019-10-14 14:29:30.96704+02" , "status_end" : "2019-10-14 14:29:31.98557+02" , "user_name" : "Nagy Napóleon" }, { "counts_as_work" : true , "description" : "Előmunka" , "duration" : 656.19123, "id" : 2680, "project_name" : "Ügyfélszolgálat feladat II. kör" , "queue_name" : "Ügyfélszolgálat feladat II. kör" , "status_begin" : "2019-10-14 14:29:32.79901+02" , "status_end" : "2019-10-14 14:40:28.99024+02" , "user_name" : "Nagy Napóleon" }, { "counts_as_work" : true , "description" : "Állapotváltást kér" , "duration" : 2.01933, "id" : 2681, "project_name" : "Telesales, Ügyfélszolgálat feladat II. kör, Ügyfélszolgálat feladat I. kör" , "queue_name" : "Telesales, Ügyfélszolgálat feladat II. kör, Ügyfélszolgálat feladat I. kör" , "status_begin" : "2019-10-14 14:40:28.99024+02" , "status_end" : "2019-10-14 14:40:31.00957+02" , "user_name" : "Nagy Napóleon" }, { "counts_as_work" : true , "description" : "Állapotváltást kér" , "duration" : 0.01216, "id" : 2683, "project_name" : "Telesales, Ügyfélszolgálat feladat II. kör, Ügyfélszolgálat feladat I. kör" , "queue_name" : "Telesales, Ügyfélszolgálat feladat II. kör, Ügyfélszolgálat feladat I. kör" , "status_begin" : "2019-10-14 14:40:35.98446+02" , "status_end" : "2019-10-14 14:40:35.99662+02" , "user_name" : "Nagy Napóleon" } ] } |
Munkaidő-statisztika operátoronként
/stat/worklog_by_users/list
Ez az endpoint a rendszerben töltött időket operátorok szerint csoportosítva adja vissza.
Kérés
Ez a lekérdezés abból a szempontból speciális, hogy a kötött, előre definiált oszlopokon kívül, amelyekhez szűrő is tartozik, az egyes operátori állapotok nevei is szerepelhetnek az oszloplistában (ezekhez azonban nem tartozik szűrő). Az előre definiált oszlopok:
user
: felhasználó nevesum_all
: a felhasználó által a kért időtartományon belül az összes rendszerben töltött idősum_counts_as_work
: a felhasználó által a kért időtartományon belül az összes munkának számító idő
Ezenkívül a lekérdezés filters
tömbjében szerepelnie kell egy időtartam-szűrőnek, interval
néven.
{ "columns" : [ /* a lekért oszlopok */ { "name" : "user" , "order" : "asc" /* növekvő sorrend ezen oszlopok alapján */ }, { "name" : "sum_all" }, { "name" : "sum_counts_as_work" }, { "name" : "Ügyfélre vár" }, { "name" : "Beszélget" }, { "name" : "Regisztrál" }, { "name" : "Visszahívásra vár" }, { "name" : "Kézi hívás" }, { "name" : "Előmunka" }, { "name" : "Ki akar lépni" }, { "name" : "Állapotváltást kér" }, { "name" : "Operátori beszélgetés" }, { "name" : "Hívási sor váltás" }, { "name" : "Szünetet tart" }, { "name" : "Ebédel" }, { "name" : "Oktatáson van" } ], "filters" : [ { "condition" : { "type" : "relative" , "value" : "last month" }, "name" : "interval" , "type" : "datetime" } ], "limit" : 50 } |
Válasz
Az összes számérték (adott állapotban eltöltött idő) másodpercben értendő.
{ "config" : { "have_more" : false }, "data" : [ { "Beszélget" : 926, "Ebédel" : 0, "Előmunka" : 15985, "Hívási sor váltás" : 0, "Ki akar lépni" : 4, "Kézi hívás" : 59, "Oktatáson van" : 0, "Operátori beszélgetés" : 0, "Regisztrál" : 430, "Szünetet tart" : 5702, "Visszahívásra vár" : 0, "id" : "21" , "sum_all" : 23232, "sum_counts_as_work" : 17530, "user" : "XXX YYY" , "Állapotváltást kér" : 92, "Ügyfélre vár" : 34 }, { "Beszélget" : 1215, "Ebédel" : 0, "Előmunka" : 53411, "Hívási sor váltás" : 0, "Ki akar lépni" : 32, "Kézi hívás" : 92, "Oktatáson van" : 0, "Operátori beszélgetés" : 0, "Regisztrál" : 1101, "Szünetet tart" : 24571, "Visszahívásra vár" : 0, "id" : "sum" , "sum_all" : 80987, "sum_counts_as_work" : 56416, "user" : "∑" , "Állapotváltást kér" : 234, "Ügyfélre vár" : 331 } ] } |
Integráció külső rendszerekkel
Többször felmerült az igény a Calgo/Comnica CC élete során, hogy az ügyfél szeretné a saját szoftverével összekötni a Comnica rendszert. Erre hoztuk létre az integrációs endpointokat, amiknél az a kritérium, hogy az adatokat minél felhasználható, utómunkát minél kevésbé igénylő formában, és lehetőleg egyszerű interakció hatására adjuk vissza.
Integrációs endpointok:
CC rekord letöltése
Path: /integration/cc/record/load/v1
Request payload:
{ "id" : 42 } |
Az egyetlen mező az id, a rekord egyedi azonosítója.
Response payload:
{ "comments" : [ { "comment" : "Example comment 1" , "created_at" : "2019-11-19 16:21:17+01" , "id" : 13, "user_id" : 0 }, { "comment" : "Example comment 2" , "created_at" : "2019-11-19 16:22:57+01" , "id" : 14, "user_id" : 0 } ], "contacts" : [ { "active" : true , "contact" : "3611234567" , "id" : 141, "name" : "" , "priority" : 1, "type" : "phone" }, { "active" : true , "contact" : "3619876543" , "id" : 142, "name" : "" , "priority" : 2, "type" : "phone" } ], "custom_data" : { "aaa" : "äää" , "bbb" : "ßßß" , "phone" : "3611234567" }, "system_columns" : { "callback_to_user_id" : null , "dial_from" : null , "dial_to" : null , "id" : 72, "is_redial" : false , "manual_redial" : false , "next_call" : null , "priority" : 1, "project_id" : 9, "termination_id" : null , "tries_since_last_contact" : null } } |
Részletek:
- comments: a rekord kommentjei tömbben; tartalom, időpont, id, user_id mezőkkel
- contacts: a rekordhoz tartozó kontaktok tömbben; active, telefonszám, id, kontakt neve, prioritás, típus
- custom_data: a rekordhoz tartozó szkriptmezők
- system_columns: a rekord rendszermezői; visszahívás usere, hívhatóság tól-ig, id, visszahívás-e, kézi beállítású visszahívás-e, következő hívás időpontja, prioritás, project_id, terminációs kód, utolsó sikeres kapcsolatfelvétel óta próbálkozások száma
CC rekord létrehozása
Path: /integration/cc/record/save/v1
Request payload:
{ "comments" : [ { "comment" : "Example comment 1" , "created_at" : "2019-11-19 16:21:17+01" }, { "comment" : "Example comment 2" , "created_at" : "2019-11-19 16:22:57+01" } ], "contacts" : [ { "active" : true , "contact" : "3611234567" , "name" : "" , "preferred" : true , "priority" : 1, "source_column" : "phone" , "type" : "phone" }, { "active" : true , "contact" : "3619876543" , "name" : "" , "preferred" : false , "priority" : 2, "source_column" : "phone2" , "type" : "phone" } ], "custom_data" : { "aaa" : "äää" , "bbb" : "ßßß" , "phone" : "3611234567" }, "system_columns" : { "callback_to_user_id" : null , "dial_from" : null , "dial_to" : null , "manual_redial" : null , "next_call" : null , "priority" : 1, "project_id" : 9 } } |
Részletek:
- comments: a rekord kommentjei tömbben; tartalom, időpont
- contacts: a rekordhoz tartozó kontaktok tömbben; active, telefonszám, kontakt neve, preferált-e (ebből lesz a rekordba bejegyezve a preferred_contact_id, ami alapján a hívást intézzük), prioritás (1 es 9 kozott, a 9 a magasabb!), forrásoszlop (ezt a kliens megjeleníti az operátornak, hogy tudja, hogy miféle telefonszám az – otthoni, munkahelyi –, például), kontakt típusa (általában phone vagyis telefonszám, de a jövőben lehet ez más is)
- custom_data: a rekordhoz tartozó adatmezők. A choice típusú mezők értékei mindig tömbként adandók meg, akkor is, ha csak egy értéke van:
["savoury"]
,["red"]
(lásd később az adatmezők lekérdezése részt) - system_columns: a rekord rendszermezői; visszahívás usere, hívhatóság tól-ig, kézi beállítású visszahívás-e, következő hívás időpontja, prioritás, project_id (ez az egyetlen kötelező mező)
A bevitt adatokon típusellenőrzéseket végzünk. A rekordok adatmezőinek a típusát a CC projekt adatmezőinek lekérdezése szakaszban leírtak szerint lehet lekérdezni.
Response payload:
{ "id" : 42 } |
CC rekord szerkesztése
Path: /integration/cc/record/update/v1
Request payload:
{ "id" : 42, "custom_data" : { "aaa" : "äää" , "bbb" : "ßßß" , "phone" : "3611234567" }, "system_columns" : { "callback_to_user_id" : null , "manual_redial" : null , "next_call" : null , "termination_id" : 9 } } |
Részletek:
- id: a rekord azonosítója
- custom_data: a rekordhoz tartozó adatmezők. A choice típusú mezők értékei mindig tömbként adandók meg, akkor is, ha csak egy értéke van:
["savoury"]
,["red"]
(lásd később az adatmezők lekérdezése részt) - system_columns: a rekord rendszermezői; visszahívás usere, kézi beállítású visszahívás-e, következő hívás időpontja, termináció id (ez a terminations filterdata adott project_id-ra szűkített lekérdezésével tudható meg, lásd a Filterdata szakaszt)
A bevitt adatokon típusellenőrzéseket végzünk. A rekordok adatmezőinek a típusát a CC projekt adatmezőinek lekérdezése szakaszban leírtak szerint lehet lekérdezni.
Response payload:
{ "id" : 42 } |
CC projekt adatmezőinek lekérdezése
Path: /integration/cc/project/fields/list/v1
Request payload:
{ "project_id" : 9 } |
Response payload:
[ { "datatype" : "phone" , "name" : "phone" , "type" : "input" , "is_contact" : true , "id" : 153 }, { "type" : "input" , "is_contact" : true , "id" : 154 , "datatype" : "phone" , "name" : "phone2" }, { "is_contact" : false , "type" : "input" , "id" : 155 , "datatype" : "string" , "name" : "aaa" }, { "name" : "bbb" , "datatype" : "string" , "id" : 156 , "type" : "input" , "is_contact" : false }, { "datatype" : "number" , "name" : "num" , "type" : "input" , "is_contact" : false , "id" : 157 }, { "is_contact" : false , "type" : "input" , "id" : 158 , "datatype" : "date" , "name" : "birthday" }, { "datatype" : "datetime" , "name" : "appointment" , "type" : "input" , "is_contact" : false , "id" : 159 }, { "selection" : "single" , "is_contact" : false , "name" : "flavour" , "datatype" : "string" , "content" : [ { "savoury" : "Savoury" }, { "sweet" : "Sweet" } ], "id" : 160 , "type" : "choice" }, { "type" : "choice" , "id" : 161 , "content" : [ { "black" : "Black" }, { "white" : "White" }, { "red" : "Red" }, { "grue" : "Grue" }, { "yellow" : "Yellow" } ], "datatype" : "string" , "name" : "colour" , "is_contact" : false , "selection" : "multi" } ] |
Részletek:
- Az előzőekhez képest (amikor csak phone, phone2, aaa, bbb mezők voltak) kiegészítettük pár extra oszloppal a rekordot a példa kedvéért. A következő oszlopok lettek felvéve:
- num nevű oszlop, amibe szám kell kerüljön;
- birthday oszlop amibe dátum (YYYY-MM-DD);
- appointment, amibe időpont (YYYY-MM-DD HH24:MI:SS[.UUUUUU][ZZZZ] — vagyis a törtmásodpercek és az időzóna opcionális, de előfordulhat; az óra 24 órás formában elfogadott);
- flavour, ami egy lista ahol egy konkrét értéket kell kiválasztani egy véges készletből (pl. a szkripten „egyválasztós választó” néven hozható ilyen létre);
- colour, ami egy többértékes lista („többválasztós választó”);
Duplikáció szűrés
Endpoint: api/integration/cc/record/save/v1 (rekord betöltés)
Változás:
- ha valtozatlanul hivjuk az endpointot, akkor nincs duplikacio szures
- ha a payload-ba az kovetkezo key:value parosok kerulnek, akkor normal duplikacioszures tortenik:
"options": { "check_duplicates": "basic" }
- ha a payload-ba az kovetkezo key:value parosok kerulnek, akkor szigoru duplikacioszures tortenik:
"options": { "check_duplicates": "strict" }
CC hívásrekordok lekérdezése
Path: /integration/cc/calls/list/v1
Request payload:
{ "rq_sent" : "2020-09-01 00:00:00+00" , "payload" : { "columns" : [ { "name" : "soundfile_exists" }, { "name" : "call_id" }, { "name" : "record_id" }, { "name" : "calldirection" }, { "name" : "project_name" }, { "name" : "operator_name" }, { "name" : "phone" }, { "name" : "terminated" }, { "name" : "terminating_code" }, { "name" : "termination_category" }, { "name" : "started_at" }, { "name" : "queued_at" }, { "name" : "linked_at" }, { "name" : "hangup_at" }, { "name" : "queue_length" }, { "name" : "hold_length" }, { "name" : "talk_length_without_hold" }, { "name" : "talk_length" }, { "name" : "hangup_reason_type" }, { "name" : "operator_name_not_empty" }, { "name" : "comments" }, { "name" : "ivr_custom_field_1" }, { "name" : "ivr_custom_field_2" }, { "name" : "ivr_custom_field_3" }, { "name" : "ivr_custom_field_4" }, { "name" : "ivr_custom_field_5" }, { "name" : "incomingnumber" } ], "filters" : [ { "name" : "call_id" , "type" : "string" }, { "name" : "record_id" , "type" : "string" }, { "name" : "project_name" , "type" : "multiselect" , "items" : "projects" }, { "name" : "operator_name" , "type" : "multiselect" , "items" : "users" }, { "name" : "phone" , "type" : "string" }, { "name" : "terminated" , "type" : "boolean" }, { "name" : "terminating_code" , "type" : "multiselect" , "items" : "terminations" }, { "name" : "started_at" , "type" : "datetime" , "required" : true , "condition" : { "type" : "relative" , "value" : "this week" } }, { "name" : "queued_at" , "type" : "datetime" }, { "name" : "linked_at" , "type" : "datetime" }, { "name" : "hangup_at" , "type" : "datetime" }, { "name" : "queue_length" , "type" : "integer" , "display_format" : "time" }, { "name" : "hold_length" , "type" : "integer" }, { "name" : "talk_length_without_hold" , "type" : "integer" }, { "name" : "talk_length" , "type" : "integer" }, { "name" : "listened" , "type" : "boolean" }, { "name" : "rating" , "type" : "multiselect" , "items" : "ratings" }, { "name" : "listened_by" , "type" : "multiselect" , "items" : "users" }, { "name" : "listened_at" , "type" : "datetime" }, { "name" : "rated_by" , "type" : "multiselect" , "items" : "users" }, { "name" : "rated_at" , "type" : "datetime" }, { "name" : "termination_category" , "type" : "multiselect" , "items" : "termination_categories" }, { "name" : "soundfile_exists" , "type" : "boolean" }, { "name" : "hangup_by" , "type" : "multiselect" , "items" : "hangup_by" }, { "name" : "calldirection" , "type" : "multiselect" }, { "name" : "hangup_reason_type" , "type" : "multiselect" , "items" : "callreason_types" }, { "name" : "calltype" , "type" : "string" }, { "name" : "operator_name_not_empty" , "type" : "boolean" }, { "name" : "comments" , "type" : "string" }, { "name" : "ivr_custom_field_1" , "type" : "string" }, { "name" : "ivr_custom_field_2" , "type" : "string" }, { "name" : "ivr_custom_field_3" , "type" : "string" }, { "name" : "ivr_custom_field_4" , "type" : "string" }, { "name" : "ivr_custom_field_5" , "type" : "string" }, { "name" : "incomingnumber" , "type" : "multiselect" , "items" : "incomingnumbers" } ], "limit" : 50 } } |
Részletek:
- soundfile_exists: létezik hangfájl.
- call_id: hívás azonosítója
- record_id: ügyfélrekord azonosítója, amellyel kapscolatban létrejött a hívás.
- calldirection: hívás irány (bejövő / kimenő)
- project_name: melyik kampányban található az ügyfélrekord. Szűrőknél a kampányok azonosítóját tartalmazó tömb.
- operator_name: hívást kezelő operátor neve. Szűrőknél az operátorok azonosítóját tartalmazó tömb.
- phone: az ügyfél telefonszáma
- terminated: lezárt-e az ügyfélrekord
- terminating_code: terminációs kód, amivel lezárták a beszélgetést.
- termination_category: terminációs kód kategóriája.
- started_at: hívás indítás időpontja.
- queued_at: hívás hívási sorba kerülésének időpontja (ekkor kezdett el várakozni az operátorra)
- linked_at: hívás operátorhoz kapcsolásának időpontja.
- hangup_at: hívás megszakítás időpontja.
- queue_length: operátorra várakozás hossza (sec)
- hold_length: hívástartás hossza (sec)
- talk_length_without_hold: beszélgetés hossza hívástartás nélkül.
- talk_length: beszélgetés hossza
- hangup_reason_type: hívás megszakításának oka
- operator_name_not_empty: operátorhoz kapcsolódott a hívás
- comments: megjegyzések a híváshoz tartozó ügyfélrekordnál.
- ivr_custom_field_{1..5}: egyeztetés alapján IVR-on keresztül kitöltött mezők
- incomingnumber: telefonszám, amit bejövő hívás esetén tárcsázott az ügyfél.
Response payload:
{ "payload" : { "data" : [ { "listened" : false , "project_name" : "teszt1" , "record_id" : "46844" , "talk_length_without_hold" : 13.84735, "call_id" : "8765" , "id" : 8765, "operator_name" : "Tesz Elek" , "project_id" : 838, "soundfile_exists" : true , "phone" : "3612550567" , "terminating_code" : "bye" , "talk_length" : 13.84735, "started_at" : "2020-08-18 08:48:06.88883+02" , "rating" : 0, "terminated" : true }, { "terminating_code" : "bye" , "talk_length" : 3.2809, "started_at" : "2020-07-27 14:18:47.91042+02" , "rating" : 0, "terminated" : true , "record_id" : "46679" , "project_name" : "teszt1" , "listened" : false , "talk_length_without_hold" : 3.2809, "operator_name" : "Tesz Elek" , "call_id" : "8764" , "id" : 8764, "soundfile_exists" : true , "project_id" : 684, "phone" : "3612550567" }, { "record_id" : "46669" , "project_name" : "teszt2" , "listened" : false , "id" : 8763, "call_id" : "8763" , "operator_name" : "Tesz Elek" , "project_id" : 683, "soundfile_exists" : true , "talk_length_without_hold" : 3.4847, "phone" : "3612550567" , "terminating_code" : "bye" , "started_at" : "2020-07-27 14:17:17.94854+02" , "talk_length" : 3.4847, "rating" : 0, "terminated" : true }, { "talk_length_without_hold" : 4.09818, "id" : 8762, "call_id" : "8762" , "operator_name" : "Tesz Elek" , "soundfile_exists" : true , "project_id" : 681, "phone" : "3612550567" , "project_name" : "teszt2" , "listened" : false , "record_id" : "46649" , "rating" : 0, "terminated" : true , "terminating_code" : "bye" , "talk_length" : 4.09818, "started_at" : "2020-07-27 14:13:22.91056+02" } ], "config" : { "have_more" : false } }, "res_sent" : "2020-10-06 11:04:20.775860+0000" , "rq_rcvd" : "2020-10-06 11:04:20.729428+0000" } |
CC rekordok lekérdezése
Path: /integration/cc/record/list/v1
Request payload:
{ "payload" : { "columns" : [ { "name" : "record_id" }, { "name" : "upload" , "order" : "desc" }, { "name" : "terminated" }, { "name" : "terminating_code" }, { "name" : "phone" }, { "name" : "phone_comment" } ], "filters" : [ { "condition" : 280, "name" : "project" , "type" : "select" }, { "condition" : { "type" : "absolute" , "value" : { "from" : "2019-11-25 00:00:00+00" , "to" : "2019-12-01 23:59:59+00" } }, "name" : "upload" , "type" : "datetime" } ], "limit" : 50 }, "rq_sent" : "2022-05-31 16:04:57.879+0000" } |
Filterek:
- project: type=select, kötelező — a project id-je.
- record_id: type=string
- upload: type=datetime — feltöltés időpontja
- terminated: type=boolean — terminált-e?
- terminating_code: type=multiselect, filterdata=terminations — terminációs kód
- termination_category: type=multiselect, filterdata=termination_categories — terminációs kategória
- next_call: type=datetime — következő (vissza)hívás ideje
- callback_to_user: type=multiselect, filterdata=users — szűrés visszahíváshoz rendelt user alapján
- is_redial: type=boolean — visszahívás-e?
- manual_redial: type=boolean — kézi, explicite beállított visszahívás-e, vagy automatikus újrapróbálkozás
- last_comment: type=string — utolsó komment
- last_agent_work_at: type=datetime — utolsó operátori munka ideje
- updated_at: type=datetime — utolsó módosítás ideje
- inserted_at: type=datetime — a rekord rendszerbe kerülésének ideje
- last_agent: type=multiselect, filterdata=users — a rekorddal utoljára dolgozó operátor
- last_call_at: type=datetime — az utolsó hívás időpontja
- valamint a projektmező listázóval begyűjthető adatmezők amiket az adatbázis feltöltésekor vagy a szkript kitöltésekor töltünk fel adattal
Response payload:
{ "payload" : { "config" : { "have_more" : false }, "data" : [ { "phone" : "3655555123" , "id" : 14396, "upload" : "2019-11-27 10:57:17.801476+00" , "terminated" : true , "phone_comment" : "" , "record_id" : 14396, "terminating_code" : "bye" }, { "upload" : "2019-11-27 10:57:17.801476+00" , "phone" : "3655555987" , "id" : 14397, "record_id" : 14397, "terminated" : false , "phone_comment" : "" }, ... ] }, "rq_rcvd" : "2022-05-31 18:04:58.128130+0200" , "res_sent" : "2022-05-31 18:04:58.386605+0200" } |
CC tömeges művelet rekordokon (bulk)
Path: /integration/cc/record/bulk_modify/v1
Method: POST
A request alapvetően olyan, mint a fenti Rekordok listázása listrequest, pár extra paraméterrel. A filterekkel beállítjuk hogy milyen tulajdonságú rekordokkal szeretnénk dolgozni, majd az action, subaction és params paraméterekkel felkonfiguráljuk a bulk műveletet. Példa a fenti lista alapján: vesszük az összes 356-os kódú terminált rekordot, és áttermináljuk őket 458-as terminációs kódra.
{ "payload" : { "action" : "change_termination" , "filters" : [ { "condition" : 280 , "name" : "project" , "type" : "select" }, { "condition" : { "type" : "absolute" , "value" : { "from" : "2019-11-25 00:00:00+00:00" , "to" : "2019-12-01 23:59:59+00:00" } }, "name" : "upload" , "type" : "datetime" }, { "condition" : [ 356 ], "name" : "terminating_code" , "type" : "multiselect" } ], "params" : { "condition" : 458 } }, "rq_sent" : "2022-05-31 16:53:55.841+0000" } |
Request mezők a listrequest paramétereken felül:
- action: a művelet, lehetséges értékei „change_termination”, „change_callback”, „change_data”
- subaction: néha a műveletnek vannak alváltozatai.
- change_callback action esetén: „change_to_manual_callback”, „change_to_auto_callback”, „change_callback_user”, „remove_callback”
- params: a művelet és az alművelet által igényelt egyéb argumentumok, mint a terminációs kód vagy az átírandó mező neve és új értéke
- dry_run: nem végzi el a műveletet, csak visszatér a talált rekordok számával
Válasz:
{ "payload" : { "count" : 11 }, "res_sent" : "2022-05-31 18:53:56.438751+0200" , "rq_rcvd" : "2022-05-31 18:53:56.037511+0200" } |
Termináció átállítása (action: change_termination)
A params rész tartalma egyetlen „condition” kulcsú érték, a kívánt értéknek megfelelően.
Mezőérték átírása (action: change_data)
A params rész tartalma a mezőnév és az érték:
{ ... "params" : { "field" : "szuletesi_hely" , "value" : "Budapest" } } |
Visszahívás átállítása (action: change_callback)
A payload a subactionoktól függően változik
- change_to_manual_callback: Userhez rendelt visszahívás beállítása; szükséges paraméterek a user_id és next_call (a hívás időpontja)
- change_to_auto_callback: Kicsit hibás elnevezés, ez közös listás visszahívást állít be, tehát nincs user_id-hez rendelve; szükséges paraméter a next_call
- change_callback_user: Minden marad, de a rekordok kezelését más usernek adjuk; szükséges paraméter a user_id
- remove_callback: Visszahívás megszüntetése; nincs extra paraméter
CC hangfájl letöltése
Path: /recording/<callid>/download
Method: GET
Auth: basic
Az adott callid-hoz tartozó hangfájlt tölti le.
Video rekord létrehozása
Path: /video/projectdata/create
Request payload:
{ "rq_sent" : "2020-09-01 00:00:00+00" , "payload" : { "video_project_id" : 1, "data" : { "identifying_company" : "Comnica" , "name" : "Teszt Elke" , "birth_name" : "Tesztelő Elke" , "birth_place" : "Csömör" , "birth_date" : "2000-01-01" , "mothers_maiden_name" : "Kulcsos Katalin" , "permanent_zip" : "1119" , "permanent_country" : "Magyarország" , "permanent_city" : "Budapest" , "permanent_street" : "Mohai út 38." , "temporary_zip" : "1119" , "temporary_country" : "Magyarország" , "temporary_city" : "Budapest" , "temporary_street" : "Mohai út 38." , "email" : "support@comnica.cc" , "phone" : "3612550991" , "simplified_identification" : true } } } |
Részletek:
- video_project_id: a video kampány azonosítója (lásd. Filterdata fejezet)
- data: a rekordban tárolni kívánt adatok
- kulcsok: oszlopnevek
- értékek: az oszlopban tárolni kívánt értékek
A példában megadott oszlopok kötelező elemek. Hiányuk vagy érték nélküli megadásuk sikertelen betöltést eredményez.
További – a data-ban nem szerplő oszlopok – is megadhatóak, amennyiben léteznek. A rekordok adatmezőinek a típusát a Video projekt adatmezőinek lekérdezése szakaszban leírtak szerint lehet lekérdezni.
Response payload:
{ "payload" : { "url" : "video url, amin kersztül az ügyfél be tud lépni a rendszerbe" , "video_projectdata_id" : 42 }, "res_sent" : "2020-01-01 00:00:00+00" , "rq_rcvd" : "2020-01-01 00:00:00+00" } |
Video projekt adatmezőinek lekérdezése
Path: /video/project/column/list
Request payload:
{ "rq_sent" : "2020-09-01 00:00:00+00" , "payload" : { "project_id" : 1 } } |
Response payload:
{ "rq_rcvd" : "2020-09-22 16:47:15.706141+0200" , "res_sent" : "2020-09-22 16:47:15.821405+0200" , "payload" : [ { "mandatory_at_output" : true , "mandatory_at_input" : true , "output_only" : false , "name" : "identifying_company" , "datatype" : "string" , "type" : "input" , "id" : 165 , "editable" : false }, { "mandatory_at_output" : true , "mandatory_at_input" : true , "output_only" : false , "name" : "name" , "datatype" : "string" , "type" : "input" , "editable" : true , "id" : 166 }, { "output_only" : false , "name" : "birth_name" , "mandatory_at_output" : true , "mandatory_at_input" : true , "type" : "input" , "editable" : true , "id" : 167 , "datatype" : "string" }, { "name" : "birth_place" , "output_only" : false , "mandatory_at_input" : true , "mandatory_at_output" : true , "id" : 168 , "editable" : true , "type" : "input" , "datatype" : "string" }, { "output_only" : false , "name" : "birth_date" , "mandatory_at_output" : true , "mandatory_at_input" : true , "type" : "input" , "editable" : true , "id" : 169 , "datatype" : "date" }, { "datatype" : "string" , "type" : "input" , "id" : 170 , "editable" : true , "mandatory_at_output" : true , "mandatory_at_input" : true , "output_only" : false , "name" : "mothers_maiden_name" }, { "datatype" : "string" , "editable" : true , "id" : 171 , "type" : "input" , "mandatory_at_input" : true , "mandatory_at_output" : true , "name" : "permanent_zip" , "output_only" : false }, { "mandatory_at_input" : true , "mandatory_at_output" : true , "name" : "permanent_country" , "output_only" : false , "datatype" : "string" , "id" : 172 , "editable" : true , "type" : "input" }, { "type" : "input" , "id" : 173 , "editable" : true , "datatype" : "string" , "name" : "permanent_city" , "output_only" : false , "mandatory_at_output" : true , "mandatory_at_input" : true }, { "id" : 174 , "editable" : true , "type" : "input" , "datatype" : "string" , "output_only" : false , "name" : "permanent_street" , "mandatory_at_input" : true , "mandatory_at_output" : true }, { "name" : "temporary_zip" , "output_only" : false , "mandatory_at_input" : true , "mandatory_at_output" : true , "editable" : true , "id" : 175 , "type" : "input" , "datatype" : "string" }, { "output_only" : false , "name" : "temporary_country" , "mandatory_at_input" : true , "mandatory_at_output" : true , "editable" : true , "id" : 176 , "type" : "input" , "datatype" : "string" }, { "mandatory_at_output" : true , "mandatory_at_input" : true , "output_only" : false , "name" : "temporary_cit" , "datatype" : "string" , "type" : "input" , "id" : 177 , "editable" : true }, { "mandatory_at_output" : true , "mandatory_at_input" : true , "name" : "temporary_street" , "output_only" : false , "datatype" : "string" , "type" : "input" , "editable" : true , "id" : 178 }, { "type" : "input" , "id" : 179 , "editable" : true , "datatype" : "string" , "name" : "email" , "output_only" : false , "mandatory_at_output" : true , "mandatory_at_input" : true }, { "output_only" : false , "name" : "phone" , "mandatory_at_output" : true , "mandatory_at_input" : true , "type" : "input" , "editable" : true , "id" : 180 , "datatype" : "string" }, { "datatype" : "string" , "content" : [ { "label" : "útlevél" , "value" : "passport" }, { "value" : "license" , "label" : "jogosítvány" }, { "label" : "személyi igazolvány" , "value" : "identity card" } ], "type" : "choice" , "id" : 181 , "editable" : true , "mandatory_at_output" : true , "mandatory_at_input" : false , "selection" : "single" , "name" : "id_card_type" , "output_only" : true }, { "type" : "input" , "editable" : true , "id" : 182 , "datatype" : "string" , "name" : "id_card_number" , "output_only" : true , "mandatory_at_output" : true , "mandatory_at_input" : false }, { "datatype" : "string" , "type" : "input" , "editable" : true , "id" : 183 , "mandatory_at_output" : true , "mandatory_at_input" : false , "output_only" : true , "name" : "address_card_number" }, { "datatype" : "string" , "id" : 184 , "editable" : true , "type" : "input" , "mandatory_at_input" : false , "mandatory_at_output" : true , "output_only" : false , "name" : "nationality" }, { "output_only" : true , "name" : "public_figure" , "selection" : "single" , "mandatory_at_input" : false , "mandatory_at_output" : true , "editable" : true , "id" : 185 , "type" : "choice" , "content" : [ { "value" : "customer" , "label" : "célszemély" }, { "value" : "family member" , "label" : "családtag" } ], "datatype" : "string" }, { "type" : "input" , "editable" : false , "id" : 186 , "datatype" : "string" , "name" : "external_id" , "output_only" : false , "mandatory_at_output" : true , "mandatory_at_input" : false }, { "mandatory_at_output" : true , "mandatory_at_input" : true , "output_only" : false , "name" : "simplified_identification" , "datatype" : "boolean" , "type" : "input" , "editable" : false , "id" : 187 }, { "type" : "input" , "editable" : false , "id" : 188 , "datatype" : "date" , "output_only" : false , "name" : "preferred_time" , "mandatory_at_output" : true , "mandatory_at_input" : false }, { "type" : "input" , "id" : 189 , "editable" : true , "datatype" : "boolean" , "output_only" : true , "name" : "statements_accepted" , "mandatory_at_output" : true , "mandatory_at_input" : false }, { "datatype" : "boolean" , "id" : 190 , "editable" : true , "type" : "input" , "mandatory_at_input" : false , "mandatory_at_output" : true , "output_only" : true , "name" : "recordings_confirmed" }, { "datatype" : "boolean" , "id" : 191 , "editable" : true , "type" : "input" , "mandatory_at_input" : false , "mandatory_at_output" : true , "name" : "data_check_completed" , "output_only" : true } ] } |
Részletek: A válaszban a payload elem tartalmazza a kampányban található oszlopokat. Az oszlopok tulajdonságai:
- name: a neve
- datatype: adattípus
- id: rendszerben használt azonosító
- type: mező típusa
- content (choice type esetén): a tartalmazott elemek
- editable: módosítható
- output_only: betöltésnél, rekordmódosításnál nem módosítható, csak a rekord adatainak lekérdezésekor jelenik meg.
- mandatory_at_input: rekord létrehozásnál kötelező mező
- mandatory_at_output: rekord lekérdezésében kötelezően megjelenik
Webhookok
A Comnica bizonyos eseményekre tud egy távoli URL meghívásával reagálni. Azon a címen valamilyen HTTP szervernek kell figyelnie, és JSON bodyval rendelkező POST kéréseket fogadnia. A Comnica rendszere csak egy requestet küld minden eseményről és nem figyeli, hogy arra milyen válasz érkezik a beállított végponttól, és ennek megfelelően nem is próbálkozik újra az adott eseménnyel kapcsolatos figyelmeztetéssel.
Beállítás
Minden CC (telefonos) és azonosítás (videó, NRTI) projekthez lehet külön rendelni 1 darab webhook URL-t, például https://api.example.com:8080/comnica-webhook-receiver/
Egyelőre más konfigurációs lehetőség nincs.
Formátum
A webhook hívás bodyja UTF-8 kódolású JSON string. Három kulccsal rendelkezik.
event
: az esemény, ami miatt a hívás érkezett, példáulcc.record.save
, mindig ki van töltveevent_reason
: egyfajta megkülönböztető jelzés az adott eseményen belül, példáuloperator.termination
, lehetnull
payload
: objektum, benne valamennyi adattal, ami szükségesnek és elégségesnek tűnik. Legalább{}
az értéke.
{ "event" : "i12n.record.state.change" , "event_reason" : null , "payload" : { "record_id" : 42, "previous_state" : "active" , "new_state" : "reviewing" } } |
Tartalom
A lehetséges események jelenleg a következők:
CC rekord mentése
- event:
cc.record.save
- event_reason:
site.edit
— az adminfelületen szerkesztettékoperator.save
— az operátori kliensben mentették el a rekordotoperator.termination
— az operátori kliensben elmentették és lezárták a rekordot
- payload:
record_id
— a rekord azonosítójatermination_id
— a termináció azonosítója vagynull
terminating_code
— a termináció neve vagynull
Azonosítás állapotváltása
- event:
i12n.record.state.change
- event_reason:
null
— általábantimeout
— a rekord készen állt arra, hogy az ügyfél az azonosítást megkezdje, de az időlimiten belül ez nem történt megtimeout_before_ready
— a rekord nem került használható állapotba az időlimiten belülreview_timeout
— a rekord ellenőrzése nem történt meg az időlimiten belül
- payload:
record_id
— a rekord azonosítójaprevious_state
— az előző állapotnew_state
— az új állapot