mirror of
https://github.com/Fishwaldo/huginn.git
synced 2025-03-15 19:31:26 +00:00
add webhooks controller
This commit is contained in:
parent
db5cb918bf
commit
d0715756f0
8 changed files with 115 additions and 2 deletions
1
Gemfile
1
Gemfile
|
@ -1,6 +1,7 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'rails'
|
||||
gem 'rake'
|
||||
gem 'mysql2'
|
||||
gem 'devise'
|
||||
gem 'rails_admin'
|
||||
|
|
39
app/controllers/webhooks_controller.rb
Normal file
39
app/controllers/webhooks_controller.rb
Normal file
|
@ -0,0 +1,39 @@
|
|||
# This controller is designed to allow your Agents to receive cross-site Webhooks (posts). When POSTed, your Agent will
|
||||
# have #receive_webhook called on itself with the POST params.
|
||||
#
|
||||
# Make POSTs to the following URL:
|
||||
# http://yourserver.com/users/:user_id/webhooks/:agent_id/:secret
|
||||
# where :user_id is your User's id, :agent_id is an Agent's id, and :secret is a token that should be
|
||||
# user-specifiable in your Agent. It is highly recommended that you verify this token whenever #receive_webhook
|
||||
# is called. For example, one of your Agent's options could be :secret and you could compare this value
|
||||
# to params[:secret] whenever #receive_webhook is called on your Agent, rejecting invalid requests.
|
||||
#
|
||||
# Your Agent's #receive_webhook method should return an Array of [json_or_string_response, status_code]. For example:
|
||||
# [{status: "success"}, 200]
|
||||
# or
|
||||
# ["not found", 404]
|
||||
|
||||
class WebhooksController < ApplicationController
|
||||
skip_before_filter :authenticate_user!
|
||||
|
||||
def create
|
||||
user = User.find_by_id(params[:user_id])
|
||||
if user
|
||||
agent = user.agents.find_by_id(params[:agent_id])
|
||||
if agent
|
||||
response, status = agent.trigger_webhook(params.except(:action, :controller, :agent_id, :user_id))
|
||||
if response.is_a?(String)
|
||||
render :text => response, :status => status || 200
|
||||
elsif response.is_a?(Hash)
|
||||
render :json => response, :status => status || 200
|
||||
else
|
||||
head :ok
|
||||
end
|
||||
else
|
||||
render :text => "agent not found", :status => :not_found
|
||||
end
|
||||
else
|
||||
render :text => "user not found", :status => :not_found
|
||||
end
|
||||
end
|
||||
end
|
|
@ -60,6 +60,11 @@ class Agent < ActiveRecord::Base
|
|||
# Implement me in your subclass of Agent.
|
||||
end
|
||||
|
||||
def receive_webhook(params)
|
||||
# Implement me in your subclass of Agent.
|
||||
["not implemented", 404]
|
||||
end
|
||||
|
||||
# Implement me in your subclass to decide if your Agent is working.
|
||||
def working?
|
||||
raise "Implement me in your subclass"
|
||||
|
@ -88,6 +93,13 @@ class Agent < ActiveRecord::Base
|
|||
message.gsub(/<([^>]+)>/) { Utils.value_at(payload, $1) || "??" }
|
||||
end
|
||||
|
||||
def trigger_webhook(params)
|
||||
receive_webhook(params).tap do
|
||||
self.last_webhook_at = Time.now
|
||||
save!
|
||||
end
|
||||
end
|
||||
|
||||
def set_default_schedule
|
||||
self.schedule = default_schedule unless schedule.present? || cannot_be_scheduled?
|
||||
end
|
||||
|
|
|
@ -16,6 +16,7 @@ Huginn::Application.routes.draw do
|
|||
match "/worker_status" => "worker_status#show"
|
||||
|
||||
post "/users/:user_id/update_location/:secret" => "user_location_updates#create"
|
||||
post "/users/:user_id/webhooks/:agent_id/:secret" => "webhooks#create"
|
||||
|
||||
mount RailsAdmin::Engine => '/admin', :as => 'rails_admin'
|
||||
# match "/delayed_job" => DelayedJobWeb, :anchor => false
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddLastWebhookAtToAgents < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :agents, :last_webhook_at, :datetime
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20130126080736) do
|
||||
ActiveRecord::Schema.define(:version => 20130509053743) do
|
||||
|
||||
create_table "agents", :force => true do |t|
|
||||
t.integer "user_id"
|
||||
|
@ -26,6 +26,7 @@ ActiveRecord::Schema.define(:version => 20130126080736) do
|
|||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.text "memory", :limit => 2147483647
|
||||
t.datetime "last_webhook_at"
|
||||
end
|
||||
|
||||
add_index "agents", ["schedule"], :name => "index_agents_on_schedule"
|
||||
|
|
54
spec/controllers/webhooks_controller_spec.rb
Normal file
54
spec/controllers/webhooks_controller_spec.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe WebhooksController do
|
||||
class Agents::WebhookReceiverAgent < Agent
|
||||
cannot_receive_events!
|
||||
cannot_be_scheduled!
|
||||
|
||||
def receive_webhook(params)
|
||||
if params.delete(:secret) == options[:secret]
|
||||
memory[:webhook_values] = params
|
||||
["success", 200]
|
||||
else
|
||||
["failure", 404]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
stub(Agents::WebhookReceiverAgent).valid_type?("Agents::WebhookReceiverAgent") { true }
|
||||
@agent = Agents::WebhookReceiverAgent.new(:name => "something", :options => { :secret => "my_secret" })
|
||||
@agent.user = users(:bob)
|
||||
@agent.save!
|
||||
end
|
||||
|
||||
it "should not require login to trigger a webhook" do
|
||||
@agent.last_webhook_at.should be_nil
|
||||
post :create, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5"
|
||||
@agent.reload.last_webhook_at.should be_within(2).of(Time.now)
|
||||
response.body.should == "success"
|
||||
response.should be_success
|
||||
end
|
||||
|
||||
it "should call receive_webhook" do
|
||||
post :create, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5"
|
||||
@agent.reload.memory[:webhook_values].should == { :key => "value", :another_key => "5" }
|
||||
response.body.should == "success"
|
||||
response.should be_success
|
||||
|
||||
post :create, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "not_my_secret", :no => "go"
|
||||
@agent.reload.memory[:webhook_values].should_not == { :no => "go" }
|
||||
response.body.should == "failure"
|
||||
response.should be_missing
|
||||
end
|
||||
|
||||
it "should fail on incorrect users" do
|
||||
post :create, :user_id => users(:jane).to_param, :agent_id => @agent.id, :secret => "my_secret", :no => "go"
|
||||
response.should be_missing
|
||||
end
|
||||
|
||||
it "should fail on incorrect agents" do
|
||||
post :create, :user_id => users(:bob).to_param, :agent_id => 454545, :secret => "my_secret", :no => "go"
|
||||
response.should be_missing
|
||||
end
|
||||
end
|
|
@ -49,7 +49,7 @@ describe Agent do
|
|||
end
|
||||
end
|
||||
|
||||
describe "with a mock source" do
|
||||
describe "with an example Agent" do
|
||||
class Agents::SomethingSource < Agent
|
||||
default_schedule "2pm"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue