Examples for Catalyst Type Extension

Have a look at the following few examples with their sample codes in order to better understand catalyst type extensions. The examples featured are :

  • My Notes
  • Url Shortner

My Notes:

My Notes - Notepad is an easy-to-use, intuitive, fast, elegant and secure notepad with cloud syncing. You can use My Notes as a notepad, notebook, journal, agenda or diary. With this extension you can:

  • Use message action to add notes.
  • Use slash commands to view notes.

Here are the sample codes for handlers of MyNotes extension:

Java:

Command handler:



//$Id$
package com.handlers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.zc.cliq.objects.CommandSuggestion;
import com.zc.cliq.requests.CommandHandlerRequest;
import com.zc.component.object.ZCRowObject;
import com.zc.component.zcql.ZCQL;
public class CommandHandler implements com.zc.cliq.interfaces.CommandHandler {
	@Override
	public Map<string, object=""> executionHandler(CommandHandlerRequest req) throws Exception {
		String text = "";
		Map<string, object=""> resp = new HashMap<string, object="">();
		List<commandsuggestion> suggestions = req.getSelections();
		if (suggestions == null || suggestions.size() == 0) {
			text = "Please select a suggestion from the command"; //NO I18N
		} else {
			CommandSuggestion cmdSuggestion = suggestions.get(0);
			String title = cmdSuggestion.getTitle();
			String query = "SELECT * FROM notes WHERE TITLE=" + title; //NO I18N
			ArrayList<zcrowobject> rows = ZCQL.getInstance().executeQuery(query);
			ZCRowObject row = rows.get(0);
			text = "*Title* : " + row.get("TITLE") + " \n\n*Note* : " + row.get("NOTE"); //NO I18N
		}
		resp.put("text", text);
		return resp;
	}
	@Override
	public List<commandsuggestion> suggestionHandler(CommandHandlerRequest req) throws Exception {
		String userId = req.getUser().getId();
		String query = "SELECT * FROM notes WHERE USER_ID=" + userId; //NO I18N
		ArrayList<zcrowobject> rows = ZCQL.getInstance().executeQuery(query);
		List<commandsuggestion> suggestionList = new ArrayList<commandsuggestion>();
		for (ZCRowObject row : rows) {
			CommandSuggestion suggestion = CommandSuggestion.getInstance((String) row.get("TITLE"), "", "https://i.imgur.com/ereVzNU.png");
			suggestionList.add(suggestion);
		}
		return suggestionList;
	}
}

Function handler:



//$Id$
package com.handlers;
import java.util.Map;
import org.json.JSONObject;
import com.zc.cliq.objects.FormChangeResponse;
import com.zc.cliq.objects.FormDynamicFieldResponse;
import com.zc.cliq.objects.MessageBuilder;
import com.zc.cliq.requests.ButtonFunctionRequest;
import com.zc.cliq.requests.FormFunctionRequest;
import com.zc.cliq.requests.WidgetFunctionRequest;
import com.zc.cliq.util.ZCCliqUtil;
import com.zc.component.object.ZCObject;
import com.zc.component.object.ZCRowObject;
import com.zc.component.object.ZCTable;
public class FunctionHandler implements com.zc.cliq.interfaces.FunctionHandler {
	@Override
	public Map<string, object=""> formSubmitHandler(FormFunctionRequest req) throws Exception {
		JSONObject values = req.getForm().getValues();
		ZCObject zcObj = ZCObject.getInstance();
		ZCTable table = zcObj.getTable("notes"); //NO I18N
		ZCRowObject row = ZCRowObject.getInstance();
		row.set("TITLE", values.get("title")); //NO I18N
		row.set("NOTE", values.get("note")); //NO I18N
		row.set("USER_ID", req.getUser().getId()); //NO I18N
		table.insertRow(row);
		MessageBuilder msg = MessageBuilder.getInstance();
		msg.setText("Note has been saved"); //NO I18N
		return ZCCliqUtil.toMap(msg);
	}
	@Override
	public Map<string, object=""> buttonFunctionHandler(ButtonFunctionRequest req) throws Exception {
		return null;
	}
	@Override
	public FormChangeResponse formChangeHandler(FormFunctionRequest req) throws Exception {
		return null;
	}
	@Override
	public FormDynamicFieldResponse formDynamicFieldHandler(FormFunctionRequest req) throws Exception {
		return null;
	}
	@Override
	public Map<string, object=""> widgetButtonHandler(WidgetFunctionRequest req) throws Exception {
		return null;
	}
}

