Some apps need to store and retrieve data. For example, consider the workflow of a project management app such as JIRA. When an agent links a ticket to an issue in JIRA, a relation between the ticket ID and issue ID is stored, which when retrieved displays the details of the relevant JIRA issue along with the ticket.
To enable the development of such apps, we provide a data store for apps to set (store) and get (retrieve) data. Also, data can be deleted when it is no longer required. The data store has the following limitations:
Data is stored on a per account AND per app basis i.e., the scope is on a per installation basis. This means that if two apps have been installed by an account, data stored by one app is not accessible by the other app.
A rate limit of 50 requests per minute applies with each set, get, and delete counting as one request. This rate limit is applied separately for each installed app which means that if two apps have been installed by an account, the rate limit will apply separately to each app. This limit is not affected by the number of agents in the account.
Take a look at the Key-Value Storage sample apps for a demonstration of this feature.
Store
client.db.set(key, value, options)
Stores the key, value pair in the data store. UTF-8 characters are supported. If an entry with the key is already present, then the value will be updated. The options field is not mandatory and by default is an empty hash.
Important:Ensure that the following conditions are met while performing the set operation.
- The key should not be blank and its length should not exceed 30 characters.
- The combined size of the key and value should not exceed 8 KB.
- The value should be of type JSON and not blank or empty "{}".
- The values in the JSON Object will be converted to null - empty strings, NaN, "+/- Infinity".
Tip:When testing, you may need to click the shield icon in your browser’s address bar and then click Load unsafe scripts. For more information, refer to the Testing section.
Options
The following attributes can be specified in the options field.
- Time to live (ttl)
Specifies the expiration period of the key in the data store in seconds. The ttl attribute supports both integer and float data types. If you do not set the ttl value or if the value is negative, the key will exist forever.
app.jsclient.db.set( "ticket:101", { "jiraIssueId": 15213 }, {ttl: 60}).then( function(data) { // success operation // "data" value is { "Created" : true } }, function(err) { // Handle error console.error(err.status); console.error(err.message); });
This sample code sets the key to expire after 60 seconds.
- Set If (setIf)
The setIf attribute takes any one of the two values: exist or not_exist. The {setIf: "exist"} code stores the value if the key exists in the data store and throws an error if the key does not exist in the data store. Similarly, {setIf: "not_exist"} stores the value if the key does not exist in the data store and throws an error if it is an existing key.
app.jsclient.db.set( "ticket:101", { "jiraIssueId": 15213 }, {setIf: "exist"}).then( function(data) { // success operation // "data" value is { "Created" : true } }, function(err) { // Handle error console.error(err.status); console.error(err.message); });
Take a look at the Advanced Data Storage sample app for a demonstration of this feature.
Retrieve
client.db.get(key)
Used to retrieve stored data. If the retrieval is successful, the JSON value can be accessed using the data parameter in the .then function.
Update
client.db.update(key, action, attributes)
Updates the corresponding key value in the data store. UTF-8 characters are supported.
Important:Ensure that the following conditions are met while performing the update operation.
- The key should not be blank and its length should not exceed 30 characters.
- The value should be of type JSON and not blank or empty "{}".
- The values in the JSON Object will be converted to null - empty strings, NaN, "+/- Infinity".
The action field can take any one of the following parameters.
Parameter | Description |
---|---|
Increment | Adds a new value to the existing attribute value in the attributes object. |
Append | Appends a new value to the existing attribute value in the attributes object. |
Set | Adds one or more top-level or nested attributes and values to the key, value pair. |
Remove | Removes one or more attributes and values from the key, value pair. |
For serverless apps, you need to use the following format.
$db.update(key, action, attributes)
Increment
Adds the new value specified in the attributes object to the existing attribute value in the data store.
client.db.update(key, "increment", attributes)
- If an attribute does not exist, the increment action adds the specified attribute and its value to the key in the data store.
- If the new value passed in the attributes object is a negative number, then it is subtracted from the existing value.
- If you execute the increment action on a key which does not exist in the data store, the attributes object is stored in the data store with the specified key. This is similar to the Store operation.
- The attributes field takes an object containing the attribute name and value which you want to increment.
- The increment action:
- Supports only number data type.
- Can be used on top-level attributes, not nested attributes.
Example
Suppose you want to store the number of customer interactions in the data store. So, when a customer interacts with an agent, you store an object with Customer ID as key using client.db.set. The sample object would look like this in the data store.
{
Name: "sample_customer",
Company: "sample_company",
Interactions: 3
}
To update the interactions value every time the customer interacts with the agent, you can use the update operation with increment action.
Updated object
{
Name: "sample_customer",
Company: "sample_company",
Interactions: 4
}
Append
Appends the new value specified in the attributes object to the existing attribute value in the data store.
client.db.update(key, "append", attributes)
- If an attribute does not exist, the append action adds the specified attribute and its value to the key in the data store.
- If you execute the append action on a key which does not exist in the data store, the attributes object is stored in the data store with the specified key. This is similar to the Store operation.
- The attributes field takes an object containing the attribute name and value which you want to append.
- The append action:
- Supports only array data type.
- Can be used on top-level attributes, not nested attributes.
Example
Suppose you want to store a list of customers interacting with an agent. You can create an object in the data store with Agent ID as key.
{
agent_name: "sample_agent",
agent_type: "support",
associated_customers: ["customer1","customer2","customer3"]
}
To add a new customer who interacted with the agent to the list, you can use the update operation with append action.
Updated object
{
agent_name: "sample_agent",
agent_type: "support",
associated_customers: ["customer1","customer2","customer3","customer4"]
}
Set
Adds one or more attributes and values to the specified key, value pair in the data store. If the attributes exist, then they are replaced with the new values. You can use the set action to update both top-level and nested attributes.
client.db.update(key, "set", attributes)
- Adds one or more attributes and values to the specified key, value pair in the data store. If the attributes exist, then they are replaced with the new values. You can use the set action to update both top-level and nested attributes.
- The path should be of type string and should not be empty.
- For a top-level attribute, the path refers to the name of the attribute in string format. For a nested attribute, the path refers to the attribute path from the top-level attribute in dot notation.
Example
Suppose, you have a timelog entry for an agent with agent ID as “key” and log information as "value" in the data store. The sample value would be as follows:
{
"logs": {
"ticket_id:11233": {
"Timelog":0,
"Updated": "False"
},
"ticket_id:12312": {
"Timelog":300,
"Updated": "True"
}
},
"agent_name": "sample name"
}
An agent can use the Set action and update the TimeLog value for the first ticket without replacing the whole value object.
Updated object
{
"logs": {
"ticket_id:11233": {
"Timelog":500,
"Updated": "True"
},
"ticket_id:12312": {
"Timelog":300,
"Updated": "True"
}
},
"agent_name": "sample name"
}
Remove
Removes one or more attributes of the specified key, value pair in the data store. You can use the remove action to remove both top-level and nested attributes.
client.db.update(key, "remove", attributes)
- The attributes field takes an array containing paths of the attributes which you want to remove.
- The path should be of type string and should not be empty.
- For a top-level attribute, the path refers to the name of the attribute in string format. For a nested attribute, the path refers to the attribute path from the top-level attribute in dot notation.
Example
Suppose, you have a timelog entry for an agent with agent ID as “key” and log information as "value" in the data store. The sample value would be as follows:
{
"logs": {
"ticket_id:11233": {
"Timelog":0,
"Updated": "False"
},
"ticket_id:12312": {
"Timelog":300,
"Updated": "True"
}
},
"agent_name": "sample name"
}
An agent can use the Remove action to remove the ticket logs.
Updated object
{
"logs": {},
"agent_name": "sample name"
}
Testing
For information on how to test an app that uses the Data Storage feature, see Test your App.
Data that the app needs to store is saved in the .fdk/localstore file in the app's root directory.
Errors
In case of failure, a status code is displayed along with a message to troubleshoot the issue.
{
"status":400,
"message":"Key length should not exceed 30 characters"
}
The following table lists the supported status code.
Status code | Description |
---|---|
400 | Is returned due to invalid input. For example, in the set request, if you provide an invalid input for value you may receive this status code. |
401 | Is returned if you performed an unauthorized request. |
404 | Is returned if the record is not found. |
422 | Is returned if the server does not recognize your request. This may occur due to incorrect syntax. |
429 | Is returned when the number of requests exceeds the threshold. |
500 | Is returned if the server encounters an unexpected condition which prevents it from fulfilling the request. |
502 | Is returned if the server cannot process the request due to request overload. |