---
# System prepended metadata

title: Callcenter solution protocol

---

# Callcenter solution protocol

New engine will not only sent messages in new format but also receive messages from call center device.

## **payloads format**


Message contains binary data in message pack format, after encoding it will have json in next format
```
 {"method": {method_name}, "params": {params}, "id": {optional_string}}
```

Service supports 2 types of messages: 
- event/command
- request/responce

--------------------------------

### request/responce

Message is request if it changes data source and requires response with confirmation. Such message and responce should containt the same "id" parametr

response format
```
{"result": object, "id": "9", "meta": object }
```
 * result - mandatory - result of method
 * id - mandatory id that was specified by client in request
 * meta - optional, reserved for future

--------------------------------

### event/command

Message is event/command if it does not change data source and uses for synchronization/communication purposes. Such message does not  contain “id” parametr in payload and responce is no needed

--------------------------------
Please note: data source (databases, blob storage, etc) ids for objects in params/result should be hidden, uuids should be used instead


# Session start & service healh checking

## **session.start** *(session registration)*
Direction: ***client -> server***
Type: ***request/responce***

```
{"method": "session.start", "params": {"inst_id":"uuid", "br":"cc_windows_desktop_beta", "c_ver": "1.20", "agents_timestamp":"timestamp","contacts_groups_timestamp":"timestamp", "contacts_timestamp":"timestamp", "queues_timestamp":"timestamp" }, "id":"1232131"}
```

where params contains: 
* **inst_id, br, c_ver** - session information (device id, branch, client version)
* **agents_timestamp, contacts_timestamp, queues_timestamp, contacts_groups_timestamp** - timestamps of main resources for full synchronization

response payload includes session id, that inform client about session establishment

```
{"result": {"sid":"uuid"}, "id": "1232131"}
```

## **ping** *(command for service healh checking)*
Direction: ***client -> server***
Type: ***event/command***

```
{"method": "ping", "params": {"sid":"uuid"}}
```

where params contains: 
* **sid** - session id

After receiving "ping" command cc_socket_engine should send "pong" command to client.

## **pong** *(command for service healh checking)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "pong", "params": {"sid":"uuid"}}
```

where params contains: 
* **sid** - session id

"ping/pong" commands will help to understand that all service components work well. Espesially in case when we have no  much events in socket.    
 
The absence of "pong" command will tell cc client that service is not work correctly. In this case client may restart socket connection and synchronization process.  

Details like time intervals and actions should be disscused.

# Full data synchronizaton after session start

After successful session establishment server should analyze data timestamps received from client in "session.start" request and send update events to clients if server's data timestamps were changed.  

## **agents.updated**  *(directory synchronization)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "agents.updated", "params": {"sid":"uuid", "agents_timestamp":"timestamp", "agents":[agent1, agent2, ... , agentn] }}
```
where params contains: 
* **sid** - session id
* **agents_timestamp** - new agents timestamp
* **agents** - array of agents

where agent is json object with next attributes:

**first_name,
last_name,
image_url, 
company, 
department, 
job_title,
show_in_company_directory, 
phone_numbers, 
id, 
interlink_id**

## **contact_groups.updated**  *(external contacts groups synchronization)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "contact_groups.updated", "params": {"sid":"uuid", "groups_timestamp":"timestamp", "groups":[group1, group2, ... , groupn] }}
```

where params contains: 
* **sid** - session id
* **groups_timestamp** - new timestamp
* **groups** - array of groups

where group is json object with next attributes:

**id, 
name,
icon_url**

## **contacts.updated**  *(external contacts synchronization)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "contacts.updated", "params": {"sid":"uuid", "contacts_timestamp":"timestamp", "contacts":[contact1, contact2, ... , contact3] }}
```

where params contains: 
* **sid** - session id
* **contacts_timestamp** - new timestamp
* **contacts** - array of contacts

where contact is json object with next attributes:

**first_name,
last_name,
image_url,
company, 
department,
job_title, 
phone_numbers, 
id,
group**

## **queues.updated**  *(queues synchronization)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "queues.updated", "params": {"sid":"uuid", "queues_timestamp":"timestamp", "queues":[queue1, queue2, ... , queuen] }}
```

where params contains: 
* **sid** - session id
* **queues_timestamp** - new timestamp
* **queues** - array of queues

where queue is json object with next attributes:
**id,
name,
icon_url,
members**   

members is an array of queue members information ***{"contactid":"uuid",  "state":"online"}***


## **agents.statuses.updated**  *(presence synchronization)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "agents.statuses.updated", "params": {"sid":"uuid", "agents_statuses":[agent_status1, agent_status2, ... , agent_statusn] }}
```

where params contains: 
* **sid** - session id
* **agents_statuses** - array of agents statuses

where agent_status is json object with next attributes:
**id,** - agent id
**status** - agent status

As an option server can include to array only agents with non default status ("offline") 

# Other synchronizaton events
Such events uses for keeping data updated after full synchronization

## **agent.updated**  *(create/update event for agent)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "agent.updated", "params": {"sid":"uuid", "agents_timestamp":"timestamp", "agent":{agent}}}
```

where params contains: 
* **sid** - session id
* **queues_timestamp** - new timestamp
* **agent** - json object

where agent is json object with next attributes:

**first_name,
last_name,
image_url,
company, 
department,
job_title,
show_in_company_directory,
phone_numbers,
id,
interlink_id**

## **agent.deleted**  *(delete event for agent)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "agent.deleted", "params": {"sid":"uuid", "agents_timestamp":"timestamp", "id":"uuid"}}
```

where params contains: 

* **sid** - session id
* **agents_timestamp** - new timestamp 
* **id** - uuid of deleted agent

## **agent.status_changed**  *(status change event for agent)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "agent.status_changed", "params": {"sid":"uuid", "agent_status":{ "id":"uuid", "status": "online" }}}
```

where params contains: 

* **sid** - session id
* **status** - new status 
* **id** - uuid of agent


## **queue.updated**  *(create/change event for queue)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "queue.updated", "params": {"sid":"uuid", "queues_timestamp":"timestamp", "queue":queue }}
```

where params contains: 

* **sid,** - session id
* **queues_timestamp** - new timestamp 
* **queue** - json object

where queue is json object with next attributes:

**id, 
name,
icon_url,
members**

members is an array of queue members ***{"contactid":"uuid",  "state":"online"}***


## **queue.deleted**  *(delete event for queue)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "queue.deleted", "params": {"sid":"uuid", "queues_timestamp":"timestamp", "id":"uuid" }}
```

where params contains: 

*  **sid** - session id
*  **queues_timestamp** - new timestamp 
*  **id** - uuid of deleted queue


## **contact_group.updated**  *(create/change event for contact group)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "contact_group.updated", "params": {"sid":"uuid", "groups_timestamp":"timestamp", "group":{"id":"uuid", "name": group_name, "icon_url": "url" }}}
```

where 

**sid** - session id
**groups_timestamp** - new timestamp 
**group** - json object 

## **contact_group.deleted**  *(delete event for contact group)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "contact_group.deleted", "params": { "sid":"uuid", "groups_timestamp":"timestamp", "id":"uuid" }}
```

where params contains:

* **sid** - session id
* **groups_timestamp** - new timestamp 
* **id** - uuid of deleted group

## **contact.updated**  *(create/update event for contact)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "contact.updated", "params": { "sid":"uuid", "contacts_timestamp":"timestamp", "contact":{contact}}}
```

where params contains:

* **sid** - session id
* **contacts_timestamp** - new timestamp 
* **contact** -json object

where contact is json object with next attributes:

**first_name, 
last_name, 
image_url, 
company, 
department, 
job_title,
phone_numbers,
id, 
group**


## **contact.deleted**  *(delete event for contact)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "contact.deleted", "params": { "sid":"uuid", "contacts_timestamp":"timestamp", "id":"uuid" }}
```

where params contains:

* **sid** - session id
* **contacts_timestamp** - new timestamp 
* **id** - uuid of deleted contact


## **bulk update event**  *(for example contacts import)*

server can use events that were described in ***"Full data synchronizaton after session start"*** section with extra parameter "fullSync"

For example: 
```
{"method": "contacts.updated", "params": {"sid":"uuid", "contacts_timestamp":"timestamp", "contacts":[contact1, contact2, ... , contact3], "fullSync":"false" }}
```

where contact is json object with next attributes:

**first_name,
last_name,
image_url,
company, 
department,
job_title, 
phone_numbers, 
id,
group**


fullSync (false) indicates that another local contacts should not be affected by synchronization


# Client to server requests

Such requests client sends to server to change main objects in data source. 

## **queue.member.login**   *(Change member(contact) status in queue)*
Direction: ***client -> server***
Type: ***request/responce***

```
  {"method": "queue.member.login", "params": {"sid":"uuid", "id":"uuid", "contact":"uuid", "state":"online"}, "id": "213213"}
```
 * **params** - hash with parameters:
    * **id** - mandatory queue UUID. If defined server will return only queue with specified uuid
    * **sid** - session id
    * **contact** - UUID of contact to change logged in state, if absent than contact should be detected from X-Channel-Id header
    * **state** - new state. possible values: **online**, **offline**
 * **id** - mandatory request ID


response payload should include status of request and new timestamp

```
{"result": {"sid":"uuid", "queues_timestamp":"timestamp", "code":"200"}, "id": "213213"}
```

## **contact.create**   *(create contact operation)*
Direction: ***client -> server***
Type: ***request/responce***

```
{"method": "contact.create", "params": {"sid":"uuid", "icon_url": string, "name": string, "phone_numbers": [phone_number1, phone_number2], "group": uuid }, "id":"1232"}
```
 * params - hash with parameters:
     * **icon_url** - optional path to contact avatar
     * **name** - mandatory contact name
     * **phone_numbers** - optional array of phone numbers objects
     * **group**  - mandatory UUID of group
     * **sid** - session id
 * id - mandatory request ID

response payload should include id of created contact
```
{"result": {"sid":"uuid", "contacts_timestamp":"timestamp", "id": uuid}, "id": "1232"}
```
 * result - json object with parameters:
     * **id** - UUID of new contact
     * **contacts_timestamp** - new timestamp
 * id - mandatory request ID
 
## **contact.update**   *(update contact operation)*
Direction: ***client -> server***
Type: ***request/responce***

```
  {"method": "contact.create", "params": { "sid":"uuid", "id":uuid, icon_url": string, "name": string, "phone_numbers": [phone_number1, phone_number2], "group": uuid }, "id":"1232"}
```
 * params - hash with parameters:
     * **id** - mandatory UUID of contact to update
     * **icon_url** - optional path to contact avatar
     * **name** - optional contact name
     * **phone_numbers** - optional array of phone numbers objects
     * **group** - opional UUID of group
 * id - mandatory request ID

response payload should include id of updated contact
```
{"result": {"sid":"uuid", "contacts_timestamp":"timestamp","id": uuid}, "id": "1232"}
```
 * result - hash with parameters:
     * **id** - UUID of new contact
     * **contacts_timestamp** - new timestamp
 * id - mandatory request ID

 
## **contact.delete**   *(delete contact operation)*
Direction: ***client -> server***
Type: ***request/responce***

```
  {"method": "contact.delete", "params": {"sid":"uuid", "id":uuid}, "id":"1232"}
```
* params - hash with parameters:
    * **id** - mandatory UUID of contact to delete
* id - mandatory request ID

response payload should include all the filtered contacts from external directory:
```
{"result": {"sid":"uuid", "contacts_timestamp":"timestamp", "status": 200}, "id": "1232"}
```

# Storages for shared data between all devices

Abstract storages designed to save shared data between all devices of contact. This data is not shared beetween another contacts. Type of storeges is key/value. Any storage modification will cause emitting event to all devices owned by contact.

We are going to create 2 types of storages: 
- Storage for shared data object settings ***(storage_data_objects)***
- Storage for shared app settings ***(storage_app_settings)***

--------------
### Storage for shared data object settings

This storage designed to save data object specific settings between all devices of contact. 

#### *Key & Value definition*
**Data object** - object in data source like: contact, agent, queue, etc (execept records in shared data storages). call.center apps will use uuid of data object as a key of record in the storage.

**Data object settings** - abstract json document. cc clients will use it as a value of the record in the storage. cc client will take care about format of the json document.  

#### *Behavior in case of deleting data object from the system*
After deleting data object(contact, agent, queue, etc) from data source, server should clean all records in the storages related to deleted data object(uuid) and send notifications    

After deleting data object who is owner of the storage(we call it person in old rest api) server should clean all records in the storage

--------------
### Storage for shared app settings

Abstract storage designed to save and share between all devices(related to owner) app-specific settings (like call settings, default sip line, ui settings, etc) that is not related to main data objects in data source.

#### *Key & Value definition*
**Abstract key** - abstract string value defined by call.center apps and used as a key of record in the storage.

**App settings** - abstract json document. cc clients will use it as a value of the record in the storage. cc client will take care about format of the json document.  

#### *Behavior in case of deleting data object from the system*
After deleting data object who is owner of devices (we call it person in old rest api) server should clean all records in the storage    


# Storages full synchronization

## **storages_timestamps.validate** *(command for validation of storages timestamps)*
Direction: ***client -> server***
Type: ***event/command***

```
{"method": "storages_timestamps.validate", "params": {"sid":"uuid", "storage_data_objects_timestamp":"timestamp", "storage_app_settings_timestamp":"timestamp" }}
```

where params contains: 
* **sid** - session id
* **storage_data_objects_timestamp, storage_app_settings_timestamp** - timestamps of storages for full synchronization

After receiving "storages_timestamps.validate" command server should analyze data timestamps received from client and send update events to clients if server's data timestamps were changed.  

## **storage_data_objects.updated**  *(storage_data_objects full synchronization)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "storage_data_object.updated", "params": {"sid":"uuid", "storage_data_objects_timestamp":"timestamp", "storage":[key_value1, key_value2, ... , key_valuen] }}
```

where params contains: 
* **sid** - session id
* **storage_data_objects_timestamp** - new timestamp 
* **storage** - array of key_value objects

where key_value is json object with next attributes:
**key** - data object(contact, agent, queue, etc) uuid 
**value** - json object   

## **storage_app_settings.updated**  *(storage_app_settings full synchronization)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "storage_app_settings.updated", "params": {"sid":"uuid", "storage_app_settings_timestamp":"timestamp", "storage":[key_value1, key_value2, ... , key_valuen] }}
```

where params contains: 
* **sid** - session id
* **storage_app_settings_timestamp** - new timestamp 
* **storage** - array of key_value objects

where key_value is json object with next attributes:
**key** - abstract key 
**value** - json object   


# Storages client to server requests

Such requests client sends to server to change key_value objects in  storages. 

## **storage_data_object.set**  *(update/create key & value in storage)*
Direction: ***client -> server***
Type: ***request/responce***

```
{"method": "storage_data_object.set", "params": {"sid":"uuid", "key_value":{key: id, value: object}, "id":"1232"}
```
* params - json object with parameters:
    - sid - session id
    - key_value - json key value object
* id - mandatory request ID

where key_value:
key - data object id
value - abstract json document defined by cc client

response payload will include operation status and new storage timestamp 
```
{"result": {"sid":"uuid", "storage_data_objects_timestamp":"timestamp", "status": 200}, "id": "1232"}
```

## **storage_app_setting.set**  *(update/create key & value in storage)*
Direction: ***client -> server***
Type: ***request/responce***

```
{"method": "storage_app_setting.set", "params": {"sid":"uuid", "key_value":{key: abstract_key, value: object}, "id":"1232"}
```
* params - json object with parameters:
    - sid - session id
    - key_value - json key value object
* id - mandatory request ID

where key_value:
key - abstract key defined by cc client
value - abstract json document defined by cc client

response payload will include operation status and new storage timestamp 
```
{"result": {"sid":"uuid", "storage_app_settings_timestamp":"timestamp", "status": 200}, "id": "1232"}
```

## **storage_app_setting.delete**  *(delete key & value in storage)*
Direction: ***client -> server***
Type: ***request/responce***

```
  {"method": "storage_app_setting.delete", "params": {"sid":"uuid", "key":key}, "id":"1232"}
```
* params - json object with parameters:
    - sid - session id
    - key - abstract key defined by cc client
* id - mandatory request ID

response payload will include operation status and new storage timestamp 
```
{"result": {"sid":"uuid", "storage_app_settings_timestamp":"timestamp", "status": 200}, "id": "1232"}
```

# Other storages synchronizaton events
Such events uses for keeping data updated after full synchronization

## **storage_data_object.updated**  *(storage_data_object synchronization)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "storage_data_object.updated", "params": {"sid":"uuid", "storage_data_objects_timestamp":"timestamp", "key_value":{"key":key, "value":value}}}
```

## **storage_data_object.deleted**  *(storage_data_object synchronization)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "storage_data_object.deleted", "params": {"sid":"uuid", "storage_data_objects_timestamp":"timestamp", "key":key}}
```

## **storage_app_setting.updated**  *(storage_app_setting synchronization)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "storage_app_setting.updated", "params": {"sid":"uuid", "storage_app_settings_timestamp":"timestamp", "key_value":{"key":key, "value":value}}}
```

## **storage_app_setting.deleted**  *(storage_app_setting synchronization)*
Direction: ***server -> client***
Type: ***event/command***

```
{"method": "storage_app_setting.deleted", "params": {"sid":"uuid", "storage_app_settings_timestamp":"timestamp", "key":key}}
```

# Errors specification

Define general error classes only. 
Specifics may be filled in via description

#### Example with defined id

###### Request
```
 {"method": "000000", "params": { "group": uuid }, "id":"1232"}
```
###### Response
```
{"error": {"code": -32601, "message": "Method not found"}, "id": "1232"}
```

#### Example without defined id

###### Request
```
 {"method": "000000", "params": { "group": uuid }}
```
###### Response
```
{"error": {"code": -32601, "message": "Method not found"} }
```


The error codes from and including -32768 to -32000 are reserved for pre-defined errors. Any code within this range, but not defined explicitly below is reserved for future use


| code  | message	meaning |
| -------- | -------- 
| -32700     | Parse error	Invalid JSON was received by the server.  An error occurred on the server while parsing the JSON text.   | 
| -32600     | Invalid Request	The JSON sent is not a valid Request object.     | 
| -32601     | Method not found	The method does not exist / is not available.     | 
| -32602     | 	Invalid params	Invalid method parameter(s     | 
| -32603     | Internal error	Internal JSON-RPC error.     | 
| -32000 to -32099     | Reserved for implementation-defined server-errors.     | 
-32000 to -32099	Server error	Reserved for implementation-defined server-errors.



# Tools for development, support and QA


 #### Device Connection form
 - input for token 
 - input for connection url 
- button connect (after successfull connect changes to disconnect and vice-versa)
- label with status (disconnected, connected, error)

#### Request Form

should be available after successfull connection

dropdown with all method available (see all *requests from documentation)
input to add params object (json)
button to send event to webscoket 


text area to see all logs events + requests + responses

