wechat 0.11.10 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,7 +24,7 @@ module Wechat
24
24
  else
25
25
  controller.request.original_url
26
26
  end
27
- page_url = page_url.split('#').first if ios?
27
+ page_url = page_url.split('#').first
28
28
  js_hash = api.jsapi_ticket.signature(page_url)
29
29
 
30
30
  config_js = <<~WECHAT_CONFIG_JS
@@ -39,11 +39,5 @@ module Wechat
39
39
  WECHAT_CONFIG_JS
40
40
  javascript_tag config_js, type: 'application/javascript'
41
41
  end
42
-
43
- private
44
-
45
- def ios?
46
- controller.request.user_agent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
47
- end
48
42
  end
49
43
  end
@@ -14,7 +14,7 @@ module Wechat
14
14
  HTTP.timeout(:global, write: timeout, connect: timeout, read: timeout)
15
15
  end
16
16
  @ssl_context = OpenSSL::SSL::SSLContext.new
17
- @ssl_context.ssl_version = :TLSv1_2
17
+ @ssl_context.ssl_version = 'TLSv1_2'
18
18
  @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE if skip_verify_ssl
19
19
  end
20
20
 
@@ -77,12 +77,12 @@ module Wechat
77
77
  def parse_response(response, as_type)
78
78
  content_type = response.headers[:content_type]
79
79
  parse_as = {
80
- %r{^application\/json} => :json,
81
- %r{^image\/.*} => :file,
82
- %r{^audio\/.*} => :file,
83
- %r{^voice\/.*} => :file,
84
- %r{^text\/html} => :xml,
85
- %r{^text\/plain} => :probably_json
80
+ %r{^application/json} => :json,
81
+ %r{^image/.*} => :file,
82
+ %r{^audio/.*} => :file,
83
+ %r{^voice/.*} => :file,
84
+ %r{^text/html} => :xml,
85
+ %r{^text/plain} => :probably_json
86
86
  }.each_with_object([]) { |match, memo| memo << match[1] if content_type =~ match[0] }.first || as_type || :text
87
87
 
88
88
  # try to parse response as json, fallback to user-specified format or text if failed
@@ -32,6 +32,7 @@ module Wechat
32
32
 
33
33
  class ArticleBuilder
34
34
  attr_reader :items
35
+
35
36
  delegate :count, to: :items
36
37
  def initialize
37
38
  @items = []
@@ -40,14 +41,14 @@ module Wechat
40
41
 
41
42
  class NewsArticleBuilder < ArticleBuilder
42
43
  def item(title: 'title', description: nil, pic_url: nil, url: nil)
43
- items << { Title: title, Description: description, PicUrl: pic_url, Url: url }.reject { |_k, v| v.nil? }
44
+ items << { Title: title, Description: description, PicUrl: pic_url, Url: url }.compact
44
45
  end
45
46
  end
46
47
 
47
48
  class MpNewsArticleBuilder < ArticleBuilder
48
49
  def item(thumb_media_id:, title:, content:, author: nil, content_source_url: nil, digest: nil, show_cover_pic: '0')
49
50
  items << { Thumb_Media_ID: thumb_media_id, Author: author, Title: title, ContentSourceUrl: content_source_url,
50
- Content: content, Digest: digest, ShowCoverPic: show_cover_pic }.reject { |_k, v| v.nil? }
51
+ Content: content, Digest: digest, ShowCoverPic: show_cover_pic }.compact
51
52
  end
52
53
  end
53
54
 
@@ -168,7 +169,7 @@ module Wechat
168
169
  items = article.items
169
170
  else
170
171
  items = collection.collect do |item|
171
- camelize_hash_keys(item.symbolize_keys.slice(:title, :description, :pic_url, :url).reject { |_k, v| v.nil? })
172
+ camelize_hash_keys(item.symbolize_keys.slice(:title, :description, :pic_url, :url).compact)
172
173
  end
173
174
  end
174
175
 
@@ -183,7 +184,7 @@ module Wechat
183
184
  items = article.items
184
185
  else
185
186
  items = collection.collect do |item|
186
- camelize_hash_keys(item.symbolize_keys.slice(:thumb_media_id, :title, :content, :author, :content_source_url, :digest, :show_cover_pic).reject { |_k, v| v.nil? })
187
+ camelize_hash_keys(item.symbolize_keys.slice(:thumb_media_id, :title, :content, :author, :content_source_url, :digest, :show_cover_pic).compact)
187
188
  end
188
189
  end
189
190
 
data/lib/wechat/mp_api.rb CHANGED
@@ -1,14 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'wechat/api_base'
4
- require 'wechat/http_client'
5
- require 'wechat/token/public_access_token'
6
- require 'wechat/ticket/public_jsapi_ticket'
7
- require 'wechat/concern/common'
8
-
9
3
  module Wechat
10
4
  class MpApi < ApiBase
5
+ def initialize(appid, secret, token_file, timeout, skip_verify_ssl, jsapi_ticket_file, qcloud_env, qcloud_token_file, qcloud_token_lifespan)
6
+ super()
7
+ @client = HttpClient.new(Wechat::Api::API_BASE, timeout, skip_verify_ssl)
8
+ @access_token = Token::PublicAccessToken.new(@client, appid, secret, token_file)
9
+ @jsapi_ticket = Ticket::PublicJsapiTicket.new(@client, @access_token, jsapi_ticket_file)
10
+ @qcloud = Qcloud::Token.new(@client, @access_token, qcloud_env, qcloud_token_file, qcloud_token_lifespan)
11
+ end
12
+
11
13
  include Concern::Common
14
+ include Concern::Qcloud
12
15
 
13
16
  def template_message_send(message)
14
17
  post 'message/wxopen/template/send', message.to_json, content_type: :json
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wechat
4
+ module Qcloud
5
+ FILE_TYPE_JSON = 1
6
+ FILE_TYPE_CSV = 2
7
+ CONFLICT_MODE_INSERT = 1
8
+ CONFLICT_MODE_UPSERT = 2
9
+
10
+ class Token
11
+ attr_reader :client, :access_token, :qcloud_env, :qcloud_token_file, :qcloud_token_lifespan, :qcloud_token, :qcloud_token_expired_time
12
+
13
+ def initialize(client, access_token, qcloud_env, qcloud_token_file, lifespan)
14
+ @client = client
15
+ @access_token = access_token
16
+ @qcloud_env = qcloud_env
17
+ @qcloud_token_file = qcloud_token_file
18
+ @qcloud_token_lifespan = lifespan
19
+ @random_generator = Random.new
20
+ end
21
+
22
+ def token(tries = 2)
23
+ # Possible two worker running, one worker refresh ticket, other unaware, so must read every time
24
+ read_qcloud_token_from_store
25
+ refresh if remain_life_seconds < @random_generator.rand(30..3 * 60)
26
+ qcloud_token
27
+ rescue AccessTokenExpiredError
28
+ access_token.refresh
29
+ retry unless (tries -= 1).zero?
30
+ end
31
+
32
+ def refresh
33
+ data = client.post('getqcloudtoken', JSON.generate(lifespan: qcloud_token_lifespan), base: ::Wechat::ApiBase::TCB_BASE, params: { access_token: access_token.token })
34
+ write_qcloud_token_to_store(data)
35
+ read_qcloud_token_from_store
36
+ end
37
+
38
+ protected
39
+
40
+ def read_qcloud_token_from_store
41
+ td = read_qcloud_token
42
+ @qcloud_token_expired_time = td.fetch('qcloud_token_expired_time').to_i
43
+ @qcloud_token = td.fetch('token') # return qcloud_token same time
44
+ rescue JSON::ParserError, Errno::ENOENT, KeyError, TypeError
45
+ refresh
46
+ end
47
+
48
+ def write_qcloud_token_to_store(qcloud_token_hash)
49
+ qcloud_token_hash['qcloud_token_expired_time'] = qcloud_token_hash.delete('expired_time')
50
+ write_qcloud_token(qcloud_token_hash)
51
+ end
52
+
53
+ def read_qcloud_token
54
+ JSON.parse(File.read(qcloud_token_file))
55
+ end
56
+
57
+ def write_qcloud_token(qcloud_token_hash)
58
+ File.write(qcloud_token_file, qcloud_token_hash.to_json)
59
+ end
60
+
61
+ def remain_life_seconds
62
+ qcloud_token_expired_time - Time.now.to_i
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'English'
4
- require 'wechat/signature'
4
+ require 'rexml/document'
5
5
 
6
6
  module Wechat
7
7
  module Responder
@@ -10,24 +10,9 @@ module Wechat
10
10
  include Cipher
11
11
 
12
12
  included do
13
- # Rails 5 remove before_filter and skip_before_filter
14
- if respond_to?(:skip_before_action)
15
- if respond_to?(:verify_authenticity_token)
16
- skip_before_action :verify_authenticity_token
17
- else
18
- # Rails 5 API mode won't define verify_authenticity_token
19
- # https://github.com/rails/rails/blob/v5.0.0.beta3/actionpack/lib/abstract_controller/callbacks.rb#L66
20
- # https://github.com/rails/rails/blob/v5.0.0.beta3/activesupport/lib/active_support/callbacks.rb#L640
21
- skip_before_action :verify_authenticity_token, raise: false
22
- end
23
-
24
- before_action :config_account, only: %i[show create]
25
- before_action :verify_signature, only: %i[show create]
26
- else
27
- skip_before_filter :verify_authenticity_token
28
- before_filter :config_account, only: %i[show create]
29
- before_filter :verify_signature, only: %i[show create]
30
- end
13
+ skip_before_action :verify_authenticity_token, raise: false
14
+ before_action :config_account, only: %i[show create]
15
+ before_action :verify_signature, only: %i[show create]
31
16
  end
32
17
 
33
18
  module ClassMethods
@@ -145,9 +130,10 @@ module Wechat
145
130
  next
146
131
  end
147
132
 
148
- if condition.is_a? Regexp
133
+ case condition
134
+ when Regexp
149
135
  memo[:scoped] ||= [responder] + $LAST_MATCH_INFO.captures if value =~ condition
150
- elsif value == condition
136
+ when value
151
137
  memo[:scoped] ||= [responder, value]
152
138
  end
153
139
  end
@@ -178,15 +164,9 @@ module Wechat
178
164
  def show
179
165
  if @we_corpid.present?
180
166
  echostr, _corp_id = unpack(decrypt(Base64.decode64(params[:echostr]), @we_encoding_aes_key))
181
- if Rails::VERSION::MAJOR >= 4
182
- render plain: echostr
183
- else
184
- render text: echostr
185
- end
186
- elsif Rails::VERSION::MAJOR >= 4
187
- render plain: params[:echostr]
167
+ render plain: echostr
188
168
  else
189
- render text: params[:echostr]
169
+ render plain: params[:echostr]
190
170
  end
191
171
  end
192
172
 
@@ -195,11 +175,7 @@ module Wechat
195
175
  response_msg = run_responder(request_msg)
196
176
 
197
177
  if response_msg.respond_to? :to_xml
198
- if Rails::VERSION::MAJOR >= 4
199
- render plain: process_response(response_msg)
200
- else
201
- render text: process_response(response_msg)
202
- end
178
+ render plain: process_response(response_msg)
203
179
  else
204
180
  head :ok, content_type: 'text/html'
205
181
  end
@@ -246,15 +222,9 @@ module Wechat
246
222
  end
247
223
 
248
224
  data_hash = data.fetch('xml', {})
249
- if Rails::VERSION::MAJOR >= 5
250
- data_hash = data_hash.to_unsafe_hash if data_hash.instance_of?(ActionController::Parameters)
251
- HashWithIndifferentAccess.new(data_hash).tap do |msg|
252
- msg[:Event]&.downcase!
253
- end
254
- else
255
- HashWithIndifferentAccess.new_from_hash_copying_default(data_hash).tap do |msg|
256
- msg[:Event]&.downcase!
257
- end
225
+ data_hash = data_hash.to_unsafe_hash if data_hash.instance_of?(ActionController::Parameters)
226
+ HashWithIndifferentAccess.new(data_hash).tap do |msg|
227
+ msg[:Event]&.downcase!
258
228
  end
259
229
  end
260
230
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'wechat/ticket/jsapi_base'
4
-
5
3
  module Wechat
6
4
  module Ticket
7
5
  class CorpJsapiTicket < JsapiBase
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'wechat/ticket/jsapi_base'
4
-
5
3
  module Wechat
6
4
  module Ticket
7
5
  class PublicJsapiTicket < JsapiBase
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'wechat/token/access_token_base'
4
-
5
3
  module Wechat
6
4
  module Token
7
5
  class CorpAccessToken < AccessTokenBase
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'wechat/token/access_token_base'
4
-
5
3
  module Wechat
6
4
  module Token
7
5
  class PublicAccessToken < AccessTokenBase
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.11.10
4
+ version: 0.13.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Skinnyworm
@@ -35,7 +35,7 @@ cert_chain:
35
35
  spvOK5/LPXWX6ZGc2SR8SH/s7ftYH2EkeM1VUbtemow08NdgCwJ4IG+fRQ9dcrJ+
