Skip to content

Instantly share code, notes, and snippets.

@Aupajo
Last active March 15, 2017 02:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Aupajo/1ad8bd1cc21befab52f97c96e03e477d to your computer and use it in GitHub Desktop.
Save Aupajo/1ad8bd1cc21befab52f97c96e03e477d to your computer and use it in GitHub Desktop.
ITTT trigger responder
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
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