class Sinatra::Wechat::Endpoint::DispatcherBuilder

Work as a Ruby Builder, treat every Wechat ‘MsgType’ as method name the method arguments are the Wechat message it self

Public Class Methods

new(&block) click to toggle source
# File lib/sinatra/wechat.rb, line 9
def initialize(&block)
  @message_handlers = {}
  instance_eval(&block) if block_given?
end

Public Instance Methods

dispatch!(values) click to toggle source
# File lib/sinatra/wechat.rb, line 28
def dispatch!(values)
  return nil unless msg_type = values[:msg_type]
  handlers = @message_handlers[msg_type.to_sym] || []
  handlers.find { |m, _| m.call(values) }
end
method_missing(sym, *args, &resp_blk) click to toggle source

resp_blk is used to generate HTTP response, need to eval in Sinatra context

# File lib/sinatra/wechat.rb, line 15
def method_missing(sym, *args, &resp_blk)
  @message_handlers[sym] ||= []
  matchers = args.collect do |arg|
    if arg.respond_to?(:call) then lambda &arg
    # for named parameters
    elsif arg.respond_to?(:all?) then lambda { |values| arg.all? { |k,v| v === values[k]} }
    else raise TypeError, "\"#{v} (#{v.class})\" is not an acceptable condition"
    end
  end
  matcher = lambda { |values| matchers.all? { |m| m.call(values) } }
  @message_handlers[sym] << [ matcher, resp_blk ]
end