wechat 0.17.7 → 1.0.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: 01d659a1b0109803a9d9a7efcfa27c60d0a741f135fb1df1ea7eda8bfc1840f1
4
- data.tar.gz: 79d712076d72b55661649ddcd3de79e39823b53dd366e82552f8f080b162910a
3
+ metadata.gz: 7c59986fcf04aecd798a52b731fb9dfbe5cf145198defa76dfcb73351a8b2096
4
+ data.tar.gz: b4c2bd303e624cadd77537642f74e913d566d5dcc30eca97d5616807b70dd696
5
5
  SHA512:
6
- metadata.gz: 959af434e46ae8e97d22e5c9263a92add7e9b6fc8b19acf72b7a6522ae4c747f140b9c3535fb1bc979522a9b8c0953f22ac08650e6fe8b5b65910f70f95447be
7
- data.tar.gz: 1e3a8f527f15ace70e5fd49fba1bd5b298c3f5150f4b904a965363c02d631bd54b1325fb0afadaa0cc2a58796fdcfe6dc7e5c639e81b82669b806354d636bbac
6
+ metadata.gz: 44916ab7ae7f8881d7d8c6e9b5f92165e253530f6d4a0dee020fe2e6af677ba1e551cbaed437fef6787b8da9fa33ef206a98fd1226bab1290090650a72b96746
7
+ data.tar.gz: 552eef6ce3131be319c5aa5a68e0eecb775f74e036f90b8287c3c8995992ee0525d265c787430aa210a673e2330387b6fb145d429b79c1fd4963fe85b0c47c1c
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+
4
+ ## v1.0.0 (released at 2025-05-17)
5
+
6
+ * WECHAT_PROXY_URL should be writen with port, like `export WECHAT_PROXY_URL=http://127.0.0.1:6152`, since WECHAT_PROXY_PORT removed.
7
+ * Replace http with httpx, [reason](https://honeyryderchuck.gitlab.io/2023/10/15/state-of-ruby-http-clients-use-httpx.html)
8
+ * Feat: add account_type to WechatConfig. by @leepood #324
9
+
3
10
  ## v0.17.7 (released at 2025-03-02)
4
11
 
5
12
  * Adding ostruct into its gemspec. Fix #323
data/README-CN.md CHANGED
@@ -227,6 +227,7 @@ test:
227
227
  environment | 字串 | 必填。配置对应的运行环境,一般有:`production`、`development`、`test`。比如 `production` 配置仅在生产环境有效。默认为 `development`。
228
228
  account | 字串 | 必填。自定义的微信账户名称。同一 `environment` 下,账户名称不允许重复。
229
229
  enabled | 布尔 | 必填。配置是否生效。默认 `true`。
230
+ account_type | 字串 | 非必填。当前只支持`mp`,表示小程序。
230
231
  appid | 字串 | 公众号 id ,此字段和 `corpid` 两者必填其一。
231
232
  secret | 字串 | 公众号相关配置。当公众号 `appid` 存在时必填。
232
233
  corpid | 字串 | 企业号 id。此字段和 `appid` 两者必填其一。
@@ -896,6 +897,5 @@ end
896
897
 
897
898
  ## 已知问题
898
899
 
899
- * 企业微信接受菜单消息时,Wechat 腾讯服务器无法解析部分域名,请使用 iP 绑定回调 URL,用户的普通消息目前不受影响。
900
900
  * 企业微信全量覆盖成员使用的 CSV 通讯录格式,直接将下载的模板导入[是不工作的](http://qydev.weixin.qq.com/qa/index.php?qa=13978),必须使用 Excel 打开,然后另存为 CSV 格式才会变成合法格式。
901
- * 如果使用 Nginx + Unicron 部署方案,并且使用了 Https,必须设置 `trusted_domain_fullname` 为 Https,否则会导致 JS-SDK 签名失效。
901
+ * 在开发模式上使用外部反响代理 https 回调,可能需要设置 `trusted_domain_fullname` 为 https,否则会导致 JS-SDK 签名失效。
data/README.md CHANGED
@@ -254,6 +254,7 @@ Attribute | Type | Annotation
254
254
  ---- | ---- | ----
255
255
  environment | string | Required. Environment of account configuration. Typical values are: `production`, `development` and `test`. For example, a `production` config will only be available in `production`. Default to `development`.
256
256
  account | string | Required. Custom wechat account name. Account names must be unique within each environment.
257
+ account_type | string | account type, only support `mp` which is short for `mini program` currently
257
258
  enabled | boolean | Required. Whether this configuration is activated. Default to `true`.
258
259
  appid | string | Public account id. Either this attribute or `corpid` must be specified.
259
260
  secret | string | Public account configuration. Required when `appid` exists.
@@ -928,6 +929,5 @@ end
928
929
 
929
930
  ## Known Issues
930
931
 
931
- * Sometimes, enterprise account can not receive the menu message due to Tencent server unable to resolve DNS, so using IP as a callback URL is more stable, but it never happens for user sent text messages.
932
932
  * Enterprise batch "replace users" uses a CSV format file, but if you are using the downloaded template directly, it's [not working](http://qydev.weixin.qq.com/qa/index.php?qa=13978), must open the CSV file in Excel first, then save as CSV format again, seems Tencent only supports Excel "Save as CSV" file format.
933
- * If you using unicorn behind nginx and https, you need to set `trusted_domain_fullname` and point it to https, otherwise it will be http and will lead to invalid signature in the JS-SDK.
933
+ * Using an external feedback proxy HTTPS callback in development mode may require setting `trusted_domain_fullname` to HTTPS, otherwise the JS-SDK signature will be invalid.
@@ -41,7 +41,6 @@ module ActionController
41
41
  self.skip_verify_ssl = opts.key?(:skip_verify_ssl) ? opts[:skip_verify_ssl] : cfg.skip_verify_ssl
42
42
 
43
43
  proxy_url = opts.key?(:proxy_url) ? opts[:proxy_url] : cfg.proxy_url
44
- proxy_port = opts.key?(:proxy_port) ? opts[:proxy_port] : cfg.proxy_port
45
44
  proxy_username = opts.key?(:proxy_username) ? opts[:proxy_username] : cfg.proxy_username
46
45
  proxy_password = opts.key?(:proxy_password) ? opts[:proxy_password] : cfg.proxy_password
47
46
 
@@ -56,7 +55,7 @@ module ActionController
56
55
  api_type = opts[:type] || cfg.type
57
56
  secret = corpid.present? ? opts[:corpsecret] || cfg.corpsecret : opts[:secret] || cfg.secret
58
57
 
59
- network_setting = Wechat::NetworkSetting.new(timeout, skip_verify_ssl, proxy_url, proxy_port, proxy_username, proxy_password)
58
+ network_setting = Wechat::NetworkSetting.new(timeout, skip_verify_ssl, proxy_url, proxy_username, proxy_password)
60
59
  qcloud_setting = Wechat::Qcloud::Setting.new(qcloud_env, qcloud_token, qcloud_token_lifespan)
61
60
  get_wechat_api(api_type, corpid, appid, secret, access_token, agentid, network_setting, jsapi_ticket, qcloud_setting)
62
61
  end
@@ -9,10 +9,11 @@ class WechatConfig < ActiveRecord::Base
9
9
  validates :access_token, presence: true
10
10
  validates :jsapi_ticket, presence: true
11
11
  validates :encoding_aes_key, presence: { if: :encrypt_mode? }
12
+ validates :account_type, inclusion: { in: %w[mp] }, if: -> { account_type.present? }
12
13
 
13
14
  validate :app_config_is_valid
14
15
 
15
- ATTRIBUTES_TO_REMOVE = %w[environment account created_at updated_at enabled].freeze
16
+ ATTRIBUTES_TO_REMOVE = %w[environment account created_at updated_at enabled account_type].freeze
16
17
 
17
18
  def self.get_all_configs(environment)
18
19
  WechatConfig.where(environment: environment, enabled: true).each_with_object({}) do |config, hash|
@@ -21,7 +22,9 @@ class WechatConfig < ActiveRecord::Base
21
22
  end
22
23
 
23
24
  def build_config_hash
24
- as_json(except: ATTRIBUTES_TO_REMOVE)
25
+ config_hash = as_json(except: ATTRIBUTES_TO_REMOVE)
26
+ config_hash[:type] = account_type if account_type.present?
27
+ config_hash
25
28
  end
26
29
 
27
30
  private
@@ -5,6 +5,8 @@ class CreateWechatConfigs < ActiveRecord::Migration<%= migration_version %>
5
5
  t.string :environment, null: false, default: 'development'
6
6
  # account name
7
7
  t.string :account, null: false
8
+ # account type, "mp" is short for mini program
9
+ t.string :account_type
8
10
  # whether this config is activated
9
11
  t.boolean :enabled, default: true
10
12
 
@@ -12,7 +12,7 @@ module Wechat
12
12
  js_token_file = options[:js_token_file] || c.jsapi_ticket.presence || '/var/tmp/wechat_jsapi_ticket'
13
13
  type = options[:type] || c.type
14
14
 
15
- network_setting = Wechat::NetworkSetting.new(c.timeout, c.skip_verify_ssl, c.proxy_url, c.proxy_port, c.proxy_username, c.proxy_password)
15
+ network_setting = Wechat::NetworkSetting.new(c.timeout, c.skip_verify_ssl, c.proxy_url, c.proxy_username, c.proxy_password)
16
16
  if c.appid && c.secret && token_file.present?
17
17
  if type == 'mp'
18
18
  qcloud_env = options[:qcloud_env] || c.qcloud_env
@@ -166,7 +166,6 @@ module Wechat
166
166
  timeout: ENV.fetch('WECHAT_TIMEOUT', nil),
167
167
  skip_verify_ssl: ENV.fetch('WECHAT_SKIP_VERIFY_SSL', nil),
168
168
  proxy_url: ENV.fetch('WECHAT_PROXY_URL', nil),
169
- proxy_port: ENV.fetch('WECHAT_PROXY_PORT', nil),
170
169
  proxy_username: ENV.fetch('WECHAT_PROXY_USERNAME', nil),
171
170
  proxy_password: ENV.fetch('WECHAT_PROXY_PASSWORD', nil),
172
171
  encoding_aes_key: ENV.fetch('WECHAT_ENCODING_AES_KEY', nil),
@@ -144,12 +144,6 @@ module Wechat
144
144
  post 'menu/delconditional', JSON.generate(menuid: menuid)
145
145
  end
146
146
 
147
- def material(media_id)
148
- ActiveSupport::Deprecation.new.warn('material is deprecated. use get_material instead.')
149
-
150
- post 'material/get_material', JSON.generate(media_id: media_id), as: :file
151
- end
152
-
153
147
  def get_material(media_id)
154
148
  post 'material/get_material', JSON.generate(media_id: media_id), as: :file
155
149
  end
@@ -102,7 +102,7 @@ module Wechat
102
102
  'x-cos-security-token': x_cos_security_token,
103
103
  'x-cos-meta-fileid': x_cos_meta_fileid,
104
104
  file: form_file })