Message action handler:



//$Id$
package com.handlers;
import java.util.Map;
import com.zc.cliq.enums.FORM_FIELD_TYPE;
import com.zc.cliq.objects.Form;
import com.zc.cliq.objects.FormActionsObject;
import com.zc.cliq.objects.FormInput;
import com.zc.cliq.objects.MessageBuilder;
import com.zc.cliq.requests.MessageActionHandlerRequest;
import com.zc.cliq.util.ZCCliqUtil;
public class MessageActionHandler implements com.zc.cliq.interfaces.MessageActionHandler {
	@Override
	public Map<string, object=""> executionHandler(MessageActionHandlerRequest req) throws Exception {
		String text = "";
		String note = req.getMessage().getText().trim();
		if (note.isEmpty()) {
			text = "Nothing here to add note."; //NO I18N
		} else {
			return getForm(note);
		}
		MessageBuilder resp = MessageBuilder.getInstance();
		resp.setText(text);
		return ZCCliqUtil.toMap(resp);
	}
	private static Map<string, object="">getForm(String notes) {
		Form form = Form.getInstance();
		form.setTitle("Notes"); //NO I18N
		form.setHint("");
		form.setName("notes"); //NO I18N
		form.setButtonLabel("Save Note"); //NO I18N
		form.setVersion(1);
		FormActionsObject actions = FormActionsObject.getInstance();
		actions.setSubmitAction("storeNotes"); //NO I18N
		form.setActions(actions);
		FormInput title = FormInput.getIntance();
		title.setType(FORM_FIELD_TYPE.TEXT);
		title.setName("title"); //NO I18N
		title.setLabel("Title"); //NO I18N
		title.setHint("");
		title.setPlaceholder("Enter the note title"); //NO I18N
		title.setMandatory(true);
		form.addFormInput(title);
		FormInput note = FormInput.getIntance();
		note.setType(FORM_FIELD_TYPE.TEXTAREA);
		note.setName("note"); //NO I18N
		note.setLabel("Note"); //NO I18N
		note.setHint("");
		note.setPlaceholder("");
		note.setMandatory(true);
		note.setValue(notes);
		form.addFormInput(note);
		return ZCCliqUtil.toMap(form);
	}
}

Download full source code (MyNotes - Java)
To try out this extension you can install it from here

Node.js:

Command handler:



'use strict'; // NO I18N
const cliq = require('zcatalyst-integ-cliq'); // NO I18N
const command = cliq.command();
command.executionHandler(async (req, res, app) => {
    let text;
    let suggestions = req.selections;
    if(suggestions === undefined || suggestions.length === 0) {
        text = 'Please select a suggestion from the command'; // NO I18N
    } else {
        let rowId = req.selections[0].id;
        const zcql = app.zcql();
        const query = `SELECT * FROM notes WHERE ROWID=${rowId}`;
        let rows = await zcql.executeZCQLQuery(query);
        let row = rows[0].notes;
        text = "*Title* : " + row.TITLE + " \n\n*Note* : " + row.NOTE; // NO I18N
    }
    res.setText(text);
    return res;
});
command.suggestionHandler(async (req, res, app) => {
        let userId = req.user.id;
        const zcql = app.zcql();
        const query = `SELECT * FROM notes WHERE USER_ID=${userId}`;
        let rows = await zcql.executeZCQLQuery(query);
        for(let row of rows)
        {
            let eachRow = row.notes;
            let suggestion = command.newCommandSugestion();
            suggestion.id = eachRow.ROWID;
            suggestion.title = eachRow.TITLE;
            suggestion.description = '';
            suggestion.imageurl = 'https://i.imgur.com/ereVzNU.png'; // NO I18N
            res.push(suggestion);
        }
        return res;
});

Function handler:



'use strict'; // NO I18N
const Cliq = require('zcatalyst-integ-cliq'); // NO I18N
const functionHandler = Cliq.CliqFunction();
functionHandler.formSubmitHandler(async (req, res, app) => {
    const values = req.form.values;
    const datastore = app.datastore();
    const table = datastore.table("notes"); // NO I18N
    let rowData = {
        TITLE : values.title,
        NOTE : values.note,
        USER_ID : req.user.id
    };
    const newRow = await table.insertRow(rowData);
    res.setText('Note has been saved'); // NO I18N
    return res;
});

Message action handler:



'use strict'; // NO I18N
const Cliq = require('zcatalyst-integ-cliq'); // NO I18N
const messageActionHandler = Cliq.messageAction();
messageActionHandler.executionHandler(async (req, res) => {
    let text = '';
    let note = req.message.text.trim() || "";
    if (note == "") {
        text = "Nothing here to add note."; // NO I18N
    } else {
        return getForm(note);
    }
    res.setText(text);
    return res;
});
function getForm(note) {
    const form = messageActionHandler.newHandlerResponse().newForm();
    form.title = 'Notes'; // NO I18N
    form.hint = '';
    form.name = 'notes';
    form.button_label = 'Save Note'; // NO I18N
    form.version = 1;
    const actions = form.newFormActionsObject();
    actions.submit = actions.newFormAction('storeNotes'); // NO I18N
    form.actions = actions;
    const noteName = form.newFormInput();
    noteName.type = 'text';
    noteName.name = 'title';
    noteName.label = 'Title'; // NO I18N
    noteName.hint = '';
    noteName.placeholder = 'Enter the note title'; // NO I18N
    noteName.mandatory = true;
    form.addInputs(noteName);
    const notes = form.newFormInput();
    notes.type = 'textarea';
    notes.name = 'note';
    notes.label = 'Note'; // NO I18N
    notes.hint = '';
    notes.placeholder = '';
    notes.value = note;
    notes.mandatory = true;
    form.addInputs(notes);
    return form;
}

Download full source code (MyNotes - Node.js)
To try out this extension you can install it from here

The database schema for MyNotes extension:

Url Shortner:

Url Shortner works by transforming any long URL into a shorter, more readable link. With this extension you can shorten links by:

  • passing the link as an argument in a slash command
  • using message action to shorten a URL in a message

Here are the sample codes for handlers of Url Shortner extension

Java:

Command handler:



//$Id$
package com.handlers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.JSONObject;
import com.zc.api.APIConstants.RequestMethod;
import com.zc.api.APIRequest;
import com.zc.cliq.objects.CommandSuggestion;
import com.zc.cliq.requests.CommandHandlerRequest;
public class CommandHandler implements com.zc.cliq.interfaces.CommandHandler {
	@Override
	public Map<string, object=""> executionHandler(CommandHandlerRequest req) throws Exception {
		Map<string, object=""> resp = new HashMap<string, object="">();
		String text = "";
		String url = req.getArguments();
		if (url == null || url == "") {
			text = "Please provide the url along with this command. \nSyntax : /shortenurl <link>)";
		} else {
			try {
				String shortenurl = getShortenedUrl(url);
				text = "Short URL : ```" + shortenurl + "```"; // NO I18N
			} catch (Exception e) {
				text = "Seems to be invalid URL."; // NO I18N
			}
		}
		resp.put("text", text);
		return resp;
	}
	private String getShortenedUrl(String url) throws Exception {
		APIRequest req = new APIRequest();
		req.setUrl("https://cleanuri.com/api/v1/shorten"); // NO I18N
		req.setRequestMethod(RequestMethod.POST);
		HashMap<string, object=""> postData = new HashMap<string, object="">();
		postData.put("url", url);
		req.setPostData(postData);
		req.setAuthNeeded(false);
		JSONObject respJson = new JSONObject(req.getResponse().getResponseJSON().get(0).toString());
		String result_url = respJson.getString("result_url");
		return result_url;
	}
	@Override
	public List<commandsuggestion> suggestionHandler(CommandHandlerRequest req) {
		return new ArrayList<commandsuggestion>();
	}
}

Installation handler:



