All Projects → jejacks0n → bitbot

jejacks0n / bitbot

Licence: other
Bitbot: Rack based Slack bot with a responder DSL and support for Wit.ai natural language processing.

Programming Languages

ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to bitbot

notify
推送通知 sdk(Bark、Chanify、钉钉群机器人、Discord、邮件、飞书群机器人、Gitter、Google Chat、iGot、Logger、Mattermost、Now Push、PushBack、Push、PushDeer、PushPlus、QQ 频道机器人、Rocket Chat、Server 酱、Showdoc Push、Slack、Telegram、Webhook、企业微信群机器人、息知、Zulip)。
Stars: ✭ 335 (+2476.92%)
Mutual labels:  slack
slatify
Slack Notification for GitHub Actions 🔔
Stars: ✭ 132 (+915.38%)
Mutual labels:  slack
git-slack-notify
Sends Slack notifications for new commits in Git repositories
Stars: ✭ 12 (-7.69%)
Mutual labels:  slack
emojibot
Emojibot is a Slack bot that announces new custom emoji to a specific channel.
Stars: ✭ 17 (+30.77%)
Mutual labels:  slack
openwhisk-slackapp
A serverless Slack app built with Slack Events API and IBM Cloud Functions
Stars: ✭ 24 (+84.62%)
Mutual labels:  slack
slackteams
Manage and Interact with multiple Slack teams in R
Stars: ✭ 21 (+61.54%)
Mutual labels:  slack
enhanced-slack
🌴 PoC Slack enhancer/injector
Stars: ✭ 48 (+269.23%)
Mutual labels:  slack
magento2-module-slack
Magento 2 Module to send Notifications to a Slack Channel via Webhook.
Stars: ✭ 14 (+7.69%)
Mutual labels:  slack
pr-reviews-reminder-action
A GitHub Action to send Slack/Teams notification for Pull Request that are waiting for reviewers.
Stars: ✭ 18 (+38.46%)
Mutual labels:  slack
worldcup-slack-bot
WorldCupBot will notify a Slack channel/group for every match during a FIFA World Cup
Stars: ✭ 33 (+153.85%)
Mutual labels:  slack
st2chatops
Packaging environment for building StackStorm chatops native packages
Stars: ✭ 26 (+100%)
Mutual labels:  slack
slack-discord-bridge
Bridges a text channel between Slack and Discord
Stars: ✭ 21 (+61.54%)
Mutual labels:  slack
SlackLateX
Bot that posts posts Latex pictures
Stars: ✭ 39 (+200%)
Mutual labels:  slack
humhub-oauth
Social OAuths built for the Social Platform HumHub
Stars: ✭ 16 (+23.08%)
Mutual labels:  slack
slacky-dark
Dark mode theme for Slack desktop clients
Stars: ✭ 24 (+84.62%)
Mutual labels:  slack
Yasuf
Very simple way of controlling your Python application via Slack
Stars: ✭ 23 (+76.92%)
Mutual labels:  slack
rota-slackbot
Slackbot that helps manage rotations.
Stars: ✭ 50 (+284.62%)
Mutual labels:  slack
slack-to-opsgenie-alert-creator
Create alerts from messages sent to a Slack channel
Stars: ✭ 25 (+92.31%)
Mutual labels:  slack
oauth2-slack
Slack OAuth 2.0 Client Provider for The PHP League OAuth2-Client
Stars: ✭ 20 (+53.85%)
Mutual labels:  slack
zoom-slack-status-updater
Update your Slack status automatically when you join a Zoom meeting.
Stars: ✭ 23 (+76.92%)
Mutual labels:  slack

Bitbot

Gem Version Build Status Maintainability Test Coverage License

Bitbot is a lightweight Rack endpoint specifically intended for Slack webhooks. It can be mounted within a Rails app, or can be run as a standalone Rack app with the config.ru provided as an example.

You can write custom responders that take advantage of the logic within your larger application. Responders have support for custom routing and can utilize Wit.ai natural language processing.

For more complex responder examples, check out the bitbot-responders project.

Installation

gem "bitbot", github: "jejacks0n/bitbot"

Rails

Bitbot can run fine without Rails, but if you're using Rails, you can run the install generator. The generator will provide an initializer and mount the rack app within your routes -- be sure to update both the initializer and route if you change where it's mounted.

rails generate bitbot:install

Configuration

Bitbot requires being configured, but to simplify the README it's not included here, please check the config.ru for an example and configuration documentation.

The config.ru file is provided as a convenience and only serves as an example -- it is not included with the gem.

You can grab the config.ru and run the listener with rackup. Or if you've installed the generator, you can test your setup by starting your rails server and running (based on your configuration and port):

curl --data 'text=help+me&user_name=tester&channel=none&token=token' \
http://localhost:9292/rack-bitbot-webhook

