Build commands for your Bot powered by Knit

Commands are kind of shortcuts to or specific actions in the Bot. Generally speaking, most bots supports these commands. There are some some inbuilt commands for simple tasks like starting call, archiving channel, etc. In this tutorial we will be talking about how to build these commands using Knit.

Users can create any bot command which can trigger complex workflows or do wide range of chained tasks . It can help your users to save time and effort.

But before we begin, lets understand how Knit is making this easy for you

Commands on Slack and Teams

Slack commands are called Slash commands. They can be executed in any channel or as a direct message by a bot. They always start with / Once you type this then all the slash commands present in the workspace will be populated in autocomplete passion.

MS Teams commands are also similar but you have to just type as direct message to Bot and if you want to execute in channel then you have to mention Bot by typing @Bot name then command.

How to build commands

For Slack you need to visit your apps section page and on clicking on Slash Commands in App Features. For the complete process see Build Slash command.

For MS Teams you can visit Developer Portal App and select your app. For the complete process see Build Teams command.

Publish commands

As soon as you have created any command you have to publish your app. you need to reinstall Bot in Slack and Teams both.

Modify commands

For adding new commands or editing will require you to publish your app again which makes it rigid to implement in both bots.


Build bot commands for both Slack and Teams using Knit

Building commands directly on the bot have some challenges. Let's categorize and see how Knit solving them for you.

Unified API for building bot commands

Knit will provide you register bot command API through which you can build commands using single API for both Slack and Teams. You can modify or add more commands using same API. You need not worry about publishing you bot again!

Processing command payload

Knit will provide you payload in Knit command payload format so that you can easily write your logic and will need not to take care of processing different payloads.

Responding back to a bot command

You can send your command response back to Knit in the same payload request and Knit will deliver that in appropriate channel depending on the message context.

🚧

This feature is production only!!!

You must create your own Bot for building commands.

Now let's look at how to build commands via Knit for your Bots.

1. Register your command with Knit

Firstly, let's understand the structure of a Knit Bot command

command-key command-argument other-command-options....

Example: knit logs slack

Knit cares about the command key and argument only

1. Command Key - All the commands should start with this key . This help us to recognise it is command. For instance in the example above knitis the command key.

2. Command Argument - It is identifier of action that command suppose to do. Going back to the example above, logs is the command argument in this case.

While registering commands, there are a few more things that we need:

  • Destination URL - Once commands get issued then you will be receiving payload from bot on this URL. This is your backend URL so that you can process this send the response back to Knit.
  • Help Command URL - For any syntax error in command argument , you will receive payload on this. You can use this to inform user by listing all commands or some meaningful message.

👍

Always include a help command

Help command educates your users about the capabilities and scope of the bot. It can also be use used a default response for erroneous commands.


Let's build with an example

Lets take example of Payroll app- zpay. If you want to build commands that will allow your user to download link for their payslips, check their reimbursement status, etc. Let's build commands for these two examples:

  1. Get payslip link
  2. Get reimbursement status

Picking right key name for you command

This will help us to recognize this is command. This is one time process all the commands under this group can be extend by adding argument command. Here this can be zzpay

Picking argument command

This is the actual command you can use above API by selecting argument in commandType query parameter. In the above example

  1. payslip

    2.reimbursment

Decide the destination for the command payload

You have to choose destination of the commands it can be your backend URL where you can process command payload to generate response.

zzpay payslip

zzpay reimbursment

Now let's look at how you can register them using Register Command API.

Register zzpay key command

We will register first zzpay key with Knit. If key command is already registered then you can directly register command argument.

 public static void registerBotKeyCommand(String appId, String keyCommand) {
        OkHttpClient client = new OkHttpClient();
        String commandType = "key";
        String url = "https://api.getknit.dev/v1.0/comm.bot.registerCommand";
        url = url + "?commandType=" + commandType;

        Map<String, Object> map = new HashMap<>();
        map.put("keyCommand", keyCommand);
        map.put("appId", appId);
        String body = toJson(map); // convert to json

        Request request = new Request.Builder()
                .url(url)
                .addHeader("Authorization", "Bearer " + "API_KEY")
                .post(RequestBody.create(body, JSON))
                .build();


        Response response = client.newCall(request).execute();
        if (response.code() != 200) {
            // Handle Error
        }

    }

👍

For Slack you must register key as Slash command

For complete process see Register Slash command

