initial code in state marchote
This commit is contained in:
commit
efcf4e2bee
15 changed files with 3166 additions and 0 deletions
10
.env.example
Normal file
10
.env.example
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
BOT_LOG_LEVEL=debug
|
||||||
|
BOT_NAME=brocket
|
||||||
|
BOT_SHELL_USER_NAME=user
|
||||||
|
BOT_SHELL_ROOM_NAME=shell
|
||||||
|
ROCKETCHAT_URL=http://localhost:3000
|
||||||
|
ROCKETCHAT_USER=brocket
|
||||||
|
ROCKETCHAT_PASSWORD=pass
|
||||||
|
RESPOND_TO_DM=true
|
||||||
|
RESPOND_TO_EDITED=true
|
||||||
|
LISTEN_ON_ALL_PUBLIC=false
|
64
.gitignore
vendored
Normal file
64
.gitignore
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# npm lockfile (using yarn)
|
||||||
|
package-lock.json
|
29
Dockerfile
Normal file
29
Dockerfile
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
FROM node:8.11.2-alpine
|
||||||
|
LABEL maintainer="Rocket.Chat Team <buildmaster@rocket.chat>"
|
||||||
|
|
||||||
|
ENV npm_config_loglevel=error
|
||||||
|
ENV BOT_OWNER "No owner specified"
|
||||||
|
ENV BOT_DESC "bBot with the Rocket.Chat adapter"
|
||||||
|
|
||||||
|
USER root
|
||||||
|
|
||||||
|
COPY bin/bbot /home/bbot/bin/
|
||||||
|
COPY package.json /home/bbot/
|
||||||
|
COPY index.js /home/bbot/
|
||||||
|
COPY src/* /home/bbot/src/
|
||||||
|
|
||||||
|
RUN apk add --update --no-cache \
|
||||||
|
git && \
|
||||||
|
adduser -S bbot && \
|
||||||
|
addgroup -S bbot && \
|
||||||
|
touch ~/.bashrc && \
|
||||||
|
npm install --global npm@latest && \
|
||||||
|
chown -R bbot:bbot /home/bbot/
|
||||||
|
|
||||||
|
WORKDIR /home/bbot/
|
||||||
|
|
||||||
|
USER bbot
|
||||||
|
|
||||||
|
RUN npm install --no-audit
|
||||||
|
|
||||||
|
CMD ["/bin/ash", "/home/bbot/bin/bbot"]
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Amazebot
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
50
README.md
Normal file
50
README.md
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
[create-user]: https://rocket.chat/docs/bots/creating-bot-users/
|
||||||
|
[configure-bot]: https://rocket.chat/docs/bots/configure-bot-environment/
|
||||||
|
|
||||||
|
![bRocket | A bBot boilerplate for Rocket.Chat bots](https://github.com/Amazebot/bbot-rocketchat-boilerplate/raw/master/img/banner.png)
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
## 1. 🍴 Fork or clone this repo
|
||||||
|
- `git clone amazebot/bbot-rocketchat-boilerplate MY_BOT`
|
||||||
|
- to clone without git history, add `--depth 1` flag
|
||||||
|
- or once cloned, start a fresh history `rm -rf .git && git init`
|
||||||
|
## 2. 💻 Setup your project
|
||||||
|
- `npm install` get dependencies
|
||||||
|
- `npm run setup` add your details
|
||||||
|
## 3. ✨ Test in shell
|
||||||
|
- `npm start -- -m shell`
|
||||||
|
## 4. 👨💻 Start coding
|
||||||
|
- customise **index.js**
|
||||||
|
- look at **examples.js**
|
||||||
|
## 5. 💬 Run in Rocket.Chat
|
||||||
|
- create user with bot role
|
||||||
|
- set login credentials in .env
|
||||||
|
- `npm start` (`rocketchat` is default adapter)
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
You'll need a Rocket.Chat instance to test. See Rocket.Chat's docs on
|
||||||
|
[Creating Bot Users][create-user] before you begin.
|
||||||
|
|
||||||
|
Easy deployment options coming soon.
|
||||||
|
|
||||||
|
See [bbot.chat](http://bbot.chat) for get started guides.
|
||||||
|
|
||||||
|
## Configure
|
||||||
|
|
||||||
|
All **bBot** settings require the `BOT_` prefix on environment variables.
|
||||||
|
|
||||||
|
See Rocket.Chat's docs on [Configuring Bot Environments][configure-bot] for
|
||||||
|
settings specific to the SDK.
|
||||||
|
|
||||||
|
Configs can be given from command line. Try `node index.js -h` for options.
|
||||||
|
|
||||||
|
They can also be set in **package.json** under the `"bot"` attribute. You should
|
||||||
|
review all the package details and customise it to your own project details.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
You can run and interact with the bot directly in shell, for quick development.
|
||||||
|
|
||||||
|
Run `node index.js -m shell` to override Rocket.Chat as the message adapter.
|
148
bin/bbot
Normal file
148
bin/bbot
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Stop NPM from complaining about useless stuff.
|
||||||
|
export npm_config_loglevel=error
|
||||||
|
|
||||||
|
# Listen for SIGINT/SIGTERM so the container can be killed with CTRL+C
|
||||||
|
# Also prevents reboot bug where the container freezes for 30-60 seconds
|
||||||
|
asyncRun() {
|
||||||
|
"$@" &
|
||||||
|
pid="$!"
|
||||||
|
trap "echo 'Stopping PID $pid'; kill -SIGTERM $pid" SIGINT SIGTERM
|
||||||
|
|
||||||
|
# Signal emitted while waiting will make the wait command return code > 128
|
||||||
|
# Wrap it in a loop that doesn't end before the process is indeed stopped
|
||||||
|
while kill -0 $pid >/dev/null 2>&1; do
|
||||||
|
wait
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
|
||||||
|
888 888888b. 888
|
||||||
|
888 888 "88b 888
|
||||||
|
888 888 .88P 888
|
||||||
|
88888b. 8888888K. .d88b. 888888
|
||||||
|
888 "88b 888 "Y88b d88""88b 888
|
||||||
|
888 888 888 888 888 888 888
|
||||||
|
888 d88P 888 d88P Y88..88P Y88b.
|
||||||
|
88888P" 8888888P" "Y88P" "Y888
|
||||||
|
|
||||||
|
8888888b. 888 888 .d8888b. 888 888
|
||||||
|
888 Y88b 888 888 d88P Y88b 888 888
|
||||||
|
888 888 888 888 888 888 888 888
|
||||||
|
888 d88P .d88b. .d8888b 888 888 .d88b. 888888 888 88888b. 8888b. 888888
|
||||||
|
8888888P" d88""88b d88P" 888 .88P d8P Y8b 888 888 888 "88b "88b 888
|
||||||
|
888 T88b 888 888 888 888888K 88888888 888 888 888 888 888 .d888888 888
|
||||||
|
888 T88b Y88..88P Y88b. 888 "88b Y8b. Y88b. d8b Y88b d88P 888 888 888 888 Y88b.
|
||||||
|
888 T88b "Y88P" "Y8888P 888 888 "Y8888 "Y888 Y8P "Y8888P" 888 888 "Y888888 "Y888
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Your bBot Rocket.Chat Docker container is now starting. Please wait..."
|
||||||
|
|
||||||
|
# Check if the Rocket.Chat URL has been set
|
||||||
|
if [[ -z "${ROCKETCHAT_URL}" ]]; then
|
||||||
|
echo "-------------"
|
||||||
|
echo "----ERROR----"
|
||||||
|
echo "-------------"
|
||||||
|
echo "ROCKETCHAT_URL environment variable has not been set."
|
||||||
|
echo "Set this to your Rocket.Chat Server URL. e.g."
|
||||||
|
echo "ROCKETCHAT_URL=https://bots.rocket.chat"
|
||||||
|
echo "-------------"
|
||||||
|
echo "Exiting...."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if the Rocket.Chat User has been set
|
||||||
|
if [[ -z "${ROCKETCHAT_USER}" ]]; then
|
||||||
|
echo "-------------"
|
||||||
|
echo "----ERROR----"
|
||||||
|
echo "-------------"
|
||||||
|
echo "ROCKETCHAT_USER environment variable has not been set."
|
||||||
|
echo "Set this to the bot account username on your Rocket.Chat server. e.g."
|
||||||
|
echo "ROCKETCHAT_USER=brocket"
|
||||||
|
echo "-------------"
|
||||||
|
echo "Exiting...."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if the Rocket.Chat password has been set
|
||||||
|
if [[ -z "${ROCKETCHAT_PASSWORD}" ]]; then
|
||||||
|
echo "-------------"
|
||||||
|
echo "----ERROR----"
|
||||||
|
echo "-------------"
|
||||||
|
echo "The ROCKETCHAT_PASSWORD Environment Variable has not been set."
|
||||||
|
echo "Set this to the bot account password on your Rocket.Chat server. e.g."
|
||||||
|
echo "ROCKETCHAT_PASSWORD=supersecret"
|
||||||
|
echo "-------------"
|
||||||
|
echo "Exiting...."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check there's either rooms defined, or the bot is listening to all
|
||||||
|
if [[ -z "${ROCKETCHAT_ROOM}" ]]; then
|
||||||
|
if [[ -z "${LISTEN_ON_ALL_PUBLIC}" ]]; then
|
||||||
|
echo "-------------"
|
||||||
|
echo "----ERROR----"
|
||||||
|
echo "-------------"
|
||||||
|
echo "Either ROCKETCHAT_ROOM or LISTEN_ON_ALL_PUBLIC need to be defined."
|
||||||
|
echo "Without rooms to join, if it's not listening on all public rooms,"
|
||||||
|
echo "the bot won't receive any messages to respond to. e.g."
|
||||||
|
echo "ROCKETCHAT_ROOM=general,my-private-room"
|
||||||
|
echo "or"
|
||||||
|
echo "LISTEN_ON_ALL_PUBLIC=true"
|
||||||
|
echo "-------------"
|
||||||
|
echo "Exiting...."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install any required deps.
|
||||||
|
cd /home/bbot/
|
||||||
|
|
||||||
|
# Allow using custom registry for node modules
|
||||||
|
if [[ -z "${NPM_REGISTRY}" ]]; then
|
||||||
|
echo "INFO: The NPM_REGISTRY environment variable has not been set."
|
||||||
|
echo "INFO: Using npmjs as the default."
|
||||||
|
else
|
||||||
|
echo "INFO: The NPM_REGISTRY environment variable is $NPM_REGISTRY."
|
||||||
|
echo "INFO: NPM will use this registry to pull packages from."
|
||||||
|
npm set registry $NPM_REGISTRY
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This happens here as well as during the container build process.
|
||||||
|
# This is insurance that no dependencies were missed.
|
||||||
|
# If node_modules externally mounted, insures the base deps are there.
|
||||||
|
echo "INFO: Attempting to install this containers dependancies"
|
||||||
|
npm install --no-audit
|
||||||
|
|
||||||
|
# Report information about optional behviour environment variables
|
||||||
|
if [[ -z "${RESPOND_TO_DM}" ]]; then
|
||||||
|
echo "-------------"
|
||||||
|
echo "INFO: The RESPOND_TO_DM environment variable has not been set."
|
||||||
|
echo "INFO: Set RESPOND_TO_DM=true to respond to direct messages."
|
||||||
|
echo "Default: RESPOND_TO_DM=false"
|
||||||
|
echo "-------------"
|
||||||
|
fi
|
||||||
|
if [[ -z "${RESPOND_TO_EDITED}" ]]; then
|
||||||
|
echo "-------------"
|
||||||
|
echo "INFO: The RESPOND_TO_EDITED environment varialbe is not set."
|
||||||
|
echo "INFO: Set RESPOND_TO_EDITED=true to respond to messages after edits."
|
||||||
|
echo "Default: RESPOND_TO_EDITED=false"
|
||||||
|
echo "-------------"
|
||||||
|
fi
|
||||||
|
if [[ -z "${RESPOND_TO_LIVECHAT}" ]]; then
|
||||||
|
echo "-------------"
|
||||||
|
echo "INFO: The RESPOND_TO_LIVECHAT environment varialbe is not set."
|
||||||
|
echo "INFO: Set RESPOND_TO_LIVECHAT=true to respond to livechat messages."
|
||||||
|
echo "Default: RESPOND_TO_LIVECHAT=false"
|
||||||
|
echo "-------------"
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export PATH="node_modules/.bin:node_modules/bbot/node_modules/.bin:$PATH"
|
||||||
|
|
||||||
|
# Start bBot using the asyncRun function
|
||||||
|
asyncRun node index.js "$@"
|
4
bin/bbot.cmd
Normal file
4
bin/bbot.cmd
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
@echo off
|
||||||
|
call npm install
|
||||||
|
SETLOCAL
|
||||||
|
node ../index.js %*
|
BIN
img/avatar.png
Normal file
BIN
img/avatar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
img/banner.png
Normal file
BIN
img/banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
14
index.js
Normal file
14
index.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
const bot = require('bbot')
|
||||||
|
|
||||||
|
/** This is a workaround for Heroku to confirm web binding. */
|
||||||
|
// @todo Remove this when bBot includes Express (next release)
|
||||||
|
const http = require('http')
|
||||||
|
const handle = (req, res) => res.end('hit')
|
||||||
|
const server = http.createServer(handle)
|
||||||
|
server.listen(process.env.PORT || 5000)
|
||||||
|
|
||||||
|
/** Add your bot logic here. Removing the imported examples. */
|
||||||
|
// require('./src/examples')
|
||||||
|
require('./src/reactions')
|
||||||
|
|
||||||
|
bot.start() // 🚀
|
76
init.js
Normal file
76
init.js
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
const fs = require('fs')
|
||||||
|
const cpm = require('child_process')
|
||||||
|
const { promisify } = require('util')
|
||||||
|
const inquirer = require('./node_modules/inquirer')
|
||||||
|
const readFile = promisify(fs.readFile)
|
||||||
|
const writeFile = promisify(fs.writeFile)
|
||||||
|
const copyFile = promisify(fs.copyFile)
|
||||||
|
const exec = promisify(cpm.exec)
|
||||||
|
|
||||||
|
async function replaceInFile (file, regex, value) {
|
||||||
|
const content = await readFile(file, 'utf8')
|
||||||
|
const update = content.replace(regex, value)
|
||||||
|
await writeFile(file, update, 'utf8')
|
||||||
|
}
|
||||||
|
|
||||||
|
inquirer.prompt([
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'package',
|
||||||
|
message: 'Name your node package',
|
||||||
|
default: 'bbot-bot',
|
||||||
|
validate: (name) => (new RegExp('^[a-z@/-]*$').test(name))
|
||||||
|
? true
|
||||||
|
: 'Invalid name for npm package.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'bot',
|
||||||
|
message: 'Name your new bot',
|
||||||
|
default: 'bot'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'author',
|
||||||
|
message: 'What is your name?'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'email',
|
||||||
|
message: 'Email (for package author field)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'confirm',
|
||||||
|
name: 'env',
|
||||||
|
message: 'Create .env with defaults?'
|
||||||
|
}
|
||||||
|
]).then(async (answers) => {
|
||||||
|
if (answers.package) {
|
||||||
|
await replaceInFile(
|
||||||
|
'./package.json',
|
||||||
|
/^(\s\s"name":\s")(.*?)(")/gm,
|
||||||
|
`$1${answers.package}$3`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (answers.bot) {
|
||||||
|
await replaceInFile(
|
||||||
|
'./package.json',
|
||||||
|
/^(\s{2}"bot": {\n\s{4}"name": ")(.*?)(")/gm,
|
||||||
|
`$1${answers.bot}$3`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (answers.author || answers.email) {
|
||||||
|
let author = answers.author ? answers.author : ''
|
||||||
|
if (answers.email) author += `<${answers.email}>`
|
||||||
|
await replaceInFile(
|
||||||
|
'./package.json',
|
||||||
|
/^(\s\s"author":\s")(.*?)(")/gm,
|
||||||
|
`$1${author}$3`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (answers.env) {
|
||||||
|
await copyFile('.env.example', '.env')
|
||||||
|
await replaceInFile('.env', /brocket/g, answers.bot)
|
||||||
|
await exec('open .env')
|
||||||
|
}
|
||||||
|
})
|
46
package.json
Normal file
46
package.json
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
"name": "bbot-bot",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "bRocket is a bBot boilerplate for building Rocket.Chat bots",
|
||||||
|
"main": "index.js",
|
||||||
|
"files": [
|
||||||
|
"index.js",
|
||||||
|
"src"
|
||||||
|
],
|
||||||
|
"repository": "git@github.com:Amazebot/bbot-rocketchat-boilerplate.git",
|
||||||
|
"author": "mose<mose@mose.com>",
|
||||||
|
"contributors": [],
|
||||||
|
"license": "MIT",
|
||||||
|
"private": false,
|
||||||
|
"engines": {
|
||||||
|
"node": "> 8.0.0",
|
||||||
|
"npm": "> 5.0.0"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"bBot",
|
||||||
|
"Rocket.Chat",
|
||||||
|
"rocketchat",
|
||||||
|
"chatbot",
|
||||||
|
"chat",
|
||||||
|
"messaging",
|
||||||
|
"conversation",
|
||||||
|
"CUI"
|
||||||
|
],
|
||||||
|
"bot": {
|
||||||
|
"name": "bot",
|
||||||
|
"message-adapter": "rocketchat",
|
||||||
|
"avatar": "https://crapaud-fou.org/images/coaaaa.png"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"bbot": "^1.3.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^1.18.3"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"setup": "node init.js",
|
||||||
|
"start": "node index.js",
|
||||||
|
"watch": "nodemon index.js",
|
||||||
|
"debug": "nodemon --inspect index.js"
|
||||||
|
}
|
||||||
|
}
|
201
src/examples.js
Normal file
201
src/examples.js
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
const bot = require('bbot')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All branch examples start from the "global" conversation scope.
|
||||||
|
* We are working on features to provide branching within a conversational
|
||||||
|
* context, but as those methods are changing in the beta, they aren't included
|
||||||
|
* as examples to follow just yet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Branch types are declared from their scope, see all available types here:
|
||||||
|
* http://bbot.chat/docs/path#builtforbranching
|
||||||
|
*
|
||||||
|
* `text` branches take the following arguments:
|
||||||
|
* - matcher: expression, semantic conditions object, or array of conditions
|
||||||
|
* - callback: to fire on successful match, given the state object (b)
|
||||||
|
* - [options]: object with `id` (string) and/or `force` (boolean) attributes
|
||||||
|
*
|
||||||
|
* Test with "Hello bots!"
|
||||||
|
*/
|
||||||
|
bot.global.text(/(hi|hello).*bots?/, (b) => b.respond('Hello :wave:'), {
|
||||||
|
id: 'hello-bots'
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `direct` branch type requires the bot to be explicitly addressed.
|
||||||
|
*
|
||||||
|
* `reply` instead of `respond` prepends messages with user's name.
|
||||||
|
*
|
||||||
|
* In Rocket.Chat all messages to a bot in a direct room have the name prepended
|
||||||
|
* by the Rocket.Chat SDK before it's processed by the bot framework.
|
||||||
|
*
|
||||||
|
* Test with "@brocket Hello" or just "Hello" in a DM.
|
||||||
|
*/
|
||||||
|
bot.global.direct(/hi|hello/i, (b) => b.reply('Hey there.'), {
|
||||||
|
id: 'hello-direct'
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `respondVia` allows using custom platform methods to dispatch response.
|
||||||
|
*
|
||||||
|
* Matcher conditions allow semantic attributes with a string or array of
|
||||||
|
* optional values to match against, possibly capturing content.
|
||||||
|
* Accepted atts: is, starts, ends, contains, excludes, after, before, range
|
||||||
|
*
|
||||||
|
* Test with "Hello anyone?"
|
||||||
|
*/
|
||||||
|
bot.global.text({
|
||||||
|
contains: ['hi', 'hello']
|
||||||
|
}, (b) => b.respondVia('react', ':wave:'), {
|
||||||
|
id: 'hello-react'
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Branch callbacks allow asynchronous responding, if they return a promise.
|
||||||
|
* State (b) includes branch matching attributes, see bbot.chat/docs/thought.
|
||||||
|
*
|
||||||
|
* Test with "@brocket ping back in 5 seconds"
|
||||||
|
*/
|
||||||
|
bot.global.direct(/ping back in (\d*)/i, async (b) => {
|
||||||
|
const ms = parseInt(b.match[1]) * 1000
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, ms))
|
||||||
|
return b.respond('Ping :ping_pong:')
|
||||||
|
}, {
|
||||||
|
id: 'ping-delay'
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `respond` method can accept attachment objects as well as strings.
|
||||||
|
* Rendering support depends on the message platform and adapter. In shell,
|
||||||
|
* it will display the fallback text.
|
||||||
|
*
|
||||||
|
* Test with "bot attach image"
|
||||||
|
*/
|
||||||
|
bot.global.text(/attach image/i, (b) => {
|
||||||
|
return b.respond({
|
||||||
|
fallback: `See: https://www.wikiwand.com/en/Three_Laws_of_Robotics`,
|
||||||
|
image: `https://upload.wikimedia.org/wikipedia/en/8/8e/I_Robot_-_Runaround.jpg`,
|
||||||
|
title: {
|
||||||
|
text: `Asimov's Three Laws of Robotics`,
|
||||||
|
link: `https://www.wikiwand.com/en/Three_Laws_of_Robotics`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, { id: 'attach-image' })
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `envelope` provides helpers for adding rich-message payloads before
|
||||||
|
* responding. Preparing envelopes before dispatch also allows changing the
|
||||||
|
* user/room the envelope is addressed to or dispatching multiple envelopes.
|
||||||
|
*
|
||||||
|
* Test with "I want a prize"
|
||||||
|
*/
|
||||||
|
bot.global.text({
|
||||||
|
contains: 'prize'
|
||||||
|
}, (b) => {
|
||||||
|
b.envelope.write('Choose your fate! 🚪... 🎁 ')
|
||||||
|
b.envelope.attach({ color: '#f4426e' })
|
||||||
|
b.envelope.payload
|
||||||
|
.quickReply({ text: 'Door number 1' })
|
||||||
|
.quickReply({ text: 'Door number 2' })
|
||||||
|
.quickReply({ text: 'Door number 3' })
|
||||||
|
return b.respond().catch((err) => console.error(err))
|
||||||
|
}, { id: 'door-prize-intro' })
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `conditions` attribute contains results of semantic condition matching
|
||||||
|
* and capture groups. Each condition can be given a key for easy reference.
|
||||||
|
*
|
||||||
|
* Test with "what's behind door number 2"
|
||||||
|
*/
|
||||||
|
bot.global.text({
|
||||||
|
door: { after: 'door', range: '1-3' }
|
||||||
|
}, (b) => {
|
||||||
|
switch (b.conditions.captured.door) {
|
||||||
|
case '1': return b.respond(`You win nothing 💔`)
|
||||||
|
case '2': return b.respond(`You win a monkey 🐒`)
|
||||||
|
case '3': return b.respond(`It's a new car!! 🚗`)
|
||||||
|
}
|
||||||
|
}, { id: 'door-prize-award' })
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Branch callbacks can be async functions, to awaiting one or more processes
|
||||||
|
* before responding. This example uses API requests to fill a dynamic array
|
||||||
|
* of actions, using the url property to provide link action buttons.
|
||||||
|
*
|
||||||
|
* Test with "@brocket plan meeting" in a public or private room.
|
||||||
|
*/
|
||||||
|
bot.global.direct({
|
||||||
|
is: 'plan meeting'
|
||||||
|
}, async (b) => {
|
||||||
|
if (bot.adapters.message.name !== 'rocketchat-message-adapter') return
|
||||||
|
b.envelope.write('Please review time zones in the room...')
|
||||||
|
const { id, type } = b.message.user.room
|
||||||
|
let room
|
||||||
|
const q = { roomId: id }
|
||||||
|
if (type === 'c') {
|
||||||
|
room = await bot.adapters.message.api.get('channels.members', q, true)
|
||||||
|
} else if (type === 'p') {
|
||||||
|
room = await bot.adapters.message.api.get('groups.members', q, true)
|
||||||
|
} else {
|
||||||
|
return b.respond('Sorry, that only works in channels and private groups.')
|
||||||
|
}
|
||||||
|
const offsets = room.members
|
||||||
|
.map((member) => member.utcOffset || undefined)
|
||||||
|
.filter((offset) => !!offset)
|
||||||
|
for (let utc of offsets) {
|
||||||
|
b.envelope.payload.quickReply({
|
||||||
|
text: `🌐 UTC ${utc}`,
|
||||||
|
url: `https://www.timeanddate.com/worldclock/timezone/utc${utc}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
b.respond()
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo This example requires PR #11811 to be merged. Room names are undefined.
|
||||||
|
*/
|
||||||
|
bot.global.text(/where am i/i, (b) => {
|
||||||
|
const { name, type } = b.message.user.room
|
||||||
|
switch (type) {
|
||||||
|
case 'c': return b.respond(`You're in the #${name} public channel.`)
|
||||||
|
case 'p': return b.respond(`You're in a private group called **${name}**.`)
|
||||||
|
case 'l': return b.respond(`You're in a livechat channel.`)
|
||||||
|
case 'd': return b.respond(`You're in a DM with me :hugging:`)
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
id: 'location-check'
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom options can be added to the bot, with the full config utility of bBot,
|
||||||
|
* allowing them to be defined as environment variables, command line args or
|
||||||
|
* package.json attributes. Extend settings with a yargs option format.
|
||||||
|
*
|
||||||
|
* Try any of the following:
|
||||||
|
* - `node index.js --avatar <YOUR_AVATAR_URL>`
|
||||||
|
* - BOT_AVATAR=<YOUR_AVATAR_URL> in .env
|
||||||
|
* - `{ "bot": { "avatar": "<YOUR_AVATAR_URL>" } }` in package.json
|
||||||
|
*/
|
||||||
|
bot.settings.extend({
|
||||||
|
avatar: {
|
||||||
|
'type': 'string',
|
||||||
|
'description': 'Set a custom avatar for your bot account profile'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bot can access lower level methods of the Rocket.Chat SDK through the
|
||||||
|
* message adapter, once it's connected. This example sets an avatar on login.
|
||||||
|
*
|
||||||
|
* Try replacing the avatar configured in package.json with your own.
|
||||||
|
*/
|
||||||
|
bot.events.on('started', () => {
|
||||||
|
if (bot.adapters.message.name !== 'rocketchat-message-adapter') return
|
||||||
|
if (bot.settings.get('avatar')) {
|
||||||
|
bot.logger.info('Setting bot avatar')
|
||||||
|
bot.adapters.message.api.post('users.setAvatar', {
|
||||||
|
avatarUrl: bot.settings.get('avatar')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
14
src/reactions.js
Normal file
14
src/reactions.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
const bot = require('bbot');
|
||||||
|
|
||||||
|
bot.global.text({
|
||||||
|
contains: ['facebook', 'google', 'amazon', 'apple', 'microsoft']
|
||||||
|
}, (b) => {
|
||||||
|
b.respondVia('react', ':hear_no_evil:');
|
||||||
|
}, {
|
||||||
|
id: 'gafam-react'
|
||||||
|
});
|
||||||
|
|
||||||
|
bot.global.text(/pe?tit? globe/i, (b) => b.respond('![pti globe](https://eye.mose.fr/2019-07-31-21-50_grab.png)'), {
|
||||||
|
id: 'ptiglobe-direct'
|
||||||
|
})
|
Loading…
Reference in a new issue