Module: Sinatra::Wechat::Endpoint

Defined in:
lib/sinatra/wechat.rb

Defined Under Namespace

Classes: DispatcherBuilder

Instance Method Summary collapse

Instance Method Details

#wechat(endpoint = '/', wechat_token: '', validate_msg: true, &block) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/sinatra/wechat.rb', line 35

def wechat(endpoint = '/', wechat_token: '', validate_msg: true, &block)
  # XXX: 'before' doesn't work in Padrino framework
  # seems like Padrino has redefined before, and make it incompatible with original one
  # use a proc instead.
  validation = Proc.new {
    if validate_msg then
      raw = [wechat_token, params[:timestamp], params[:nonce]].compact.sort.join
      halt 403 unless Digest::SHA1.hexdigest(raw) == params[:signature]
    end
  }

  get endpoint do
    instance_eval &validation
    content_type 'text/plain'
    params[:echostr]
  end

  dispatcher = DispatcherBuilder.new(&block)

  post endpoint do
    instance_eval &validation

    body = request.body.read || ""
    halt 400 if body.empty?  # bad request, cannot handle this kind of message

    xmldoc = Nokogiri::XML(body).root
    values = xmldoc.element_children.each_with_object(Hash.new) do |e, v|
      name = e.name.gsub(/(.)([A-Z])/,'\1_\2').downcase
      # rename 'Location_X' to 'location__x' then to 'location_x'
      name = name.gsub(/(_{2,})/,'_')
      v[name.to_sym] = e.content
    end
    _, handler = dispatcher.dispatch!(values)
    halt 404 unless handler

    request[:wechat_values] = values
    instance_eval(&handler)
  end
  self
end