wechat 0.6.5 → 0.6.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9e173474b91515c5b98160ebcf2e88c307b7a0c7
4
- data.tar.gz: 24e1eeb02200389eb39fe1aa89a0e6dd87cfeda8
3
+ metadata.gz: 38d17166a10c49de46d4e87c787b0869163e13d3
4
+ data.tar.gz: 3c80f22d8adc8219c4e0b32824d2df63269a6aa6
5
5
  SHA512:
6
- metadata.gz: deff7d137bfcf8e9ff9c9e5102fae2639289edb58c5a3d426d32190df1e1e860d83a9a9faec2e858cdb7258580408dd0d38824416735ea7ce22ae7fb0d0ea9fa
7
- data.tar.gz: 88485947385312824105e5d4a1a444fb45b8ddfdb377d24283ef463d848c96e0c9dda87c1998f57dea91ca934c4fd70ff2f3f2826d1c35d9554279987842be5d
6
+ metadata.gz: bf6b9c04a09cc228db3366c6b311731404af1a2e01581c5602d96897be3a3ddb3b52d9e0c3e4013c6307bc135f3ba8db7b85ecfa3f8880f3b9a5179e8c933619
7
+ data.tar.gz: d1091b3c0c44c974c42c9e88a16eadcf256d00c4108c527dc9b3969e24f22e4b7d24a559cf3f61779a09a5bbee90cdd744aa60f4d9522ee5ecb33e4239caa732
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.6.6 (released at 12/15/2015)
4
+
5
+ * Add jsapi_ticket support for Enterprise Account
6
+ * Default generated WechatsController < ActionController::Base, as many Rails application may having #authenticate_user or #set_current_user in ApplicationController, so easily affect the first time using experience.
7
+ * New syntax `on :view, with: 'VIEW_URL'` support.
8
+ * New command `upload_replaceparty` which combine three sub command to make uploading department easier.
9
+ * New command `upload_replaceuser` which combine three sub command to make uploading user easier.
10
+
3
11
  ## v0.6.5 (released at 11/24/2015)
4
12
 
5
13
  * Handle 48001 error if token is expire/not valid, close #71
