wechat 0.11.4 → 0.11.5

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +5 -1
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG.md +5 -0
  5. data/lib/action_controller/wechat_responder.rb +7 -5
  6. data/lib/generators/wechat/config_generator.rb +14 -10
  7. data/lib/generators/wechat/install_generator.rb +3 -1
  8. data/lib/generators/wechat/menu_generator.rb +3 -1
  9. data/lib/generators/wechat/redis_store_generator.rb +3 -1
  10. data/lib/generators/wechat/session_generator.rb +14 -10
  11. data/lib/generators/wechat/templates/app/models/wechat_config.rb +8 -13
  12. data/lib/generators/wechat/templates/app/models/wechat_session.rb +2 -0
  13. data/lib/generators/wechat/templates/config/initializers/wechat_redis_store.rb +5 -3
  14. data/lib/wechat.rb +5 -3
  15. data/lib/wechat/api.rb +2 -0
  16. data/lib/wechat/api_base.rb +8 -6
  17. data/lib/wechat/api_loader.rb +48 -49
  18. data/lib/wechat/cipher.rb +4 -2
  19. data/lib/wechat/concern/common.rb +2 -0
  20. data/lib/wechat/controller_api.rb +13 -10
  21. data/lib/wechat/corp_api.rb +2 -0
  22. data/lib/wechat/helpers.rb +14 -12
  23. data/lib/wechat/http_client.rb +21 -16
  24. data/lib/wechat/message.rb +17 -14
  25. data/lib/wechat/mp_api.rb +2 -0
  26. data/lib/wechat/responder.rb +37 -38
  27. data/lib/wechat/signature.rb +2 -0
  28. data/lib/wechat/ticket/corp_jsapi_ticket.rb +2 -0
  29. data/lib/wechat/ticket/jsapi_base.rb +4 -2
  30. data/lib/wechat/ticket/public_jsapi_ticket.rb +2 -0
  31. data/lib/wechat/token/access_token_base.rb +4 -2
  32. data/lib/wechat/token/corp_access_token.rb +2 -0
  33. data/lib/wechat/token/public_access_token.rb +2 -0
  34. metadata +42 -28
  35. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df10ca6f78d2d0546495b798889545656fe4e40f8f06cd8267b60ce26a1d1d9a
4
- data.tar.gz: c78e07d9b619a950887bd2de8e6e751f5d280db52f9458aa78456aa9aa305cc5
3
+ metadata.gz: 332ed5cc2f20211d70e994fc4549534748c9400074ece51debd7e4d147b4a1fd
4
+ data.tar.gz: 6cb347a738b602628c6dadae3ef2d90cddb9c1baff68e7e66b9bc88cc14a8643
5
5
  SHA512:
6
- metadata.gz: b528307cd3d452bd6e0733aa6a1663eae1ac4569b3e1d64f98dac8174a14276bfb7125476da1d219a02893287a693143c45bafa8ba5f164a1eaec6139f9d64ae
7
- data.tar.gz: d1205df3d31f15261fcde43b734d7abd79c99059c0a5339d9b98bbe69709ba814b7e7cbb14bd320c898b0f3c82235055dc7fde5d1cad33f5f0792b67e2a6872c
6
+ metadata.gz: 3b293b5f93fcc0f304af98f7664c73469595028b4bc38d14c60bf2506243c288d59964e17acaea563c7922493b39e67bc56ede37e638fecaf4f83c332dbb60ca
7
+ data.tar.gz: 640d2a2b5fc743189f03f680c03404cc991ff6b5e50f84f802c520eed10d7df1690080ae11ac9f1b22ada9b4f45a5f1c6a8ba5e8f01a9043026ce20ed39569ee
@@ -1 +1,5 @@
1
- }(nFS�e�n�9{��S!�<��C�p>t��t��I�ǔ���I@�nK�:��m���K^a�\j���P{:���0�>��1�^�[SSi�=z[�}Z�e.G��M�Ð���sΔ
1
+ o����6TK
2
+ [|%��)��֜��xʰJ���.�����"9?
3
+ �m�БF�XBq���:�D^��w���v|����ͿO�pn�+���a�����껅�h"�����)��1��p�A��5��C0� ���AWp��u�ˑ�\�x��ub�X�_S{N�F$%�a\�ZU��۟-�N
4
+ �曵.���k�����X�PI�ج��P�q�WT{ɷHRK�=q#��
5
+ � BKT$'��ck�V�6 Ѧ̈́*��Cl�[f�,,�v����8��#HD���P��|��C� �j�Dz�_
data.tar.gz.sig CHANGED
Binary file
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.11.5 (released at 08/30/2019)
4
+
5
+ * Add rubocop check in CI by @hophacker #267
6
+ * Support Rails 6 and Windows at #266
7
+
3
8
  ## v0.11.4 (released at 08/15/2019)
4
9
 
5
10
  * rails 6 redirect_to use allow_other_host: true by @Chen-George-Zhen #263
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  module WechatResponder
3
5
  def wechat_api(opts = {})
@@ -36,11 +38,11 @@ module ActionController
36
38
  self.trusted_domain_fullname = opts[:trusted_domain_fullname] || cfg.trusted_domain_fullname
37
39
  self.oauth2_cookie_duration = opts[:oauth2_cookie_duration] || cfg.oauth2_cookie_duration.to_i.seconds
38
40
  self.timeout = opts[:timeout] || cfg.timeout
39
- if opts.key?(:skip_verify_ssl)
40
- self.skip_verify_ssl = opts[:skip_verify_ssl]
41
- else
42
- self.skip_verify_ssl = cfg.skip_verify_ssl
43
- end
41
+ self.skip_verify_ssl = if opts.key?(:skip_verify_ssl)
42
+ opts[:skip_verify_ssl]
43
+ else
44
+ cfg.skip_verify_ssl
45
+ end
44
46
 
45
47
  return Wechat.api if account == :default && opts.empty?
46
48
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/generators/active_record'
2
4
 
3
5
  module Wechat
@@ -6,13 +8,13 @@ module Wechat
6
8
  include ::Rails::Generators::Migration
7
9
 
8
10
  desc 'Generate wechat configs in database'
9
- source_root File.expand_path('../templates', __FILE__)
11
+ source_root File.expand_path('templates', __dir__)
10
12
 
11
13
  def copy_wechat_config_migration
12
14
  migration_template(
13
- 'db/config_migration.rb.erb',
14
- 'db/migrate/create_wechat_configs.rb',
15
- {migration_version: migration_version}
15
+ 'db/config_migration.rb.erb',
16
+ 'db/migrate/create_wechat_configs.rb',
17
+ migration_version: migration_version
16
18
  )
17
19
  end
18
20
 
@@ -20,16 +22,18 @@ module Wechat
20
22
  template 'app/models/wechat_config.rb'
21
23
  end
22
24
 
23
- private
25
+ class << self
26
+ private
24
27
 
25
- def self.next_migration_number(dirname)
26
- ::ActiveRecord::Generators::Base.next_migration_number(dirname)
28
+ def next_migration_number(dirname)
29
+ ::ActiveRecord::Generators::Base.next_migration_number(dirname)
30
+ end
27
31
  end
28
32
 
33
+ private
34
+
29
35
  def migration_version
30
- if Rails.version >= '5.0.0'
31
- "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
32
- end
36
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" if Rails.version >= '5.0.0'
33
37
  end
34
38
  end
35
39
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  module Generators
3
5
  class InstallGenerator < Rails::Generators::Base
4
6
  desc 'Install Wechat support files'
5
- source_root File.expand_path('../templates', __FILE__)
7
+ source_root File.expand_path('templates', __dir__)
6
8
 
7
9
  def copy_config
8
10
  template 'config/wechat.yml'
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  module Generators
3
5
  class MenuGenerator < Rails::Generators::Base
4
6
  desc 'Generate wechat menu'
5
- source_root File.expand_path('../templates', __FILE__)
7
+ source_root File.expand_path('templates', __dir__)
6
8
  class_option :conditional, desc: 'Generate conditional menu', type: :boolean, default: false
7
9
 
8
10
  def copy_menu
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  module Generators
3
5
  class RedisStoreGenerator < Rails::Generators::Base
4
6
  desc 'Using redis as token/ticket store'
5
- source_root File.expand_path('../templates', __FILE__)
7
+ source_root File.expand_path('templates', __dir__)
6
8
 
7
9
  def copy_wechat_redis_initializer
8
10
  template 'config/initializers/wechat_redis_store.rb'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/generators/active_record'
2
4
 
3
5
  module Wechat
@@ -6,13 +8,13 @@ module Wechat
6
8
  include ::Rails::Generators::Migration
7
9
 
8
10
  desc 'Enable wechat session support'
9
- source_root File.expand_path('../templates', __FILE__)
11
+ source_root File.expand_path('templates', __dir__)
10
12
 
11
13
  def copy_wechat_sessions_migration
12
14
  migration_template(
13
- 'db/session_migration.rb.erb',
14
- 'db/migrate/create_wechat_sessions.rb',
15
- {migration_version: migration_version}
15
+ 'db/session_migration.rb.erb',
16
+ 'db/migrate/create_wechat_sessions.rb',
17
+ migration_version: migration_version
16
18
  )
17
19
  end
18
20
 
@@ -20,16 +22,18 @@ module Wechat
20
22
  template 'app/models/wechat_session.rb'
21
23
  end
22
24
 
23
- private
25
+ class << self
26
+ private
24
27
 
25
- def self.next_migration_number(dirname)
26
- ::ActiveRecord::Generators::Base.next_migration_number(dirname)
28
+ def next_migration_number(dirname)
29
+ ::ActiveRecord::Generators::Base.next_migration_number(dirname)
30
+ end
27
31
  end
28
32
 
33
+ private
34
+
29
35
  def migration_version
30
- if Rails.version >= '5.0.0'
31
- "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
32
- end
36
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" if Rails.version >= '5.0.0'
33
37
  end
34
38
  end
35
39
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Used by wechat gems, do not rename WechatConfig to other name,
2
4
  # Feel free to inherit from other class like ActiveModel::Model
3
5
  class WechatConfig < ActiveRecord::Base
@@ -10,17 +12,16 @@ class WechatConfig < ActiveRecord::Base
10
12
 
11
13
  validate :app_config_is_valid
12
14
 
13
- ATTRIBUTES_TO_REMOVE = %w(environment account created_at updated_at enabled)
15
+ ATTRIBUTES_TO_REMOVE = %w[environment account created_at updated_at enabled].freeze
14
16
 
15
17
  def self.get_all_configs(environment)
16
- WechatConfig.where(environment: environment, enabled: true).inject({}) do |hash, config|
18
+ WechatConfig.where(environment: environment, enabled: true).each_with_object({}) do |config, hash|
17
19
  hash[config.account] = config.build_config_hash
18
- hash
19
20
  end
20
21
  end
21
22
 
22
23
  def build_config_hash
23
- self.as_json(except: ATTRIBUTES_TO_REMOVE)
24
+ as_json(except: ATTRIBUTES_TO_REMOVE)
24
25
  end
25
26
 
26
27
  private
@@ -28,17 +29,11 @@ class WechatConfig < ActiveRecord::Base
28
29
  def app_config_is_valid
29
30
  if self[:appid].present?
30
31
  # public account
31
- if self[:secret].blank?
32
- errors.add(:secret, 'cannot be nil when appid is set')
33
- end
32
+ errors.add(:secret, 'cannot be nil when appid is set') if self[:secret].blank?
34
33
  elsif self[:corpid].present?
35
34
  # corp account
36
- if self[:corpsecret].blank?
37
- errors.add(:corpsecret, 'cannot be nil when corpid is set')
38
- end
39
- if self[:agentid].blank?
40
- errors.add(:agentid, 'cannot be nil when corpid is set')
41
- end
35
+ errors.add(:corpsecret, 'cannot be nil when corpid is set') if self[:corpsecret].blank?
36
+ errors.add(:agentid, 'cannot be nil when corpid is set') if self[:agentid].blank?
42
37
  else
43
38
  errors[:base] << 'Either appid or corpid must be set'
44
39
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Used by wechat gems, do not rename WechatSession to other name,
2
4
  # Feel free to inherit from other class like ActiveModel::Model
3
5
  class WechatSession < ActiveRecord::Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  def self.redis
3
5
  # You can reuse existing redis connection and remove this method if require
@@ -17,7 +19,7 @@ module Wechat
17
19
  private
18
20
 
19
21
  def redis_key
20
- "my_app_wechat_token_#{self.secret}"
22
+ "my_app_wechat_token_#{secret}"
21
23
  end
22
24
  end
23
25
  end
@@ -25,7 +27,7 @@ module Wechat
25
27
  module Ticket
26
28
  class JsapiBase
27
29
  def read_ticket
28
- JSON.parse(Wechat.redis.get(redis_key)) || {}
30
+ JSON.parse(Wechat.redis.get(redis_key)) || {}
29
31
  end
30
32
 
31
33
  def write_ticket(ticket_hash)
@@ -35,7 +37,7 @@ module Wechat
35
37
  private
36
38
 
37
39
  def redis_key
38
- "my_app_wechat_ticket_#{self.access_token.secret}"
40
+ "my_app_wechat_ticket_#{access_token.secret}"
39
41
  end
40
42
  end
41
43
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'base64'
2
4
  require 'openssl/cipher'
3
5
  require 'wechat/api_loader'
@@ -36,15 +38,15 @@ module Wechat
36
38
  ApiLoader.reload_config!
37
39
  end
38
40
 
39
- def self.decrypt(encrypted_data, session_key, iv)
41
+ def self.decrypt(encrypted_data, session_key, ivector)
40
42
  cipher = OpenSSL::Cipher.new('AES-128-CBC')
41
43
  cipher.decrypt
42
44
 
43
45
  cipher.key = Base64.decode64(session_key)
44
- cipher.iv = Base64.decode64(iv)
46
+ cipher.iv = Base64.decode64(ivector)
45
47
  decrypted_data = Base64.decode64(encrypted_data)
46
48
  JSON.parse(cipher.update(decrypted_data) + cipher.final)
47
- rescue Exception => e
49
+ rescue StandardError => e
48
50
  { 'errcode': 41003, 'errmsg': e.message }
49
51
  end
50
52
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'wechat/api_base'
2
4
  require 'wechat/http_client'
3
5
  require 'wechat/token/public_access_token'
@@ -1,13 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  class ApiBase
3
5
  attr_reader :access_token, :client, :jsapi_ticket
4
6
 
5
- API_BASE = 'https://api.weixin.qq.com/cgi-bin/'.freeze
6
- MP_BASE = 'https://mp.weixin.qq.com/cgi-bin/'.freeze
7
- WXA_BASE = 'https://api.weixin.qq.com/wxa/'.freeze
8
- OAUTH2_BASE = 'https://api.weixin.qq.com/sns/'.freeze
9
- DATACUBE_BASE = 'https://api.weixin.qq.com/datacube/'.freeze
10
- QYAPI_BASE = 'https://qyapi.weixin.qq.com/cgi-bin/'.freeze
7
+ API_BASE = 'https://api.weixin.qq.com/cgi-bin/'
8
+ MP_BASE = 'https://mp.weixin.qq.com/cgi-bin/'
9
+ WXA_BASE = 'https://api.weixin.qq.com/wxa/'
10
+ OAUTH2_BASE = 'https://api.weixin.qq.com/sns/'
11
+ DATACUBE_BASE = 'https://api.weixin.qq.com/datacube/'
12
+ QYAPI_BASE = 'https://qyapi.weixin.qq.com/cgi-bin/'
11
13
 
12
14
  def callbackip
13
15
  get 'getcallbackip'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  module ApiLoader
3
5
  def self.with(options)
@@ -8,12 +10,12 @@ module Wechat
8
10
  js_token_file = options[:js_token_file] || c.jsapi_ticket.presence || '/var/tmp/wechat_jsapi_ticket'
9
11
  type = options[:type] || c.type
10
12
  if c.appid && c.secret && token_file.present?
11
- wx_class = (type == 'mp') ? Wechat::MpApi : Wechat::Api
13
+ wx_class = type == 'mp' ? Wechat::MpApi : Wechat::Api
12
14
  wx_class.new(c.appid, c.secret, token_file, c.timeout, c.skip_verify_ssl, js_token_file)
13
15
  elsif c.corpid && c.corpsecret && token_file.present?
14
16
  Wechat::CorpApi.new(c.corpid, c.corpsecret, token_file, c.agentid, c.timeout, c.skip_verify_ssl, js_token_file)
15
17
  else
16
- raise "Need create ~/.wechat.yml with wechat appid and secret or running at rails root folder so wechat can read config/wechat.yml"
18
+ raise 'Need create ~/.wechat.yml with wechat appid and secret or running at rails root folder so wechat can read config/wechat.yml'
17
19
  end
18
20
  end
19
21
 
@@ -35,11 +37,9 @@ module Wechat
35
37
 
36
38
  configs.symbolize_keys!
37
39
  configs.each do |key, cfg|
38
- if cfg.is_a?(Hash)
39
- cfg.symbolize_keys!
40
- else
41
- raise "wrong wechat configuration format for #{key}"
42
- end
40
+ raise "wrong wechat configuration format for #{key}" unless cfg.is_a?(Hash)
41
+
42
+ cfg.symbolize_keys!
43
43
  end
44
44
 
45
45
  if defined?(::Rails)
@@ -64,9 +64,7 @@ module Wechat
64
64
  end
65
65
 
66
66
  private_class_method def self.config_from_db
67
- unless class_exists?('WechatConfig')
68
- return {}
69
- end
67
+ return {} unless class_exists?('WechatConfig')
70
68
 
71
69
  environment = defined?(::Rails) ? Rails.env.to_s : ENV['RAILS_ENV'] || 'development'
72
70
  WechatConfig.get_all_configs(environment)
@@ -74,11 +72,11 @@ module Wechat
74
72
 
75
73
  private_class_method def self.config_from_file
76
74
  if defined?(::Rails)
77
- config_file = ENV['WECHAT_CONF_FILE'] || Rails.root.join('config/wechat.yml')
78
- return resovle_config_file(config_file, Rails.env.to_s)
75
+ config_file = ENV['WECHAT_CONF_FILE'] || Rails.root.join('config', 'wechat.yml')
76
+ resolve_config_file(config_file, Rails.env.to_s)
79
77
  else
80
- rails_config_file = ENV['WECHAT_CONF_FILE'] || File.join(Dir.getwd, 'config/wechat.yml')
81
- application_config_file = File.join(Dir.getwd, 'config/application.yml')
78
+ rails_config_file = ENV['WECHAT_CONF_FILE'] || File.join(Dir.getwd, 'config', 'wechat.yml')
79
+ application_config_file = File.join(Dir.getwd, 'config', 'application.yml')
82
80
  home_config_file = File.join(Dir.home, '.wechat.yml')
83
81
  if File.exist?(rails_config_file)
84
82
  rails_env = ENV['RAILS_ENV'] || 'development'
@@ -86,54 +84,55 @@ module Wechat
86
84
  require 'figaro'
87
85
  Figaro::Application.new(path: application_config_file, environment: rails_env).load
88
86
  end
89
- config = resovle_config_file(rails_config_file, rails_env)
90
- if config.present? && (default = config[:default]) && (default['appid'] || default['corpid'])
91
- puts "Using rails project #{ENV['WECHAT_CONF_FILE'] || "config/wechat.yml"} #{rails_env} setting..."
87
+ config = resolve_config_file(rails_config_file, rails_env)
88
+ if config.present? && (default = config[:default]) && (default['appid'] || default['corpid'])
89
+ puts "Using rails project #{ENV['WECHAT_CONF_FILE'] || 'config/wechat.yml'} #{rails_env} setting..."
92
90
  return config
93
91
  end
94
92
  end
95
- if File.exist?(home_config_file)
96
- return resovle_config_file(home_config_file, nil)
97
- end
93
+ return resolve_config_file(home_config_file, nil) if File.exist?(home_config_file)
98
94
  end
99
95
  end
100
96
 
101
- private_class_method def self.resovle_config_file(config_file, env)
102
- if File.exist?(config_file)
103
- raw_data = YAML.load(ERB.new(File.read(config_file)).result)
104
- configs = {}
105
- if env
106
- # Process multiple accounts when env is given
107
- raw_data.each do |key, value|
108
- if key == env
109
- configs[:default] = value
110
- elsif m = /(.*?)_#{env}$/.match(key)
111
- configs[m[1].to_sym] = value
112
- end
97
+ private_class_method def self.resolve_config_file(config_file, env)
98
+ return unless File.exist?(config_file)
99
+
100
+ # rubocop:disable Security/YAMLLoad
101
+ raw_data = YAML.load(ERB.new(File.read(config_file)).result)
102
+ # rubocop:enable Security/YAMLLoad
103
+ configs = {}
104
+ if env
105
+ # Process multiple accounts when env is given
106
+ raw_data.each do |key, value|
107
+ if key == env
108
+ configs[:default] = value
109
+ else
110
+ m = /(.*?)_#{env}$/.match(key)
111
+ configs[m[1].to_sym] = value if m
113
112
  end
114
- else
115
- # Treat is as one account when env is omitted
116
- configs[:default] = raw_data
117
113
  end
118
- configs
114
+ else
115
+ # Treat is as one account when env is omitted
116
+ configs[:default] = raw_data
119
117
  end
118
+ configs
120
119
  end
121
120
 
122
121
  private_class_method def self.config_from_environment
123
122
  value = { appid: ENV['WECHAT_APPID'],
124
- secret: ENV['WECHAT_SECRET'],
125
- corpid: ENV['WECHAT_CORPID'],
126
- corpsecret: ENV['WECHAT_CORPSECRET'],
127
- agentid: ENV['WECHAT_AGENTID'],
128
- token: ENV['WECHAT_TOKEN'],
129
- access_token: ENV['WECHAT_ACCESS_TOKEN'],
130
- encrypt_mode: ENV['WECHAT_ENCRYPT_MODE'],
131
- timeout: ENV['WECHAT_TIMEOUT'],
132
- skip_verify_ssl: ENV['WECHAT_SKIP_VERIFY_SSL'],
133
- encoding_aes_key: ENV['WECHAT_ENCODING_AES_KEY'],
134
- jsapi_ticket: ENV['WECHAT_JSAPI_TICKET'],
135
- trusted_domain_fullname: ENV['WECHAT_TRUSTED_DOMAIN_FULLNAME'] }
136
- {default: value}
123
+ secret: ENV['WECHAT_SECRET'],
124
+ corpid: ENV['WECHAT_CORPID'],
125
+ corpsecret: ENV['WECHAT_CORPSECRET'],
126
+ agentid: ENV['WECHAT_AGENTID'],
127
+ token: ENV['WECHAT_TOKEN'],
128
+ access_token: ENV['WECHAT_ACCESS_TOKEN'],
129
+ encrypt_mode: ENV['WECHAT_ENCRYPT_MODE'],
130
+ timeout: ENV['WECHAT_TIMEOUT'],
131
+ skip_verify_ssl: ENV['WECHAT_SKIP_VERIFY_SSL'],
132
+ encoding_aes_key: ENV['WECHAT_ENCODING_AES_KEY'],
133
+ jsapi_ticket: ENV['WECHAT_JSAPI_TICKET'],
134
+ trusted_domain_fullname: ENV['WECHAT_TRUSTED_DOMAIN_FULLNAME'] }
135
+ { default: value }
137
136
  end
138
137
 
139
138
  private_class_method def self.class_exists?(class_name)
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  module Cipher
3
5
  BLOCK_SIZE = 32
4
- CIPHER = 'AES-256-CBC'.freeze
6
+ CIPHER = 'AES-256-CBC'
5
7
 
6
8
  def encrypt(plain, encoding_aes_key)
7
9
  cipher = OpenSSL::Cipher.new(CIPHER)
@@ -51,7 +53,7 @@ module Wechat
51
53
  def encode_padding(data)
52
54
  length = data.bytes.length
53
55
  amount_to_pad = BLOCK_SIZE - (length % BLOCK_SIZE)
54
- amount_to_pad = BLOCK_SIZE if amount_to_pad == 0
56
+ amount_to_pad = BLOCK_SIZE if amount_to_pad.zero?
55
57
  padding = ([amount_to_pad].pack('c') * amount_to_pad)
56
58
  data + padding
57
59
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  module Concern
3
5
  module Common
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  module ControllerApi
3
5
  extend ActiveSupport::Concern
@@ -20,10 +22,10 @@ module Wechat
20
22
  if account
21
23
  config = Wechat.config(account)
22
24
  appid = config.corpid || config.appid
23
- is_crop_account = !!config.corpid
25
+ is_crop_account = config.corpid.present?
24
26
  else
25
27
  appid = self.class.corpid || self.class.appid
26
- is_crop_account = !!self.class.corpid
28
+ is_crop_account = self.class.corpid.present?
27
29
  end
28
30
 
29
31
  raise 'Can not get corpid or appid, so please configure it first to using wechat_oauth2' if appid.blank?
@@ -37,6 +39,7 @@ module Wechat
37
39
  }
38
40
 
39
41
  return generate_oauth2_url(oauth2_params) unless block_given?
42
+
40
43
  is_crop_account ? wechat_corp_oauth2(oauth2_params, account, &block) : wechat_public_oauth2(oauth2_params, account, &block)
41
44
  end
42
45
 
@@ -47,7 +50,7 @@ module Wechat
47
50
  unionid = cookies.signed_or_encrypted[:we_unionid]
48
51
  we_token = cookies.signed_or_encrypted[:we_access_token]
49
52
  if openid.present?
50
- yield openid, { 'openid' => openid, 'unionid' => unionid, 'access_token' => we_token}
53
+ yield openid, { 'openid' => openid, 'unionid' => unionid, 'access_token' => we_token }
51
54
  elsif params[:code].present? && params[:state] == oauth2_params[:state]
52
55
  access_info = wechat(account).web_access_token(params[:code])
53
56
  cookies.signed_or_encrypted[:we_openid] = { value: access_info['openid'], expires: self.class.oauth2_cookie_duration.from_now }
@@ -55,7 +58,7 @@ module Wechat
55
58
  cookies.signed_or_encrypted[:we_access_token] = { value: access_info['access_token'], expires: self.class.oauth2_cookie_duration.from_now }
56
59
  yield access_info['openid'], access_info
57
60
  else
58
- (Rails::VERSION::MAJOR >= 6) ? (redirect_to generate_oauth2_url(oauth2_params), allow_other_host: true) : (redirect_to generate_oauth2_url(oauth2_params))
61
+ Rails::VERSION::MAJOR >= 6 ? (redirect_to generate_oauth2_url(oauth2_params), allow_other_host: true) : (redirect_to generate_oauth2_url(oauth2_params))
59
62
  end
60
63
  end
61
64
 
@@ -70,18 +73,18 @@ module Wechat
70
73
  cookies.signed_or_encrypted[:we_deviceid] = { value: userinfo['DeviceId'], expires: self.class.oauth2_cookie_duration.from_now }
71
74
  yield userinfo['UserId'], userinfo
72
75
  else
73
- (Rails::VERSION::MAJOR >= 6) ? (redirect_to generate_oauth2_url(oauth2_params), allow_other_host: true) : (redirect_to generate_oauth2_url(oauth2_params))
76
+ Rails::VERSION::MAJOR >= 6 ? (redirect_to generate_oauth2_url(oauth2_params), allow_other_host: true) : (redirect_to generate_oauth2_url(oauth2_params))
74
77
  end
75
78
  end
76
79
 
77
80
  def generate_redirect_uri(account = nil)
78
81
  domain_name = if account
79
- Wechat.config(account).trusted_domain_fullname
80
- else
81
- self.class.trusted_domain_fullname
82
- end
82
+ Wechat.config(account).trusted_domain_fullname
83
+ else
84
+ self.class.trusted_domain_fullname
85
+ end
83
86
  page_url = domain_name ? "#{domain_name}#{request.original_fullpath}" : request.original_url
84
- safe_query = request.query_parameters.reject { |k, _| %w(code state access_token).include? k }.to_query
87
+ safe_query = request.query_parameters.reject { |k, _| %w[code state access_token].include? k }.to_query
85
88
  page_url.sub(request.query_string, safe_query)
86
89
  end
87
90
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'wechat/api_base'
2
4
  require 'wechat/http_client'
3
5
  require 'wechat/token/corp_access_token'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  module Helpers
3
5
  def wechat_config_js(config_options = {})
@@ -22,25 +24,25 @@ module Wechat
22
24
  else
23
25
  controller.request.original_url
24
26
  end
25
- page_url = page_url.split('#').first if is_ios?
27
+ page_url = page_url.split('#').first if ios?
26
28
  js_hash = api.jsapi_ticket.signature(page_url)
27
29
 
28
- config_js = <<-WECHAT_CONFIG_JS
29
- wx.config({
30
- debug: #{config_options[:debug]},
31
- appId: "#{app_id}",
32
- timestamp: "#{js_hash[:timestamp]}",
33
- nonceStr: "#{js_hash[:noncestr]}",
34
- signature: "#{js_hash[:signature]}",
35
- jsApiList: ['#{config_options[:api].join("','")}']
36
- });
37
- WECHAT_CONFIG_JS
30
+ config_js = <<~WECHAT_CONFIG_JS
31
+ wx.config({
32
+ debug: #{config_options[:debug]},
33
+ appId: "#{app_id}",
34
+ timestamp: "#{js_hash[:timestamp]}",
35
+ nonceStr: "#{js_hash[:noncestr]}",
36
+ signature: "#{js_hash[:signature]}",
37
+ jsApiList: ['#{config_options[:api].join("','")}']
38
+ });
39
+ WECHAT_CONFIG_JS
38
40
  javascript_tag config_js, type: 'application/javascript'
39
41
  end
40
42
 
41
43
  private
42
44
 
43
- def is_ios?
45
+ def ios?
44
46
  controller.request.user_agent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
45
47
  end
46
48
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'http'
2
4
 
3
5
  module Wechat
@@ -35,10 +37,10 @@ module Wechat
35
37
  params = header.delete(:params)
36
38
  form_file = file.is_a?(HTTP::FormData::File) ? file : HTTP::FormData::File.new(file)
37
39
  httprb.headers(header)
38
- .post(url, params: params,
39
- form: { media: form_file,
40
- hack: 'X' }, # Existing here for http-form_data 1.0.1 handle single param improperly
41
- ssl_context: ssl_context)
40
+ .post(url, params: params,
41
+ form: { media: form_file,
42
+ hack: 'X' }, # Existing here for http-form_data 1.0.1 handle single param improperly
43
+ ssl_context: ssl_context)
42
44
  end
43
45
  end
44
46
 
@@ -51,6 +53,7 @@ module Wechat
51
53
  response = yield("#{url_base}#{path}", header)
52
54
 
53
55
  raise "Request not OK, response status #{response.status}" if response.status != 200
56
+
54
57
  parse_response(response, as || :json) do |parse_as, data|
55
58
  break data unless parse_as == :json && data['errcode'].present?
56
59
 
@@ -71,25 +74,27 @@ module Wechat
71
74
  end
72
75
  end
73
76
 
74
- def parse_response(response, as)
77
+ def parse_response(response, as_type)
75
78
  content_type = response.headers[:content_type]
76
79
  parse_as = {
77
80
  %r{^application\/json} => :json,
78
- %r{^image\/.*} => :file,
79
- %r{^audio\/.*} => :file,
80
- %r{^voice\/.*} => :file,
81
- %r{^text\/html} => :xml,
82
- %r{^text\/plain} => :probably_json
83
- }.each_with_object([]) { |match, memo| memo << match[1] if content_type =~ match[0] }.first || as || :text
81
+ %r{^image\/.*} => :file,
82
+ %r{^audio\/.*} => :file,
83
+ %r{^voice\/.*} => :file,
84
+ %r{^text\/html} => :xml,
85
+ %r{^text\/plain} => :probably_json
86
+ }.each_with_object([]) { |match, memo| memo << match[1] if content_type =~ match[0] }.first || as_type || :text
84
87
 
85
88
  # try to parse response as json, fallback to user-specified format or text if failed
86
89
  if parse_as == :probably_json
87
- data = JSON.parse response.body.to_s.gsub(/[\u0000-\u001f]+/, '') rescue nil
88
- if data
89
- return yield(:json, data)
90
- else
91
- parse_as = as || :text
90
+ begin
91
+ data = JSON.parse response.body.to_s.gsub(/[\u0000-\u001f]+/, '')
92
+ rescue StandardError
93
+ nil
92
94
  end
95
+ return yield(:json, data) if data
96
+
97
+ parse_as = as_type || :text
93
98
  end
94
99
 
95
100
  case parse_as
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  class Message
3
5
  class << self
@@ -70,6 +72,7 @@ module Wechat
70
72
 
71
73
  def session
72
74
  return nil unless Wechat.config.have_session_class
75
+
73
76
  @message_hash[:WechatSession] ||= WechatSession.find_or_initialize_session(underscore_hash_keys(message_hash))
74
77
  end
75
78
 
@@ -120,8 +123,8 @@ module Wechat
120
123
 
121
124
  def markdown(content)
122
125
  update(MsgType: 'markdown', Markdown: {
123
- content: content
124
- })
126
+ content: content
127
+ })
125
128
  end
