Table of contents
Button Function Handler
A function is triggered to execute a deluge task, when an action (click) is performed on the button associated with the function. A list of attributes are passed when a function is triggered. They are listed in the table below:
Attribute | Description |
User | Details of the user who has triggered the function. |
Message | Details of the message map, to which the function is associated. |
Button (Arguments) | Details of the button object inside the message object. |
Chat | Chat details in which the function is triggered. |
Target | Button object details such as button name, hint and key. |
Sample Target Map
{
"hint": "button_hint",
"name": "button_name"
}
Sample Arguments Map
{
"key": "button_key"
}
Key parameter:
The 'key' parameter in the arguments map can be used as a unique identifier for each button. The parameter serves the purpose of identifying the button clicked to execute the respective on-click action.
Note:
The Rest API document explains in detail about the button object and the different types of actions that can be invoked.
Button Navigation Control:
Adding the navigation control attribute in the return map of a button function will replace the initial (original) response with a new updated response and will also provide an option to navigate back to the initial response.
{
"navigation":true
}
Sample Command and Button with Navigation Control Syntax
command = {"text":"List of issues created today!","card":{"title":"Recent Bugs","theme":"modern-inline","thumbnail":"https://www.zoho.com/cliq/help/restapi/images/announce_icon.png"},"slides":{{"type":"table","title":"Details","styles":{"width":{20,50,30}},"data":{"headers":{"Bug ID","Bug Title","Assigned To"},"rows":{{"Bug ID":"123","Bug Title":"Sign up UI fields misalignment","Assigned To":"Li Jung"},{"Bug ID":"124","Bug Title":"Login page not optimized for mobile browser","Assigned To":"Patricia James"}}}}},"buttons":{{"label":"View Details","type":"+","action":{"type":"invoke.function","data":{"name":"bugdetails"}}}}};
return command;
Function execution code
response = Map();
response = {
"text": "Detailed description of bugs reported today!",
"card": {
"title": "Bug Details",
"theme": "modern-inline"
},
"slides": [
{
"type": "list",
"title": "Sign up UI fields misalignment",
"data": [
"Misalignment while signing up from mobile and web. Happens only for sign up and not sign in!"
]
},
{
"type": "list",
"title": "Login page optimization",
"data": [
"Login page not optimized for mobile browser"
]
}
]
};
response.put("navigation","true");
return response;
Workflow of the button function
A function works in association with a button. Ideally, the workflow for a function will be:
- Create a function for a specific task.
- Customise a message card with the button object.
- Optimise the button action, by adding the function name as a value for the key type in the button object. Take a look at the example given below for better understanding.
For example, let us try creating a /bugs command that will list get the list of issues filed under your name in Projects. The issues assigned to you will be listed in a table with a View Info button (inline button) to view more details of the issue. We can also add two more buttons on the card, to get the list of all open issues and closed issues. The function execution code is shown below.
//Button Object
"buttons":[
{
"label": "All Open Issues",
"type": "+",
"action": {
"type": "invoke.function",
"data": {
"name": "projects"
}
},
"arguments": {
"key": portalproject
}
}
]
/bugs command execution code
message = Map();
zuid = user.get("id");
info selections.get(0).get("id");
info selections.get(1).get("id");
portalproject = selections.get(0).get("id") + "-" + selections.get(1).get("id");
info portalproject;
params = {"assignee":{user.get("id").trim()},"statustype":"open","index":0};
response = invokeurl
[
url :"https://projects.zoho.com/restapi/portal/" + selections.get(0).get("id").trim() + "/projects/" + selections.get(1).get("id").trim() + "/bugs/"
type :GET
parameters: params
connection:"ENTER YOUR CONNECTION NAME"
];
info response;
bugs = response.toMap().get("bugs");
rows = List();
for each bug in bugs
{
row = Map();
row.put("Issue Title",bug.get("title"));
row.put("Issue ID",bug.get("bug_number"));
row.put("Severity",bug.get("severity").toMap().get("type"));
row.put("View Details","[+:bug: Info](invoke.function|issues|scott.fisher@zylker.com|" + portalproject + "-" + bug.get("id") + ") ");
rows.add(row);
}
message = {"text":"Hey " + user.get("first_name") + " ! :smile: These are the issues found under your name.","card":{"theme":"modern-inline","title":"Issue List:"},"slides":{{"type":"table","title":"","data":{"headers":{"Issue Title","Issue ID","Severity","View Details"},"rows":rows}}},"buttons":{{"label":"All Open Issues","type":"+","action":{"type":"invoke.function","data":{"name":"issues","owner":"GIVE YOUR EMAIL ID"}},"arguments":{"key":portalproject}}}};
return message;
/bugs command suggestion code
list = List();
if(selections.size() == 0)
{
resp = invokeurl
[
url :"https://projectsapi.zoho.com/restapi/portals/"
type :GET
connection:"GIVE YOUR CONNECTION NAME"
];
portals = resp.get("portals");
info portals;
for each portal in portals
{
info portal;
entry = Map();
entry.put("id","" + portal.get("id"));
entry.put("title",portal.get("name"));
if(portal.get("default") == "true")
{
entry.put("imageurl","");
}
else
{
entry.put("imageurl","");
}
list.add(entry);
}
}
else if(selections.size() == 1)
{
portal = selections.get(0);
resp = invokeurl
[
url :"https://projectsapi.zoho.com/restapi/portal/" + portal.get("id") + "/projects/"
type :GET
connection:"GIVE YOUR CONNECTION NAME"
];
info resp;
projects = resp.get("projects");
count = 1;
for each project in projects
{
entry = Map();
entry.put("id","" + project.get("id"));
entry.put("title",project.get("name"));
if(project.get("description") != null)
{
//entry.put("description",project.get("description"));
}
if(portal.get("default") == "true")
{
entry.put("imageurl","");
}
else
{
entry.put("imageurl","");
}
if(count < 25)
{
list.add(entry);
count = count + 1;
}
}
}
return list;
/bugs function execution code
//Function Execution Code
response = Map();
if(target.get("name") == ":bug: Info")
{
buttonid = arguments.get("key").toList("-");
portal = buttonid.get(0);
project = buttonid.get(1);
ID = buttonid.get(2);
bugdetails = invokeurl
[
url :"https://projects.zoho.com/restapi/portal/" + portal + "/projects/" + project + "/bugs/" + ID + "/"
type :GET
connection:"<insert_connection_name>"
];
response = {"text":"Details about " + bugdetails.get("bugs").toMap().get("title"),"card":{"theme":"modern-inline"},"slides":{{"type":"label","data":{{"Reported By":bugdetails.get("bugs").toMap().get("reported_person")},{"Issue Status": bugdetails.get("bugs").toMap().get("status").toMap().get("type")}}}}};
info response;
}
else if(target.get("name") == "All Open Issues")
{
info arguments;
buttonid = arguments.get("key").toList("-");
portal = buttonid.get(0);
project = buttonid.get(1);
bugdetails = invokeurl
[
url :"https://projects.zoho.com/restapi/portal/" + portal + "/projects/" + project + "/bugs/?statustype=open"
type :GET
connection:"<insert_connection_name>"
];
info bugdetails;
bugs = bugdetails.toMap().get("bugs");
info bugs.size();
if(bugs.size() > 0)
{
rows = List();
for each bug in bugs
{
row = Map();
info bug;
row.put("Issue ID",bug.get("key"));
row.put("Assigned To",bug.get("assignee_name"));
row.put("Severity",bug.get("severity").toMap().get("type"));
row.put("Issue Status",bug.get("status").toMap().get("type"));
if(rows.size() <= 5)
{
rows.add(row);
}
}
response = {"text":"Hey " + user.get("first_name") + " ! Recently reported issues!","card":{"theme":"modern-inline","title":"Issue List:"},"slides":{{"type":"table","title":"hello","data":{"headers":{"Issue ID","Assigned To","Severity","Issue Status"},"rows":rows}}}};
}
else
{
response = {"text": "Good news. Looks like there are no open issues in this project! :grinning:"};
}
}
return response;
The below-shown series of screenshots explain how the command /bugs works
- Typing /bugs in the chat window, will trigger the suggestions list for portal selection.
- On selecting the project portal from the command suggestion list, another list to select the relevant project is shown.
- Once the portal and the project is selected, the selected entities are shown in the text window. Execute the command once the suggestions are selected!
- The command is executed to display a response with the list of issues tagged under the your (that is, the command executor) name.
- Clicking the bug info inline button, will fetch the details of each particular issue.
- Clicking the 'All Open Issues' button will get the recent issues reported in projects.
Related Articles:
Cards & Functions: An inside view into how Cliq's custom buttons work!
The exact workflow of this /bugs command along with the command execution and suggestion code is explained in this forum post.