Use Slack Command Endpoint in place of Request URL during registration.

Register arguments (payslip, reimbursement)

If you have already registered key then you can directly register command using this step.

public static void registerArgumentCommand(String appId, String keyCommand, String argumentCommand, String destination) {
        OkHttpClient client = new OkHttpClient();
        String commandType = "argument";
        String url = "https://api.getknit.dev/v1.0/comm.bot.registerCommand";
        url = url + "?commandType=" + commandType;

        Map<String, Object> map = new HashMap<>();
        map.put("keyCommand", keyCommand);
        map.put("appId", appId);
        map.put("argumentCommand", argumentCommand);
        map.put("destination", destination);
        String body = toJson(map); // convert to json
     
        Request request = new Request.Builder()
                .url(url)
                .addHeader("Authorization", "Bearer " + "API_KEY")
                .post(RequestBody.create(body, JSON))
                .build();

        Response response = client.newCall(request).execute();
        if (response.code() != 200) {
            // Handle Error
        }
    }

Registering help command (Skip if done before)

This is optional if you have never done it then you can use above API for help command.

public static void registerBotHelpCommand(String appId, String destination) {
        OkHttpClient client = new OkHttpClient();
        String commandType = "help";
        String url = "https://api.getknit.dev/v1.0/comm.bot.registerCommand";
        url = url + "?commandType=" + commandType;

        Map<String, Object> map = new HashMap<>();
        map.put("destination", destination);
        map.put("appId", appId);
        String body = toJson(map); // convert to json


        Request request = new Request.Builder()
                .url(url)
                .addHeader("Authorization", "Bearer " + "API_KEY")
                .post(RequestBody.create(body, JSON))
                .build();


        Response response = client.newCall(request).execute();

        if (response.code() != 200) {
            // Handle Error
        }

    }

👍

Always register a Help message for your commands

It is best practice to set Help Command URL so that users can get the appropriate info in case of wrong syntax.


Processing command payload

Knit makes this step super simple for you as soon as your user invokes these commands you will receive payload on destination that is set in the previous step. It will have all relevant information.

Lets say a user has invoked below command:

zzpay payslip February 2023

Now you will receive payload in Knit Webhook structure like -

{
    "eventId": "ev_sDtbfXbVt6I81hhBNVjGxK",
    "eventData": {
        "keyCommand": "zzpay",
        "argumentCommand": "payslip",
        "option": "February,2023,",
        "fullCommandString": "zzpay payslip February 2023",
        "channelId": "19:[email protected]",
        "userId": "29:1dVs-j_FbsGr4gxKoaYkHFnfOZBiTpY0byEfLQmB2gMSHEFkjzCm_QwWK0yWGQb2a1S2buXh1xmjbUGymwTJ0YQ"
    },
    "eventType": "bot.command"
}

Now, you can see option key contains comma separated values typed after argument command . That let's you build your logic for processing payslip. Additionally userId etc. can be used to get details for user like email.

3. Sending command response to Knit

After processing command logic you should respond back to Knit on the same request . with payload in the format of message object described below. Please note that in the response we support some of markdown properties. See Knit message formatting and send your message in the same format.

For Non Interactive message as Response-

{
  "commandResponse": {
  "messageType": "nonInteractive",
  "message": "Find your payslip - [link](https://razrpay.com/payslip/234)"
  }
}

For Interactive message as Response -

Visit - Message Formatting for designing messages in Knit Format.

{
  "commandResponse": {
  "messageType": "interactive",
  "interactiveMessage": {"sections":[{"sectionType":"textBlock","text":"This is sample text"},{"sectionType":"keyValueSet","values":[{"key":"Key1","value":"value1"},{"key":"key2","value":"Value2"}]}],"interactiveComponents":[{"id":"approveBtn","label":"Approve","value":"value1","style":"primary","interactiveComponentType":"button"},{"label":"Deny","id":"denyBtn","value":"value2","style":"danger","interactiveComponentType":"button"},{"label":"Neutral","id":"neutralBtn","value":"value3","interactiveComponentType":"button"}],"destination":"https://38f0-110-235-237-164.in.ngrok.io/slack"}
  }
}

🚧

Command Response should strictly follow the payload structure.

Ensure that you should return your command response in appropriate format as described above.

We will redirect this response to right place from where it was invoked.

That's it! Go ahead and build commands for your bot using Knit.