A Hubot helper to make easy group chatter.
npm install hubot-groupchatterscripts` file
chatter` Required
chatter.addResponse(key, message)` Required
key`
message`
chatter.delay(key, seconds)`
key`
seconds`
chatter.delayRandom(key, seconds)`
key`
seconds`
chatter.flipFlop(key, keyA, keyB, percentA)`
key`
keyA`
keyB`
percentA`
chatter.logLevel(setMode)` Optional Setup
setMode`
chatter.percentChance(key, percent, bonus)`
key`
percent`
bonus`
chatter.regex(key, regex)` Required
key`
regex`
chatter.regexIgnore(key, regex)`
key`
regex`
chatter.setUserPrefix(prefix)` Optional Setup
prefix`
chatter.setUserSuffix(suffix)` Optional Setup
suffix`
chatter.startup(robot)` Required
robot`
chatter.throttle(key, seconds, random)`
key`
seconds`
random`
chatter.waitForIt(key, count, seconds)`
key`
count`
seconds`
npm install hubot-groupchatter`.
1. Copy `node_modules/hubot-groupchatter/groupchatter.coffee.sample` to your Hubot `scripts` directory and rename the file to `groupchatter.coffee`.
1. Edit `groupchatter.coffee` to your liking.
1. Run your bot and trigger the responses.
Note: If you want to install from GitHub, use `npm install git://github.com/BrynM/hubot-groupchatter.git` or `npm install git://github.com/BrynM/hubot-groupchatter.git#0.1.0` for a specific version ("0.1.0" in this example). It is advised you install from npm's copy.
Usage
$3
The functionality and logic for groupchatter is organized by "keys". This facilitates tying things together to make more complex actions. A key should always contain one regular expression (`chatter.regex()`) and at least one response (`chatter.addResponse()`). If one of those is missing, no replies will be sent for that key.
When your Hubot observes the string your regular expression matches, whatever logic you may have specified for that key will be tested. If the tests all pass, Hubot will respond with one of your responses chosen at random.
$3
The only exception to a key needing a regular expression are the two response keys used to store replies by `chatter.flipFlop()`. In that case, you should use `chatter.addResponse()` for those keys and nothing else.
Concurrently, the only exception to a key needing responses added is the primary key used for `chatter.flipFlop()` (the first argument). That key still does require a regular expression.
It is highly recommended that you thoroughly read through the sample `scripts` file even if you wish to start your file from scratch. The examples in it are functional and commented.
$3
The file "groupchatter.coffee.sample" contains examples for using and combining logic. It should be located at `node_modules/hubot-groupchatter/groupchatter.coffee.sample` relative to your Hubot or viewed online at GitHub.
Every function available to groupchatter should have an example in that file. Along with the reference section of this document, you should be able to . Here's a list of the examples:
DO IT* - Respond with the classic "Do it" GIF from Starsky and Hutch.
yo* - Join in the group all saying "yo".
Count 30* - A cheapo countdown for showing off delays.
BOO!* - A simple random delay for those scared of robots.
Mentions of your mom* - Self-explanatory and often used, just like your mom.
gratuitous thanks* - Acknowledge gladhanding except for Geoff.
Magic 8 Ball* - A 50% flip-flop example.
table flip* - A tendency to mostly reprimand, but sometimes reward, table flipping using flip-floping.
Reference
This reference assumes you're using CoffeeScript and are at least a little familiar with it, as CoffeeScript is what Hubot was meant to use. That said, the translation to JavaScript is near-nonexistent so feel free to apply this documentation to that as well.
$3
To use a template variable in your response, surround it in two hash marks ("##"). For now, the number of variables is fixed and limited.
##### List of Template Variables
|Variable|Explanation|
|:---|:---|
|date|The current server date|
|fulldate|The full date and time|
|id|The user id of the robot|
|match|Exact regex matched string from the detected message|
|quote|Full quote of the detected message|
|robot|The name of the robot|
|room|The current chat room's name|
|time|The current server time|
|user|The user who sent the detected message|
|utc|The current server date and time translated to UTC|
|1|The first sub-match in your regular expression 1|
Note 1: Regular expression matches are actually template variables 1 through 30 ("##1##", "##2##", "##3##", "##4##" ... "##30##",). Regular expression sub-matches that don't exist will be replaced with an empty string (""). This was the best way to deal with it for now.
##### Example
`coffeescript
chatter.addResponse('iRule', 'Long live ##user##, Sovereign Ruler of ##room##!')
`
$3
Our core object that gets exported when you require the module. Of course, you can call it whatever you want but it's absolutely required for groupchatter to work. You should put this at the top of your script along with your other imported modules.
##### Example
`coffeescript
chatter = require 'hubot-groupchatter'
`
$3
Add a message for a given set key. Returns the message back on success and undefined on failure.
##### Argument: `key`
string*
The key name for the set you'd like to use.
##### Argument: `message`
string*
The message you wish to reply with. This may include template variables.
##### Example
`coffeescript
chatter.addResponse('beratement', 'Well, you suck ##user##!')
`
$3
Respond `seconds` after the detected message. For random delayed responses, see `chatter.delayRandom()`.
##### Argument: `key`
string*
The key name for the set you'd like to use.
##### Argument: `seconds`
positive integer*
The number of seconds you wish groupchatter to wait before responding. If this number is less than 1, chatter.delay() will be ignored.
##### Example
`coffeescript
chatter.delay('thritySecLater', 30)
`
$3
Respond between 0 and `seconds` after the detected message.
##### Argument: `key`
string*
The key name for the set you'd like to use.
##### Argument: `seconds`
positive integer*
The maximum number of seconds you wish groupchatter to wait before responding. If this number is less than 1, chatter.delayRandom() will be ignored.
##### Example
`coffeescript
chatter.delayRandom('derp', 60)
`
$3
Create a superset of keyed responses to alternate between. Currently, only supports two sets.
##### Argument: `key`
string*
The key name for the set you'd like to use. This key is used for triggering regular expressions on this pairing of responses and does not require responses of its own.
##### Argument: `keyA`
string*
The key name of a set where you've done nothing but store responses with `chatter.addResponse()`. If you (by mistake perhaps) assign a regular expression to this key, it may get selected on its own and its responses may seem to trigger at random.
##### Argument: `keyB`
string*
The key name of a second set where you've done nothing but store responses with `chatter.addResponse()`. If you (by mistake perhaps) assign a regular expression to this key, it may get selected on its own and its responses may seem to trigger at random.
##### Optional Argument: `percentA`
positive integer between 1 and 100*
You may optionally provide a percentage chance that keyA will be chosen for responses. By default, keyA and keyB each will have a 50% chance.
##### Example
`coffeescript
reply yes or no evenly
chatter.flipFlop('yesOrNo', 'yesResponses', 'noResponses')
join in flipping tables with a 75% chance of being positive/constructive/calming
chatter.flipFlop('tableFlip', 'tablesPositive', 'tablesNegative', 75)
`
$3
Set the log level for node console output. This is helpful for debugging your Hubot script or developing groupchatter.
##### Argument: `setMode`
string*
The name of the logging mode you desire. The default is "warn". Valid names are as follows. Each log level also enables the ones listed after it up to "silent".
|Name||
|---:|:---|
|debug|Full logging. This is very noisy and is really only meant for development.|
|info|Some extra information about what's going on and which tests are failing.|
|warn|Log only warnings and errors.|
|silent|Don't log anything at all.|
##### Example
`coffeescript
chatter.logLevel('info')
`
$3
Only have a percentage chance of responding. This is the last test performed before a response is chosen, so delays and timeouts supersede it.
##### Argument: `key`
string*
The key name for the set you'd like to use.
##### Argument: `percent`
positive integer between 1 and 100*
The percentage chance you'd like to give to respond.
##### Optional Argument: `bonus`
positive integer between 1 and 100*
The value of this argument will be added to the generated random number, much like a role playing game. This can be used to give a "bottom-floor" to your `percent` chance.
##### Example
`coffeescript
chatter.percentChance('rarelyRespond', 15)
chatter.percentChance('sometimesRespond', 20, 20)
`
$3
Set a regular expression to match something another user says that you'd like your set to trigger on. Only one regular expression is allowed per set, so multiple calls will overwrite each other with the newest call winning.
##### Argument: `key`
string*
The key name for the set you'd like to use.
##### Argument: `regex`
`RegExp` object*
The regular expression that you'd like your set to trigger on. This expression supports sub-matches that count from 1-30. Regular expression sub-matches that don't exist, but appear in templates, will be replaced with an empty string ("").
##### Example
`coffeescript
set a simple regex
chatter.regex('noWay', /^way[!.]?$/i)
use sub-matches in template vars
chatter.regex('matchedThing', /^look at (that|this|my|your|their|its) thing$/)
chatter.addResponse('matchedThing', 'Nobody wants ##1## thing, ##user##!')
`
$3
Set a regular expression to match something another user says that you'd like your set to trigger on. Quite handy for avoiding embarrassing phrases and situations if you need to. These must be created per-set as you need them and multiple ignored regular expressions are supported per set.
##### Argument: `key`
string*
The key name for the set you'd like to use.
##### Argument: `regex`
`RegExp` object*
The regular expression that you'd like your set to ignore.
##### Example
`coffeescript
chatter.regex('stayOutOfIt', /(vim|emacs).*(emacs|vim)/i)
`
$3
Set a prefix to be prepended to the `##user##` response template variable. By detault "@" is used. Thus, the template "Hi ##user##!" for the user "steve" would end up with the response of "Hi @steve!".
##### Argument: `prefix`
string*
The string you'd like to be prepended to the user that triggered the response..
##### Example
`coffeescript
change this for a reddit bot
chatter.setUserPrefix('/u/')
`
$3
Set a prefix to be prepended to the `##user##` response template variable. By default an empty string ("") is used. Thus, the template "Hi ##user##!" with a suffix of "(jerk)" for the user "steve" would end up with the response of "Hi steve(jerk)!".
##### Argument: `suffix`
string*
The string you'd like to be appended to the user that triggered the response..
##### Example
`coffeescript
add the clan tag to user names
chatter.setUserPrefix('[APES]')
`
$3
This is to be assigned as the `module.exports` of your Hubot script. If you do not put this somewhere in your script, groupchatter will never respond.
##### Argument: `robot`
`module.exports` invocated Hubot Robot object*
`module.exports` will deal with this argument. Unless you're doing groupchatter development, you can safely ignore it.
##### Example
`coffeescript
module.exports = chatter.startup
`
$3
Throttle a set to only respond again after `seconds`. Until that time expires, groupchatter will ignore any new triggers as well - including incrementing `chatter.waitForIt()` counts.
Optionally, a `random` variation in seconds can be provided. This number is split and applied centered to the end of `seconds`. For example, with `seconds` set to 30 and `random` set to 10, groupchatter will not respond again for a random time between 25 and 35 seconds.
##### Argument: `key`
string*
The key name for the set you'd like to use.
##### Argument: `seconds`
positive integer*
The number of seconds groupchatter should wait. Using a value of `seconds` below 1 will be ignored and throttling will be disabled.
##### Optional Argument: `random`
positive integer*
The number of seconds to randomly add/subtract to `seconds`. Using a value of `random` below 1 will nullify the randomization, but timing out may continue.
##### Example
`coffeescript
wait 5 minutes before responding again
chatter.throttle('wait5Mins', 300)
only respond every 30 to 90 seconds
chatter.throttle('notTooFast', 60, 60)
`
$3
Will wait until triggered `count` times before responding. Optionally, `count` can be constrained to a specific time window in `seconds`.
##### Argument: `key`
string*
The key name for the set you'd like to use.
##### Argument: `count`
positive integer*
The number of triggers that must happen before groupchatter will respond. Using a value of `count` below 1 will be ignored.
##### Optional Argument: `seconds`
positive integer*
Optional number of `seconds` that `count` must be achieved in. If not achieved, the counter will be reset on the next trigger after `seconds` expires. Using a value of `seconds` below 1 will be ignored, but triggering will continue.
##### Example
`coffeescript
chatter.waitForIt('replyEvery100', 100)
chatter.waitForIt('replyYesWithin1Min', 5, 60)
`
Technical Details
* This code is released under the GPLv3 License.
* Most of the normal Hubot response setup logic has been abstracted away.
* This module will not help you write regular expressions. You're on your own there. Don't give up. They're infinitely useful.
* I wrote this code quickly and don't have a lot of time for maintaining it. If you have issues please feel free to file a bug, but I cannot guarantee a decent response time. If you'd like to join the project let me know, but I must ask that you have a history of contributing before allowing you direct access (unless I can personally vouch for you).
As mentioned above, contribution is encouraged. If you make a pull request, please feel free to add yourself at the bottom* of the contributors list in package.json with your PR.
* If you want to use the internal console messaging, keep your changes to being declarative. That is, report raw values - don't try to do things like math or calculation. This will keep the console functionality messages cheap.
* I didn't write any tests. My bad. See note further above about being written quickly. See GPLv3 language for fitness of use.
Future Hopes
These are in order of importance. If you'd like to contribute, feel free to take a stab at one of them.
* Make a `chatter.waitForItRandom()``.