126
129
 
127
130
  def transfer_customer_service(kf_account = nil)
@@ -207,25 +210,25 @@ module Wechat
207
210
  end
208
211
 
209
212
  TO_JSON_KEY_MAP = {
210
- 'TextCard' => 'textcard',
211
- 'Markdown' => 'markdown',
212
- 'ToUserName' => 'touser',
213
- 'ToPartyName' => 'toparty',
214
- 'ToWxName' => 'towxname',
215
- 'MediaId' => 'media_id',
216
- 'MpNews' => 'mpnews',
217
- 'ThumbMediaId' => 'thumb_media_id',
218
- 'TemplateId' => 'template_id',
219
- 'FormId' => 'form_id',
213
+ 'TextCard' => 'textcard',
214
+ 'Markdown' => 'markdown',
215
+ 'ToUserName' => 'touser',
216
+ 'ToPartyName' => 'toparty',
217
+ 'ToWxName' => 'towxname',
218
+ 'MediaId' => 'media_id',
219
+ 'MpNews' => 'mpnews',
220
+ 'ThumbMediaId' => 'thumb_media_id',
221
+ 'TemplateId' => 'template_id',
222
+ 'FormId' => 'form_id',
220
223
  'ContentSourceUrl' => 'content_source_url',
221
- 'ShowCoverPic' => 'show_cover_pic'
224
+ 'ShowCoverPic' => 'show_cover_pic'
222
225
  }.freeze
