Belső interfész dokumentáció

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étel true vagy false 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észletezett filterdata 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 a type és value kulcsokat tartalmazza. Ha type értéke absolute, akkor a value egy objektum kell legyen, amelyben a from illetve to kulcsok határozzák meg a kívánt időtartomány elejét és végét. Ha a type értéke relative, akkor a value é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,  boolean
    • minimum és maximum, 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 a value (ha is_range hamis), vagy a  from és to kulcsoknak kell szerepelnie (ha is_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

  • “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

  • “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

  • “queues”: hívási sorok nevei 

    • opcionális paraméterek:

      • all: boolean

  • “robinson_lists”: Robinson-listák

    • opcionális paraméterek:

      • all: boolean – ha true, az inaktívakat is listázza

  • “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
  • “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 ಠ_ಠ
  • “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

  • “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

  • “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 és maximum 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ó neve
  • sum_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:

CC record load response
{
    "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ó”);

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ául cc.record.save, mindig ki van töltve
  • event_reason: egyfajta megkülönböztető jelzés az adott eseményen belül, például operator.termination, lehet null
  • 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ék
    • operator.save — az operátori kliensben mentették el a rekordot
    • operator.termination — az operátori kliensben elmentették és lezárták a rekordot
  • payload:
    • record_id — a rekord azonosítója
    • termination_id — a termináció azonosítója vagy null
    • terminating_code — a termináció neve vagy null

Azonosítás állapotváltása

  • event: i12n.record.state.change 
  • event_reason:
    • null — általában
    • timeout — 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 meg
    • timeout_before_ready — a rekord nem került használható állapotba az időlimiten belül
    • review_timeout — a rekord ellenőrzése nem történt meg az időlimiten belül
  • payload:
    • record_id — a rekord azonosítója
    • previous_state — az előző állapot
    • new_state — az új állapot