105
- client.httprb.post(upload_url, form: form_data, ssl_context: client.ssl_context)
105
+ client.httpx.post(upload_url, form: form_data)
106
106
  end
107
107
 
108
108
  def tcb_upload_file(q_path, file)
@@ -170,12 +170,6 @@ module Wechat
170
170
  post 'material/batchget', JSON.generate(type: type, agentid: agentid, offset: offset, count: count)
171
171
  end
172
172
 
173
- def material(media_id)
174
- ActiveSupport::Deprecation.new.warn('material is deprecated. use get_material instead.')
175
-
176
- post 'material/get_material', JSON.generate(media_id: media_id), params: { agentid: agentid }, as: :file
177
- end
178
-
179
173
  def get_material(media_id)
180
174
  post 'material/get_material', JSON.generate(media_id: media_id), params: { agentid: agentid }, as: :file
181
175
  end
@@ -1,51 +1,49 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'http'
3
+ require 'httpx'
4
4
 
5
5
  module Wechat
6
6
  class HttpClient
7
- attr_reader :base, :ssl_context, :httprb
7
+ attr_reader :base, :httpx
8
8
 
9
9
  def initialize(base, network_setting)
10
10
  @base = base
11
- @httprb = if HTTP::VERSION.to_i >= 4
12
- HTTP.timeout(write: network_setting.timeout, connect: network_setting.timeout, read: network_setting.timeout)
13
- else
14
- HTTP.timeout(:global, write: network_setting.timeout, connect: network_setting.timeout, read: network_setting.timeout)
15
- end
16
-
17
- unless network_setting.proxy_url.nil?
18
- @httprb = @httprb.via(network_setting.proxy_url, network_setting.proxy_port.to_i, network_setting.proxy_username, network_setting.proxy_password)
11
+ @httpx = HTTPX.with(timeout: { connect_timeout: network_setting.timeout, request_timeout: network_setting.timeout })
12
+
13
+ if network_setting.proxy_url.present?
14
+ @httpx = @httpx.with_proxy(uri: network_setting.proxy_url,
15
+ username: network_setting.proxy_username,
16
+ password: network_setting.proxy_password)
19
17
  end