223
226
 
224
227
  TO_JSON_ALLOWED = %w[touser toparty msgtype content image voice video file textcard markdown
225
228
  music news articles template agentid filter
226
229
  send_ignore_reprint mpnews towxname].freeze
227
230
 
228
- def to_json
231
+ def to_json(*_args)
229
232
  keep_camel_case_key = message_hash[:MsgType] == 'template'
230
233
  json_hash = deep_recursive(message_hash) do |key, value|
231
234
  key = key.to_s
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'wechat/api_base'
2
4
  require 'wechat/http_client'
3
5
  require 'wechat/token/public_access_token'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'English'
2
4
  require 'wechat/signature'
3
5
 
@@ -19,12 +21,12 @@ module Wechat
19
21
  skip_before_action :verify_authenticity_token, raise: false
20
22
  end
21
23
 
22
- before_action :config_account, only: [:show, :create]
23
- before_action :verify_signature, only: [:show, :create]
24
+ before_action :config_account, only: %i[show create]
25
+ before_action :verify_signature, only: %i[show create]
24
26
  else
25
27
  skip_before_filter :verify_authenticity_token
26
- before_filter :config_account, only: [:show, :create]
27
- before_filter :verify_signature, only: [:show, :create]
28
+ before_filter :config_account, only: %i[show create]
29
+ before_filter :verify_signature, only: %i[show create]
28
30
  end
