hubot Documentation

A customizable life embetterment robot.

16,783 stars JavaScript JavaScript 1 file Β· ~7,679 tokens #bot#chat#hubot
RAW Doc

File: README.md

Hubot

Note: v10.0.4 accidentally contains the removal of CoffeeScript; v10.0.5 puts it back in
Note: v11 removes CoffeeScript and converts this codebase to ESM

Hubot is a framework to build chat bots, modeled after GitHub's Campfire bot of the same name, hubot.
He's pretty cool. He's extendable with scripts and can work
on many different chat services.

This repository provides a library that's distributed by npm that you
use for building your own bots. See the documentation
for details on getting up and running with your very own robot friend.

In most cases, you'll probably never have to hack on this repo directly if you
are building your own bot. But if you do, check out CONTRIBUTING.md

Create your own Hubot instance

This will create a directory called myhubot in the current working directory.

sh
npx hubot --create myhubot --adapter @hubot-friends/hubot-slack
npx hubot --create myhubot --adapter @hubot-friends/hubot-discord
npx hubot --create myhubot --adapter @hubot-friends/hubot-ms-teams
npx hubot --create myhubot --adapter @hubot-friends/hubot-irc

Review scripts/example.mjs. Create more scripts in the scripts folder.

Command bus (robot.commands)

Hubot includes a deterministic command subsystem for slash-style commands. It is safe by default and does not interfere with legacy hear and respond listeners.

Basic Command Registration

mjs
export default (robot) => {
	robot.commands.register({
		id: 'tickets.create',
		aliases: ['ticket new', 'new ticket'],
		args: {
			title: { type: 'string', required: true },
			priority: { type: 'enum', values: ['low', 'medium', 'high'], default: 'medium' }
		},
		sideEffects: ['creates external ticket'],
		handler: async (ctx) => {
			return `Created ticket: ${ctx.args.title}`
		}
	})
}

Invoke with addressing the bot:

  • @hubot tickets.create --title "VPN down" --priority high
  • @hubot tickets.create title:"VPN down" priority:high

Commands that declare side effects will require confirmation before execution.

The user is asked to confirm. They do so like so:

sh
@hubot yes
@hubot no
@hubot cancel

Aliases are for discovery and search only. They do not execute commands or create proposals. They are intent utterances.

Built-in Help Command

Hubot automatically registers a help command that provides command discovery and documentation:

text
@hubot help                          # List all commands
@hubot help tickets                  # Filter commands by prefix
@hubot help search "create ticket"   # Search by keyword, alias, description, or example

Search for Commands

mjs
const results = robot.commands.search('ticket new')
// [{ id: 'tickets.create', score: 100, matchedOn: 'alias' }, ...]

Custom Type Resolvers

Extend validation with custom argument types:

mjs
export default (robot) => {
	// Register custom type resolver
	robot.commands.registerTypeResolver('project_id', async (value, schema, context) => {
		if (!value.startsWith('PRJ-')) {
			throw new Error('must start with PRJ-')
		}
		return value.toUpperCase()
	})

	// Use it in a command
	robot.commands.register({
		id: 'projects.deploy',
		args: {
			projectId: { type: 'project_id', required: true }
		},
		handler: async (ctx) => {
			return `Deploying ${ctx.args.projectId}`
		}
	})
}

Configuration Options

When creating a CommandBus instance, you can configure:

  • prefix - Command prefix (default: '')
  • proposalTTL - Timeout for pending confirmations in milliseconds (default: 300000 = 5 minutes)
  • logPath - Path to NDJSON event log file (default: .data/commands-events.ndjson)
  • disableLogging - Disable event logging to disk (default: true - logging is disabled by default)
  • permissionProvider - Custom permission checking handler (optional)

Permissions

Control who can execute commands using room-based and role-based permissions.

Room-Based Permissions

Restrict command execution to specific chat rooms:

mjs
robot.commands.register({
	id: 'sensitive.action',
	permissions: {
		rooms: ['#admin', '#ops']  // Only allowed in these rooms
	},
	handler: async (ctx) => {
		return 'Action executed!'
	}
})

