wechat 1.0.0 → 1.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c59986fcf04aecd798a52b731fb9dfbe5cf145198defa76dfcb73351a8b2096
4
- data.tar.gz: b4c2bd303e624cadd77537642f74e913d566d5dcc30eca97d5616807b70dd696
3
+ metadata.gz: 8d81118b4e78b92ca291b74b4040ac07d36c3c3bf5c433c583e247262a564598
4
+ data.tar.gz: 134affd462f41d996fa4cf30eb1787e3f682283ccf95b1eebd83b2ce63fdedd3
5
5
  SHA512:
6
- metadata.gz: 44916ab7ae7f8881d7d8c6e9b5f92165e253530f6d4a0dee020fe2e6af677ba1e551cbaed437fef6787b8da9fa33ef206a98fd1226bab1290090650a72b96746
7
- data.tar.gz: 552eef6ce3131be319c5aa5a68e0eecb775f74e036f90b8287c3c8995992ee0525d265c787430aa210a673e2330387b6fb145d429b79c1fd4963fe85b0c47c1c
6
+ metadata.gz: a73a0946f5e5451f731699f58c37133745a5403428cc74bccdd00006c0bff2ee935afc34d3bc4ac3f282c7fe3b59b21758b432e7d53d629adb3d6d94de3bc47a
7
+ data.tar.gz: 6a552e883d2218c46558c9f72eba7113c54f3019691c4c9874884244425958ede2487079f8ae671794bb5d5f0e2a8efd5ee4ba98afa6dcbc3cd9ce6f97bee20e
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.1.0 (released at 2025-11-24)
4
+
5
+ * Feat: api wxa_get_user_risk_rank. by @leepood #327
6
+
7
+ ## v1.0.1 (released at 2025-07-09)
8
+
9
+ * Fix after introduce httpx, status method not available for HTTPX::ErrorResponse bug
10
+ * Some Google Jules Refactor
3
11
 
4
12
  ## v1.0.0 (released at 2025-05-17)
5
13
 