data/README.md CHANGED
@@ -10,7 +10,11 @@ WeChat gem 可以帮助开发者方便地在Rails环境中集成微信[公众平
10
10
  - [微信JS-SDK](http://qydev.weixin.qq.com/wiki/index.php?title=%E5%BE%AE%E4%BF%A1JS%E6%8E%A5%E5%8F%A3) config接口注入权限验证
11
11
  - OAuth 2.0认证机制
12
12
 
13
- 命令行工具`wechat`可以调用各种无需web环境的API。同时也提供了Rails Controller的responder DSL, 可以帮助开发者方便地在Rails应用中集成微信的消息处理机制。如果你的App还需要集成微信OAuth2.0, 你可以考虑[omniauth-wechat-oauth2](https://github.com/skinnyworm/omniauth-wechat-oauth2), 以便和devise集成,提供完整的用户认证。
13
+ 命令行工具`wechat`可以调用各种无需web环境的API。同时也提供了Rails Controller的responder DSL, 可以帮助开发者方便地在Rails应用中集成微信的消息处理机制。
14
+
15
+ 如果你的App还需要集成微信OAuth2.0, 你可以考虑[omniauth-wechat-oauth2](https://github.com/skinnyworm/omniauth-wechat-oauth2), 以便和devise集成,提供完整的用户认证。
16
+
17
+ 如果你对如何制作微信网页UI没有灵感,可以参考官方的[weui](https://github.com/weui/weui),针对Rails的Gem是[weui-rails](https://github.com/Eric-Guo/weui-rails)。
14
18
 
15
19
 
16
20
  ## 安装
@@ -106,6 +110,7 @@ default: &default
106
110
  access_token: "C:/Users/[user_name]/wechat_access_token"
107
111
  token: ""
108
112
  encoding_aes_key: ""
113
+ jsapi_ticket: "C:/Users/[user_name]/wechat_jsapi_ticket"
109
114
 
110
115
  production:
111
116
  corpid: <%= ENV['WECHAT_CORPID'] %>
@@ -115,6 +120,7 @@ production:
115
120
  token: <%= ENV['WECHAT_TOKEN'] %>
116
121
  skip_verify_ssl: false
117
122
  encoding_aes_key: <%= ENV['WECHAT_ENCODING_AES_KEY'] %>
123
+ jsapi_ticket: <%= ENV['WECHAT_JSAPI_TICKET'] %>
118
124
 
119
125
  development:
120
126
  <<: *default
@@ -136,7 +142,7 @@ Wechat服务器有报道曾出现[RestClient::SSLCertificateNotVerified](http://
136
142
  在个别情况下,单个Rails应用可能需要处理来自多个账号的消息,此时可以配置多个responder controller。
137
143
 
138
144
  ```ruby
139
- class WechatFirstController < ApplicationController
145
+ class WechatFirstController < ActionController::Base
140
146
  wechat_responder appid: "app1", secret: "secret1", token: "token1", access_token: Rails.root.join("tmp/access_token1")
141
147
 
142
148
  on :text, with:"help", respond: "help content"
@@ -230,8 +236,6 @@ Wechat commands:
230
236
  wechat menu_create [MENU_YAML_PATH] # 创建菜单
231
237
  wechat menu_delete # 删除菜单
232
238
  wechat message_send [OPENID, TEXT_MESSAGE] # 发送文字消息
233
- wechat qrcode_create_limit_scene [SCENE_ID_OR_STR] # 请求永久二维码
234
- wechat qrcode_create_scene [SCENE_ID, EXPIRE_SECONDS] # 请求临时二维码
235
239
  wechat qrcode_download [TICKET, QR_CODE_PIC_PATH] # 通过ticket下载二维码
236
240
  wechat tag [TAG_ID] # 获取标签成员
237
241
  wechat tag_add_department [TAG_ID, PARTY_IDS] # 增加标签部门
@@ -243,6 +247,8 @@ Wechat commands:
243
247
  wechat tag_update [TAG_ID, TAGNAME] # 更新标签名字
244
248
  wechat tags # 获取标签列表
245
249
  wechat template_message [OPENID, TEMPLATE_YAML_PATH] # 模板消息接口
250
+ wechat upload_replaceparty [BATCH_PARTY_CSV_PATH] # 上传文件方式全量覆盖部门
251
+ wechat upload_replaceuser [BATCH_USER_CSV_PATH] # 上传文件方式全量覆盖成员
246
252
  wechat user [OPEN_ID] # 获取用户基本信息
247
253
  wechat user_batchdelete [USER_ID_LIST] # 批量删除成员
248
254
  wechat user_delete [USER_ID] # 删除成员
@@ -398,7 +404,7 @@ $ wechat template_message oCfEht9oM*********** template.yml
398
404
  然后创建Controller class, 例如
399
405
 
400
406
  ```ruby
401
- class WechatsController < ApplicationController
407
+ class WechatsController < ActionController::Base
402
408
  wechat_responder
403
409
 
404
410
  # 默认文字信息responder
@@ -459,6 +465,11 @@ class WechatsController < ApplicationController
459
465
  request.reply.text "User: #{request[:FromUserName]} click #{key}"
460
466
  end
461
467
 
468
+ # 当用户点击菜单时
469
+ on :view, with: 'http://wechat.somewhere.com/view_url' do |request, view|
470
+ request.reply.text "#{request[:FromUserName]} view #{view}"
471
+ end
472
+
462
473
  # 处理图片信息
463
474
  on :image do |request|
464
475
  request.reply.image(request[:MediaId]) #直接将图片返回给用户
@@ -533,7 +544,8 @@ end
533
544
  - :video 响应视频消息
534
545
  - :link 响应链接消息
535
546
  - :event 响应事件消息, 可以用`:with`参数来匹配事件类型
536
- - :click 虚拟响应事件消息, 微信仍然传入:event,但gem内部会单独处理
547
+ - :click 虚拟响应事件消息, 微信传入:event,但gem内部会单独处理
548
+ - :view 虚拟响应事件消息, 微信传入:event,但gem内部会单独处理
537
549
  - :scan 虚拟响应事件消息
538
550
  - :batch_job 虚拟响应事件消息
539
551
  - :location 虚拟响应上报地理位置事件消息
@@ -542,7 +554,7 @@ end
542
554
  ### 多客服消息转发
543
555
 
544
556
  ```ruby
545
- class WechatsController < ApplicationController
557
+ class WechatsController < ActionController::Base
546
558
  # 当无任何responder处理用户信息时,转发至客服处理。
547
559
  on :fallback do |message|
548
560
  message.reply.transfer_customer_service
data/bin/wechat CHANGED
@@ -16,7 +16,7 @@ require 'wechat/api_loader'
16
16
 
17
17
  class App < Thor
18
18
  package_name 'Wechat'
19
- option :toke_file, aliases: '-t', desc: 'File to store access token'
19
+ option :token_file, aliases: '-t', desc: 'File to store access token'
20
20
 
21
21
  attr_reader :wechat_api_client
22
22
  no_commands do
@@ -170,6 +170,15 @@ class App < Thor
170
170
  puts wechat_api.batch_replaceparty(batch_party_csv_media_id)
171
171
  end
172
172
 
173
+ desc 'upload_replaceparty [BATCH_PARTY_CSV_PATH]', '上传文件方式全量覆盖部门'
174
+ def upload_replaceparty(batch_party_csv_path)
175
+ file = File.new(batch_party_csv_path)
176
+ media_id = wechat_api.media_create('file', file)['media_id']
177
+ job_id = wechat_api.batch_replaceparty(media_id)['jobid']
178
+ puts "running job_id: #{job_id}"
179
+ puts wechat_api.batch_job_result(job_id)
180
+ end
181
+
173
182
  desc 'batch_syncuser [SYNC_USER_CSV_MEDIA_ID]', '增量更新成员'
174
183
  def batch_syncuser(sync_user_csv_media_id)
175
184
  puts wechat_api.batch_syncuser(sync_user_csv_media_id)
@@ -180,6 +189,15 @@ class App < Thor
180
189
  puts wechat_api.batch_replaceuser(batch_user_csv_media_id)
181
190
  end
182
191
 
192
+ desc 'upload_replaceuser [BATCH_USER_CSV_PATH]', '上传文件方式全量覆盖成员'
193
+ def upload_replaceuser(batch_user_csv_path)
194
+ file = File.new(batch_user_csv_path)
195
+ media_id = wechat_api.media_create('file', file)['media_id']
196
+ job_id = wechat_api.batch_replaceuser(media_id)['jobid']
197
+ puts "running job_id: #{job_id}"
198
+ puts wechat_api.batch_job_result(job_id)
199
+ end
200
+
183
201
  desc 'convert_to_openid [USER_ID]', 'userid转换成openid'
184
202
  def convert_to_openid(userid)
185
203
  puts wechat_api.convert_to_openid(userid)
@@ -14,7 +14,7 @@ module ActionController
14
14
  self.wechat = Wechat.api
15
15
  else
16
16
  if corpid.present?
17
- self.wechat = Wechat::CorpApi.new(corpid, opts[:corpsecret], opts[:access_token], agentid, skip_verify_ssl)
17
+ self.wechat = Wechat::CorpApi.new(corpid, opts[:corpsecret], opts[:access_token], agentid, skip_verify_ssl, opts[:jsapi_ticket])
18
18
  else
19
19
  self.wechat = Wechat::Api.new(opts[:appid], opts[:secret], opts[:access_token], skip_verify_ssl, opts[:jsapi_ticket])
20
20
  end
@@ -1,4 +1,8 @@
1
+ <% if defined? ActionController::API -%>
1
2
  class WechatsController < ApplicationController
3
+ <% else -%>
4
+ class WechatsController < ActionController::Base
5
+ <% end -%>
2
6
  wechat_responder
3
7
 
4
8
  # default text responder when no other match
@@ -59,6 +63,11 @@ class WechatsController < ApplicationController
59
63
  request.reply.text "User: #{request[:FromUserName]} click #{key}"
60
64
  end
61
65
 
66
+ # When user view URL in the menu button
67
+ on :view, with: 'http://wechat.somewhere.com/view_url' do |request, view|
68
+ request.reply.text "#{request[:FromUserName]} view #{view}"
69
+ end
70
+
62
71
  # When user sent the imsage
63
72
  on :image do |request|
64
73
  request.reply.image(request[:MediaId]) # Echo the sent image to user
@@ -9,6 +9,7 @@ default: &default
9
9
  access_token: "C:/Users/[username]/wechat_access_token"
10
10
  encrypt_mode: false # if true must fill encoding_aes_key
11
11
  encoding_aes_key: "my_encoding_aes_key"
12
+ jsapi_ticket: "C:/Users/[user_name]/wechat_jsapi_ticket"
12
13
 
13
14
  production:
14
15
  corpid: <%%= ENV['WECHAT_CORPID'] %>
@@ -21,6 +22,7 @@ production:
21
22
  access_token: <%%= ENV['WECHAT_ACCESS_TOKEN'] %>
22
23
  encrypt_mode: false # if true must fill encoding_aes_key
23
24
  encoding_aes_key: <%%= ENV['WECHAT_ENCODING_AES_KEY'] %>
25
+ jsapi_ticket: <%= ENV['WECHAT_JSAPI_TICKET'] %>
24
26
 
25
27
  development:
26
28
  <<: *default
@@ -22,6 +22,6 @@ module Wechat
22
22
  end
23
23
 
24
24
  def self.api
25
- ApiLoader.api
25
+ @wechat_api ||= ApiLoader.with({})
26
26
  end
27
27
  end
@@ -5,12 +5,10 @@ require 'wechat/jsapi_ticket'
5
5
 
6
6
  module Wechat
7
7
  class Api < ApiBase
8
- attr_reader :jsapi_ticket
9
-
10
8
  API_BASE = 'https://api.weixin.qq.com/cgi-bin/'
11
9
  OAUTH2_BASE = 'https://api.weixin.qq.com/sns/oauth2/'
12
10
 
13
- def initialize(appid, secret, token_file, skip_verify_ssl, jsapi_ticket_file = '/var/tmp/wechat_jsapi_ticket')
11
+ def initialize(appid, secret, token_file, skip_verify_ssl, jsapi_ticket_file)
14
12
  @client = Client.new(API_BASE, skip_verify_ssl)
15
13
  @access_token = AccessToken.new(@client, appid, secret, token_file)
16
14
  @jsapi_ticket = JsapiTicket.new(@client, @access_token, jsapi_ticket_file)
@@ -1,6 +1,6 @@
1
1
  module Wechat
2
2
  class ApiBase
3
- attr_reader :access_token, :client
3
+ attr_reader :access_token, :client, :jsapi_ticket
4
4
 
5
5
  MP_BASE = 'https://mp.weixin.qq.com/cgi-bin/'
6
6
 
@@ -1,23 +1,15 @@
1
1
  module Wechat
2
2
  module ApiLoader
3
- def self.api
4
- c = ApiLoader.config
5
- if c.corpid.present?
6
- @api ||= CorpApi.new(c.corpid, c.corpsecret, c.access_token, c.agentid, c.skip_verify_ssl)
7
- else
8
- @api ||= Api.new(c.appid, c.secret, c.access_token, c.skip_verify_ssl, c.jsapi_ticket)
9
- end
10
- end
11
-
12
3
  def self.with(options)
13
- c = config
4
+ c = ApiLoader.config
14
5
 
15
- token_file = options[:toke_file] || c.access_token || '/var/tmp/wechat_access_token'
6
+ token_file = options[:token_file] || c.access_token || '/var/tmp/wechat_access_token'
7
+ js_token_file = options[:js_token_file] || c.jsapi_ticket || '/var/tmp/wechat_jsapi_ticket'
16
8
 
17
9
  if c.appid && c.secret && token_file.present?
18
- Wechat::Api.new(c.appid, c.secret, token_file, c.skip_verify_ssl)
10
+ Wechat::Api.new(c.appid, c.secret, token_file, c.skip_verify_ssl, js_token_file)
19
11
  elsif c.corpid && c.corpsecret && token_file.present?
20
- Wechat::CorpApi.new(c.corpid, c.corpsecret, token_file, c.agentid, c.skip_verify_ssl)
12
+ Wechat::CorpApi.new(c.corpid, c.corpsecret, token_file, c.agentid, c.skip_verify_ssl, js_token_file)
21
13
  else
22
14
  puts <<-HELP
23
15
  Need create ~/.wechat.yml with wechat appid and secret
@@ -77,7 +69,8 @@ HELP
77
69
  access_token: ENV['WECHAT_ACCESS_TOKEN'],
78
70
  encrypt_mode: ENV['WECHAT_ENCRYPT_MODE'],
79
71
  skip_verify_ssl: ENV['WECHAT_SKIP_VERIFY_SSL'],
80
- encoding_aes_key: ENV['WECHAT_ENCODING_AES_KEY'] }
72
+ encoding_aes_key: ENV['WECHAT_ENCODING_AES_KEY'],
73
+ jsapi_ticket: ENV['WECHAT_JSAPI_TICKET'] }
81
74
  end
82
75
  end
83
76
  end
@@ -1,6 +1,7 @@
1
1
  require 'wechat/api_base'
2
2
  require 'wechat/client'
3
3
  require 'wechat/access_token'
4
+ require 'wechat/corp_jsapi_ticket'
4
5
 
5
6
  module Wechat
6
7
  class CorpAccessToken < AccessToken
@@ -17,10 +18,11 @@ module Wechat
17
18
 
18
19
  API_BASE = 'https://qyapi.weixin.qq.com/cgi-bin/'
19
20
 
20
- def initialize(appid, secret, token_file, agentid, skip_verify_ssl)
21
+ def initialize(appid, secret, token_file, agentid, skip_verify_ssl, jsapi_ticket_file)
21
22
  @client = Client.new(API_BASE, skip_verify_ssl)
22
23
  @access_token = CorpAccessToken.new(@client, appid, secret, token_file)
23
24
  @agentid = agentid
25
+ @jsapi_ticket = CorpJsapiTicket.new(@client, @access_token, jsapi_ticket_file)
24
26
  end
25
27
 
26
28
  def agent_list
@@ -0,0 +1,13 @@
1
+ require 'wechat/jsapi_base'
2
+
3
+ module Wechat
4
+ class CorpJsapiTicket < JsapiBase
5
+ # refresh jsapi ticket
6
+ def refresh
7
+ data = client.get('get_jsapi_ticket', params: { access_token: access_token.token })
8
+ data.merge!('created_at'.freeze => Time.now.to_i)
9
+ File.open(jsapi_ticket_file, 'w') { |f| f.write(data.to_json) } if valid_ticket(data)
10
+ @jsapi_ticket_data = data
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,67 @@
1
+ # coding: utf-8
2
+ require 'digest/sha1'
3
+
4
+ module Wechat
5
+ class JsapiBase
6
+ attr_reader :client, :access_token, :jsapi_ticket_file, :jsapi_ticket_data
7
+
8
+ def initialize(client, access_token, jsapi_ticket_file)
9
+ @client = client
10
+ @access_token = access_token
11
+ @jsapi_ticket_file = jsapi_ticket_file
12
+ end
13
+
14
+ # 获取微信 jssdk 签名所需的 jsapi_ticket, 返回具有如下结构的 hash:
15
+ # {
16
+ # "errcode":0,
17
+ # "errmsg":"ok",
18
+ # "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
19
+ # "expires_in":7200
20
+ # }
21
+ def ticket
22
+ begin
23
+ @jsapi_ticket_data ||= JSON.parse(File.read(jsapi_ticket_file))
24
+ created_at = jsapi_ticket_data['created_at'].to_i
25
+ expires_in = jsapi_ticket_data['expires_in'].to_i
26
+ if Time.now.to_i - created_at >= expires_in - 3 * 60
27
+ fail 'jsapi_ticket may be expired'
28
+ end
29
+ rescue
30
+ refresh
31
+ end
32
+ valid_ticket(@jsapi_ticket_data)
33
+ end
34
+
35
+ # 获取 jssdk 签名及注册所需其他参数, 返回具有如下结构的 hash:
36
+ # params = {
37
+ # noncestr: noncestr,
38
+ # timestamp: timestamp,
39
+ # jsapi_ticket: ticket,
40
+ # url: url,
41
+ # signature: signature
42
+ # }
43
+ def signature(url)
44
+ timestamp = Time.now.to_i
45
+ noncestr = SecureRandom.base64(16)
46
+ params = {
47
+ noncestr: noncestr,
48
+ timestamp: timestamp,
49
+ jsapi_ticket: ticket,
50
+ url: url
51
+ }
52
+ pairs = params.keys.sort.map do |key|
53
+ "#{key}=#{params[key]}"
54
+ end
55
+ result = Digest::SHA1.hexdigest pairs.join('&')
56
+ params.merge(signature: result)
57
+ end
58
+
59
+ protected
60
+
61
+ def valid_ticket(jsapi_ticket_data)
62
+ ticket = jsapi_ticket_data['ticket'] || jsapi_ticket_data[:ticket]
63
+ fail "Response didn't have ticket" if ticket.blank?
64
+ ticket
65
+ end
66
+ end
67
+ end
@@ -1,75 +1,13 @@
1
- # coding: utf-8
2
- require 'digest/sha1'
1
+ require 'wechat/jsapi_base'
3
2
 
4
3
  module Wechat
5
- class JsapiTicket
6
- attr_reader :client, :access_token, :jsapi_ticket_file, :jsapi_ticket_data
7
-
8
- def initialize(client, access_token, jsapi_ticket_file)
9
- @client = client
10
- @access_token = access_token
11
- @jsapi_ticket_file = jsapi_ticket_file
12
- end
13
-
14
- # 获取微信 jssdk 签名所需的 jsapi_ticket, 返回具有如下结构的 hash:
15
- # {
16
- # "errcode":0,
17
- # "errmsg":"ok",
18
- # "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
19
- # "expires_in":7200
20
- # }
21
- def ticket
22
- begin
23
- @jsapi_ticket_data ||= JSON.parse(File.read(jsapi_ticket_file))
24
- created_at = jsapi_ticket_data['created_at'].to_i
25
- expires_in = jsapi_ticket_data['expires_in'].to_i
26
- if Time.now.to_i - created_at >= expires_in - 3 * 60
27
- fail 'jsapi_ticket may be expired'
28
- end
29
- rescue
30
- refresh
31
- end
32
- valid_ticket(@jsapi_ticket_data)
33
- end
34
-
35
- # 刷新 jsapi_ticket
4
+ class JsapiTicket < JsapiBase
5
+ # refresh jsapi ticket
36
6
  def refresh
37
7
  data = client.get('ticket/getticket', params: { access_token: access_token.token, type: 'jsapi' })
38
8
  data.merge!('created_at'.freeze => Time.now.to_i)
39
9
  File.open(jsapi_ticket_file, 'w') { |f| f.write(data.to_json) } if valid_ticket(data)
40
10
  @jsapi_ticket_data = data
41
11
  end
42
-
43
- # 获取 jssdk 签名及注册所需其他参数, 返回具有如下结构的 hash:
44
- # params = {
45
- # noncestr: noncestr,
46
- # timestamp: timestamp,
47
- # jsapi_ticket: ticket,
48
- # url: url,
49
- # signature: signature
50
- # }
51
- def signature(url)
52
- timestamp = Time.now.to_i
53
- noncestr = SecureRandom.base64(16)
54
- params = {
55
- noncestr: noncestr,
56
- timestamp: timestamp,
57
- jsapi_ticket: ticket,
58
- url: url
59
- }
60
- pairs = params.keys.sort.map do |key|
61
- "#{key}=#{params[key]}"
62
- end
63
- result = Digest::SHA1.hexdigest pairs.join('&')
64
- params.merge(signature: result)
65
- end
66
-
67
- private
68
-
69
- def valid_ticket(jsapi_ticket_data)
70
- ticket = jsapi_ticket_data['ticket'] || jsapi_ticket_data[:ticket]
71
- fail "Response didn't have ticket" if ticket.blank?
72
- ticket
73
- end
74
12
  end
75
13
  end
@@ -15,21 +15,23 @@ module Wechat
15
15
  attr_accessor :wechat, :token, :corpid, :agentid, :encrypt_mode, :skip_verify_ssl, :encoding_aes_key
16
16
 
17
17
  def on(message_type, with: nil, respond: nil, &block)
18
- fail 'Unknow message type' unless [:text, :image, :voice, :video, :link, :event, :click, :scan, :batch_job, :location, :fallback].include?(message_type)
18
+ fail 'Unknow message type' unless [:text, :image, :voice, :video, :link, :event, :click, :view, :scan, :batch_job, :location, :fallback].include?(message_type)
19
19
  config = respond.nil? ? {} : { respond: respond }
20
20
  config.merge!(proc: block) if block_given?
21
21
 
22
22
  if with.present?
23
- fail 'Only text, event, click, scan and batch_job can having :with parameters' unless [:text, :event, :click, :scan, :batch_job].include?(message_type)
23
+ fail 'Only text, event, click, view, scan and batch_job can having :with parameters' unless [:text, :event, :click, :view, :scan, :batch_job].include?(message_type)
24
24
  config.merge!(with: with)
25
25
  self.known_scan_key_lists = with if message_type == :scan
26
26
  else
27
- fail 'Message type click, scan and batch_job must specify :with parameters' if [:click, :scan, :batch_job].include?(message_type)
27
+ fail 'Message type click, view, scan and batch_job must specify :with parameters' if [:click, :view, :scan, :batch_job].include?(message_type)
28
28
  end
29
29
 
30
30
  case message_type
31
31
  when :click
32
32
  user_defined_click_responders(with) << config
33
+ when :view
34
+ user_defined_view_responders(with) << config
33
35
  when :batch_job
34
36
  user_defined_batch_job_responders(with) << config
35
37
  when :location
@@ -45,6 +47,11 @@ module Wechat
45
47
  @click_responders[with] ||= []
46
48
  end
47
49
 
50
+ def user_defined_view_responders(with)
51
+ @view_responders ||= {}
52
+ @view_responders[with] ||= []
53
+ end
54
+
48
55
  def user_defined_batch_job_responders(with)
49
56
  @batch_job_responders ||= {}
50
57
  @batch_job_responders[with] ||= []
@@ -69,6 +76,8 @@ module Wechat
69
76
  when :event
70
77
  if 'click' == message[:Event] && !user_defined_click_responders(message[:EventKey]).empty?
71
78
  yield(* user_defined_click_responders(message[:EventKey]), message[:EventKey])
79
+ elsif 'view' == message[:Event] && !user_defined_view_responders(message[:EventKey]).empty?
80
+ yield(* user_defined_view_responders(message[:EventKey]), message[:EventKey])
72
81
  elsif 'click' == message[:Event]
73
82
  yield(* match_responders(responders, message[:EventKey]))
74
83
  elsif known_scan_key_lists.include?(message[:EventKey])
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wechat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.6.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Skinnyworm
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-11-24 00:00:00.000000000 Z
12
+ date: 2015-12-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -73,14 +73,14 @@ dependencies:
73
73
  requirements:
74
74
  - - "~>"
75
75
  - !ruby/object:Gem::Version
76
- version: '3.3'
76
+ version: '3.4'
77
77
  type: :development
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
- version: '3.3'
83
+ version: '3.4'
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: rails
86
86
  requirement: !ruby/object:Gem::Requirement
@@ -119,6 +119,8 @@ files:
119
119
  - lib/wechat/cipher.rb
120
120
  - lib/wechat/client.rb
121
121
  - lib/wechat/corp_api.rb
122
+ - lib/wechat/corp_jsapi_ticket.rb
123
+ - lib/wechat/jsapi_base.rb
122
124
  - lib/wechat/jsapi_ticket.rb
123
125
  - lib/wechat/message.rb
124
126
  - lib/wechat/responder.rb