Users in other rooms get: Permission denied: command not allowed in this room

Role-Based Permissions

Restrict command execution to users with specific roles:

mjs
robot.commands.register({
	id: 'deploy.production',
	permissions: {
		roles: ['admin', 'devops']  // Only users with these roles
	},
	handler: async (ctx) => {
		return 'Deploying...'
	}
})

To enable role checking, provide a permissionProvider when creating CommandBus:

mjs
const commandBus = new CommandBus(robot, {
	permissionProvider: {
		hasRole: async (user, requiredRoles, context) => {
			// Custom logic to check if user has any of the required roles
			const userRoles = await fetchUserRoles(user.id)
			return requiredRoles.some(role => userRoles.includes(role))
		}
	}
})

Without a permission provider, role-based permissions are ignored (allow by default). Room-based permissions are always enforced.

License

See the LICENSE file for license rights and limitations (MIT).

Hubot History

Say hello to Hubot

Cartoon with Hubot

The Most Important Startup's Hardest Worker Isn't a Person

The Story of Hubot

Hubot by Hubotics

Automating Inefficiencies

Getting Started with Hubot


File: docs/adapters/campfire.md


Campfire adapter

Campfire is a web based chat application built by 37signals. The Campfire adapter is one of the original adapters in Hubot.

Getting Started

You will need a Campfire account to start.

Next, you will need to create a user on your Campfire account for your Hubot, then give it access so it can join to your rooms. You will need to create a room if you haven't already.

Hubot defaults to using its Shell, so to use Campfire instead, you can run hubot with -a Campfire:

text
% bin/hubot -a campfire

If you are using foreman, you need to make sure the hubot is called with -a Campfire in the Procfile:

text
web: bin/hubot -a campfire -n Hubot

Configuring

The adapter requires the following environment variables.

  • HUBOT_CAMPFIRE_ACCOUNT
  • HUBOT_CAMPFIRE_TOKEN
  • HUBOT_CAMPFIRE_ROOMS

Campfire API Token

This can be found by logging in with your hubot's account click the My Info
link and make a note of the API token.

Campfire Room IDs

If you join the rooms you want your hubot to join will see notice a numerical
ID for the room in the URL. Make a note of each ID for the rooms you want your
hubot to join.

Campfire Account

This is simply the first part of the domain you visit for your Campfire
account. For example if your Campfire was at hubot.campfirenow.com your
subdomain is hubot. Make a note of the subdomain.

Configuring the variables on UNIX

text
% export HUBOT_CAMPFIRE_TOKEN="..."

% export HUBOT_CAMPFIRE_ROOMS="123,321"

% export HUBOT_CAMPFIRE_ACCOUNT="..."

Configuring the variables on Windows

Using PowerShell:

text
setx HUBOT_CAMPFIRE_TOKEN "..." /m

setx HUBOT_CAMPFIRE_ROOMS "123,321" /m

setx HUBOT_CAMPFIRE_ACCOUNT "..." /m

File: docs/adapters/development.md


Development adapter

Adapter Basics

All adapters inherit from the Adapter class in the src/Adapter.mjs file.

javascript
const Adapter = require('hubot/index.mjs').Adapter;

There are certain methods that you will want to override. Here is a basic stub of what an extended Adapter class would look like:

javascript
const Adapter = require('../adapter')
const User = require('../user')
const TextMessage = require('../message').TextMessage
class Sample extends Adapter {
    constructor(robot) {
        super(robot)
        this.robot.logger.info('Constructor')
    }
    send(envelope, ...strings) {
        this.robot.logger.info('Send')
    }
    reply(envelope, ...strings) {
        this.robot.logger.info('Reply')
    }
    run() {
        this.robot.logger.info('Run')
        this.emit('connected') // The 'connected' event is required to trigger loading of Hubot scripts.
        const user = new User(1001, 'Sample User')
        const message = new TextMessage(user, 'Some Sample Message', 'MSG-001')
        this.robot.receive(message)
    }
}
exports.use = (robot) => new Sample(robot)

Option 1. Setting Up Your Development Environment

  1. Create a new folder for your adapter hubot-sample
  • mkdir hubot-sample
  1. Change your working directory to hubot-sample
  • cd hubot-sample
  1. Run npm init to create your package.json
  • make sure the entry point is src/sample.js
  1. Add your .gitignore to include node_modules
  2. Edit the src/sample.js file to include the above stub for your adapter
  3. Edit the package.json to add a peer dependency on hubot
json
"dependencies": {
},
"peerDependencies": {
  "hubot": ">=11"
}
  1. Generate your Hubot using the npx hubot --create myhubot
  2. Change working directories to the hubot you created in step 7.
  3. Now perform an npm link to add your adapter to hubot
  • npm link ../hubot-sample
  1. Run hubot -a sample

Gotchas

There is a an open issue in the node community around npm linked peer dependencies not working. To get this working for our project you will need to do some minor changes to your code.

  1. For the import in your hubot-sample adapter, add the following code
javascript
let  {Robot,Adapter,TextMessage,User} = {}
try {
  {Robot,Adapter,TextMessage,User} = require('hubot')
} catch {
  const prequire = require('parent-require')
  {Robot,Adapter,TextMessage,User} = prequire('hubot')
}
  1. In your hubot-sample folder, modify the package.json to include the following dependency so this custom import mechanism will work
json
"dependencies": {
  "parent-require": "^1.0.0"
}
  1. Now try running hubot -a sample again and see that the imports are properly loaded.
  2. Once this is working properly, you can build out the functionality of your adapter as you see fit. Take a look at some of the other adapters to get some ideas for your implementation.
  • Once packaged and deployed via npm, you won't need the dependency in hubot anymore since the peer dependency should work as an official module.

Option 2. Setting Up Your Development Environment

Another option is to load the file from local disk.

  1. Create a new folder for your adapter hubot-sample
  • mkdir hubot-sample
  1. Change your working directory to hubot-sample
  • cd hubot-sample
  1. Run npm init to create your package.json
  • make sure the entry point is src/sample.js
  1. Add your .gitignore to include node_modules
  2. Edit the src/sample.js file to include the above stub for your adapter
  3. Edit the package.json to add a peer dependency on hubot
json
"dependencies": {
},
"peerDependencies": {
  "hubot": ">=11"
}
  1. Run npx hubot -p ./src -a sample.js

File: docs/adapters/shell.md


Shell adapter

The shell adapter provides a simple read-eval-print loop for interacting with a hubot locally.
It can be useful for testing scripts before using them on a live hubot.

Getting Started

To use the Shell adapter you can simply omit the -a option when running
hubot as it will use the Shell adapter by default.

text
% bin/hubot

Configuring

This adapter doesn't require any configuration.

It supports two environment variables to make it possible to test scripts as different users:

  • HUBOT_SHELL_USER_ID: default is 1
  • HUBOT_SHELL_USER_NAME: default is Shell

File: docs/deploying/azure.md


Deploying to Azure

If you've been following along with Getting Started, it's time to deploy so you can use it beyond just your local machine.
Azure is a way to deploy hubot.

You will need to install the azure-cli via npm after you have follow the initial instructions for your hubot.

text
% npm install azure-cli

Inside your new hubot directory, make sure you've created a git repository, and that your work is committed:

text
% git init
% git add .
% git commit -m "Initial commit"

Then create a GitHub repository for your hubot. This is where Azure will pull your code from instead of needing to deploy directly from your dev machine to Azure.

text
% git remote add origin _your GitHub repo_
% git push -u origin main

Once you have your GitHub repo, create an Azure website linked to your repo. In Azure, create a website and select integrated source control. When it asks "where is your source control" select GitHub and link this website to your git repo that you created in the previous step. If you have downloaded the Azure PowerShell modules, you can also do this via PowerShell.

text
% $creds = Get-Credential
% New-AzureWebsite mynewhubot -github -githubrepository yourgithubaccount/yourhubotreponame -githubcredentials $creds

Once you have done this, Azure will deploy your site any time you commit and push to GitHub. Your hubot won't run quite right yet, though. Next, you need to configure the deployment to tell Azure how to run hubot.

First, run the follow command to add deploy.cmd to your hubot directory. This is the file that Azure uses to know how to deploy your node application.

text
% azure site deploymentscript --node

Then, edit this file and look for the sections that give you steps 1, 2 and 3. You're going to add a 4th step:

text
:: 4. Create Hubot file with a js extension
copy /Y "%DEPLOYMENT_TARGET%\node_modules\hubot\bin\hubot" "%DEPLOYMENT_TARGET%\node_modules\hubot\bin\Hubot.mjs"

Now, create a new file in the base directory of hubot called server.js and put these two lines into it:

text
module.exports = await import('hubot/bin/Hubot.mjs');

Finally you will need to add the environment variables to the website to make sure it runs properly. You can either do it through the GUI (under configuration) or you can use the Azure PowerShell command line, as follows (example is showing slack as an adapter and mynewhubot as the website name).

text
% $settings = New-Object Hashtable
% $settings["HUBOT_ADAPTER"] = "Slack"
% $settings["HUBOT_SLACK_TOKEN"] = "yourslackapikey"
% Set-AzureWebsite -AppSettings $settings mynewhubot

Commit your changes in git and push to GitHub and Azure will automatically pick up the changes and deploy them to your website.

text
% git commit -m "Add Azure settings for hubot"
% git push

Azure offers a marketplace where you can use the default hubot-redis-brain using Redis Cloud provided by Redis Labs. Alternatively, to add an Azure blob storage brain, you will need to create an Azure storage account. Then you can do the following in your base hubot directory.

text
% npm install hubot-azure-brain --save

Then add the following line in external-scripts.json in the list with the other external scripts

text
"hubot-azure-brain"

Finally, add one more environment variables to your website. You can do this either via the GUI or the following PowerShell commands.

text
% $settings = New-Object Hashtable
% $settings["HUBOT_BRAIN_AZURE_CONNSTRING"] = "your Azure blob storage connection string"
% Set-AzureWebsite -AppSettings $settings mynewhubot

Now any scripts that require a brain will function. You should look up other scripts or write your own by looking at the documentation. All of the normal scripts for hubot are compatible with hosting hubot on Azure.

Troubleshooting tips and tricks

Due to Azure being Windows-based, you may run into path length problems. To overcome this issue you can set the environment variable IN_PLACE_DEPLOYMENT to 1 and use custom deployment scripts to take advantage of NPM3 and flat module installation.

If you have your instance of hubot deploying directly from source control to Azure, it will perform various bootstrapping tasks along with calling npm install via kudu. Now that Azure supports npm5, this process generates a package-lock.json file which may result in some of your packages failing to install remotely. You can edit deploy.cmd to include --no-package-lock as part of the "Step 3" install command.

If using the free tier of Azure, you can also add a post-deployment step to ping the server on startup by setting the environment variable POST_DEPLOYMENT_ACTION with a script (relative to the src dir) such as startup.sh

An example of a startup script:

text
let retrys=0
while : ; do
    STATUSCODE=$(curl --silent --output /dev/stderr --write-out "%{http_code}" https://${WEBSITE_SITE_NAME}.azurewebsites.net/hubot/keepalive)
    echo $STATUSCODE
    [[ $retrys -ne 5 ]] || break
    echo $retrys
    ((retrys++))
    [[ $STATUSCODE -ne 200 ]] || break
done

Slack Integration

Currently the Slack integration has trouble finding hubot when deployed to Azure. Adding a NODE_PATH application setting with the value D:\home\site\wwwroot\node_modules will allow the Slack module to find hubot.


File: docs/deploying/bluemix.md


Deploying to Bluemix

If you've been following along with Getting Started, it's time
to deploy so you can use it beyond just your local machine.
IBM Bluemix is a way to deploy hubot. It is built on the open-source project
Cloud Foundry, so we'll be using the cf cli
throughout these examples.

Hubot was originally very closely coupled to Heroku, so there are a couple of
things to clean up first that we don't need or that might get in the way on
another platform:

  • remove Procfile as we'll create the manifest.yml that Bluemix needs in a
    moment

  • remove the hubot-heroku-keepalive line from external_scripts.json and also
    remove the related npm module (it causes errors on other platforms):

    npm uninstall --save hubot-heroku-keepalive

In preparation for working with Bluemix, install the Cloud Foundry
CLI
, and create a Bluemix
Account
.

First we need to define a manifest.yml file in the root directory. The
contents of the manifest at the bare minimum should look like:

yml
applications:
- name: myVeryOwnHubot
  command: ./bin/hubot --adapter slack
  instances: 1
  memory: 512M

In this example, we're using the slack adapter, if you choose slack as your
adapter when creating a hubot this will work, otherwise add the hubot-slack
module to your package.json. Change the name of your hubot in the
manifest.yml file
because otherwise your application will clash with someone
else's who already deployed an app called this! There are many more useful
things you can change about your hubot using the manifest file, so check out
these docs
for more information.

You then need to connect your hubot project to Bluemix:

sh
$ cd your_hubot_project
$ cf api https://api.ng.bluemix.net
$ cf login

Note that the cf api command changes per Bluemix region so to deploy somewhere
other than "US South", replace this api as appropriate. The cf login command
will prompt you with your login credentials.

Next, we need to set up our environment variables, but we need to create the app
first. It won't work properly without the environment variables it needs, so
we'll first of all use the --no-start flag to deploy but not attempt to start
it.

sh
$ cf push NAME_OF_YOUR_HUBOT_APP --no-start

Now the app exists, we can set its environment variables. To access slack,
you'll need a slack token from the "Apps and Integrations" page; it's visible
when you go to create a slackbot. Copy that token and set it as an environment
variable called HUBOT_SLACK_TOKEN, like this:

sh
$ cf set-env NAME_OF_YOUR_HUBOT_APP HUBOT_SLACK_TOKEN TOKEN_VALUE

If you have other environment variables to set, such as configuring the
REDIS_URL for hubot-redis-brain, this is a good time to do that.

Finally, we're ready to go! Deploy "for real" this time:

sh
$ cf push NAME_OF_YOUR_HUBOT_APP

You should see your bot connect to slack!

Further Reading

Troubleshooting

Bot doesn't connect

Check your logs for more information using the command cf logs YOUR_APP_NAME --recent. If you have NodeJS installed locally, you can also try running the
bot on your local machine to inspect any output: simply do bin/hubot from the
top level of the project.

Bot crashes repeatedly

It is sometimes necessary to to assign more memory to your hubot, depending
which plugins you are using (if your app crashes with error 137, try increasing
the memory limit).


File: docs/deploying/unix.md


Deploying to Unix

Because there are so many variations of Linux, and more generally UNIX, it's
difficult for the hubot team to have canonical documentation for installing and
deploying it to every version out there. So, this is an attempt to give an
overview of what's needed to get deploying.

There are 3 primary things to deploying and running hubot:

  • node and npm
  • a way to get source code updated on the server
  • a way to start hubot, start it up if it crashes, and restart it when code
    updates

node and npm

To start, your UNIX server will need node and npm. Check out the node.js wiki
for installing Node.js via package manager, Building on GNU/Linux and other UNIX.

Updating code on the server

The simplest way to update your hubot's code is going to be to have a git
checkout of your hubot's source code (that you've created during Getting Started, not the github/hubot repository, and just git pull to get change. This may
feel a dirty hack, but it works when you are starting out.

If you have a Ruby background, you might be more comfortable using
capistrano.

If you have a Chef background, there's a
deploy resource for managing
deployments.

Starting, stopping, and restarting hubot

Every hubot install has a bin/hubot script to handle starting up the hubot.
You can run this command from your git checkout on the server, but there are some problems you can encounter:

  • you disconnect, and hubot dies
  • hubot dies, for any reason, and doesn't start again
  • it doesn't start up at boot automatically

For handling you disconnecting, you can start with running bin/hubot in
screen session or with
nohup.

For handling hubot dying, and restarting it automatically, you can imagine
running bin/hubot in a
bash while loop. But
really, you probably want some process monitoring using tools like
monit,
god,
bluepill,
upstart,
runit,
systemd.

For starting at boot, you can create an init script appropriate for your UNIX
distribution. If you are using one of the process monitoring tools above, make
sure it boots at startup. See the examples
for configuration examples.

Recommendations

This document has been deliberately light on strong recommendations. At a high
level though, it's strongly recommended to avoid anything that is overly manual
and non-repeatable. That would mean using your OS's packages and tools whenever
possible, and having a proper deploy tool to update hubot, and process
management to keep hubot running.


File: docs/deploying/windows.md


Deploying to Windows

Hasn't been fully tested - YMMV

There are 4 primary steps to deploying and running hubot on a Windows machine:

  • node and npm
  • a way to get source code updated on the server
  • setting up environment variables for hubot
  • a way to start hubot, start it up if it crashes, and restart it when code updates

node and npm

To start, your windows server will need node and npm.
The best way to do this is with chocolatey using the nodejs.install package.
I've found that sometimes the system path variable is not correctly set; ensure you can run node/npm from the command line. If needed set the PATH variable with set PATH=%PATH%;\"C:\Program Files\nodejs\"

Your other option is to install directly from NodeJS and run the current download (v0.12.4 as of this documentation). This should set your PATH variables for you.

Updating code on the server

To get the code on your server, you can follow the instructions at Getting Started on your local development machine or directly on the server. If you are building locally, push your hubot to GitHub and clone the repo onto your server. Don't clone the normal github/hubot repository, make sure you're using npx hubot --create myhubot to build your own hubot.

Setting up environment vars

You will want to set up your hubot environment variables on the server where it will run. You can do this by opening an administrative PowerShell and typing the following:

text
[Environment]::SetEnvironmentVariable("HUBOT_ADAPTER", "Campfire", "Machine")

This is equivalent to going into the system menu -> selecting advanced system settings -> environment vars and adding a new system variable called HUBOT_ADAPTER with the value of Campfire.

Starting, stopping, and restarting hubot

Every hubot install has a bin/hubot script to handle starting up the hubot.
You can run this command directly from your hubot folder by typing the following:

text
.\bin\hubot –adapter campfire

There are a few issues if you call it manually, though.

  • you disconnect, and hubot dies
  • hubot dies, for any reason, and doesn't start again
  • it doesn't start up at boot automatically

To fix this, you will want to create a .ps1 file with whatever name makes you happy that you will call from your hubot directory. There is a copy of this file in the examples directory here. It should contain the following:

text
Write-Host "Starting Hubot Watcher"
While (1)
{
    Write-Host "Starting Hubot"
    Start-Process powershell -ArgumentList ".\bin\hubot –adapter slack" -wait
}

Remember to allow local unsigned PowerShell scripts if you are using the .ps1 file to run hubot. Run this command in an Administrator PowerShell window.

text
Set-ExecutionPolicy RemoteSigned

You can set this .ps1 as scheduled task on boot if you like or some other way to start your process.

Expanding the documentation

Not yet fleshed out. Help contribute by submitting a pull request, please?


File: docs/adapters.md


Adapters

Adapters are the interface to the service you want your hubot to run on.

Hubot includes two official adapters:

There are Third-party adapters available for most chat services. Here are the most popular ones:

Browse all repositories with the hubot-adapter topic on GitHub or search for adapters on NPM. Add the hubot-adapter topic to your repository on GitHub to include it in this list.

Writing Your Own Adapter

Interested in adding your own adapter? Check out our documentation for developing adapters