data/README-CN.md CHANGED
@@ -1,4 +1,4 @@
1
- WeChat [![Gem Version](https://badge.fury.io/rb/wechat.svg)](https://rubygems.org/gems/wechat) [![Build Status](https://mixtint.semaphoreci.com/badges/wechat/branches/main.svg?style=shields)](https://mixtint.semaphoreci.com/projects/wechat) [![Maintainability](https://api.codeclimate.com/v1/badges/12885358487c13e91e00/maintainability)](https://codeclimate.com/github/Eric-Guo/wechat/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/12885358487c13e91e00/test_coverage)](https://codeclimate.com/github/Eric-Guo/wechat/test_coverage)
1
+ WeChat [![Gem Version](https://badge.fury.io/rb/wechat.svg)](https://rubygems.org/gems/wechat) [![Build Status](https://mixtint.semaphoreci.com/badges/wechat/branches/main.svg?style=shields)](https://mixtint.semaphoreci.com/projects/wechat)[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Eric-Guo/wechat)
2
2
  ======
3
3
 
4
4
  [![Join the chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Eric-Guo/wechat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- WeChat [![Gem Version](https://badge.fury.io/rb/wechat.svg)](https://rubygems.org/gems/wechat) [![Build Status](https://mixtint.semaphoreci.com/badges/wechat/branches/main.svg?style=shields)](https://mixtint.semaphoreci.com/projects/wechat) [![Maintainability](https://api.codeclimate.com/v1/badges/12885358487c13e91e00/maintainability)](https://codeclimate.com/github/Eric-Guo/wechat/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/12885358487c13e91e00/test_coverage)](https://codeclimate.com/github/Eric-Guo/wechat/test_coverage)
1
+ WeChat [![Gem Version](https://badge.fury.io/rb/wechat.svg)](https://rubygems.org/gems/wechat) [![Build Status](https://mixtint.semaphoreci.com/badges/wechat/branches/main.svg?style=shields)](https://mixtint.semaphoreci.com/projects/wechat)[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Eric-Guo/wechat)
2
2
  ======
3
3
 
4
4
  [![Join the chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Eric-Guo/wechat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -4,6 +4,7 @@ module ActionController
4
4
  module WechatResponder
5
5
  def wechat_api(opts = {})
6
6
  include Wechat::ControllerApi
7
+
7
8
  account = opts.delete(:account)
8
9
  self.wechat_cfg_account = account ? account.to_sym : :default
9
10
  self.wechat_api_client = load_controller_wechat(wechat_cfg_account, opts)
@@ -11,6 +12,7 @@ module ActionController
11
12
 
12
13
  def wechat_responder(opts = {})
13
14
  include Wechat::Responder
15
+
14
16
  account = opts.delete(:account)
15
17
  self.account_from_request = opts.delete(:account_from_request)
16
18
  self.wechat_cfg_account = account ? account.to_sym : :default
@@ -56,17 +58,19 @@ module ActionController
56
58
  secret = corpid.present? ? opts[:corpsecret] || cfg.corpsecret : opts[:secret] || cfg.secret
57
59
 
58
60
  network_setting = Wechat::NetworkSetting.new(timeout, skip_verify_ssl, proxy_url, proxy_username, proxy_password)
61
+ # access_token is token_file, jsapi_ticket is jsapi_ticket_file
62
+ api_config = Wechat::ApiConfig.new(corpid.presence || appid, secret, access_token, jsapi_ticket, network_setting)
59
63
  qcloud_setting = Wechat::Qcloud::Setting.new(qcloud_env, qcloud_token, qcloud_token_lifespan)
60
- get_wechat_api(api_type, corpid, appid, secret, access_token, agentid, network_setting, jsapi_ticket, qcloud_setting)
64
+ get_wechat_api(api_type, api_config, agentid, qcloud_setting)
61
65
  end
62
66
 
63
- def get_wechat_api(api_type, corpid, appid, secret, access_token, agentid, network_setting, jsapi_ticket, qcloud_setting)
67
+ def get_wechat_api(api_type, api_config, agentid, qcloud_setting)
64
68
  if api_type && api_type.to_sym == :mp
65
- Wechat::MpApi.new(appid, secret, access_token, network_setting, jsapi_ticket, qcloud_setting)
66
- elsif corpid.present?
67
- Wechat::CorpApi.new(corpid, secret, access_token, agentid, network_setting, jsapi_ticket)
69
+ Wechat::MpApi.new(api_config, qcloud_setting)
70
+ elsif api_config.appid.present? && agentid.present? # Assuming corpid is now in api_config.appid for CorpApi
71
+ Wechat::CorpApi.new(api_config, agentid)
68
72
  else
69
- Wechat::Api.new(appid, secret, access_token, network_setting, jsapi_ticket)
73
+ Wechat::Api.new(api_config)
70
74
  end
71
75
  end
72
76
  end
data/lib/wechat/api.rb CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  module Wechat
4
4
  class Api < ApiBase
5
- def initialize(appid, secret, token_file, network_setting, jsapi_ticket_file, record = nil)
5
+ def initialize(api_config, record = nil)
6
6
  super()
7
- @client = HttpClient.new(Wechat::Api::API_BASE, network_setting)
8
- @access_token = Token::PublicAccessToken.new(@client, appid, secret, token_file, record)
9
- @jsapi_ticket = Ticket::PublicJsapiTicket.new(@client, @access_token, jsapi_ticket_file)
7
+ @client = HttpClient.new(Wechat::Api::API_BASE, api_config.network_setting)
8
+ @access_token = Token::PublicAccessToken.new(@client, api_config.appid, api_config.secret, api_config.token_file, record)
9
+ @jsapi_ticket = Ticket::PublicJsapiTicket.new(@client, @access_token, api_config.jsapi_ticket_file)
10
10
  @qcloud = nil
11
11
  end
12
12
 
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wechat
4
+ class ApiConfig
5
+ attr_reader :appid, :secret, :token_file, :jsapi_ticket_file, :network_setting
6
+
7
+ def initialize(appid, secret, token_file, jsapi_ticket_file, network_setting)
8
+ @appid = appid
9
+ @secret = secret
10
+ @token_file = token_file
11
+ @jsapi_ticket_file = jsapi_ticket_file
12
+ @network_setting = network_setting
13
+ end
14
+ end
15
+ end
@@ -13,20 +13,25 @@ module Wechat
13
13
  type = options[:type] || c.type
14
14
 
15
15
  network_setting = Wechat::NetworkSetting.new(c.timeout, c.skip_verify_ssl, c.proxy_url, c.proxy_username, c.proxy_password)
16
- if c.appid && c.secret && token_file.present?
17
- if type == 'mp'
18
- qcloud_env = options[:qcloud_env] || c.qcloud_env
19
- qcloud_token_file = options[:qcloud_token_file] || c.qcloud_token_file.presence || '/var/tmp/qcloud_access_token'
20
- qcloud_token_lifespan = options[:qcloud_token_lifespan] || c.qcloud_token_lifespan
21
- qcloud_setting = Wechat::Qcloud::Setting.new(qcloud_env, qcloud_token_file, qcloud_token_lifespan)
22
- Wechat::MpApi.new(c.appid, c.secret, token_file, network_setting, js_token_file, qcloud_setting)
23
- else
24
- Wechat::Api.new(c.appid, c.secret, token_file, network_setting, js_token_file)
25
- end
26
- elsif c.corpid && c.corpsecret && token_file.present?
27
- Wechat::CorpApi.new(c.corpid, c.corpsecret, token_file, c.agentid, network_setting, js_token_file)
28
- else
29
- raise 'Need create ~/.wechat.yml with wechat appid and secret or running at rails root folder so wechat can read config/wechat.yml'
16
+
17
+ current_appid = c.corpid.presence || c.appid
18
+ current_secret = c.corpsecret.presence || c.secret
19
+
20
+ unless current_appid && current_secret && token_file.present?
21
+ raise 'Need create ~/.wechat.yml with wechat appid and secret or corpid and corpsecret, or running at rails root folder so wechat can read config/wechat.yml'
22
+ end
23
+
24
+ api_config = Wechat::ApiConfig.new(current_appid, current_secret, token_file, js_token_file, network_setting)
25
+ if type == 'mp'
26
+ qcloud_env = options[:qcloud_env] || c.qcloud_env
27
+ qcloud_token_file = options[:qcloud_token_file] || c.qcloud_token_file.presence || '/var/tmp/qcloud_access_token'
28
+ qcloud_token_lifespan = options[:qcloud_token_lifespan] || c.qcloud_token_lifespan
29
+ qcloud_setting = Wechat::Qcloud::Setting.new(qcloud_env, qcloud_token_file, qcloud_token_lifespan)
30
+ Wechat::MpApi.new(api_config, qcloud_setting)
31
+ elsif c.corpid.present? # CorpApi needs agentid
32
+ Wechat::CorpApi.new(api_config, c.agentid)
33
+ else # Regular Public Api
34
+ Wechat::Api.new(api_config)
30
35
  end
31
36
  end
32
37
 
@@ -93,6 +93,12 @@ module Wechat
93
93
  post 'business/getuserphonenumber', JSON.generate(code: code), base: Wechat::Api::WXA_BASE
94
94
  end
95
95
 
96
+ def wxa_get_user_risk_rank(openid, scene, **payload)
97
+ # https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/sec-center/safety-control-capability/getUserRiskRank.html
98
+ request_body = { appid: access_token.appid, openid: openid, scene: scene }.merge(payload)
99
+ post 'getuserriskrank', JSON.generate(request_body), base: Wechat::Api::WXA_BASE
100
+ end
101
+
96
102
  def wxa_get_wxacode(path, width = 430)
97
103
  post 'getwxacode', JSON.generate(path: path, width: width), base: Wechat::Api::WXA_BASE
98
104
  end
@@ -158,7 +164,7 @@ module Wechat
158
164
 
159
165
  def material_add(type, file, opts = {})
160
166
  params = { type: type }
161
- params.merge!(description: opts.slice(:title, :introduction).to_json) if type == 'video'
167
+ params[:description] = opts.slice(:title, :introduction).to_json if type == 'video'
162
168
 
163
169
  post_file 'material/add_material', file, params: params
164
170
  end
@@ -4,12 +4,12 @@ module Wechat
4
4
  class CorpApi < ApiBase
5
5
  attr_reader :agentid
6
6
 
7
- def initialize(appid, secret, token_file, agentid, network_setting, jsapi_ticket_file)
7
+ def initialize(api_config, agentid)
8
8
  super()
9
- @client = HttpClient.new(QYAPI_BASE, network_setting)
10
- @access_token = Token::CorpAccessToken.new(@client, appid, secret, token_file)
9
+ @client = HttpClient.new(QYAPI_BASE, api_config.network_setting)
10
+ @access_token = Token::CorpAccessToken.new(@client, api_config.appid, api_config.secret, api_config.token_file)
11
11
  @agentid = agentid
12
- @jsapi_ticket = Ticket::CorpJsapiTicket.new(@client, @access_token, jsapi_ticket_file)
12
+ @jsapi_ticket = Ticket::CorpJsapiTicket.new(@client, @access_token, api_config.jsapi_ticket_file)
13
13
  @qcloud = nil
14
14
  end
15
15
 
@@ -55,7 +55,18 @@ module Wechat
55
55
  header['Accept'] ||= 'application/json'
56
56
  response = yield("#{url_base}#{path}", header)
57
57
 
58
- raise "Request not OK, response status #{response.status}" if response.status != 200
58
+ # Error responses (network failures, DNS errors, etc.) are returned as
59
+ # `HTTPX::ErrorResponse` objects which **do not** implement `#status`.
60
+ # Attempting to access that method would raise a `NoMethodError`.
61
+ # Instead, surface the underlying error immediately so that callers can
62
+ # handle it using the existing error-handling flow.
63
+ if defined?(HTTPX::ErrorResponse) && response.is_a?(HTTPX::ErrorResponse)
64
+ # `response.error` returns the wrapped exception (e.g. Errno::ECONNREFUSED)
65
+ # Fallback to raising the response itself if no wrapped error exists.
66
+ raise(response.error || StandardError.new(response.inspect))
67
+ end
68
+
69
+ raise "Request not OK, response #{response}" if response.respond_to?(:status) && response.status != 200
59
70
 
60
71
  parse_response(response, as || :json) do |parse_as, data|
61
72
  break data unless parse_as == :json && data['errcode'].present?
@@ -9,16 +9,16 @@ module Wechat
9
9
 
10
10
  def to(to_users = '', towxname: nil, send_ignore_reprint: 0)
11
11
  if towxname.present?
12
- new(ToWxName: towxname, CreateTime: Time.now.to_i)
12
+ new(ToWxName: towxname, CreateTime: Time.zone.now.to_i)
13
13
  elsif send_ignore_reprint == 1
14
- new(ToUserName: to_users, CreateTime: Time.now.to_i, send_ignore_reprint: send_ignore_reprint)
14
+ new(ToUserName: to_users, CreateTime: Time.zone.now.to_i, send_ignore_reprint: send_ignore_reprint)
15
15
  else
16
- new(ToUserName: to_users, CreateTime: Time.now.to_i)
16
+ new(ToUserName: to_users, CreateTime: Time.zone.now.to_i)
17
17
  end
18
18
  end
19
19
 
20
20
  def to_party(party)
21
- new(ToPartyName: party, CreateTime: Time.now.to_i)
21
+ new(ToPartyName: party, CreateTime: Time.zone.now.to_i)
22
22
  end
23
23
 
24
24
  def to_mass(tag_id: nil, send_ignore_reprint: 0)
@@ -65,7 +65,7 @@ module Wechat
65
65
  Message.new(
66
66
  ToUserName: message_hash[:FromUserName],
67
67
  FromUserName: message_hash[:ToUserName],
68
- CreateTime: Time.now.to_i,
68
+ CreateTime: Time.zone.now.to_i,
69
69
  WechatSession: session
70
70
  )
71
71
  end
@@ -239,7 +239,13 @@ module Wechat
239
239
  [TO_JSON_KEY_MAP[key] || (keep_camel_case_key ? key : key.downcase), value]
240
240
  end
241
241
  json_hash = json_hash.transform_keys(&:downcase).slice(*TO_JSON_ALLOWED)
242
+ json_hash = transform_json_hash_by_msgtype(json_hash)
243
+ JSON.generate(json_hash)
244
+ end
245
+
246
+ private
242
247
 
248
+ def transform_json_hash_by_msgtype(json_hash)
243
249
  case json_hash['msgtype']
244
250
  when 'text'
245
251
  json_hash['text'] = { 'content' => json_hash.delete('content') }
@@ -255,7 +261,7 @@ module Wechat
255
261
  when 'template'
256
262
  json_hash = { 'touser' => json_hash['touser'] }.merge!(json_hash['template'])
257
263
  end
258
- JSON.generate(json_hash)
264
+ json_hash
259
265
  end
260
266
 
261
267
  def save_to!(model_class)
@@ -264,8 +270,6 @@ module Wechat
264
270
  self
265
271
  end
266
272
 
267
- private
268
-
269
273
  def camelize_hash_keys(hash)
270
274
  deep_recursive(hash) { |key, value| [key.to_s.camelize.to_sym, value] }
271
275
  end
data/lib/wechat/mp_api.rb CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  module Wechat
4
4
  class MpApi < ApiBase
5
- def initialize(appid, secret, token_file, network_setting, jsapi_ticket_file, qcloud_setting)
5
+ def initialize(api_config, qcloud_setting)
6
6
  super()
7
- @client = HttpClient.new(Wechat::Api::API_BASE, network_setting)
8
- @access_token = Token::PublicAccessToken.new(@client, appid, secret, token_file)
9
- @jsapi_ticket = Ticket::PublicJsapiTicket.new(@client, @access_token, jsapi_ticket_file)
7
+ @client = HttpClient.new(Wechat::Api::API_BASE, api_config.network_setting)
8
+ @access_token = Token::PublicAccessToken.new(@client, api_config.appid, api_config.secret, api_config.token_file)
9
+ @jsapi_ticket = Ticket::PublicJsapiTicket.new(@client, @access_token, api_config.jsapi_ticket_file)
10
10
  @qcloud = Qcloud::Token.new(@client, @access_token, qcloud_setting)
11
11
  end
12
12
 
@@ -59,7 +59,7 @@ module Wechat
59
59
  end
60
60
 
61
61
  def remain_life_seconds
62
- qcloud_token_expired_time - Time.now.to_i
62
+ qcloud_token_expired_time - Time.zone.now.to_i
63
63
  end
64
64
  end
65
65
  end
@@ -41,7 +41,7 @@ module Wechat
41
41
  def signature(url)
42
42
  params = {
43
43
  noncestr: SecureRandom.base64(16),
44
- timestamp: Time.now.to_i,
44
+ timestamp: Time.zone.now.to_i,
45
45
  jsapi_ticket: ticket,
46
46
  url: url
47
47
  }
@@ -65,7 +65,7 @@ module Wechat
65
65
  end
66
66
 
67
67
  def write_ticket_to_store(ticket_hash)
68
- ticket_hash['got_ticket_at'] = Time.now.to_i
68
+ ticket_hash['got_ticket_at'] = Time.zone.now.to_i
69
69
  ticket_hash['ticket_expires_in'] = ticket_hash.delete('expires_in')
70
70
  write_ticket(ticket_hash)
71
71
  end
@@ -79,7 +79,7 @@ module Wechat
79
79
  end
80
80
 
81
81
  def remain_life_seconds
82
- ticket_life_in_seconds - (Time.now.to_i - got_ticket_at)
82
+ ticket_life_in_seconds - (Time.zone.now.to_i - got_ticket_at)
83
83
  end
84
84
  end
85
85
  end
@@ -35,7 +35,7 @@ module Wechat
35
35
  def write_token_to_store(token_hash)
36
36
  raise InvalidCredentialError unless token_hash.is_a?(Hash) && token_hash['access_token']
37
37
 
38
- token_hash['got_token_at'] = Time.now.to_i
38
+ token_hash['got_token_at'] = Time.zone.now.to_i
39
39
  token_hash['token_expires_in'] = token_hash.delete('expires_in')
40
40
  write_token(token_hash)
41
41
  end
@@ -63,7 +63,7 @@ module Wechat
63
63
  end
64
64
 
65
65
  def remain_life_seconds
66
- token_life_in_seconds - (Time.now.to_i - got_token_at)
66
+ token_life_in_seconds - (Time.zone.now.to_i - got_token_at)
67
67
  end
68
68
 
69
69
  private
@@ -77,7 +77,7 @@ module Wechat
77
77
 
78
78
  record.access_token = token_hash['access_token']
79
79
  record.token_expires_in = token_hash['token_expires_in']
80
- record.got_token_at = Time.now
80
+ record.got_token_at = Time.zone.now
81
81
  record.save || record.save(validate: false)
82
82
  end
83
83
 
data.tar.gz.sig CHANGED
Binary file
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: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Skinnyworm
@@ -147,14 +147,14 @@ dependencies:
147
147
  requirements:
148
148
  - - "~>"
149
149
  - !ruby/object:Gem::Version
150
- version: 1.72.2
150
+ version: 1.81.7
151
151
  type: :development
152
152
  prerelease: false
153
153
  version_requirements: !ruby/object:Gem::Requirement
154
154
  requirements:
155
155
  - - "~>"
156
156
  - !ruby/object:Gem::Version
157
- version: 1.72.2
157
+ version: 1.81.7
158
158
  - !ruby/object:Gem::Dependency
159
159
  name: rails
160
160
  requirement: !ruby/object:Gem::Requirement
@@ -175,14 +175,14 @@ dependencies:
175
175
  requirements:
176
176
  - - "~>"
177
177
  - !ruby/object:Gem::Version
178
- version: '7.1'
178
+ version: '8.0'
179
179
  type: :development
180
180
  prerelease: false
181
181
  version_requirements: !ruby/object:Gem::Requirement
182
182
  requirements:
183
183
  - - "~>"
184
184
  - !ruby/object:Gem::Version
185
- version: '7.1'
185
+ version: '8.0'
186
186
  - !ruby/object:Gem::Dependency
187
187
  name: rspec-mocks
188
188
  requirement: !ruby/object:Gem::Requirement
@@ -242,6 +242,7 @@ files:
242
242
  - lib/wechat.rb
243
243
  - lib/wechat/api.rb
244
244
  - lib/wechat/api_base.rb
245
+ - lib/wechat/api_config.rb
245
246
  - lib/wechat/api_loader.rb
246
247
  - lib/wechat/cipher.rb
247
248
  - lib/wechat/concern/common.rb
@@ -270,8 +271,8 @@ licenses:
270
271
  metadata:
271
272
  bug_tracker_uri: https://github.com/Eric-Guo/wechat/issues
272
273
  changelog_uri: https://github.com/Eric-Guo/wechat/releases
273
- documentation_uri: https://github.com/Eric-Guo/wechat/tree/v1.0.0#readme
274
- source_code_uri: https://github.com/Eric-Guo/wechat/tree/v1.0.0
274
+ documentation_uri: https://github.com/Eric-Guo/wechat/tree/v1.1.0#readme
275
+ source_code_uri: https://github.com/Eric-Guo/wechat/tree/v1.1.0
275
276
  rubygems_mfa_required: 'true'
276
277
  post_install_message: |2
277
278
 
@@ -290,7 +291,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
290
291
  - !ruby/object:Gem::Version
291
292
  version: 3.1.6
292
293
  requirements: []
293
- rubygems_version: 3.6.9
294
+ rubygems_version: 3.7.2
294
295
  specification_version: 4
295
296
  summary: DSL for wechat message handling and API
296
297
  test_files: []
metadata.gz.sig CHANGED
Binary file