weichat_rails 0.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/README.md +1 -1
- data/lib/weichat_rails/access_token.rb +2 -3
- data/lib/weichat_rails/api.rb +122 -27
- data/lib/weichat_rails/auto_generate_secret_key.rb +1 -0
- data/lib/weichat_rails/client.rb +34 -17
- data/lib/weichat_rails/message.rb +53 -26
- data/lib/weichat_rails/responder.rb +69 -62
- data/lib/weichat_rails/version.rb +1 -1
- data/lib/weichat_rails.rb +17 -7
- data/spec/examples.txt +74 -0
- data/spec/lib/weichat_rails/access_token_spec.rb +48 -0
- data/spec/lib/weichat_rails/api_spec.rb +276 -0
- data/spec/lib/weichat_rails/client_spec.rb +96 -0
- data/spec/lib/weichat_rails/message_spec.rb +283 -0
- data/spec/lib/weichat_rails/responder_spec.rb +5 -0
- data/spec/spec_helper.rb +99 -0
- data/weichat_rails.gemspec +9 -6
- metadata +102 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6947568df2f6ecc2e476ce76782c0bb8aa8fb0c258e23c7650961ffed0537286
|
4
|
+
data.tar.gz: d2a55100220b51f4b564f8d713877d3e3e47efdd4260cbc48e3845840f27b8db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6d8b90c02ef4cb79d4ddb91123b9150fae916fed3ad6916fce707c682112a62cbb650b63fc90dfea43bfd6c03ebf8da73a4bced3d7e3e820e062176ac46e997
|
7
|
+
data.tar.gz: 53f50eb90fc4ed1e93db47dfe4b83a8230761e2cebabf8e022d8658a47a6d87bca33c362b9b7c0de06cb4bfecabbe36bc84d053ce05e9f933c602435678181fd
|
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rails6
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-3.0.0
|
data/README.md
CHANGED
@@ -2,7 +2,6 @@ module WeichatRails
|
|
2
2
|
class AccessToken
|
3
3
|
attr_reader :client, :appid, :secret
|
4
4
|
|
5
|
-
CacheScope = "#{Rails.application.class.parent_name}_access_token"
|
6
5
|
def initialize(client, appid, secret)
|
7
6
|
@appid = appid
|
8
7
|
@secret = secret
|
@@ -11,7 +10,7 @@ module WeichatRails
|
|
11
10
|
|
12
11
|
#store token in rails.cache
|
13
12
|
def token
|
14
|
-
|
13
|
+
WeichatRails.config.cache.fetch(appid,expires_in: 7200) do
|
15
14
|
data = client.get("token", params:{grant_type: "client_credential", appid: appid, secret: secret})
|
16
15
|
valid_token(data)
|
17
16
|
end
|
@@ -19,7 +18,7 @@ module WeichatRails
|
|
19
18
|
|
20
19
|
#delete the cache
|
21
20
|
def refresh
|
22
|
-
|
21
|
+
WeichatRails.config.cache.delete(appid)
|
23
22
|
end
|
24
23
|
|
25
24
|
private
|
data/lib/weichat_rails/api.rb
CHANGED
@@ -5,22 +5,60 @@ class WeichatRails::Api
|
|
5
5
|
attr_reader :access_token, :client
|
6
6
|
|
7
7
|
API_BASE = "https://api.weixin.qq.com/cgi-bin/"
|
8
|
-
FILE_BASE = "http://file.api.weixin.qq.com/cgi-bin/"
|
8
|
+
#FILE_BASE = "http://file.api.weixin.qq.com/cgi-bin/"
|
9
9
|
KEFU_BASE = "https://api.weixin.qq.com/customservice/"
|
10
|
+
MP_BASE = 'https://mp.weixin.qq.com/cgi-bin/'
|
10
11
|
#https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=ACCESS_TOKEN
|
11
12
|
|
12
|
-
def initialize appid, secret
|
13
|
-
@client = WeichatRails::Client.new(API_BASE)
|
13
|
+
def initialize appid, secret,timeout = 20,skip_verify_ssl = true
|
14
|
+
@client = WeichatRails::Client.new(API_BASE,timeout,skip_verify_ssl)
|
14
15
|
@access_token = WeichatRails::AccessToken.new(@client, appid, secret)
|
15
16
|
end
|
16
17
|
|
17
|
-
def
|
18
|
-
get
|
18
|
+
def callbackip
|
19
|
+
get 'getcallbackip'
|
19
20
|
end
|
20
21
|
|
21
|
-
def
|
22
|
-
get
|
22
|
+
def groups
|
23
|
+
get 'groups/get'
|
23
24
|
end
|
25
|
+
alias_method :group_get,:groups
|
26
|
+
|
27
|
+
def group_create(group_name)
|
28
|
+
post 'groups/create', JSON.generate(group: { name: group_name })
|
29
|
+
end
|
30
|
+
|
31
|
+
def group_update(groupid, new_group_name)
|
32
|
+
post 'groups/update', JSON.generate(group: { id: groupid, name: new_group_name })
|
33
|
+
end
|
34
|
+
alias_method :group_name_update,:group_update
|
35
|
+
|
36
|
+
def group_delete(groupid)
|
37
|
+
post 'groups/delete', JSON.generate(group: { id: groupid })
|
38
|
+
end
|
39
|
+
|
40
|
+
def users(nextid = nil)
|
41
|
+
params = { params: { next_openid: nextid } } if nextid.present?
|
42
|
+
get('user/get', params || {})
|
43
|
+
end
|
44
|
+
|
45
|
+
def user(openid)
|
46
|
+
get 'user/info', params: { openid: openid }
|
47
|
+
end
|
48
|
+
|
49
|
+
def user_group(openid)
|
50
|
+
post 'groups/getid', JSON.generate(openid: openid)
|
51
|
+
end
|
52
|
+
alias_method :group_user_id,:user_group
|
53
|
+
|
54
|
+
def user_change_group(openid, to_groupid)
|
55
|
+
post 'groups/members/update', JSON.generate(openid: openid, to_groupid: to_groupid)
|
56
|
+
end
|
57
|
+
|
58
|
+
def user_update_remark(openid, remark)
|
59
|
+
post 'user/info/updateremark', JSON.generate(openid: openid, remark: remark)
|
60
|
+
end
|
61
|
+
|
24
62
|
|
25
63
|
def menu
|
26
64
|
get("menu/get")
|
@@ -34,22 +72,9 @@ class WeichatRails::Api
|
|
34
72
|
get("customservice/getkflist")
|
35
73
|
end
|
36
74
|
|
37
|
-
def group_get
|
38
|
-
get("groups/get")
|
39
|
-
end
|
40
|
-
|
41
|
-
def group_user_id openid
|
42
|
-
json_str = JSON.generate({openid: openid})
|
43
|
-
post("groups/getid", json_str)
|
44
|
-
end
|
45
|
-
|
46
|
-
def group_update openid, to_groupid
|
47
|
-
json_str = JSON.generate({openid: openid,to_groupid: to_groupid})
|
48
|
-
post("groups/members/update", json_str)
|
49
|
-
end
|
50
75
|
|
51
76
|
def get_duokefu_records time,pageindex
|
52
|
-
json_str = JSON.generate({starttime: time.beginning_of_day.to_i,endtime: time.end_of_day.to_i,pagesize:
|
77
|
+
json_str = JSON.generate({starttime: time.beginning_of_day.to_i,endtime: time.end_of_day.to_i,pagesize: 10,pageindex: pageindex})
|
53
78
|
post("msgrecord/getrecord",json_str,base: KEFU_BASE)
|
54
79
|
end
|
55
80
|
|
@@ -67,18 +92,82 @@ class WeichatRails::Api
|
|
67
92
|
end
|
68
93
|
|
69
94
|
#返回媒体文件
|
70
|
-
def media media_id
|
71
|
-
|
95
|
+
#def media media_id
|
96
|
+
# get "media/get", params:{media_id: media_id}, base: FILE_BASE, as: :file
|
97
|
+
#end
|
98
|
+
|
99
|
+
#def media_create type, file
|
100
|
+
# post "media/upload", {upload:{media: file}}, params:{type: type}, base: FILE_BASE
|
101
|
+
#end
|
102
|
+
|
103
|
+
def media(media_id)
|
104
|
+
get 'media/get', params: { media_id: media_id }, as: :file
|
72
105
|
end
|
73
106
|
|
74
|
-
def media_create
|
75
|
-
|
107
|
+
def media_create(type, file)
|
108
|
+
post_file 'media/upload', file, params: { type: type }
|
76
109
|
end
|
77
110
|
|
78
|
-
def
|
79
|
-
|
111
|
+
def material(media_id)
|
112
|
+
get 'material/get', params: { media_id: media_id }, as: :file
|
80
113
|
end
|
81
114
|
|
115
|
+
def material_count
|
116
|
+
get 'material/get_materialcount'
|
117
|
+
end
|
118
|
+
|
119
|
+
def material_list(type, offset, count)
|
120
|
+
post 'material/batchget_material', JSON.generate(type: type, offset: offset, count: count)
|
121
|
+
end
|
122
|
+
|
123
|
+
def material_add(type, file)
|
124
|
+
post_file 'material/add_material', file, params: { type: type }
|
125
|
+
end
|
126
|
+
|
127
|
+
def material_delete(media_id)
|
128
|
+
post 'material/del_material', media_id: media_id
|
129
|
+
end
|
130
|
+
|
131
|
+
def custom_message_send(message)
|
132
|
+
post 'message/custom/send', message.to_json, content_type: :json
|
133
|
+
end
|
134
|
+
|
135
|
+
def template_message_send(message)
|
136
|
+
post 'message/template/send', message.to_json, content_type: :json
|
137
|
+
end
|
138
|
+
|
139
|
+
def qrcode(ticket)
|
140
|
+
client.get 'showqrcode', params: { ticket: ticket }, base: MP_BASE, as: :file
|
141
|
+
end
|
142
|
+
|
143
|
+
def qrcode_create_scene(scene_id, expire_seconds = 604800)
|
144
|
+
post 'qrcode/create', JSON.generate(expire_seconds: expire_seconds,
|
145
|
+
action_name: 'QR_SCENE',
|
146
|
+
action_info: { scene: { scene_id: scene_id } })
|
147
|
+
end
|
148
|
+
|
149
|
+
def qrcode_create_limit_scene(scene_id_or_str)
|
150
|
+
case scene_id_or_str
|
151
|
+
when Fixnum
|
152
|
+
post 'qrcode/create', JSON.generate(action_name: 'QR_LIMIT_SCENE',
|
153
|
+
action_info: { scene: { scene_id: scene_id_or_str } })
|
154
|
+
else
|
155
|
+
post 'qrcode/create', JSON.generate(action_name: 'QR_LIMIT_STR_SCENE',
|
156
|
+
action_info: { scene: { scene_str: scene_id_or_str } })
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
|
161
|
+
# 第二步:通过code换取网页授权access_token
|
162
|
+
def web_access_token(code)
|
163
|
+
params = {
|
164
|
+
appid: access_token.appid,
|
165
|
+
secret: access_token.secret,
|
166
|
+
code: code,
|
167
|
+
grant_type: 'authorization_code'
|
168
|
+
}
|
169
|
+
get 'access_token', params: params, base: OAUTH2_BASE
|
170
|
+
end
|
82
171
|
|
83
172
|
protected
|
84
173
|
def get path, headers={}
|
@@ -89,6 +178,12 @@ class WeichatRails::Api
|
|
89
178
|
with_access_token(headers[:params]){|params| client.post path, payload, headers.merge(params: params)}
|
90
179
|
end
|
91
180
|
|
181
|
+
def post_file(path, file, headers = {})
|
182
|
+
with_access_token(headers[:params]) do |params|
|
183
|
+
client.post_file path, file, headers.merge(params: params)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
92
187
|
def with_access_token params={}, tries=2
|
93
188
|
begin
|
94
189
|
params ||= {}
|
data/lib/weichat_rails/client.rb
CHANGED
@@ -1,33 +1,54 @@
|
|
1
|
-
require '
|
1
|
+
require 'http'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'active_support/core_ext/object/blank'
|
2
4
|
|
3
5
|
module WeichatRails
|
4
6
|
class Client
|
5
7
|
|
6
|
-
attr_reader :base
|
8
|
+
attr_reader :base,:ssl_context
|
7
9
|
|
8
|
-
def initialize(base)
|
10
|
+
def initialize(base, timeout, skip_verify_ssl)
|
9
11
|
@base = base
|
12
|
+
HTTP.timeout(:global, write: timeout, connect: timeout, read: timeout)
|
13
|
+
@ssl_context = OpenSSL::SSL::SSLContext.new
|
14
|
+
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE if skip_verify_ssl
|
10
15
|
end
|
11
16
|
|
12
|
-
def get
|
13
|
-
request(path,
|
14
|
-
|
17
|
+
def get(path, get_header = {})
|
18
|
+
request(path, get_header) do |url, header|
|
19
|
+
params = header.delete(:params)
|
20
|
+
HTTP.headers(header).get(url, params: params, ssl_context: ssl_context)
|
15
21
|
end
|
16
22
|
end
|
17
23
|
|
18
|
-
def post
|
19
|
-
request(path,
|
20
|
-
|
24
|
+
def post(path, payload, post_header = {})
|
25
|
+
request(path, post_header) do |url, header|
|
26
|
+
params = header.delete(:params)
|
27
|
+
HTTP.headers(header).post(url, params: params, body: payload, ssl_context: ssl_context)
|
21
28
|
end
|
22
29
|
end
|
23
30
|
|
31
|
+
def post_file(path, file, post_header = {})
|
32
|
+
request(path, post_header) do |url, header|
|
33
|
+
params = header.delete(:params)
|
34
|
+
HTTP.headers(header)
|
35
|
+
.post(url, params: params,
|
36
|
+
form: { media: HTTP::FormData::File.new(file),
|
37
|
+
hack: 'X' }, # Existing here for http-form_data 1.0.1 handle single param improperly
|
38
|
+
ssl_context: ssl_context)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
|
24
45
|
def request path, header={}, &block
|
25
46
|
url = "#{header.delete(:base) || self.base}#{path}"
|
26
47
|
as = header.delete(:as)
|
27
|
-
header.merge!(
|
48
|
+
header.merge!('Accept' => 'application/json')
|
28
49
|
response = yield(url, header)
|
29
50
|
|
30
|
-
raise "Request not OK, response
|
51
|
+
raise "Request not OK, response status #{response.status}" if response.status != 200
|
31
52
|
parse_response(response, as || :json) do |parse_as, data|
|
32
53
|
break data unless (parse_as == :json && data["errcode"].present?)
|
33
54
|
#break data if (parse_as != :json || data["errcode"].blank?)
|
@@ -38,12 +59,8 @@ module WeichatRails
|
|
38
59
|
when 0 # for request didn't expect results
|
39
60
|
[true,data]
|
40
61
|
|
41
|
-
when 42001, 40014 #42001: access_token超时, 40014:不合法的access_token
|
62
|
+
when 42001, 40014,40001,48001 #42001: access_token超时, 40014:不合法的access_token
|
42
63
|
raise AccessTokenExpiredError
|
43
|
-
|
44
|
-
when 1613189120 # for wx duokefu' msg code
|
45
|
-
[true,data]
|
46
|
-
|
47
64
|
else
|
48
65
|
raise ResponseError.new(data['errcode'], data['errmsg'])
|
49
66
|
end
|
@@ -67,7 +84,7 @@ module WeichatRails
|
|
67
84
|
data = file
|
68
85
|
|
69
86
|
when :json
|
70
|
-
data = JSON.parse
|
87
|
+
data = JSON.parse response.body.to_s.gsub(/[\u0000-\u001f]+/, '')
|
71
88
|
|
72
89
|
else
|
73
90
|
data = response.body
|
@@ -1,31 +1,34 @@
|
|
1
|
+
#require 'active_support/core_ext/module/delegation'
|
2
|
+
require 'active_support/core_ext/hash/slice'
|
3
|
+
require 'active_support/core_ext/string/inflections'
|
4
|
+
require 'active_support/core_ext/hash/keys'
|
5
|
+
require 'active_support/core_ext/hash/conversions'
|
6
|
+
|
1
7
|
module WeichatRails
|
2
8
|
class Message
|
3
|
-
|
4
|
-
JSON_KEY_MAP = {
|
5
|
-
"ToUserName" => "touser",
|
6
|
-
"MediaId" => "media_id",
|
7
|
-
"ThumbMediaId" => "thumb_media_id"
|
8
|
-
}
|
9
|
-
|
10
9
|
class << self
|
11
10
|
def from_hash msg_hash
|
12
11
|
self.new(msg_hash)
|
13
12
|
end
|
14
13
|
|
15
14
|
def to to_user
|
16
|
-
|
15
|
+
new(:ToUserName=>to_user, :CreateTime=>Time.now.to_i)
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
20
19
|
class ArticleBuilder
|
21
20
|
attr_reader :items
|
22
|
-
delegate :count, to: :items
|
21
|
+
#delegate :count, to: :items
|
23
22
|
def initialize
|
24
23
|
@items=Array.new
|
25
24
|
end
|
26
25
|
|
27
|
-
def
|
28
|
-
items
|
26
|
+
def count
|
27
|
+
items.length
|
28
|
+
end
|
29
|
+
|
30
|
+
def item title:"title", description:nil, pic_url:nil, url:nil
|
31
|
+
items << {:Title=> title, :Description=> description, :PicUrl=> pic_url, :Url=> url}.reject { |_k, v| v.nil? }
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
@@ -48,7 +51,7 @@ module WeichatRails
|
|
48
51
|
when :text
|
49
52
|
message_hash[:Content]
|
50
53
|
|
51
|
-
when :image, :voice, :video
|
54
|
+
when :image, :voice, :video, :shortvideo
|
52
55
|
WeichatRails.api.media(message_hash[:MediaId])
|
53
56
|
|
54
57
|
when :location
|
@@ -61,18 +64,26 @@ module WeichatRails
|
|
61
64
|
end
|
62
65
|
end
|
63
66
|
|
64
|
-
#add wechat_user for load wechat_user in proc callback
|
65
|
-
#def wechat_user user
|
66
|
-
# update(:wechat_user=>user)
|
67
|
-
#end
|
68
67
|
def kefu msg_type
|
69
68
|
update(:MsgType => msg_type)
|
70
69
|
end
|
71
70
|
|
71
|
+
def transfer_customer_service
|
72
|
+
update(MsgType: 'transfer_customer_service')
|
73
|
+
end
|
74
|
+
|
72
75
|
def to openid
|
73
76
|
update(:ToUserName=>openid)
|
74
77
|
end
|
75
78
|
|
79
|
+
def agent_id(agentid)
|
80
|
+
update(AgentId: agentid)
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
def success
|
85
|
+
update(MsgType: 'success')
|
86
|
+
end
|
76
87
|
def text content
|
77
88
|
update(:MsgType=>"text", :Content=>content)
|
78
89
|
end
|
@@ -102,32 +113,48 @@ module WeichatRails
|
|
102
113
|
items = article.items
|
103
114
|
else
|
104
115
|
items = collection.collect do |item|
|
105
|
-
|
116
|
+
item.symbolize_keys.slice(:title, :description, :pic_url, :url).reject { |_k,v| v.nil? }
|
106
117
|
end
|
107
118
|
end
|
108
119
|
|
109
|
-
update(:MsgType=>"news", :ArticleCount=> items.count
|
110
|
-
|
120
|
+
update(:MsgType=>"news", :ArticleCount=> items.count,:Articles=> items.collect{|item| camelize_hash_keys(item)})
|
121
|
+
end
|
122
|
+
|
123
|
+
def template(opts = {})
|
124
|
+
template_fields = camelize_hash_keys(opts.symbolize_keys.slice(:template_id, :topcolor, :url, :data))
|
125
|
+
update(MsgType: 'template', Template: template_fields)
|
111
126
|
end
|
112
127
|
|
113
128
|
def to_xml
|
114
129
|
message_hash.to_xml(root: "xml", children: "item", skip_instruct: true, skip_types: true)
|
115
130
|
end
|
116
131
|
|
132
|
+
TO_JSON_KEY_MAP = {
|
133
|
+
'ToUserName' => 'touser',
|
134
|
+
'MediaId' => 'media_id',
|
135
|
+
'ThumbMediaId' => 'thumb_media_id',
|
136
|
+
'TemplateId' => 'template_id'
|
137
|
+
}
|
138
|
+
|
139
|
+
TO_JSON_ALLOWED = %w(touser msgtype content image voice video music news articles template agentid)
|
140
|
+
|
117
141
|
def to_json
|
118
142
|
json_hash = deep_recursive(message_hash) do |key, value|
|
119
143
|
key = key.to_s
|
120
|
-
[(
|
144
|
+
[(TO_JSON_KEY_MAP[key] || key.downcase), value]
|
121
145
|
end
|
122
146
|
|
123
|
-
json_hash
|
124
|
-
case json_hash[
|
125
|
-
when
|
126
|
-
json_hash[
|
127
|
-
when
|
128
|
-
json_hash[
|
147
|
+
json_hash = json_hash.select { |k, _v| TO_JSON_ALLOWED.include? k }
|
148
|
+
case json_hash['msgtype']
|
149
|
+
when 'text'
|
150
|
+
json_hash['text'] = { 'content' => json_hash.delete('content') }
|
151
|
+
when 'news'
|
152
|
+
json_hash['news'] = { 'articles' => json_hash.delete('articles') }
|
153
|
+
when 'template'
|
154
|
+
json_hash.merge! json_hash['template']
|
129
155
|
end
|
130
156
|
JSON.generate(json_hash)
|
157
|
+
|
131
158
|
end
|
132
159
|
|
133
160
|
def save_to! model_class
|
@@ -3,10 +3,16 @@ module WeichatRails
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
# Rails 5 API mode won't define verify_authenticity_token
|
7
|
+
if defined?(:skip_before_action)
|
8
|
+
before_action :init_wechat_or_token
|
9
|
+
skip_before_action :verify_authenticity_token unless defined?(:verify_authenticity_token)
|
10
|
+
before_action :verify_signature, only: [:show, :create]
|
11
|
+
else
|
12
|
+
before_filter :init_wechat_or_token
|
13
|
+
skip_before_filter :verify_authenticity_token
|
14
|
+
before_filter :verify_signature, only: [:show, :create]
|
15
|
+
end
|
10
16
|
end
|
11
17
|
|
12
18
|
attr_accessor :wechat, :token,:wechat_user
|
@@ -18,25 +24,25 @@ module WeichatRails
|
|
18
24
|
#on :text do |res,content|
|
19
25
|
#
|
20
26
|
#end
|
21
|
-
def on message_type, with: nil, respond: nil, &block
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
27
|
+
#def on message_type, with: nil, respond: nil, &block
|
28
|
+
# raise "Unknow message type" unless message_type.in? [:text, :image, :voice, :video, :location, :link, :event, :fallback]
|
29
|
+
# config=respond.nil? ? {} : {:respond=>respond}
|
30
|
+
# config.merge!(:proc=>block) if block_given?
|
31
|
+
|
32
|
+
# if (with.present? && !message_type.in?([:text, :event]))
|
33
|
+
# raise "Only text and event message can take :with parameters"
|
34
|
+
# else
|
35
|
+
# config.merge!(:with=>with) if with.present?
|
36
|
+
# end
|
37
|
+
|
38
|
+
# responders(message_type) << config
|
39
|
+
# return config
|
40
|
+
#end
|
35
41
|
|
36
|
-
def responders type
|
37
|
-
|
38
|
-
|
39
|
-
end
|
42
|
+
#def responders type
|
43
|
+
# @responders ||= Hash.new
|
44
|
+
# @responders[type] ||= Array.new
|
45
|
+
#end
|
40
46
|
|
41
47
|
|
42
48
|
#指定的过滤方法,默认不使用指定的匹配方法,如为true,
|
@@ -52,29 +58,29 @@ module WeichatRails
|
|
52
58
|
#事件类型:subscribe(订阅)、unsubscribe(取消订阅),SCAN(关注后扫描),LOCATION(上报地理位置),CLICK(自定义菜单事件),VIEW(点击菜单跳转链接时的事件推送)
|
53
59
|
def responder_for message, &block
|
54
60
|
message_type = message[:MsgType].to_sym
|
55
|
-
responders = responders(message_type)
|
56
|
-
if use_matcher?
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
else
|
66
|
-
yield(responder)
|
67
|
-
end
|
61
|
+
#responders = responders(message_type)
|
62
|
+
#if use_matcher?
|
63
|
+
responder = {:method => :find_matcher}
|
64
|
+
case message_type
|
65
|
+
when :text
|
66
|
+
yield(responder,message[:Content])
|
67
|
+
when :event
|
68
|
+
yield(responder,message[:Event],message[:EventKey])
|
69
|
+
when :image,:voice,:shortvideo
|
70
|
+
yield(responder,'MEDIA',picurl: message[:PicUrl],media_id: message[:MediaId])
|
68
71
|
else
|
69
|
-
|
70
|
-
when :text
|
71
|
-
yield(* match_responders(responders, message[:Content]))
|
72
|
-
when :event
|
73
|
-
yield(* match_responders(responders, message[:Event]))
|
74
|
-
else
|
75
|
-
yield(responders.first)
|
76
|
-
end
|
72
|
+
yield(responder)
|
77
73
|
end
|
74
|
+
#else
|
75
|
+
# case message_type
|
76
|
+
# when :text
|
77
|
+
# yield(* match_responders(responders, message[:Content]))
|
78
|
+
# when :event
|
79
|
+
# yield(* match_responders(responders, message[:Event]))
|
80
|
+
# else
|
81
|
+
# yield(responders.first)
|
82
|
+
# end
|
83
|
+
#end
|
78
84
|
end
|
79
85
|
|
80
86
|
private
|
@@ -84,24 +90,25 @@ module WeichatRails
|
|
84
90
|
#value : 请求内容
|
85
91
|
#优先返回具有with值的on规则
|
86
92
|
#注:使用on定义的规则只适用于直接在控制器中写死的规则,属于类级别,不适用于后台配置类型,如果responders[msg_type]为空的情况下不产生任何内容
|
87
|
-
def match_responders responders, value
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
end
|
93
|
+
#def match_responders responders, value
|
94
|
+
# mat = responders.inject({scoped:nil, general:nil}) do |matched, responder|
|
95
|
+
# condition = responder[:with]
|
96
|
+
|
97
|
+
# if condition.nil?
|
98
|
+
# matched[:general] ||= [responder, value]
|
99
|
+
# next matched
|
100
|
+
# end
|
101
|
+
|
102
|
+
# if condition.is_a? Regexp
|
103
|
+
# matched[:scoped] ||= [responder] + $~.captures if(value =~ condition)
|
104
|
+
# else
|
105
|
+
# matched[:scoped] ||= [responder, value] if(value == condition)
|
106
|
+
# end
|
107
|
+
# matched
|
108
|
+
# end
|
109
|
+
# return mat[:scoped] || mat[:general]
|
110
|
+
#end
|
111
|
+
|
105
112
|
end
|
106
113
|
|
107
114
|
|
@@ -147,7 +154,7 @@ module WeichatRails
|
|
147
154
|
|
148
155
|
|
149
156
|
#def wechat_model
|
150
|
-
|
157
|
+
#@wechat_model || WeichatRails.config.public_account_class.constantize
|
151
158
|
#end
|
152
159
|
|
153
160
|
#TODO init wechat , wechat_user,token from database
|