Table of Contents
Dynamic Ticket Contents
Updated
by Niamh Ferns
Dynamic Ticket Contents Overview
Ticket dynamic content is similar to Dynamic Form Content, it is available for both Client Portal and TECH portal.
Because is an advanced feature, you can either develop the API yourselves or seek for consultation from us on next steps in getting this set up for your customers.
The goal of ticket dynamic contents is to provide content's that tailored for specific user or company.
The information we will hand over to your API is as follows:
- Ticket Database ID (So you can use it to get more detail of the ticket.)
- Access Token for current user:
The token is available for a maximum of one hour and the portal will try to reuse the token, so please check the access token expiration parameter. Check here to see how you can use our access token.- Tokens provide security to verify a given user
- Tokens allow you to reference and access information about the current user.
- Database name for your instance. (You don't have to utilize on this info, it is for our consulting team to provide solution for different customers.)
API Contract
Similar to Microsoft's Adaptive Cards, DeskDirector will define an API contract. As a user of this feature, you'll have to respect the contract before dynamic ticket content functions as expected.
API Request Design
Client portal or TECH portal will perform POST request against your API. The request body is JSON formatted.
Request Body Contract TypeScript Definition:
interface GetContents {
ticketId: number;
accessToken: string;
// Seconds before token expire
accessTokenExpiresIn: number;
// When will the token expire. ISO8601 format.
accessTokenExpiresOn: string;
database: string;
}Request Example:
{
"ticketId": 12345,
"accessToken": "<token, use to verify user or get ticket information>",
"accessTokenExpiresIn": 3600,
"accessTokenExpiresOn": "2022-06-22T00:00:00Z"
}API Response Design
Your API should respond with following format for our portal to understand.
DeskDirector will not provide support for 3rd party services when used with Dynamic Ticket Content although we can provide some advice on building your own API.
Response Body Contract TypeScript Definition:
type ContentType = 'list' | 'description' | 'progress';
type ContentColor = 'default' | 'accent' | 'good' | 'warning' | 'attention' | 'light';
interface GetContentsResponse {
// if refresh rate is provided, portal will auto refresh on whole contents.
// valid value is between 30 and 300 (seconds)
refreshRate?: number;
// maximum of 3 items
value: Array<DynamicContent>;
}
type DynamicContent = ListContent | DescriptionContent | ProgressContent;
interface SvgContent {
fill?: string;
viewBox: string;
content: string;
}
interface Content<T> {
type: ContentType;
// if identifier has been provided, portal will allow this specific content to refresh
// refresh under path https://your.host.com/path/{identifier}
identifier?: string;
// if refresh rate is provided, portal will auto refresh this content block.
// valid value is between 30 and 300 (seconds)
refreshRate?: number;
// you can provide SVG icon, portal will use it to populate left side icon.
icon?: SvgContent;
title: string;
titleColor?: ContentColor;
// Portal treat description as markdown. Which allows you to provide rich content.
// System will not accept HTML within, for security reason. Any HTML will be removed.
description?: string;
borderColor?: ContentColor;
value: Array<T>;
}
interface ListContent extends Content<ContentListItem> {
type: 'list';
}
interface DescriptionContent extends Content<ContentDescriptionItem> {
type: 'description';
}
interface ProgressContent extends Content<ContentProgressItem> {
type: 'progress';
}
interface ContentListItem {
// max length of 200 chars
title: string;
// max length of 1,000 chars. This is for plain text, markdown does not work here.
description?: string;
url?: string;
}
type ProgressState =
| 'neutral'
| 'queued'
| 'in_progress'
| 'success'
| 'cancelled'
| 'failure';
interface ContentProgressItem {
// max length of 200 chars
title: string;
// max length of 500 chars. portal will treat this as plain text. Markdown does not work here.
description?: string;
state: ProgressState;
url?: string;
}
interface ContentDescriptionItem {
// max length of 50 chars
title: string;
// max length of 1,000 chars. Markdown does not work here.
detail?: string;
// Type used to determine detail's format. The format is restricted, if you don't know how to use, leave this blank. Portal will treat it as string.
type?: 'string' | 'number' | 'currency' | 'date' | 'date_time' | 'time';
}
Example Payload:
{
"value": [
{
"type": "description",
"title": "Additional PSA related ticket info",
"description": "This is only an demonstration for what you can achieve. We only provide consultation to utilize this feature.",
"identifier": "ticket-additional-info",
"refreshRate": 180,
"borderColor": "attention",
"value": [
{
"title": "Time spent",
"type": "number",
"detail": "3945.1"
},
{
"title": "Cost",
"type": "currency",
"detail": "2300.34"
}
]
}
]
}Error Responses
If your API wants to return errors, you should use following format. That way our portal can correctly display the error message:
{
"error": {
"code": "internal_error",
"message": "The system encountered a problem retrieving information; please try again later."
}
}Our Portal will display the following to help diagnose issues and inform end users. You can also return normal content format to make error looks nicer.

Description Content Format
In description content, we allow you to specify the format of your content.
Special formats allow the portal to format your data according to a user's current environment:
currency: normal number format (e.g. 2300.342 will format as $2,300.34)number: normal number format (e.g. 2300.34 will format as 2,300.34)date: ISO8601 format (e.g. 2022-03-23 will format as 23rd of Mar 2022)date_time: ISO8601 format (e.g. 2022-03-23T00:00:00Z will format according to user local time. 22nd of Mar 2022, 03:00 PM)time: ISO8601 format (e.g. 13:30 will format as 01:30 PM)
Refresh Rate
You can provide refresh rates at the individual content level or global content level. The global level will take priority over individual level when the UI performs a period check. The refresh rate in seconds should be provided as an integer that between 30 and 300 inclusive. UI will ignore the rate if the value is invalid.
Individual Content Request Contract
If you have provided identifier in one some piece of content, the portal will allow a user to refresh that content. Say, for example, your API is https://sample.com/your/api/contents, we concatenate an identifier such that you have https://sample.com/your/api/contents/your-identifier.
The response of your API should be a single piece of content. Which is DynamicContent instead of GetContentsResponse.
Individual content query should now be aware of query parameters. If your API URL is https://sample.com/your/api/contents?variants=psa_info&variants=security_check. Then, when appending an identifier, the system will only append to URL path. For example: https://sample.com/your/api/contents/psa_info?variants=psa_info&variants=security_check.
Custom SVG Icon
By default, the system will provide built in icons for content based on its type. You can specify custom icons using SVGs:
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
<path d="M0 0h24v24H0z" fill="none" />
<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" />
</svg>
When translated to JSON for our UI to understand, you will need to provide 3 properties:
{
"fill": "currentcolor",
"viewBox": "0 0 24 24",
"content": "<path d="M0 0h24v24H0z" fill="none" /> <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" />"
}- fill: This is an optional property, without specify, UI will use currentcolor by default.
currentcolor: The text color of local scopenone: Do not fill any color. It is useful for certain SVG.- HTML color name (e.g.
red,blueetc) - Hash based color (e.g.
#000000as black)
- viewBox: The
viewBoxattribute defines the position and dimension, in user space, of an SVG viewport. - content: The contents within the <svg> HTML tag. Be aware of new line when format in JSON. Replace new line as \n.
Interface Sample
You can view a demo by visiting your TECH portal with following link.
https://yourdomain.deskdirector.com/tech/demo/ticket-dynamic-contents
