wechat 1.0.0 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c59986fcf04aecd798a52b731fb9dfbe5cf145198defa76dfcb73351a8b2096
4
- data.tar.gz: b4c2bd303e624cadd77537642f74e913d566d5dcc30eca97d5616807b70dd696
3
+ metadata.gz: 8862a096490e208b18609027a14e80d12b386dcd86094065e4412856012ec3db
4
+ data.tar.gz: a71e7b18973fab14ff351b04e840c534ea6229ff59c98d0cc2deee93587237ed
5
5
  SHA512:
6
- metadata.gz: 44916ab7ae7f8881d7d8c6e9b5f92165e253530f6d4a0dee020fe2e6af677ba1e551cbaed437fef6787b8da9fa33ef206a98fd1226bab1290090650a72b96746
7
- data.tar.gz: 552eef6ce3131be319c5aa5a68e0eecb775f74e036f90b8287c3c8995992ee0525d265c787430aa210a673e2330387b6fb145d429b79c1fd4963fe85b0c47c1c
6
+ metadata.gz: 0dc2fab306d761d1a887478c2eb3d355064fa0c3a18bc5a91df6fb426eed5fe4d73073738d0011ca15e0b1a8042035fcb53b0d57937b9749c31d8efd94cb704e
7
+ data.tar.gz: 83eb3e8c604000a515888c0bca6f7d059de49f07fd691c67dd6a0a5bc1262a8fd1758a672f6244b54f3771bd6f591593b0b03b3d660c3a1c030397dd8ee87a0e
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.0.1 (released at 2025-07-09)
4
+
5
+ * Fix after introduce httpx, status method not available for HTTPX::ErrorResponse bug
6
+ * Some Google Jules Refactor
3
7
 
4
8
  ## v1.0.0 (released at 2025-05-17)
5
9
 
@@ -56,17 +56,19 @@ module ActionController
56
56
  secret = corpid.present? ? opts[:corpsecret] || cfg.corpsecret : opts[:secret] || cfg.secret
57
57
 
58
58
  network_setting = Wechat::NetworkSetting.new(timeout, skip_verify_ssl, proxy_url, proxy_username, proxy_password)
59
+ # access_token is token_file, jsapi_ticket is jsapi_ticket_file
60
+ api_config = Wechat::ApiConfig.new(corpid.presence || appid, secret, access_token, jsapi_ticket, network_setting)
59
61
  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)
62
+ get_wechat_api(api_type, api_config, agentid, qcloud_setting)
61
63
  end
62
64
 
63
- def get_wechat_api(api_type, corpid, appid, secret, access_token, agentid, network_setting, jsapi_ticket, qcloud_setting)
65
+ def get_wechat_api(api_type, api_config, agentid, qcloud_setting)
64
66
  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)
67
+ Wechat::MpApi.new(api_config, qcloud_setting)
68
+ elsif api_config.appid.present? && agentid.present? # Assuming corpid is now in api_config.appid for CorpApi
69
+ Wechat::CorpApi.new(api_config, agentid)
68
70
  else
69
- Wechat::Api.new(appid, secret, access_token, network_setting, jsapi_ticket)
71
+ Wechat::Api.new(api_config)
70
72
  end
71
73
  end
72
74
  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
 
@@ -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.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Skinnyworm
@@ -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.0.1#readme
275
+ source_code_uri: https://github.com/Eric-Guo/wechat/tree/v1.0.1
275
276
  rubygems_mfa_required: 'true'
276
277
  post_install_message: |2
277
278
 
metadata.gz.sig CHANGED
Binary file