Coder Social home page Coder Social logo

chatops-controller's Introduction

Chatops Controller

Rails helpers for easy and well-tested Chatops RPC. See the protocol docs for background information on Chatops RPC.

A minimal controller example:

class ChatopsController < ApplicationController
  include ::Chatops::Controller

  # The default chatops RPC prefix. Clients may replace this.
  chatops_namespace :echo

  chatop :echo,
  /(?<text>.*)?/,
  "<text> - Echo some text back" do
    jsonrpc_success "Echoing back to you: #{jsonrpc_params[:text]}"
  end
end

Some routing boilerplate is required in config/routes.rb:

Rails.application.routes.draw do
  # Replace the controller: argument with your controller's name
  post "/_chatops/:chatop", controller: "chatops", action: :execute_chatop
  get  "/_chatops" => "chatops#list"
end

It's easy to test:

class MyControllerTestCase < ActionController::TestCase
  include Chatops::Controller::TestCaseHelpers
  before do
    chatops_prefix "echo"
    chatops_auth!
  end

  def test_it_works
    chat "echo foo bar baz"
    assert_equal "foo bar baz", chatop_response
  end
end

Before you deploy, add the RPC authentication tokens to your app's environment, below.

You're all done. Try .echo foo, and you should see your client respond with Echoing back to you: foo.

A hubot client implementation is available at https://github.com/bhuga/hubot-chatops-rpc

Usage

Namespaces

Every chatops controller has a namespace. All commands associated with this controller will be displayed with .<namespace> in chat. The namespace is a default chatops RPC prefix and may be overridden by a client.

chatops_namespace :foo

Creating Chatops

Creating a chatop is a DSL:

chatop :echo,
/(?<text>.*)?/,
"<text> - Echo some text back" do
  jsonrpc_success "Echoing back to you: #{jsonrpc_params[:text]}"
end

In this example, we've created a chatop called echo. The next argument is a regular expression with named captures. In this example, only one capture group is available, text.

The next line is a string, which is a single line of help that will be displayed in chat for .echo.

The DSL takes a block, which is the code that will run when the chat robot sees this regex. Arguments will be available in the params hash. params[:user] and params[:room_id] are special, and will be set by the client. user will always be the login of the user typing the command, and room_id will be where it was typed. The optional mention_slug parameter will provide the name to use to refer to the user when sending a message; this may or may not be the same thing as the username, depending on the chat system being used. The optional message_id parameter will provide a reference to the message that invoked the rpc.

You can return jsonrpc_success with a string to return text to chat. If you have an input validation or other handle-able error, you can use jsonrpc_failure to send a helpful error message.

Chatops are regular old rails controller actions, and you can use niceties like before_action and friends. before_action :echo, :load_user for the above case would call load_user before running echo.

Authentication

Authentication uses the Chatops v3 public key signing protocol. You'll need two environment variables to use this protocol:

CHATOPS_AUTH_PUBLIC_KEY is the public key of your chatops client in PEM format. This environment variable will be the contents of a .pub file, newlines and all.

CHATOPS_AUTH_BASE_URL is the base URLs of your servers as the chatops client sees it. This is specified as an environment variable since rails will trust client headers about a forwarded hostname. For example, if your chatops client has added the url https://example.com/_chatops, you'd set this to https://example.com. You can specify more than one base url divided by comma, e.g. https://example.com,https://example2.com

You can also optionally set CHATOPS_AUTH_ALT_PUBLIC_KEY to a second public key which will be accepted. This is helpful when rolling keys.

Rails compatibility

This gem is intended to work with rails 6.x and 7.x. If you find a version with a problem, please report it in an issue.

Development

Changes are welcome. Getting started:

script/bootstrap
script/test

See CONTRIBUTING.md for contribution instructions.

Upgrading from early versions

Early versions of RPC chatops had two major changes:

Using Rails' dynamic :action routing, which was deprecated in Rails 5.

To work around this, you need to update your router boilerplate:

This:

  post  "/_chatops/:action", controller: "chatops"

Becomes this:

  post  "/_chatops/:chatop", controller: "chatops" action: :execute_chatop
Adding a prefix

Version 2 of the Chatops RPC protocol assumes a unique prefix for each endpoint. This decision was made for several reasons:

  • The previous suffix-based system creates semantic ambiguities with keyword arguments
  • Prefixes allow big improvements to .help
  • Prefixes make regex-clobbering impossible

To upgrade to version 2, upgrade to version 2.x of this gem. To migrate:

  • Migrate your chatops to remove any prefixes you have:
 chatop :foo, "help", /ci build whatever/, do "yay" end

Becomes:

 chatop :foo, "help", /build whatever/, do "yay" end
  • Update your tests:
  chat "ci build foobar"

Becomes:

  chat "build foobar"
  # or
  chatops_prefix "ci"
  chat "ci build foobar"
Using public key authentication

Previous versions used a CHATOPS_ALT_AUTH_TOKEN as a shared secret. This form of authentication was deprecated and the public key form used above is now used instead.

License

MIT. See the accompanying LICENSE file.

chatops-controller's People

Contributors

anglinb avatar dbussink avatar itoys avatar jakedouglas avatar jbarnette avatar jhawthorn avatar kevinsawicki avatar koddsson avatar leequarella avatar mistydemeo avatar parkr avatar raffo avatar rnkaufman avatar royetadmor avatar technicalpickles avatar technoweenie avatar twp avatar wagnerm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chatops-controller's Issues

Release version 3.2.0

@mistydemeo would you be willing to push up version 3.2.0 to rubygems. I do not have permission there to release this gem. Thank you ๐Ÿ™‡โ€โ™‚๏ธ

Error bundling module to a new rails project.

This may be a common error (I'm not really a rails developer) but when I add the following line to my Gemfile:

gem 'chatops_controller', :git => '[email protected]:github/chatops_controller.git' 

... and run bundle install --path vendor/gems/ errrors with:

NoMethodError: undefined method `spec' for nil:NilClass
An error occurred while installing chatops_controller (0.2.0), and Bundler cannot continue.

It's probably me, but I'm not sure what to do about it. Any help would be appreciated.

It installs globally If I gem build chatops_controller.gemspec and then just gem install chatops_controller-0.2.0.gem I've tried copying the gem to vendor/gems/*/cache and running bundler from there setting its :path => in the Gemfile. It results in the same no method `spec' error.

Spec questions

I spent some time this weekend building a Golang implementation: https://github.com/github/go-chatops. The spec is really good, but I ran into a few questions:

  1. What is the difference between a method name (options in the protocol doc example) and the path (wcid)? In that example, is it possible to leave out the path property if it happened to be options?
  2. Why does a chat command POST have the method path in the URL and the input JSON? Does it matter if they conflict?
  3. What is the keyid in a signature header like Chatops-Signature: Signature keyid="rsakey1",signature="<base64-encoded-signature>"? Will it be something like keyid="hubot" in our environment? Doesn't look like it's needed to sign or verify CRPC commands, but is it worth logging?
  4. What about HTTP response codes? You can see the HTTP statuses returned in this file. Is that legit, or should I return 200, potentially with json rpc error messages to denote a CRPC protocol error?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.