36
36
  L9TbpLHvVrCe1w8duMqNeUmqj+M1iC/5Zst2vIe14QcOTuAh
37
37
  -----END CERTIFICATE-----
38
- date: 2020-09-02 00:00:00.000000000 Z
38
+ date: 2021-03-15 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: activesupport
@@ -43,7 +43,7 @@ dependencies:
43
43
  requirements:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: '3.2'
46
+ version: '6.0'
47
47
  - - "<"
48
48
  - !ruby/object:Gem::Version
49
49
  version: '7'
@@ -53,7 +53,7 @@ dependencies:
53
53
  requirements:
54
54
  - - ">="
55
55
  - !ruby/object:Gem::Version
56
- version: '3.2'
56
+ version: '6.0'
57
57
  - - "<"
58
58
  - !ruby/object:Gem::Version
59
59
  version: '7'
@@ -105,34 +105,62 @@ dependencies:
105
105
  - - ">="
106
106
  - !ruby/object:Gem::Version
107
107
  version: '0'
108
+ - !ruby/object:Gem::Dependency
109
+ name: rexml
110
+ requirement: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ type: :runtime
116
+ prerelease: false
117
+ version_requirements: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ - !ruby/object:Gem::Dependency
123
+ name: zeitwerk
124
+ requirement: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - "~>"
127
+ - !ruby/object:Gem::Version
128
+ version: '2.4'
129
+ type: :runtime
130
+ prerelease: false
131
+ version_requirements: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: '2.4'
108
136
  - !ruby/object:Gem::Dependency
109
137
  name: rubocop
110
138
  requirement: !ruby/object:Gem::Requirement
111
139
  requirements:
112
140
  - - "~>"
113
141
  - !ruby/object:Gem::Version
114
- version: '0.74'
142
+ version: '1.9'
115
143
  type: :development
116
144
  prerelease: false
117
145
  version_requirements: !ruby/object:Gem::Requirement
118
146
  requirements:
119
147
  - - "~>"
120
148
  - !ruby/object:Gem::Version
121
- version: '0.74'
149
+ version: '1.9'
122
150
  - !ruby/object:Gem::Dependency
123
151
  name: rails
124
152
  requirement: !ruby/object:Gem::Requirement
125
153
  requirements:
126
154
  - - ">="
127
155
  - !ruby/object:Gem::Version
128
- version: '5.1'
156
+ version: '6.0'
129
157
  type: :development
130
158
  prerelease: false
131
159
  version_requirements: !ruby/object:Gem::Requirement
132
160
  requirements:
133
161
  - - ">="
134
162
  - !ruby/object:Gem::Version
135
- version: '5.1'
163
+ version: '6.0'
136
164
  - !ruby/object:Gem::Dependency
137
165
  name: rspec-rails
138
166
  requirement: !ruby/object:Gem::Requirement
@@ -195,12 +223,14 @@ files:
195
223
  - lib/wechat/api_loader.rb
196
224
  - lib/wechat/cipher.rb
197
225
  - lib/wechat/concern/common.rb
226
+ - lib/wechat/concern/qcloud.rb
198
227
  - lib/wechat/controller_api.rb
199
228
  - lib/wechat/corp_api.rb
200
229
  - lib/wechat/helpers.rb
201
230
  - lib/wechat/http_client.rb
202
231
  - lib/wechat/message.rb
203
232
  - lib/wechat/mp_api.rb
233
+ - lib/wechat/qcloud/token.rb
204
234
  - lib/wechat/responder.rb
205
235
  - lib/wechat/signature.rb
206
236
  - lib/wechat/ticket/corp_jsapi_ticket.rb
@@ -219,16 +249,16 @@ require_paths:
219
249
  - lib
220
250
  required_ruby_version: !ruby/object:Gem::Requirement
221
251
  requirements:
222
- - - "~>"
252
+ - - ">="
223
253
  - !ruby/object:Gem::Version
224
- version: '2.4'
254
+ version: '2.6'
225
255
  required_rubygems_version: !ruby/object:Gem::Requirement
226
256
  requirements:
227
257
  - - ">="
228
258
  - !ruby/object:Gem::Version
229
259
  version: '0'
230
260
  requirements: []
231
- rubygems_version: 3.1.4
261
+ rubygems_version: 3.2.14
232
262
  signing_key:
233
263
  specification_version: 4
234
264
  summary: DSL for wechat message handling and API