Developer Guide
copied
Teams Bots
copied
Microsoft Teams allows the creation of bots that a user can interfact with. The Commander bot allows a developer to create custom commands that a user can ask the Commande bot to run.
Teams commands with Nimbella Commander
copied
Commander provides a full development and runtime environment for developing custom Microsoft Teams commands. There are a number of advantages to using Commander to develop, host, and maintain your custom commands.
You don’t need your own server
Commander lets you host and run custom Team Comamnds in the Nimbella Cloud, so you don’t have to deploy your own server. Your command's custom code lives in the Nimbella cloud, and Nimbella servers respond to commands entered in Microsoft Teams.
In Microsoft Teams, Commander is installed as a bot and you can ask the Commander bot to run your custom commands.
Selective listening
The Commander bot does not read any messages in channels that are not directed to it. It only responds to commands that a user asks it to run. This means you don't have to worry about the Commander bot reading messages in your public or private channels.
Create custom commands and administer your app right in Teams
After you install the Commander in Teams, you can create custom commands and administer them from the Microsoft Teams interface. See the tutorial in the Quickstart Guide for an example of creating a custom command in the Teams UI.
Easy to code
Commands are written in JavaScript, and premium versions of Commander allow other options such as the Node.js runtime. This means custom commands can be developed by app developers or even DevOps staff who know shell scripting.
Advanced features
- Administrators assign user roles to control who can administer your commands, who can write code for the commands, and who can run the slash commands.
- You can create encrypted parameter values, called secrets, which keep sensitive information from being viewed by users or being stored in Microsoft Team’s history.
- You can import and export command sets to either use someone else’s code or share your own.
Security
There's nothing you need to do to secure your commands. The signatures of incoming requests from Microsoft Teams users issuing commands are verified to ensure they are coming from Microsoft Teams. See Security.
Ready to get started?
copied
Check out the Commander Overview and then use the Quickstart to get started. Then follow this Developer Guide to understand where to go from there. Once you’re proficient, you’ll be able to look up commands in the Commander Reference Guide if you need a quick reminder.
About commands
copied
Nimbella Commander for Teams lets you control nearly all of the administrative functions for your custom commands directly in the Teams interface by running administative commands. The entire set of Commander administative commands is listed in the Reference Guide. This Developer Guide also contains many examples of these commands, grouped by administrative function.
Command Parameters
copied
When you create a command, you specify the parameters the command takes by enclosing parameter names in angle brackets. Click on the Commander bot to communicate directly with it and then run the following command create command to create a command that will take two parameters:

command create add_host <hostname> <ip_addr>
In the code for the command, you can access the command's parameters by name using params:
if (params.hostname == 'a.nimbella.com') {
But also, the default generated command source code creates local variables as a convenience:
const {
Hostname,
Ip_addr
} = params;
This means you can access the parameters by name in a function without params:
if (hostname == 'a.nimbella.com') {
When a user asks the Commander bot to run this command in Teams, they add parameter values as in the following example:

run add_host a.com 100.200.3.4
If you’re working on a command and discover you want to change the command's parameters, you can change them with the command params command. For example, if you wanted to add a TTL parameter to the add_host command you created above:

command params add_host <hostname> <ip_addr> <ttl>
Note: If you use command params to create new parameters, the command source code is not regenerated, so to access those parameters directly by name without using params
, you'll need to add them to the list of local variables in the code first.
Parameter values with white space
When a custom command is run, parameter values that include white space should be enclosed in a pair of either double or single quotes. For example, if you have a print
command with a <msg>
parameter, the value could be:

run print "This parameter has multiple words"
This command passes the value This parameter has multiple words
to the command source. If you want to pass a parameter value that includes the double quotes, use single quotes to enclose the string, such as:

run print ‘“Life is what happens when you're busy making other plans.” - John Lennon’
Note: On Macs (and potentially others), double quotes appear entered as either Unicode left or right double quotes. If the string starts with a Unicode left quote, a Unicode right quote will be expected to end it.
Optional command parameter
A list of parameters can end with one optional parameter in square brackets, such as the [<ttl>]
parameter in this example:

command create add_host <hostname> <ip_addr> [<ttl>]
This command can be run with either the first two parameters or all three, so either of these commands is valid:

run add_host a.nimbella.com 1.2.3.4

run add_host a.nimbella.com 1.2.3.4 300
Parameter options
The parameter definition for a command can also include options. Options are preceded with a hyphen (-). Options can be either be flags or named options. Here's an example that contains a flag option -detail
and a named option -ttl
with value ttl_value
:

command create add_host <hostname> <ip_addr> [-detail] [-ttl <ttl_value>]
In the source code for the command, you can check to see if a flag option is present either by using the params variable:
if (params.detail) {
or by its name alone, because the default generated code creates a local variable with the name of the option:
if (detail) {
Similarly, you can check if a named option exists by its name alone and check its value using the name of the value:
if (ttl && ttl_value == 30) {
The add_host
command created above with the -detail
and -ttl
options can be run in any of the following ways:

run add_host a.com 1.2.3.4

run add_host a.com 1.2.3.4 -detail

run add_host a.com 1.2.3.4 -ttl 90 -detail
Note:
- Options may not be used when an optional command parameter is present.
- When options are specified, they must be specified at the end of the parameter definition.
Variable number of arguments
Command parameter definitions support varargs
, a variable number of arguments. A parameter definition for a command with varargs
ends with the ellipsis notation (…). The following example specifies that the add_host
command can take any number of parameters:

command create add_host ...
When varargs
is used, you must code the command parameters to be parsed. In the command source code, the text of the full command, including the command prefix and all parameters, is available in commandText
:
let parts = commandText.split(" ");
let cmdPrefix = parts[0];
let cmd = parts[1];
Note: If you use varargs
, your parameter definition cannot include any optional command parameters or parameter options.
Create/manage custom commands
copied
Print Command
copied
Now we’re ready to create our first command. We’ll ask the Commander bot to create a print
command, with a parameter that we can then use for various types of notifications.
- In Teams, enter the following slash command exactly as it appears here, including the angle brackets:User 5:09 PM
command create print <msg>Commander App 5:09 PMCreated command print <msg>, edit the code
- Click the link to edit the Commander code for the command.
- Find this line in the source code:Change the line to this:
"This is a default response for a newly created command with text: " + commandText
text: msg
- Click Save.
- In Teams, test the command by running it (
print
), followed by a text string for themsg
parameterUser 5:09 PM
run print Howdy!
If your print
message has more than one word, surround it with single or double quotes or else you’ll get a response that a parameter was not found.
You should see the response shown in this screenshot, coming from the Commander bot and displaying the print message.
Retrieve the source code link for a command
Use command code to retrieve the link to the source code for a command you’ve already created. A link is generated that will work for 24 hours.
- Retrieve the code link for the
print
command:User 5:09 PM
command code print
List all commands
Use command list.
- List all of the commands in the current app:User 5:09 PM
command list
Info about a command
Use command info to get the following information about an individual command:
- When it was created
- Who created it
- When the source was last modified
- Who modified the source
This information appears in the command output.
- Get information about the
print
command:User 5:09 PM
command info print
View or set a command’s short description
Commands have a short description that describes what they are or what they do. Use command desc to view or create the short description. If you’re adding a description that has white space, enclose the value in single or double quotes.
- View the short description of the
print
command:User 5:09 PM
command desc print - Set the short description of the
print
command:User 5:09 PM
command desc print "prints a message"
Call a webhook for a command
Commander automatically executes the source code for a command when it is run in Teams. If you don't want the command to automatically run its source code, you can set it to call a webhook instead with command webhook. When a webhook is set up for a command, the associated webhook URL will be contacted and its result returned to Teams instead of running the command's source code.
Tip: A command webhook can be useful when developing code. Use a webhook relay to proxy a command to your local development machine to develop and debug the command source code locally. After setting up a webhook relay to your local machine, you can run a Node server locally that will execute the command when it is run in Teams.
- Set up a webhook with the URL of the webhook relay to contact when the
print
command is run:
You can revert to executing the source code for the command by first clearing the webhook, then using retrieve the link to the code editor to save the command code.
- Turn off the
print
command webhook:User 5:09 PM
command webhook print clear - Retrieve the link to the code editor to save the
print
source code and return to running the command normally:User 5:09 PM
command code print
If you need to, you can use command log to get the log history of the command to see who ran the command at what times and also the time it took the command to execute. See the Logs section for more information.
- Get the log history of the print command:User 5:09 PM
command log print
Delete a command
Use command delete plus the command name.
- Delete the
print
command:User 5:09 PM
command delete print
Add npm packages for a command
copied
If your command source code is written in JavaScript and your command requires additional npm (Node Package Manager) packages to run, you can install them in your JavaScript source code with this function, which accepts an array of npm packages to install:
async function install(pkgs) {
pkgs = pkgs.join(' ');
return new Promise((resolve, reject) => {
const { exec } = require('child_process');
exec(`npm install ${pkgs}`, (err, stdout, stderr) => {
if (err) reject(err);
else resolve();
});
});
}
The following example shows the install()
function being used to install two npm packages:
let packages = [ 'read-installed', 'chalk' ];
await install(packages);
After installing the npm packages, they can be used as they normally would with require()
. This example shows the read-installed package being used:
var readInstalled = require('read-installed');
readInstalled("/", { depth: 0, dev: true }, function(err, map) { … })
Note: The installation of npm packages takes a little time, so commands that install packages will start up slower than those that do not.
To speed up subsequent runs of a command function that installs packages, the package references returned from the require()
statement can be moved into global variables in the command source code and the packages are only loaded if those values are undefined. This method will cause the packages to be installed the first time the command is executed. Note that they do not need to be installed if the same execution environment is used again by the underling serverless platform. When serverless function environments are reused in a serverless platform, the globals can maintain their previous values.
For example, if the readInstalled
variable above was global, the code could look like this:
var readInstalled;
function _command(...) {
if (!readInstalled) {
let packages = [ 'read-installed', 'chalk' ];
await install(packages);
readInstalled = require('read-installed');
}
}
The first time the code is executed, readInstalled
is undefined and the packages loaded. If the environment is reused later by the underlying serverless platform, the readInstalled
value can be used without installing the packages.
Create/manage user roles/groups
copied
About user roles
copied
For examples of assigning these user roles, see Commands to manage users and user groups.
Admin
In Teams, every Commander bot installed starts with one administrative user: the Teams user who initially installed the Commander bot. It’s up to that admin to assign other Teams users as admins. Admins in turn can assign users as coders for specific commands nd as runners of specific commands.
Admins can also create user groups to make it easier to set coder and runner roles for multiple users. See the command examples below.
Admins have no restrictions on what they can do with Commander. Only admin users can create commands, assign roles to other users, and perform other administrative tasks. Admins can do anything that coders and runners can do.
Coder
The coder role is associated with specific commands. A teams user with a coder role for a command is allowed to edit the source code for the command and also run the command. Admins manage the list of coders for commands. Coders are automatically runners for the commands they can edit.
Runner
The runner role is associated with specific commands ii the custom app. A Teams user with a runner role for a command is allowed to run that command. They cannot run Commander administative commands.
About user groups
copied
Instead of assigning Coder and Runner roles to individual users, admins can combine users into user groups to make it easier to set coder and runner roles for multiple users. The entire user group can then be added or removed as coders or runners for a command.
Commands to manage users and user groups
copied
Manage admin users
Use the app admins command to list, add, or remove Teams users as admins for the current app. A plus (+) in front of a user name adds the user to the list and a minus (-) removes a user from the list.
Note: There must be a space between the plus (+) and minus (-) signs and the user to be added or removed as admins for the current app.
- List the users who are admins for the current app:User 5:09 PM
app adminsCommander App 5:09 PMnc admins: Sam, Jill
- Add Bill and Mary and remove Larry as admins for the current app:User 5:09 PM
app admins + @Bill + @Mary - @Larry
Manage coder users
Use command coders to list, add, or remove users as coders for particular commands.
- View the current list of coders for the add_host command:User 5:09 PM
command coders add_host - Add Jim and Bob and remove John as coders for the print command:User 5:09 PM
command coders print + Jim + Bob - John
Manage users who run commands
Use command runners to list, add, or remove users as runners for particular custom commands.
- Add Joe and Sue and remove John as runners for the print command:User 5:09 PM
command runners print + Joe + Sue - John
Allow anyone to run a custom command
There is a special user group that always exists called anyone
, which includes every Teams user. If you want to allow a command to be run by anyone
, you can add the anyone group to the list of command runners:
- Let anyone run the print command: User 5:09 PM
command runners print + anyone
Create user groups
Use group create to create a user group.
- Create a user group called devgroup1:User 5:09 PM
group create devgroup1
List, add, or remove members of a user group
Use the group members command.
- Add Sue to devgroup1:User 5:09 PM
group members devgroup1 + Sue - Add Jim, Bob, and John and remove Sue from devgroup1:User 5:09 PM
group members devgroup1 + Jim + Bob + John - Sue - List the members of devgroup1:User 5:09 PM
group members devgroup1Commander App 5:09 PMdevgroup1 members: Jim, Bob, John
List all user groups
Use the group list command.
- List all user groups for the current app.User 5:09 PM
group listCommander App 5:09 PMdevgroup1
Delete a user group
Use the group delete command to delete a user group. Only the named group of users is deleted, the command does not affect the Teams users themselves in any way.
- Delete the user group devgroup1:User 5:09 PM
group delete devgroup1
Add a user group to a command
We gave examples of using command coders and command runners to add users as coders and runners respectively. Here are two examples of adding a user group instead.
Add the user group devgroup1 as coders for the print command:
User 5:09 PM
command coders print + devgroup1Add the user group bookkeeping as runners for the bills command:
User 5:09 PM
command runners bills + bookkeeping
Secrets
copied
Admins can create secrets, which are key-value pairs in which the value is encrypted. The key is an arbitrary name, and the value represents an input parameter that should not be visible, such as an API key or password. When secret keys are used as input parameters in commands, the values are automatically decrypted and appear as input parameters to the source code.
Commander has a Secret Creator web user interface (UI) in which you create the key-value pairs and and the secret values are encrypted and stored. That way, unencrypted secret values are stored outside of your app's source code and never appear in plain text in Teams. Only admins have access to the Secret Creator.
Each Commander Bot in Teams contains a unique encryption key to encrypt the values for all key-value pairs. Secrets encrypted for one Commander bot can't be decrypted by any other Commander bot. The encrypted values are stored in your app using AES-256-bit symmetric encryption.
Here’s an overview of how secrets are created, with detailed procedures below:
- Use the
secrete create
command in Teams, which outputs a link to the Secret Creator. - Create the key-value name pairs in the Secret Creator and click a button to encrypt the values.
The Secret Creator outputs a
secret add
command for each key-value pair you’ve created. - Copy and paste the
secret add
commands into Teams to add them to your app.
Note: All commands for creating and managing secrets require an admin user role, but secrets can be listed by anyone with access to the secret list command. The output of all of these commands only outputs the encrypted values, never the decrypted values.
Here are examples of procedures related to secrets.
Create secret key-value pairs and add them to your app:
- Enter the following command into Teams:

secret create

Navigate to: Secret Creator
- In the Secret Creator UI, add a set of name-value pairs, then click Make Secrets. The Secret Creator outputs a list of secret add commands, as in this example:

secret add awsKey NFa_305fe79...c21e4285385f17_

secret add gwpKey NFa_5c67f7b...85e915084650f6_
- Copy and paste each secret add command from the Secret Creator output into Teams to add the encrypted key-value pairs to your current app.
View the list of secret key-value pairs
copied
Use the secret list command.
List the secret key-value pairs:
User 5:09 PM
secret listThe output is a list of keys with their encrypted values. Only the beginning and end of the encrypted values are shown for each secret because the encrypted values can get rather long.
Delete a secret
copied
Use the secret delete command in Teams with the name of the secret key.
Delete the secret key-value pair named
gc_key
:User 5:09 PM
secret delete gc_key
Access the decrypted value of a secret in your command code
copied
Once added to your app, decrypted secret values can be accessed in source code using the secrets
input parameter.
- Example code that accesses a secret value with the key
mySecretApiKey
:async function my_command(params, text, secrets = {}) { if (!secrets.mySecretApiKey) { return { text: "you need a mySecretApiKey secret to run this command" }; } .. connect to API using secrets.mySecretApiKey .. }
- Look in the command source code under the secrets input parameter. For example:
awsConnection = createAwsConnection(secrets.awsKey); gwpConnection = createGwpConnection(secrets.gwpKey); …
Logs
copied
Commander has three log commands to view logs for an app, command, or user respectively:
The log commands are straightforward and currently only have the functionality to display the logs. Here are examples of each being used:
Show the log for the Commander bot as a whole
User 5:09 PM
app logOutput example:
Commander App 5:09 PM342. user_log @Joe Ran by @Joe 10/18/2019, 12:19:13 AM (App: /devops)
Commander App 5:09 PM343. command_code print Ran by @Joe 10/17/2019, 11:26:08 PM (App: /devops)
Show the log for the
add_host
command:User 5:09 PM
command log printOutput example:
Commander App 5:09 PM7. print Ran by @Joe 10/17/2019, 6:49:34 PM Execution time 125ms with status 200 (App: /devops)
Commander App 5:09 PM8. print Ran by @Joe 10/17/2019, 1:30:53 PM Execution time 122ms with status 200 (App: /devops)
Show the log for user
@Sam
:User 5:09 PM
user log @SamOutput example:
Commander App 5:09 PM404. command_delete print Ran by @Sam 10/17/2019, 6:49:20 PM (App: /devops)
Commander App 5:09 PM405. command_list Ran by @Sam 10/17/2019, 6:48:20 PM (App: /devops)
Tip: Every log has a line number. To go back in history, log commands support a -from
option with a line number parameter, for example:

app log -from 90

command log add_host -from 210

user log Rick -from 300
More advanced features, such as searching logs and allowing them to be exported will be supported in future releases.
Command Sets
copied
Command sets can be used to install, manage or publish a set of commands. A command set contains the definition of each command in the set, including the command's name, parameters, and a description. A command set also includes the source code for each command in the set.
Command sets are defined by a YAML file in OpenCSI Specification format. The YAML file includes links to the source code for each command. Put the YAML file in a web-accessible location, along with the source code for each command. Installing the command set using the csm install command brings in the commands and their source, so the source can be customized at the new location. The process is similar to installing npm (Node Package Manager) packages.
You can install publicly available command sets in several different ways, as shown in the following examples.
Example 1: Install the Nimbella billing command set
copied
Nimbella maintains links to commonly used command sets that can be installed using single-word names. For example, there is a billing
command set that contains billing commands for common cloud services, such as Amazon Web Services. See the Example command sets section for a list of the example command sets available.
Note: Many of the commands in the billing
command set require API keys to allow the command source to obtain billing information from the various cloud providers. For example, to use the awsbill
command, you must create secrets for awsCostExplorerAccessKeyId
, awsCostExplorerSecretAccessKeyId
, and awsCostExplorerRegion
. See the Secrets section for how to access information and API keys that need to be added to run the commands that require them. The various commands will output what API keys are required when they are run and what secrets are missing that they need.
Install a command set
Install the
billing
command set, along with the source for the commands with any of these two commands:User 5:09 PM
csm install billing
Output: List of commands installed.
Use csm commands at any time to see the list of commands that were installed in this command set:
List the commands installed with the
billing
command set:User 5:09 PM
csm commands billing
Customize and edit the source code of any of the installed commands using command code to get a link to edit the command's source code.
Retrieve a link to the
awsbill
command’s source code:User 5:09 PM
command code awsbill
Example 2: Install a command set from a GitHub repository
copied
The Github repository has a commands.yaml file in its root directory that contains the OpenCSI YAML definition of the command set. You can publish your own command set for others to use by putting a commands.yaml file for the command set into a GitHub repository. The commands.yaml file contains the definition of each command along with links to the source code for each command.
Install a command set from Github:

csm install github:<name>/<project>
Example 3: Install a command set from a URL
copied
A third way to install a command set from an external location is by specifying the full URL of the command set YAML definition.
Install a command set YAML from the URL https://a.b.com/commands.yaml:
Commands to manage command sets
copied
Update an externally loaded command set
If an externally loaded command set is updated, you can update the source for all the commands from the source location with csm update.
Update the
billing
command set:User 5:09 PM
csm update billing
Notes:
- Any changes you made to the source code of the commands in the set are overwritten by running
csm update
. - Github runs a caching service in front of the Github web site, so if a command set is updated on Github an update may not immediately reflect the changes to the command set.
List all the command sets and commands in each command set
The csm list command outputs all the command sets currently installed in the Commander bot and also all the commands in each command set. There are no parameters.
List all command sets and all commands in each set:
User 5:09 PM
csm listCommander App 5:09 PMbilling: awsbill, datadogbill
The output shows there is one command set (
billing
) with two commands:awsbill
anddatadogbill
List the commands in a specified command set
Use csm commands to see the list of commands included in one command set:
List the commands installed with the
billing
command set:User 5:09 PM
csm commands billing
Show information about a command set
The csm info command provides the following information for a specified command set that was loaded with csm install
:
- Name of the command set
- URL location
- Version number
- Description of the command set
Note: This command doesn’t work with command sets created with csm create
.
Uninstall a command set
Use csm uninstall to uninstall a command set.
Note: This command also deletes all the source code for the commands in the set, even if the source has been modified. If you don't want to delete the individual commands, delete the command set instead.
Uninstall the
billing
command set:User 5:09 PM
csm uninstall billing
Delete a command set
Use csm delete to delete a named command set. Only the command set is deleted – the commands in the set are unaffected by this command. If you want to delete the commands as well, use the csm uninstall command instead.
Delete the billing command set from the current app:
User 5:09 PM
csm uninstall myset
Create and manage a custom command set
copied
First, create a command set, then add and remove commands in a second step.
Create a command set
Use the csm create command to create an internal command set.
Create a command set called
myset
:User 5:09 PM
csm create myset
Add and remove commands
Use csm commands to add and remove commands from a command set. Use plus signs to add and minus signs to remove. Leave a space after the plus or minus sign.
Add the commands
mycommand1
andmycommand2
to themyset
command set:User 5:09 PM
csm commands myset + mycommand1 + mycommand2
The csm commands
command without the optional parameters lists the commands included in this command set.
Export an OpenCSI definition of your internal command set
The csm export command outputs an OpenCSI definition for a command set. You can copy that definition to an external location, such as into a commands.yaml file in a Github repository, then put in references to the source code for the commands.
Output an OpenCSI definition for the
myset
command set:User 5:09 PM
csm export myset
Example command sets
copied
A large number of pre-built command sets are available. All command sets include source code.
The list of command sets that can be installed with single word names is available here:
https://github.com/nimbella/command-sets
See Example 1 for how to install and view the commands in the billing
command set.
Security
copied
You’ll notice when you install the Commander bot in Teams, it doesn’t ask for permissions to read messages. Commander does not read messages in any channel, it is output only and only responds to commands directed at the bot.
The Commander bot doesn’t read any messages on its own and it doesn’t have access to read from any of the channels. User and team identities are automatically managed by Teams. When Teams commands are executed, Commander ensures Teams is the caller using a shared secret key. HTTPS is used for all communications. Internally, Commander uses the Nimbella Cloud. In the Nimbella Cloud, each command function executes in an isolated container, with its environment separated from other containers. Commands in Commander are each separated by namespaces with their own authorization keys.
Manage Accounts
copied
When you install the Commander bot in teams, an account is automatically created for you and tied to that Commader bot.
Accounts have plan information (paid/unpaid) and various limits associated with them.
- To view the account information associated with your Commander Bot in Teams, including the plan and limits, use account info.
- If you want to increase your account limits and upgrade your plan, use the account upgrade command to start the upgrade process for your Commander Bot. This command outputs a web link that will take you to a web page showing your upgrade options and various plan costs.
Upgrading
copied
The free version of Commander has limitations in terms of commands, tasks, and triggers and only allows commands to be written in JavaScript. Upgrades are available on a Commander bot basis to give a bot higher limits and enable more features. Upgrades include the ability to allow direct development using the Nimbella workbench.
See the pricing page for more information.