20
18
 
21
- @ssl_context = OpenSSL::SSL::SSLContext.new
22
- @ssl_context.ssl_version = 'TLSv1_2'
23
- @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE if network_setting.skip_verify_ssl
19
+ return unless network_setting.skip_verify_ssl
20
+
21
+ @httpx = @httpx.with(ssl: { verify_mode: OpenSSL::SSL::VERIFY_NONE })
24
22
  end
25
23
 
26
24
  def get(path, get_header = {})
27
- request(path, get_header) do |url, header|
28
- params = header.delete(:params)
29
- httprb.headers(header).get(url, params: params, ssl_context: ssl_context)
25
+ request(path, get_header) do |url, headers|
26
+ params = headers.delete(:params)
27
+ httpx.with(headers: headers)
28
+ .get(url, params: params)
30
29
  end
31
30
  end
32
31
 
33
32
  def post(path, payload, post_header = {})
34
- request(path, post_header) do |url, header|
35
- params = header.delete(:params)
36
- httprb.headers(header).post(url, params: params, body: payload, ssl_context: ssl_context)
33
+ request(path, post_header) do |url, headers|
34
+ params = headers.delete(:params)
35
+ httpx.with(headers: headers)
36
+ .post(url, params: params, body: payload)
37
37
  end
38
38
  end
39
39
 
40
40
  def post_file(path, file, post_header = {})
41
- request(path, post_header) do |url, header|
42
- params = header.delete(:params)
41
+ request(path, post_header) do |url, headers|
42
+ params = headers.delete(:params)
43
43
  form_file = file.is_a?(HTTP::FormData::File) ? file : HTTP::FormData::File.new(file)
44
- httprb.headers(header)
45
- .post(url, params: params,
46
- form: { media: form_file,
47
- hack: 'X' }, # Existing here for http-form_data 1.0.1 handle single param improperly
48
- ssl_context: ssl_context)
44
+ httpx.with(headers: headers)
45
+ .post(url, params: params,
46
+ form: { media: form_file })
49
47
  end
50
48
  end
51
49
 
@@ -80,7 +78,7 @@ module Wechat
80
78
  end
81
79
 
82
80
  def parse_response(response, as_type)
83
- content_type = response.headers[:content_type]
81
+ content_type = response.headers['content-type']
84
82
  parse_as = {
85
83
  %r{^application/json} => :json,
86
84
  %r{^image/.*} => :file,
@@ -238,7 +238,7 @@ module Wechat
238
238
  key = key.to_s
239
239
  [TO_JSON_KEY_MAP[key] || (keep_camel_case_key ? key : key.downcase), value]
240
240
  end
241
- json_hash = json_hash.transform_keys(&:downcase).select { |k, _v| TO_JSON_ALLOWED.include? k }
241
+ json_hash = json_hash.transform_keys(&:downcase).slice(*TO_JSON_ALLOWED)
242
242
 
243
243
  case json_hash['msgtype']
244
244
  when 'text'
@@ -2,13 +2,12 @@
2
2
 
3
3
  module Wechat
4
4
  class NetworkSetting
5
- attr_reader :timeout, :skip_verify_ssl, :proxy_url, :proxy_port, :proxy_username, :proxy_password
5
+ attr_reader :timeout, :skip_verify_ssl, :proxy_url, :proxy_username, :proxy_password
6
6
 
7
- def initialize(timeout, skip_verify_ssl, proxy_url, proxy_port, proxy_username, proxy_password)
7
+ def initialize(timeout, skip_verify_ssl, proxy_url, proxy_username, proxy_password)
8
8
  @timeout = timeout
9
9
  @skip_verify_ssl = skip_verify_ssl
10
10
  @proxy_url = proxy_url
11
- @proxy_port = proxy_port
12
11
  @proxy_username = proxy_username
13
12
  @proxy_password = proxy_password
14
13
  end
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: 0.17.7
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Skinnyworm
@@ -35,7 +35,7 @@ cert_chain:
35
35
  200/Tqe769E/Y40VHi+y7u06vT756gzVfC7nH5EUd2eIFAePlp8wMvNFW5+56bKl
36
36
  LbbJnkHtUxxHWQTe2lJQuFErTSuYIaN9DhzJYNot7Ot7SPbdeChVsbPtjPg=
37
37
  -----END CERTIFICATE-----
38
- date: 2025-03-01 00:00:00.000000000 Z
38
+ date: 1980-01-02 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: activesupport
@@ -58,25 +58,19 @@ dependencies:
58
58
  - !ruby/object:Gem::Version
59
59
  version: '9'
60
60
  - !ruby/object:Gem::Dependency
61
- name: http
61
+ name: httpx
62
62
  requirement: !ruby/object:Gem::Requirement
63
63
  requirements:
64
64
  - - ">="
65
65
  - !ruby/object:Gem::Version
66
- version: 1.0.4
67
- - - "<"
68
- - !ruby/object:Gem::Version
69
- version: '6'
66
+ version: 1.3.4
70
67
  type: :runtime
71
68
  prerelease: false
72
69
  version_requirements: !ruby/object:Gem::Requirement
73
70
  requirements:
74
71
  - - ">="
75
72
  - !ruby/object:Gem::Version
76
- version: 1.0.4
77
- - - "<"
78
- - !ruby/object:Gem::Version
79
- version: '6'
73
+ version: 1.3.4
80
74
  - !ruby/object:Gem::Dependency
81
75
  name: nokogiri
82
76
  requirement: !ruby/object:Gem::Requirement
@@ -153,28 +147,28 @@ dependencies:
153
147
  requirements:
154
148
  - - "~>"
155
149
  - !ruby/object:Gem::Version
156
- version: 1.70.0
150
+ version: 1.72.2
157
151
  type: :development
158
152
  prerelease: false
159
153
  version_requirements: !ruby/object:Gem::Requirement
160
154
  requirements:
161
155
  - - "~>"
162
156
  - !ruby/object:Gem::Version
163
- version: 1.70.0
157
+ version: 1.72.2
164
158
  - !ruby/object:Gem::Dependency
165
159
  name: rails
166
160
  requirement: !ruby/object:Gem::Requirement
167
161
  requirements:
168
162
  - - ">="
169
163
  - !ruby/object:Gem::Version
170
- version: 8.0.0
164
+ version: '7.2'
171
165
  type: :development
172
166
  prerelease: false
173
167
  version_requirements: !ruby/object:Gem::Requirement
174
168
  requirements:
175
169
  - - ">="
176
170
  - !ruby/object:Gem::Version
177
- version: 8.0.0
171
+ version: '7.2'
178
172
  - !ruby/object:Gem::Dependency
179
173
  name: rspec-rails
180
174
  requirement: !ruby/object:Gem::Requirement
@@ -276,9 +270,12 @@ licenses:
276
270
  metadata:
277
271
  bug_tracker_uri: https://github.com/Eric-Guo/wechat/issues
278
272
  changelog_uri: https://github.com/Eric-Guo/wechat/releases
279
- documentation_uri: https://github.com/Eric-Guo/wechat/tree/v0.17.7#readme
280
- source_code_uri: https://github.com/Eric-Guo/wechat/tree/v0.17.7
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
281
275
  rubygems_mfa_required: 'true'
276
+ post_install_message: |2
277
+
278
+ BREAKING changes: WECHAT_PROXY_URL should be written with port now, like `export WECHAT_PROXY_URL=http://127.0.0.1:6152`, since WECHAT_PROXY_PORT removed.
282
279
  rdoc_options: []
283
280
  require_paths:
284
281
  - lib
@@ -293,7 +290,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
293
290
  - !ruby/object:Gem::Version
294
291
  version: 3.1.6
295
292
  requirements: []
296
- rubygems_version: 3.6.5
293
+ rubygems_version: 3.6.9
297
294
  specification_version: 4
298
295
  summary: DSL for wechat message handling and API
299
296
  test_files: []
metadata.gz.sig CHANGED
Binary file