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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +7 -0
- data/README-CN.md +2 -2
- data/README.md +2 -2
- data/lib/action_controller/wechat_responder.rb +1 -2
- data/lib/generators/wechat/templates/app/models/wechat_config.rb +5 -2
- data/lib/generators/wechat/templates/db/config_migration.rb.erb +2 -0
- data/lib/wechat/api_loader.rb +1 -2
- data/lib/wechat/concern/common.rb +0 -6
- data/lib/wechat/concern/qcloud.rb +1 -1
- data/lib/wechat/corp_api.rb +0 -6
- data/lib/wechat/http_client.rb +25 -27
- data/lib/wechat/message.rb +1 -1
- data/lib/wechat/network_setting.rb +2 -3
- data.tar.gz.sig +0 -0
- metadata +15 -18
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c59986fcf04aecd798a52b731fb9dfbe5cf145198defa76dfcb73351a8b2096
|
4
|
+
data.tar.gz: b4c2bd303e624cadd77537642f74e913d566d5dcc30eca97d5616807b70dd696
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
*
|
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
|
-
*
|
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,
|
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
|
|
data/lib/wechat/api_loader.rb
CHANGED
@@ -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.
|
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.
|
105
|
+
client.httpx.post(upload_url, form: form_data)
|
106
106
|
end
|
107
107
|
|
108
108
|
def tcb_upload_file(q_path, file)
|
data/lib/wechat/corp_api.rb
CHANGED
@@ -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
|
data/lib/wechat/http_client.rb
CHANGED
@@ -1,51 +1,49 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'httpx'
|
4
4
|
|
5
5
|
module Wechat
|
6
6
|
class HttpClient
|
7
|
-
attr_reader :base, :
|
7
|
+
attr_reader :base, :httpx
|
8
8
|
|
9
9
|
def initialize(base, network_setting)
|
10
10
|
@base = base
|
11
|
-
@
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
22
|
-
|
23
|
-
@
|
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,
|
28
|
-
params =
|
29
|
-
|
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,
|
35
|
-
params =
|
36
|
-
|
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,
|
42
|
-
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
|
-
|
45
|
-
|
46
|
-
|
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[
|
81
|
+
content_type = response.headers['content-type']
|
84
82
|
parse_as = {
|
85
83
|
%r{^application/json} => :json,
|
86
84
|
%r{^image/.*} => :file,
|
data/lib/wechat/message.rb
CHANGED
@@ -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).
|
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, :
|
5
|
+
attr_reader :timeout, :skip_verify_ssl, :proxy_url, :proxy_username, :proxy_password
|
6
6
|
|
7
|
-
def initialize(timeout, skip_verify_ssl, proxy_url,
|
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.
|
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:
|
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:
|
61
|
+
name: httpx
|
62
62
|
requirement: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
64
|
- - ">="
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: 1.
|
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.
|
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.
|
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.
|
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:
|
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:
|
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/
|
280
|
-
source_code_uri: https://github.com/Eric-Guo/wechat/tree/
|
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.
|
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
|