29
31
  end
30
32
 
@@ -32,22 +34,22 @@ module Wechat
32
34
  attr_accessor :account_from_request
33
35
 
34
36
  def on(message_type, with: nil, respond: nil, &block)
35
- raise 'Unknow message type' unless [:text, :image, :voice, :video, :shortvideo, :link, :event, :click, :view, :scan, :batch_job, :location, :label_location, :fallback].include?(message_type)
37
+ raise 'Unknow message type' unless %i[text image voice video shortvideo link event click view scan batch_job location label_location fallback].include?(message_type)
38
+
36
39
  config = respond.nil? ? {} : { respond: respond }
37
40
  config[:proc] = block if block_given?
38
41
 
39
42
  if with.present?
40
- raise 'Only text, event, click, view, scan and batch_job can having :with parameters' unless [:text, :event, :click, :view, :scan, :batch_job].include?(message_type)
43
+ raise 'Only text, event, click, view, scan and batch_job can having :with parameters' unless %i[text event click view scan batch_job].include?(message_type)
44
+
41
45
  config[:with] = with
42
46
  if message_type == :scan
43
- if with.is_a?(String)
44
- self.known_scan_key_lists = with
45
- else
46
- raise 'on :scan only support string in parameter with, detail see https://github.com/Eric-Guo/wechat/issues/84'
47
- end
47
+ raise 'on :scan only support string in parameter with, detail see https://github.com/Eric-Guo/wechat/issues/84' unless with.is_a?(String)
48
+
49
+ self.known_scan_key_lists = with
48
50
  end
