Last active
March 15, 2017 02:09
-
-
Save Aupajo/1ad8bd1cc21befab52f97c96e03e477d to your computer and use it in GitHub Desktop.
ITTT trigger responder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative 'environment' | |
app = Server.new do | |
trigger :turn_on_lightbulb do | |
# Make an API request... | |
Net::HTTP.post_form(URI('http://lightbulb.local'), 'status' => 'on') | |
# Response (any JSON-like data) | |
{ light_bulb: "on" } | |
end | |
# Etc. | |
trigger :set_ludicrous_speed do |params| | |
Net::HTTP.post_form(URI('http://tesla.local'), 'ludicrous' => params[:value]) | |
{ ludicrous_mode: "is now #{params[:value]}" } | |
end | |
end | |
run app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rack/request' | |
require 'net/http' | |
require 'securerandom' | |
require 'json' | |
class Trigger | |
def initialize(name, &block) | |
@name, @block = name, block | |
end | |
def response_for(request) | |
request_params = JSON.parse(request.body, symbolize_names: true) | |
body = JSON.generate(data: data_for(request_params)) | |
[200, Response::JSON_HEADERS, [body]] | |
end | |
def data_for(params) | |
@block.call(params).merge( | |
meta: { | |
id: SecureRandom.uuid, | |
timestamp: Time.now.to_i | |
} | |
) | |
end | |
end | |
class Response | |
TRIGGER_SLUG_PATTERN = %r{/ifttt/v1/triggers/([^/]+?)} | |
JSON_HEADERS = { 'Content-Type' => 'application/json; charset=utf-8' } | |
def initialize(server, request) | |
@server, @request = server, request | |
end | |
def resolve | |
response_from_trigger || not_found | |
end | |
def request_data | |
JSON.parse(@request.body, symbolize_names: true) | |
end | |
def trigger_slug | |
@trigger_slug ||= @request.path[TRIGGER_SLUG_PATTERN]&.to_sym | |
end | |
def response_from_trigger | |
matching_trigger&.response_for(request) | |
end | |
def matching_trigger | |
@server.triggers.find { |trigger| trigger.name == trigger_slug } | |
end | |
def not_found | |
[404, {}, ["Not found"]] | |
end | |
end | |
class Server | |
def initialize(&block) | |
@triggers = [] | |
instance_eval(&block) | |
end | |
def trigger(name, &block) | |
@trigger << Trigger.new(name, &block) | |
end | |
def call(env) | |
request = Rack::Request.new(env) | |
Response.new(request).resolve | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment