we_chat 0.5.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.rdoc +3 -0
- data/Rakefile +26 -0
- data/app/assets/javascripts/we_chat/application.js +13 -0
- data/app/assets/stylesheets/we_chat/application.css +15 -0
- data/app/controllers/we_chat/application_controller.rb +4 -0
- data/app/helpers/we_chat/application_helper.rb +4 -0
- data/app/views/layouts/we_chat/application.html.erb +14 -0
- data/config/routes.rb +4 -0
- data/lib/tasks/we_chat/access_token.rake +26 -0
- data/lib/we_chat/access_token.rb +56 -0
- data/lib/we_chat/acts_as_we_chat_entity.rb +72 -0
- data/lib/we_chat/category.rb +19 -0
- data/lib/we_chat/category_property.rb +20 -0
- data/lib/we_chat/category_property_item.rb +17 -0
- data/lib/we_chat/engine.rb +5 -0
- data/lib/we_chat/entity/base.rb +62 -0
- data/lib/we_chat/entity/creator.rb +67 -0
- data/lib/we_chat/entity/destroyer.rb +16 -0
- data/lib/we_chat/entity/identity_entity.rb +21 -0
- data/lib/we_chat/entity/named_entity.rb +21 -0
- data/lib/we_chat/entity/retriever.rb +21 -0
- data/lib/we_chat/error.rb +105 -0
- data/lib/we_chat/headers.rb +15 -0
- data/lib/we_chat/menu.rb +36 -0
- data/lib/we_chat/messaging/message.rb +46 -0
- data/lib/we_chat/messaging/message_validator.rb +15 -0
- data/lib/we_chat/messaging/responder.rb +92 -0
- data/lib/we_chat/multipart_ext.rb +12 -0
- data/lib/we_chat/product.rb +119 -0
- data/lib/we_chat/product_attribute.rb +23 -0
- data/lib/we_chat/rest/api.rb +17 -0
- data/lib/we_chat/rest/client.rb +41 -0
- data/lib/we_chat/rest/media.rb +18 -0
- data/lib/we_chat/rest/menu.rb +21 -0
- data/lib/we_chat/rest/request.rb +103 -0
- data/lib/we_chat/rest/store.rb +172 -0
- data/lib/we_chat/rest/template_message.rb +14 -0
- data/lib/we_chat/rest/user.rb +20 -0
- data/lib/we_chat/rest/utils.rb +27 -0
- data/lib/we_chat/sku.rb +55 -0
- data/lib/we_chat/sku_definition.rb +21 -0
- data/lib/we_chat/sku_definition_item.rb +17 -0
- data/lib/we_chat/subscriber.rb +32 -0
- data/lib/we_chat/symbolizable.rb +18 -0
- data/lib/we_chat/version.rb +3 -0
- data/lib/we_chat.rb +46 -0
- metadata +257 -0
data/lib/we_chat/menu.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'we_chat/entity/base'
|
2
|
+
|
3
|
+
module WeChat
|
4
|
+
module Menu
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
include WeChat::Entity::Base
|
7
|
+
|
8
|
+
def to_we_chat_data
|
9
|
+
result = {}
|
10
|
+
result[:name] = self.name
|
11
|
+
if self.top_node?
|
12
|
+
result[:sub_button] = children_to_we_chat_data
|
13
|
+
else
|
14
|
+
result[:type] = self.menu_type
|
15
|
+
if self.view?
|
16
|
+
result[:url] = self.menu_url
|
17
|
+
else
|
18
|
+
result[:key] = self.menu_key
|
19
|
+
end
|
20
|
+
end
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
def children_to_we_chat_data
|
25
|
+
self.children.inject([]) {|list, item| list << item.to_we_chat_data}
|
26
|
+
end
|
27
|
+
|
28
|
+
included do
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
module ClassMethods
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'we_chat/symbolizable'
|
2
|
+
|
3
|
+
module WeChat
|
4
|
+
module Messaging
|
5
|
+
class Message
|
6
|
+
include WeChat::Symbolizable
|
7
|
+
|
8
|
+
attr_reader :source
|
9
|
+
|
10
|
+
def initialize(hash)
|
11
|
+
@source = symbolize_keys! hash
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_time
|
15
|
+
return nil if source[:CreateTime].nil?
|
16
|
+
Time.at(source[:CreateTime].to_i)
|
17
|
+
end
|
18
|
+
|
19
|
+
def msg_id
|
20
|
+
source[:MsgId].to_i
|
21
|
+
end
|
22
|
+
|
23
|
+
def msg_type
|
24
|
+
source[:MsgType].to_sym
|
25
|
+
end
|
26
|
+
|
27
|
+
def method_missing(method_name, *args, &block)
|
28
|
+
key = method_name.to_s.gsub(/\=/, '').camelize.to_sym
|
29
|
+
if method_name.to_s =~ /.*=$/
|
30
|
+
@source[key] = args.first
|
31
|
+
else
|
32
|
+
return source[key]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_response(message_type = :text)
|
37
|
+
response = WeChat::Messaging::Message.new({})
|
38
|
+
response.to_user_name = self.from_user_name
|
39
|
+
response.from_user_name = self.to_user_name
|
40
|
+
response.msg_type = message_type.to_s
|
41
|
+
response.create_time = Time.now.to_i
|
42
|
+
response
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
module WeChat
|
3
|
+
module Messaging
|
4
|
+
class MessageValidator
|
5
|
+
|
6
|
+
def self.is_valid?(signature, timestamp, nonce, token)
|
7
|
+
tmpArray = [token, timestamp, nonce].sort
|
8
|
+
tmpString = tmpArray.join
|
9
|
+
new_signature = Digest::SHA1.hexdigest tmpString
|
10
|
+
return false if signature.nil?
|
11
|
+
new_signature == signature
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'we_chat/messaging/message'
|
3
|
+
require 'we_chat/messaging/message_validator'
|
4
|
+
|
5
|
+
module WeChat
|
6
|
+
module Messaging
|
7
|
+
module Responder
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
self.skip_before_filter :verify_authenticity_token
|
12
|
+
self.before_filter :verify_signature, only: [:show, :create]
|
13
|
+
end
|
14
|
+
|
15
|
+
def show
|
16
|
+
render :text => params[:echostr]
|
17
|
+
end
|
18
|
+
|
19
|
+
def create
|
20
|
+
request_message = WeChat::Messaging::Message.new(params[:xml] || post_data)
|
21
|
+
response = self.class.create_response(request_message)
|
22
|
+
if response.nil?
|
23
|
+
Rails.logger.debug 'response is null'
|
24
|
+
render nothing: true, status: 200, content_type: 'text/html'
|
25
|
+
else
|
26
|
+
render xml: response.source.to_xml(root: 'xml')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def verify_signature
|
31
|
+
array = [WeChat.wechat_token, params[:timestamp], params[:nonce]].compact.collect(&:to_s).sort
|
32
|
+
Rails.logger.debug Digest::SHA1.hexdigest(array.join)
|
33
|
+
render :text => "Forbidden", :status => 403 if params[:signature] != Digest::SHA1.hexdigest(array.join)
|
34
|
+
end
|
35
|
+
|
36
|
+
def post_data
|
37
|
+
data = Hash.from_xml(request.raw_post)
|
38
|
+
HashWithIndifferentAccess.new_from_hash_copying_default data.fetch('xml', {})
|
39
|
+
end
|
40
|
+
|
41
|
+
module ClassMethods
|
42
|
+
attr_reader :responders
|
43
|
+
|
44
|
+
def responds(message_type = :text, options={}, &block)
|
45
|
+
return unless block_given?
|
46
|
+
pattern = options.delete(:pattern) || /.*/
|
47
|
+
initialize_responders(message_type)
|
48
|
+
@responders[message_type] << { pattern: pattern, proc: block }
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_response(message)
|
52
|
+
response_data = nil
|
53
|
+
responder_item = matched_responder(message)
|
54
|
+
return nil if responder_item.nil?
|
55
|
+
|
56
|
+
case message.msg_type
|
57
|
+
when :text
|
58
|
+
response_result = responder_item[:proc].call(message)
|
59
|
+
return nil if response_result.nil?
|
60
|
+
return response_result if response_result.is_a? WeChat::Messaging::Message
|
61
|
+
return create_text_message_response(message, response_result) if response_result.is_a? String
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def initialize_responders(message_type)
|
68
|
+
@responders ||= {}
|
69
|
+
@responders[message_type] ||= []
|
70
|
+
end
|
71
|
+
|
72
|
+
def matched_responder(message)
|
73
|
+
initialize_responders(message.msg_type)
|
74
|
+
responders[message.msg_type].each do |item|
|
75
|
+
if item[:pattern].is_a? Regexp
|
76
|
+
return item if message.content =~ item[:pattern]
|
77
|
+
else #String
|
78
|
+
return item if message.content.downcase == item[:pattern].downcase
|
79
|
+
end
|
80
|
+
end
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
|
84
|
+
def create_text_message_response(message, reply_content)
|
85
|
+
response = message.create_response
|
86
|
+
response.content = reply_content
|
87
|
+
return response
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# HTTP::FormData::Multipart hacking
|
2
|
+
# Adding an additional CRLF at the end of request body
|
3
|
+
|
4
|
+
CRLF = "\r\n".freeze
|
5
|
+
|
6
|
+
HTTP::FormData::Multipart.class_eval do
|
7
|
+
alias_method :_real_tail, :tail
|
8
|
+
|
9
|
+
def tail
|
10
|
+
@tail ||= "#{CRLF}--#{@boundary}--#{CRLF}"
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'we_chat/entity/base'
|
2
|
+
require 'we_chat/rest/client'
|
3
|
+
|
4
|
+
module WeChat
|
5
|
+
module Product
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
include WeChat::Entity::Base
|
9
|
+
|
10
|
+
CHILDREN = {
|
11
|
+
sku: :sku_list,
|
12
|
+
category: :category_id,
|
13
|
+
category_property_item: :property,
|
14
|
+
product_attribute: :attrext}.freeze
|
15
|
+
|
16
|
+
def to_we_chat_data
|
17
|
+
we_chat_data = {}
|
18
|
+
we_chat_data[:product_id] = self.we_chat_id
|
19
|
+
we_chat_data[:product_base] = {}
|
20
|
+
we_chat_data[:product_base][:name] = self.name
|
21
|
+
we_chat_data[:product_base][:buy_limit] = self.buy_limit
|
22
|
+
we_chat_data[:product_base][:main_img] = self.main_image_url
|
23
|
+
we_chat_data[:product_base][:detail_html] = self.description
|
24
|
+
|
25
|
+
we_chat_data[:product_base][:category_id] = []
|
26
|
+
self.categories.each { |category| we_chat_data[:product_base][:category_id] << category.we_chat_id }
|
27
|
+
|
28
|
+
we_chat_data[:product_base][:property] = []
|
29
|
+
self.category_property_items.each { |property_item| we_chat_data[:product_base][:property] << { id: property_item.category_property.we_chat_id, vid: property_item.we_chat_id } }
|
30
|
+
|
31
|
+
we_chat_data[:product_base][:sku_list] = []
|
32
|
+
we_chat_data[:product_base][:sku_info] = []
|
33
|
+
self.skus.each do |sku|
|
34
|
+
we_chat_data[:product_base][:sku_list] << sku.to_we_chat_data
|
35
|
+
|
36
|
+
if sku.sku_definition_items.length > 0
|
37
|
+
sku.sku_definition_items.each do |sku_definition_item|
|
38
|
+
index = we_chat_data[:product_base][:sku_info].index { |item| item[:id] == sku_definition_item.sku_definition.we_chat_id }
|
39
|
+
sku_info_data = {id: sku_definition_item.sku_definition.we_chat_id, vid: []}
|
40
|
+
if index && index >= 0
|
41
|
+
sku_info_data = we_chat_data[:product_base][:sku_info][index]
|
42
|
+
else
|
43
|
+
we_chat_data[:product_base][:sku_info] << sku_info_data
|
44
|
+
end
|
45
|
+
|
46
|
+
sku_info_data[:vid] << sku_definition_item.we_chat_id unless sku_info_data[:vid].include?(sku_definition_item.we_chat_id)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
we_chat_data
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_we_chat_id_from_data(data)
|
55
|
+
data[:product_id]
|
56
|
+
end
|
57
|
+
|
58
|
+
included do
|
59
|
+
end
|
60
|
+
|
61
|
+
module ClassMethods
|
62
|
+
|
63
|
+
def get_instance_data_from_reponse(response)
|
64
|
+
response[:product_info]
|
65
|
+
end
|
66
|
+
|
67
|
+
def prepare_instance_data(data)
|
68
|
+
result = {}
|
69
|
+
result[:we_chat_id] = data[:product_id]
|
70
|
+
result[:name] = data[:product_base][:name]
|
71
|
+
result[:buy_limit] = data[:product_base][:buy_limit]
|
72
|
+
result[:main_image_url] = data[:product_base][:main_img]
|
73
|
+
result[:description] = data[:product_base][:detail_html]
|
74
|
+
result
|
75
|
+
end
|
76
|
+
|
77
|
+
def prepare_one_type_of_children_data(data, child_type, definition)
|
78
|
+
if [:category, :category_property_item].include?(child_type)
|
79
|
+
data_key = definition[:data_key]
|
80
|
+
definition.merge(data: data[:product_base][data_key])
|
81
|
+
else
|
82
|
+
super(data, child_type, definition)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def prepare_one_type_of_children(instance, child_type, child_data)
|
87
|
+
case child_type
|
88
|
+
when :category
|
89
|
+
child_data[:data].each do |category_id|
|
90
|
+
child_instance = child_data[:klass].send(:find_by_we_chat_id, category_id)
|
91
|
+
instance.send(child_data[:method]) << child_instance if child_instance
|
92
|
+
end
|
93
|
+
when :category_property_item
|
94
|
+
child_data[:data].each do |item|
|
95
|
+
category_property_id = item[:id]
|
96
|
+
category_property_item_id = item[:vid]
|
97
|
+
|
98
|
+
child_instance = child_data[:klass].send(:find_by_we_chat_id, category_property_item_id)
|
99
|
+
instance.send(child_data[:method]) << child_instance if child_instance
|
100
|
+
end
|
101
|
+
when :product_attribute
|
102
|
+
child_data[:data].map do |key, value|
|
103
|
+
if key != :location
|
104
|
+
child_instance = child_data[:klass].send(:create_by_we_chat_data, { key: key.to_s.underscore, value: value, we_chat_id: key.to_s })
|
105
|
+
instance.send(child_data[:method]) << child_instance if child_instance
|
106
|
+
else
|
107
|
+
value.map do |k, v|
|
108
|
+
child_instance = child_data[:klass].send(:create_by_we_chat_data, { key: "location.#{k.to_s.underscore}", value: v, we_chat_id: k.to_s })
|
109
|
+
instance.send(child_data[:method]) << child_instance if child_instance
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
else
|
114
|
+
super(instance, child_type, child_data)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'we_chat/entity/base'
|
2
|
+
|
3
|
+
module WeChat
|
4
|
+
module ProductAttribute
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
include WeChat::Entity::Base
|
7
|
+
|
8
|
+
included do
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
|
13
|
+
def prepare_instance_data(data)
|
14
|
+
result = super data
|
15
|
+
result[:key] = data[:key]
|
16
|
+
result[:value] = data[:value]
|
17
|
+
result[:we_chat_id] = data[:we_chat_id]
|
18
|
+
result
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'we_chat/rest/user'
|
2
|
+
require 'we_chat/rest/menu'
|
3
|
+
require 'we_chat/rest/store'
|
4
|
+
require 'we_chat/rest/media'
|
5
|
+
require 'we_chat/rest/template_message'
|
6
|
+
|
7
|
+
module WeChat
|
8
|
+
module REST
|
9
|
+
module API
|
10
|
+
include WeChat::REST::User
|
11
|
+
include WeChat::REST::Menu
|
12
|
+
include WeChat::REST::Store
|
13
|
+
include WeChat::REST::Media
|
14
|
+
include WeChat::REST::TemplateMessage
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'we_chat/rest/api'
|
2
|
+
require 'we_chat/access_token'
|
3
|
+
|
4
|
+
module WeChat
|
5
|
+
module REST
|
6
|
+
class Client
|
7
|
+
include WeChat::REST::API
|
8
|
+
|
9
|
+
attr_accessor :access_token
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def default
|
13
|
+
new(access_token: WeChat::AccessToken.get_access_token)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(options = {})
|
18
|
+
options.each do |key, value|
|
19
|
+
instance_variable_set("@#{key}", value)
|
20
|
+
end
|
21
|
+
yield(self) if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
def access_token?
|
25
|
+
!!access_token
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Hash]
|
29
|
+
def credentials
|
30
|
+
{
|
31
|
+
access_token: access_token,
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Boolean]
|
36
|
+
def credentials?
|
37
|
+
credentials.values.all?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'we_chat/rest/utils'
|
2
|
+
|
3
|
+
module WeChat
|
4
|
+
module REST
|
5
|
+
module Media
|
6
|
+
include WeChat::REST::Utils
|
7
|
+
|
8
|
+
def upload(media, type)
|
9
|
+
perform_multipart_post('/media/upload', { key: 'media', file: media, params: { type: type } })
|
10
|
+
end
|
11
|
+
|
12
|
+
def upload_image(file_path)
|
13
|
+
upload(file_path, 'image')
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'we_chat/rest/utils'
|
2
|
+
|
3
|
+
module WeChat
|
4
|
+
module REST
|
5
|
+
module Menu
|
6
|
+
include WeChat::REST::Utils
|
7
|
+
|
8
|
+
def menu_get
|
9
|
+
perform_get('/menu/get')
|
10
|
+
end
|
11
|
+
|
12
|
+
def menu_create(data)
|
13
|
+
perform_post('/menu/create', data)
|
14
|
+
end
|
15
|
+
|
16
|
+
def menu_delete
|
17
|
+
perform_get('/menu/delete')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'http'
|
2
|
+
require "addressable/template"
|
3
|
+
require 'we_chat/symbolizable'
|
4
|
+
require 'we_chat/multipart_ext'
|
5
|
+
require 'we_chat/headers'
|
6
|
+
require 'we_chat/error'
|
7
|
+
|
8
|
+
module WeChat
|
9
|
+
module REST
|
10
|
+
class Request
|
11
|
+
include WeChat::Symbolizable
|
12
|
+
|
13
|
+
attr_accessor :client, :headers, :options, :path,
|
14
|
+
:request_method, :uri
|
15
|
+
alias_method :verb, :request_method
|
16
|
+
|
17
|
+
def initialize(_client, request_method, path, options = {})
|
18
|
+
@client = _client
|
19
|
+
request_params = options.delete(:params) unless options[:params].nil?
|
20
|
+
request_params ||= {}
|
21
|
+
request_params[:access_token] = @client.access_token if @client.access_token?
|
22
|
+
template = ::Addressable::Template.new(path.start_with?('http') ? path : WeChat.wechat_api_base_url + path + "{?query*}")
|
23
|
+
@uri = template.expand({
|
24
|
+
"query" => request_params
|
25
|
+
})
|
26
|
+
set_multipart_options!(request_method, options)
|
27
|
+
@path = uri.path
|
28
|
+
@options = options
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Array, Hash]
|
32
|
+
def perform
|
33
|
+
options_key = @request_method == :get ? :params : @request_method == :post ? :json : :form
|
34
|
+
response = HTTP.with(@headers).public_send(@request_method, @uri.to_s, options_key => @options)
|
35
|
+
fail_or_return_response_body(response)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def set_multipart_options!(request_method, options)
|
41
|
+
if request_method == :multipart_post
|
42
|
+
key, file = options.delete(:key), options.delete(:file)
|
43
|
+
options.merge!(key => HTTP::FormData::File.new(file, filename: File.basename(file), mime_type: mime_type(File.basename(file))))
|
44
|
+
# @request_method = :post
|
45
|
+
@headers = WeChat::Headers.new(@client, @request_method, @uri).request_headers
|
46
|
+
else
|
47
|
+
@request_method = request_method
|
48
|
+
@headers = WeChat::Headers.new(@client, @request_method, @uri, options).request_headers
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def mime_type(basename)
|
53
|
+
case basename
|
54
|
+
when /\.gif$/i
|
55
|
+
'image/gif'
|
56
|
+
when /\.jpe?g/i
|
57
|
+
'image/jpeg'
|
58
|
+
when /\.png$/i
|
59
|
+
'image/png'
|
60
|
+
else
|
61
|
+
'application/octet-stream'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def fail_or_return_response_body(response)
|
66
|
+
response_body = symbolize_keys!(response.parse) if response.status.ok?
|
67
|
+
response_body ||= response.body.to_s
|
68
|
+
error = error(response, response_body, response.headers)
|
69
|
+
fail(error) if error
|
70
|
+
response_body
|
71
|
+
end
|
72
|
+
|
73
|
+
def error(response, body, headers)
|
74
|
+
error_entity = nil
|
75
|
+
if response.status.ok?
|
76
|
+
error_entity = WeChat::Error.from_response(body, headers) if contains_error?(body)
|
77
|
+
else
|
78
|
+
klass = WeChat::Error::ERRORS[response.code]
|
79
|
+
if klass == WeChat::Error::Forbidden
|
80
|
+
error_entity = forbidden_error(body, headers)
|
81
|
+
elsif !klass.nil?
|
82
|
+
error_entity = klass.from_response(nil, headers)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
error_entity
|
86
|
+
end
|
87
|
+
|
88
|
+
def contains_error?(body)
|
89
|
+
body[:errcode] && body[:errcode] != 0
|
90
|
+
end
|
91
|
+
|
92
|
+
def forbidden_error(body, headers)
|
93
|
+
error = WeChat::Error::Forbidden.from_response(body, headers)
|
94
|
+
klass = WeChat::Error::FORBIDDEN_MESSAGES[error.message]
|
95
|
+
if klass
|
96
|
+
klass.from_response(body, headers)
|
97
|
+
else
|
98
|
+
error
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|