49
- else
50
- raise 'Message type click, view, scan and batch_job must specify :with parameters' if [:click, :view, :scan, :batch_job].include?(message_type)
51
+ elsif %i[click view scan batch_job].include?(message_type)
52
+ raise 'Message type click, view, scan and batch_job must specify :with parameters'
51
53
  end
52
54
 
53
55
  case message_type
@@ -86,15 +88,15 @@ module Wechat
86
88
  end
87
89
 
88
90
  def user_defined_scan_responders
89
- @scan_responders ||= []
91
+ @user_defined_scan_responders ||= []
90
92
  end
91
93
 
92
94
  def user_defined_location_responders
93
- @location_responders ||= []
95
+ @user_defined_location_responders ||= []
94
96
  end
95
97
 
96
98
  def user_defined_label_location_responders
97
- @label_location_responders ||= []
99
+ @user_defined_label_location_responders ||= []
98
100
  end
99
101
 
100
102
  def user_defined_responders(type)
@@ -110,17 +112,17 @@ module Wechat
110
112
  when :text
111
113
  yield(* match_responders(responders, message[:Content]))
112
114
  when :event
113
- if 'click' == message[:Event] && !user_defined_click_responders(message[:EventKey]).empty?
115
+ if message[:Event] == 'click' && !user_defined_click_responders(message[:EventKey]).empty?
114
116
  yield(* user_defined_click_responders(message[:EventKey]), message[:EventKey])
115
- elsif 'view' == message[:Event] && !user_defined_view_responders(message[:EventKey]).empty?
117
+ elsif message[:Event] == 'view' && !user_defined_view_responders(message[:EventKey]).empty?
116
118
  yield(* user_defined_view_responders(message[:EventKey]), message[:EventKey])
117
- elsif 'click' == message[:Event]
119
+ elsif message[:Event] == 'click'
118
120
  yield(* match_responders(responders, message[:EventKey]))
119
- elsif known_scan_key_lists.include?(message[:EventKey]) && %w(scan subscribe scancode_push scancode_waitmsg).freeze.include?(message[:Event])
121
+ elsif known_scan_key_lists.include?(message[:EventKey]) && %w[scan subscribe scancode_push scancode_waitmsg].freeze.include?(message[:Event])
120
122
  yield(* known_scan_with_match_responders(user_defined_scan_responders, message))
121
- elsif 'batch_job_result' == message[:Event]
123
+ elsif message[:Event] == 'batch_job_result'
122
124
  yield(* user_defined_batch_job_responders(message[:BatchJob][:JobType]), message[:BatchJob])
123
- elsif 'location' == message[:Event]
125
+ elsif message[:Event] == 'location'
124
126
  yield(* user_defined_location_responders, message)
125
127
  else
126
128
  yield(* match_responders(responders, message[:Event]))
@@ -145,8 +147,8 @@ module Wechat
145
147
 
146
148
  if condition.is_a? Regexp
147
149
  memo[:scoped] ||= [responder] + $LAST_MATCH_INFO.captures if value =~ condition
148
- else
149
- memo[:scoped] ||= [responder, value] if value == condition
150
+ elsif value == condition
151
+ memo[:scoped] ||= [responder, value]
150
152
  end
151
153
  end
152
154
  matched[:scoped] || matched[:general]
@@ -154,9 +156,9 @@ module Wechat
154
156
 
155
157
  def known_scan_with_match_responders(responders, message)
156
158
  matched = responders.each_with_object({}) do |responder, memo|