You should get a JSON response back. If you don't, Bitbot is intentionally vague about what could've gone wrong, but the likely causes are that the token isn't correct, the request isn't a post, or that the username was the same as the bots (she doesn't respond to herself).

Setting up Slack

To get all of the configuration tokens and urls, you'll need to go to Slack and add the Incoming Webhooks, and Outgoing Webhooks integrations. You can get your incoming url, and outgoing token by doing this, which you can then set as environment variables and load them into your configuration.

When setting up the Outgoing Webhook integration you will need to know where you have configured the Rack endpoint so you can provide that as the url that will be used.

Adding Responders

There's a basic DSL for creating responders, which allows you to register help for the various commands, and define responder routes. Bitbot considers commands to be "routable", and so you can define them using route. Here's an example responder that specifies category, help and a single route. The category indicates grouping within the default help responder, but is somewhat arbitrary in it's meaning should you do something else with it.

class MyResponder < Bitbot::Responder
  category "Greetings"
  help "hi bot", description: "I'll respond with a greeting"

  route :say_hi_back, /^hi bot/i do
    respond_with("awesome! hi #{message.user_name}.")
  end
end

A route must be named, and provide a regexp matcher. Here's another example, but here we capture a value from the message.

In general a responder route will return a hash that's then sent back to the Slack request but additional messages can be announced from within the responder. As a general rule you should always use the respond_with method in your responder routes because it can determine if it should return the Hash, or make the announcement itself. You can also use the private_message, or public_message helper methods, which always announce and don't return a Hash.

route :echo, /^echo (.*)/i do |string|
  respond_with("heard #{message.user_name} say \"#{string}\" in #{message.channel}.")
end

Confirmations

Confirmations are included as a base feature, but need redis to work. Provide your own redis connection in the configuration and you can add confirmations (and more) to your responders. By default the configuration assumes redis is running locally, and is available at Redis.current -- otherwise it will try to connect to redis at the standard port.

route :say_hi_back?, /^hi bot/i do
  confirm("were you saying hi to me?", "yes") do
    respond_with("awesome! hi #{message.user_name}.")
  end
end

Wit.ai

We think Wit.ai is pretty rad for a bot setup, but it does take some work to get it trained and working the way you want. This is part of the fun, and part of the challenge.

To use Wit.ai in your responders, you need to require wit_ruby and include the Wit module in your responder. Then you can define intents, and which route they go to, as well as any entities that are within them. In the most complex form this would look something like the following.

Note: wit_ruby expects ENV["WIT_AI_TOKEN"] to be defined. read more

class MyResponder < Bitbot::Responder
  include Bitbot::Responder::Wit
  category "Greetings"
  help "hi bot my name is <name>", description: "I'll respond with a greeting"

  intent "greeting", :say_hi_back, entities: { contact: ->(e) { e['value'] } }
  route :say_hi_back, /^hi bot, my name is (.*)/i do |specified_name|
    respond_with("awesome! hi #{specified_name}, I'm bot.")
  end
end

Now if you train Wit to understand "Hello, I'm Jeremy Jackson", including the name portion as a wit/contact entity, it will make it through to the responder as the specified_name argument to the block. Again, this is a complex thing to setup and train, so have fun with it. You may also note that the route has a fallback regexp that allows using directly, even if Wit.ai wasn't able to determine what the intent was.

Worth mentioning, the proc that you see in the entities above doesn't need to be specified if all you want is the value, but if it's a proc it will call the proc with the entity hash. Some entities have complex structures, like duration, where you may want to pull out the seconds, instead of the number of minutes or hours that may have been provided. In those cases use duration: ->(e) { e['normalized']['value'] }, but in our above example, we could've just used contact: nil and the value would be pulled automatically for us.

Announcing

You can announce any message into any channel on Slack using the bot, for instance in a background job to have something happen on an action or predefined schedule. You must configure Bitbot's webhook_url by setting up an Incoming Webhook Integration on Slack before this will work however.

Bitbot.announce(text: "Hello all!", channel: "#general")

You can send private messages if you like as well.

Bitbot.announce(text: "Hello you!", channel: "@username")

You can also reuse any of the existing responder routes by having the responder handle the route directly. Obviously in these cases you must provide anything that that the might expect from the message, which always includes text, and may include common things like channel or user_name. Since responder routes can be pretty vague, and implement any number of things, you may have to provide additional information as well.

Since responders can make their own announcements, or return a hash you can use the Bitbot.announce method based on configuration.

Bitbot.announce(MyResponder.new.respond_to(text: "Hi bot", channel: "#general", user_name: "system"))
# or
MyResponder.new.respond_to(text: "Hi bot", channel: "#general", user_name: "system")

Regex can get hairy, so the respond_to method also accepts a block to return any additional context you may want to use inside your route.

MyResponder.new.respond_to(text: "Archive user", channel: "#admin", user_name: "system") { { id: 2 } }

route :archive, /^archive user/i do
  # access info from blockk
  more_info = context_block.call
  # do something with the info
  User.find(more_info[:id]).archive
  respond_with("You got it, User with id: #{more_info[:id]} has been archived.")
end

License

Licensed under the MIT License

Copyright 2019 jejacks0n

Make Code Not War


Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].