//$Id$
package com.handlers;
import java.util.logging.Logger;
import com.zc.cliq.enums.STATUS;
import com.zc.cliq.objects.InstallationResponse;
import com.zc.cliq.requests.InstallationRequest;
public class InstallationHandler implements com.zc.cliq.interfaces.InstallationHandler {
	@Override
	public InstallationResponse handleInstallation(InstallationRequest arg0) throws Exception {
		InstallationResponse resp = InstallationResponse.getInstance();
		resp.setStatus(STATUS.SUCCESS);
		return resp;
	}
}

Installation validator:



//$Id$
package com.handlers;
import java.util.logging.Logger;
import com.zc.cliq.enums.STATUS;
import com.zc.cliq.objects.InstallationResponse;
import com.zc.cliq.requests.InstallationRequest;
public class InstallationValidator implements com.zc.cliq.interfaces.InstallationValidator {
	@Override
	public InstallationResponse validateInstallation(InstallationRequest req) throws Exception {
		InstallationResponse resp = InstallationResponse.getInstance();
		resp.setStatus(STATUS.SUCCESS);
		return resp;
	}
}

Message action Handler:



//$Id$
package com.handlers;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.zc.api.APIRequest;
import com.zc.api.APIConstants.RequestMethod;
import com.zc.cliq.requests.MessageActionHandlerRequest;
import org.json.JSONObject;
public class MessageActionHandler implements com.zc.cliq.interfaces.MessageActionHandler {
	@Override
	public Map<string, object=""> executionHandler(MessageActionHandlerRequest req) throws Exception {
		Map<string, object=""> resp = new HashMap<string, object="">();
		String url = req.getMessage().getText();
		String text = "";
		if (url == null || url == "") {
			text = "It's empty"; // NO I18N
		} else {
			try {
				String shortenurl = getShortenedUrl(url);
				text = "Short URL : ```" + shortenurl + "```"; // NO I18N
			} catch (Exception e) {
				text = "Seems to be invalid URL."; // NO I18N
			}
		}
		resp.put("text", text);
		return resp;
	}
	private String getShortenedUrl(String url) throws Exception {
		APIRequest req = new APIRequest();
		req.setUrl("https://cleanuri.com/api/v1/shorten"); // NO I18N
		req.setRequestMethod(RequestMethod.POST);
		HashMap<string, object=""> postData = new HashMap<string, object="">();
		postData.put("url", url);
		req.setPostData(postData);
		req.setAuthNeeded(false);
		JSONObject respJson = new JSONObject(req.getResponse().getResponseJSON().get(0).toString());
		String result_url = respJson.getString("result_url");
		return result_url;
	}
}
,>,>,>,>,>

Download full source code (Url Shortner - Java).
To try out this extension you can install it from here.

Node.js:

Command handler:



'use strict'; //NO I18N
const cliq = require('zcatalyst-integ-cliq'); //NO I18N
const axios = require('axios'); //NO I18N
const command = cliq.command();
command.executionHandler(async(req, res) => {
    let text = "";
    let url = req.arguments.trim() || "";
    if (url === "") {
        text = "Please provide the url along with this command. \nSyntax : /shortenurl <$link>";
    } else {
        text = await getShortenedUrl(url);
    }
    res.setText(text);
    return res;
});
async function getShortenedUrl(url) {
    try {
        let response = await axios.post('https://cleanuri.com/api/v1/shorten', { //NO I18N
            url: url
        });
        return "Short URL : ```" + response.data.result_url + "```"; //NO I18N
    } catch (e) {
        return "Seems to be invalid URL."; //NO I18N
    }
}

Message action Handler



'use strict'; //NO I18N
const cliq = require('zcatalyst-integ-cliq'); //NO I18N
const axios = require('axios'); //NO I18N
const messageActionHandler = cliq.messageAction();
messageActionHandler.executionHandler(async(req, res) => {
    let text = "";
    let url = req.message.text.trim() || "";
    if (url === "") {
        text = "It's empty"; //NO I18N
    } else {
        text = await getShortenedUrl(url);
    }
    res.setText(text);
    return res;
});
async function getShortenedUrl(url) {
    try {
        let response = await axios.post('https://cleanuri.com/api/v1/shorten', { //NO I18N
            url: url
        });
        return "Short URL : ```" + response.data.result_url + "```"; //NO I18N
    } catch (e) {
        return "Seems to be invalid URL."; //NO I18N
    }
}

Download full source code (Url Shortner - Node.js).
To try out this extension you can install it from here.