157
- if %w(scan subscribe).freeze.include?(message[:Event]) && message[:EventKey] == responder[:with]
159
+ if %w[scan subscribe].freeze.include?(message[:Event]) && message[:EventKey] == responder[:with]
158
160
  memo[:scaned] ||= [responder, message[:Ticket]]
159
- elsif %w(scancode_push scancode_waitmsg).freeze.include?(message[:Event]) && message[:EventKey] == responder[:with]
161
+ elsif %w[scancode_push scancode_waitmsg].freeze.include?(message[:Event]) && message[:EventKey] == responder[:with]
160
162
  memo[:scaned] ||= [responder, message[:ScanCodeInfo][:ScanResult], message[:ScanCodeInfo][:ScanType]]
161
163
  end
162
164
  end
@@ -181,12 +183,10 @@ module Wechat
181
183
  else
182
184
  render text: echostr
183
185
  end
186
+ elsif Rails::VERSION::MAJOR >= 4
187
+ render plain: params[:echostr]
184
188
  else
185
- if Rails::VERSION::MAJOR >= 4
186
- render plain: params[:echostr]
187
- else
188
- render text: params[:echostr]
189
- end
189
+ render text: params[:echostr]
190
190
  end
191
191
  end
192
192
 
@@ -249,11 +249,11 @@ module Wechat
249
249
  if Rails::VERSION::MAJOR >= 5
250
250
  data_hash = data_hash.to_unsafe_hash if data_hash.instance_of?(ActionController::Parameters)
251
251
  HashWithIndifferentAccess.new(data_hash).tap do |msg|
252
- msg[:Event].downcase! if msg[:Event]
252
+ msg[:Event]&.downcase!
253
253
  end
254
254
  else
255
255
  HashWithIndifferentAccess.new_from_hash_copying_default(data_hash).tap do |msg|
256
- msg[:Event].downcase! if msg[:Event]
256
+ msg[:Event]&.downcase!
257
257
  end
258
258
  end
259
259
  end
@@ -263,10 +263,10 @@ module Wechat
263
263
  responder ||= self.class.user_defined_responders(:fallback).first
264
264
 
265
265
  next if responder.nil?
266
- case
267
- when responder[:respond]
266
+
267
+ if responder[:respond]
268
268
  request.reply.text responder[:respond]
269
- when responder[:proc]
269
+ elsif responder[:proc]
270
270
  define_singleton_method :process, responder[:proc]
271
271
  number_of_block_parameter = responder[:proc].arity
272
272
  send(:process, *args.unshift(request).take(number_of_block_parameter))
@@ -293,8 +293,7 @@ module Wechat
293
293
  { Encrypt: encrypt,
294
294
  MsgSignature: msg_sign,
295
295
  TimeStamp: timestamp,
296
- Nonce: nonce
297
- }.to_xml(root: 'xml', children: 'item', skip_instruct: true, skip_types: true)
296
+ Nonce: nonce }.to_xml(root: 'xml', children: 'item', skip_instruct: true, skip_types: true)
298
297
  end
299
298
 
300
299
  def request_encrypt_content
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  module Signature
3
5
  def self.hexdigest(token, timestamp, nonce, msg_encrypt)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'wechat/ticket/jsapi_base'
2
4
 
3
5
  module Wechat
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'digest/sha1'
2
4
  require 'securerandom'
3
5
 
@@ -63,8 +65,8 @@ module Wechat
63
65
  end
64
66
 
65
67
  def write_ticket_to_store(ticket_hash)
66
- ticket_hash['got_ticket_at'.freeze] = Time.now.to_i
67
- ticket_hash['ticket_expires_in'.freeze] = ticket_hash.delete('expires_in')
68
+ ticket_hash['got_ticket_at'] = Time.now.to_i
69
+ ticket_hash['ticket_expires_in'] = ticket_hash.delete('expires_in')
68
70
  write_ticket(ticket_hash)
69
71
  end
70
72
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'wechat/ticket/jsapi_base'
2
4
 
3
5
  module Wechat
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wechat
2
4
  module Token
3
5
  class AccessTokenBase
@@ -32,8 +34,8 @@ module Wechat
32
34
  def write_token_to_store(token_hash)
33
35
  raise InvalidCredentialError unless token_hash.is_a?(Hash) && token_hash['access_token']
34
36
 
35
- token_hash['got_token_at'.freeze] = Time.now.to_i
36
- token_hash['token_expires_in'.freeze] = token_hash.delete('expires_in')
37
+ token_hash['got_token_at'] = Time.now.to_i
38
+ token_hash['token_expires_in'] = token_hash.delete('expires_in')
37
39
  write_token(token_hash)
38
40
  end
39
41
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'wechat/token/access_token_base'
2
4
 
3
5
  module Wechat
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'wechat/token/access_token_base'
2
4
 
3
5
  module Wechat
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.4
4
+ version: 0.11.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Skinnyworm
@@ -12,30 +12,30 @@ cert_chain:
12
12
  - |
13
13
  -----BEGIN CERTIFICATE-----
14
14
  MIIEQDCCAqigAwIBAgIBATANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBplcmlj
15
- Lmd1b2N6L0RDPWdtYWlsL0RDPWNvbTAeFw0xODA4MjcxMDM0MjBaFw0xOTA4Mjcx
16
- MDM0MjBaMCUxIzAhBgNVBAMMGmVyaWMuZ3VvY3ovREM9Z21haWwvREM9Y29tMIIB
17
- ojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvvuL8SAQjsNR1ij4IEo3u63M
18
- OST173hPCWPwvznHnDsphHMPY9erDkWWMC4Rx9Rq0mfQoONIbr7hgVMO2+ixsMuC
19
- c/sW8X3GY0WxiqCOXP7hIPycboRsb+h+dbbrzOGGsdN7jp8GQVlse75kDulGm2tz
20
- c+2uzj7qx+kAvlX1M+gAtoXwBte0BNYmqszOaHNxoiAd4MiTwxvhxmVrpd6V+oP1
21
- tNbZRQxRjDj3gJn/kV4qYQYUt5S7p7fIAnZ7JZicXsiffMSQGNcwijeMOQVyppl/
22
- DrRNnRkZLn5yge2oclPZetbeTOGMTURv5ktuykCqSlydq3+bC7uLzPTHFM9882y4
23
- +xcmWO3Ho9voGn3XtGKB5yJ+eUYTQ/Tm7bAICgi9R/0NFG01riq3RyFTFrCqmXgl
24
- PC6yn7KpelWPKRQ6oKu4vweUjgZlHa3eyAgQwTcVfS4ZOM1qXgsRtVHzUlSkiZt0
25
- 5Rp973RN1w5ZYmC9X4IqvazoWZq+uw/Tnp4bEZwRAgMBAAGjezB5MAkGA1UdEwQC
26
- MAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQGmgb/xHA1sOvdHsW8OZ0ID7cR3jAf
15
+ Lmd1b2N6L0RDPWdtYWlsL0RDPWNvbTAeFw0xOTA4MzAwODIzMTVaFw0yMDA4Mjkw
16
+ ODIzMTVaMCUxIzAhBgNVBAMMGmVyaWMuZ3VvY3ovREM9Z21haWwvREM9Y29tMIIB
17
+ ojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA2ZlFyUImo53jN4+1Kk6cyGts
18
+ LcT2x+i3G4mvZeqrZFCyhgWHJ04oAsfKBLCLRmspRsUuDQ3GQ8P5tH9oTduu55qy
19
+ ohflwuuffJHwsJYJEQ4hykJSCQ8gd4qj8WrhAmNo15ujq6mjGXPRBtZltR142kKE
20
+ o1tUYtc4Fr3oIAh65m62ZC2kJ5GATLYQ+U3JiiHWga8iJ8KSHbrzhM4N3ppaeYxD
21
+ wk6Lwk2OyppO9Iiv9Ad2BEFFd2s7mvYtaMGPWYK2fYTUuq6yKupg3CppX3ttq+bN
22
+ Ejx6dXn4RwYmATfc/Iv4aVU8lZS9HABqmProgkmi5vE2AAW1rQihm2ACm9VGlX+B
23
+ J2uIIWFJC56+TmkyqcBM87ztRxFlNLJe1G2S2TZ/qhAyWfoSEDA9eW6OUsb6qvnz
24
+ PHFPo/Vgq9BEoYMItUsEoJHdmLBjzhiccQx2XWAhZrBREpH20jIC/ereVGRpAeVf
25
+ kYdFgW84K+lL9XTt9QJNM08YM/mFcpaGq4/2YbbLAgMBAAGjezB5MAkGA1UdEwQC
26
+ MAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQdvlZDewUSWN/OWf9bTuDHHc5r+TAf
27
27
  BgNVHREEGDAWgRRlcmljLmd1b2N6QGdtYWlsLmNvbTAfBgNVHRIEGDAWgRRlcmlj
28
- Lmd1b2N6QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEAp7iNDlqk1L5zrTmD
29
- E0QAEYo0wiKZ/x29kaXuG3j0hUkkwKFbhUHjsTEl307sO8yQRg/6DuVrQhUBwS9G
30
- g749ybsn7pfOL+lCVUGGxWFJ8qsICQ4ECjtnKVXdQowDUzSeb5/IPaeN+RB4Rh7D
31
- 2msnkJhsf0IQbNNUt53tkE5KhwAkHGdY5solSLPwtUmmdW1kNt7OfGBTi5CjXwFg
32
- Jh+lbxasy+KwHA6+9O5b8Qm2QSBN5bJGd2a63QE5p8cjRBnaRuiKn4wkmqMj/C0Z
33
- OyM5lSs5iGML+eVE/dCsV+YFmSr6Ue8vokmKdrBDjtAkHwmVA0TpqHVmT+9bVUPn
34
- Jl+EzvEfsjriqcj9+WGPo4R7XDQQnseHqzlXNedkrLFX/nTnEs5RKBZ6Ter1KRU6
35
- ivoox98/nhOs6bHcSFPsxXdxUihcCfCzj+zcaHNEqpvTI/36Bnl2XW6dUJNaFQDc
36
- oWOyq5ZkxqnYrYXactjW0+vcPv6WHoHXmjv4dF7iFp8r0mvK
28
+ Lmd1b2N6QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEAkS8q1uex/jWTHtYi
29
+ 6Rgv8hZugwpFCwGPb9i4VgSSA1qkfsFhNxQji1xcpo8hYlH6zW9L6CGC9BU4n9R2
30
+ iyuuvtHVnxt5i6u39fIw0dIHJdtswSXZ6Kq58RP1Lg1nbmXX0zHz1fXp+DXL7NoJ
31
+ bBHL9Oy6jps/Lz8fIanPIZ6iT/akA7Mts94v1F9dyeA3IIJVptvmuGFC9PexX4TJ
32
+ fZ/qmk93C6KEOGEQ0zJzjnKjRZT0KOnJxbpB6/4Xvr+SrTb0yx20s+YWWa28pb0C
33
+ gNr4HHRfhmqxoTKvM4Mm9oJSBO/ENi5zfLwvwOWRuriMuDGYmKCdwmn4Y9asgYS4
34
+ 2febpVoh2LTA7GDc1VJOKhxisQ2OtYpcTR503eGyIrnS4NGs+B0rXOB7pEX+VOju
35
+ 2Gz/SZ1dgCkJpJU45GNrhatKx3kyg8eC5IHekNrEvJNJqPl0VdRIs/GtUkQyk+np
36
+ 3kTPkfLMsAZznXo3bzMe0V5TB4+a7pFEK1nN/htWrOVkIi/3
37
37
  -----END CERTIFICATE-----
38
- date: 2019-08-15 00:00:00.000000000 Z
38
+ date: 2019-08-30 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: activesupport
@@ -46,7 +46,7 @@ dependencies:
46
46
  version: '3.2'
47
47
  - - "<"
48
48
  - !ruby/object:Gem::Version
49
- version: '6'
49
+ version: '7'
50
50
  type: :runtime
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
@@ -56,7 +56,7 @@ dependencies:
56
56
  version: '3.2'
57
57
  - - "<"
58
58
  - !ruby/object:Gem::Version
59
- version: '6'
59
+ version: '7'
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: http
62
62
  requirement: !ruby/object:Gem::Requirement
@@ -105,6 +105,20 @@ dependencies:
105
105
  - - ">="
106
106
  - !ruby/object:Gem::Version
107
107
  version: '0'
108
+ - !ruby/object:Gem::Dependency
109
+ name: rubocop
110
+ requirement: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: '0.74'
115
+ type: :development
116
+ prerelease: false
117
+ version_requirements: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: '0.74'
108
122
  - !ruby/object:Gem::Dependency
109
123
  name: rails
110
124
  requirement: !ruby/object:Gem::Requirement
@@ -139,14 +153,14 @@ dependencies:
139
153
  requirements:
140
154
  - - "~>"
141
155
  - !ruby/object:Gem::Version
142
- version: 1.3.13
156
+ version: '1.4'
143
157
  type: :development
144
158
  prerelease: false
145
159
  version_requirements: !ruby/object:Gem::Requirement
146
160
  requirements:
147
161
  - - "~>"
148
162
  - !ruby/object:Gem::Version
149
- version: 1.3.13
163
+ version: '1.4'
150
164
  description: API, command and message handling for WeChat in Rails
151
165
  email: eric.guocz@gmail.com
152
166
  executables:
@@ -214,7 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
214
228
  - !ruby/object:Gem::Version
215
229
  version: '0'
216
230
  requirements: []
217
- rubygems_version: 3.0.4
231
+ rubygems_version: 3.0.6
218
232
  signing_key:
219
233
  specification_version: 4
220
234
  summary: DSL for wechat message handling and API
metadata.gz.sig CHANGED
Binary file