wechat 0.11.11 → 0.12.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +8 -0
- data/lib/action_controller/wechat_responder.rb +15 -14
- data/lib/generators/wechat/templates/app/models/wechat_config.rb +1 -1
- data/lib/wechat.rb +2 -0
- data/lib/wechat/api.rb +8 -0
- data/lib/wechat/api_base.rb +2 -1
- data/lib/wechat/api_loader.rb +14 -2
- data/lib/wechat/concern/common.rb +0 -6
- data/lib/wechat/concern/qcloud.rb +115 -0
- data/lib/wechat/controller_api.rb +1 -1
- data/lib/wechat/corp_api.rb +2 -1
- data/lib/wechat/helpers.rb +1 -7
- data/lib/wechat/http_client.rb +1 -1
- data/lib/wechat/message.rb +4 -4
- data/lib/wechat/mp_api.rb +11 -0
- data/lib/wechat/qcloud/token.rb +66 -0
- data/lib/wechat/responder.rb +1 -0
- metadata +22 -6
- 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: f7dfe45f7c68aafa5b96a2a3178ae2108f9989bb5594b6ae35d1e7dcc358219a
|
4
|
+
data.tar.gz: 25a51c65de855682ec12ee332241d9acd47c8cc8c2376995c8d8f0512825e899
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '080ada4dbb3191ed4d10d51d4cef85de0cfc469af61f636ee99b03be92e487060fa454a37ef54a8386d77d1ebede360d2819c64d59f0d1ca2a202ba199e1a31e'
|
7
|
+
data.tar.gz: f3482024b4e35f91924c384ca27819748341444047c135362552b460ccf15243fcd5fd1c896e0c15eb00e392aa73ce1c750854b78e6e0c52af0176482e4939cb
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v0.12.1 (released at 28/12/2020)
|
4
|
+
|
5
|
+
* Support Ruby 3.0.
|
6
|
+
* Qcloud_token support.
|
7
|
+
* CRUD of tencent cloud DB for miniapp
|
8
|
+
* TCB storage API support.
|
9
|
+
* Set default branch to *main*.
|
10
|
+
|
3
11
|
## v0.11.11 (released at 09/13/2020)
|
4
12
|
|
5
13
|
* FIX: fix_load_controller_wechat not support MP type, by @Msms-NJ #281
|
@@ -38,27 +38,28 @@ module ActionController
|
|
38
38
|
self.trusted_domain_fullname = opts[:trusted_domain_fullname] || cfg.trusted_domain_fullname
|
39
39
|
self.oauth2_cookie_duration = opts[:oauth2_cookie_duration] || cfg.oauth2_cookie_duration.to_i.seconds
|
40
40
|
self.timeout = opts[:timeout] || cfg.timeout
|
41
|
-
self.
|
42
|
-
|
43
|
-
else
|
44
|
-
cfg.skip_verify_ssl
|
45
|
-
end
|
41
|
+
self.qcloud_token_lifespan = opts[:qcloud_token_lifespan] || cfg.qcloud_token_lifespan
|
42
|
+
self.skip_verify_ssl = opts.key?(:skip_verify_ssl) ? opts[:skip_verify_ssl] : cfg.skip_verify_ssl
|
46
43
|
|
47
44
|
return Wechat.api if account == :default && opts.empty?
|
48
45
|
|
49
46
|
access_token = opts[:access_token] || cfg.access_token
|
50
47
|
jsapi_ticket = opts[:jsapi_ticket] || cfg.jsapi_ticket
|
48
|
+
qcloud_token = opts[:qcloud_token] || cfg.qcloud_token
|
51
49
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
api_type = opts[:type] || cfg.type
|
51
|
+
secret = corpid.present? ? opts[:corpsecret] || cfg.corpsecret : opts[:secret] || cfg.secret
|
52
|
+
|
53
|
+
get_wechat_api(api_type, corpid, appid, secret, access_token, agentid, timeout, skip_verify_ssl, jsapi_ticket, qcloud_token, qcloud_token_lifespan)
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_wechat_api(api_type, corpid, appid, secret, access_token, agentid, timeout, skip_verify_ssl, jsapi_ticket, qcloud_token, qcloud_token_lifespan)
|
57
|
+
if api_type && api_type.to_sym == :mp
|
58
|
+
Wechat::MpApi.new(appid, secret, access_token, timeout, skip_verify_ssl, jsapi_ticket, qcloud_token, qcloud_token_lifespan)
|
59
|
+
elsif corpid.present?
|
60
|
+
Wechat::CorpApi.new(corpid, secret, access_token, agentid, timeout, skip_verify_ssl, jsapi_ticket)
|
56
61
|
else
|
57
|
-
|
58
|
-
secret = opts[:secret] || cfg.secret
|
59
|
-
wechat_api_class = (type && type.to_sym == :mp ? Wechat::MpApi : Wechat::Api)
|
60
|
-
wechat_api_class.new(appid, secret, access_token, \
|
61
|
-
timeout, skip_verify_ssl, jsapi_ticket)
|
62
|
+
Wechat::Api.new(appid, secret, access_token, timeout, skip_verify_ssl, jsapi_ticket)
|
62
63
|
end
|
63
64
|
end
|
64
65
|
end
|
@@ -35,7 +35,7 @@ class WechatConfig < ActiveRecord::Base
|
|
35
35
|
errors.add(:corpsecret, 'cannot be nil when corpid is set') if self[:corpsecret].blank?
|
36
36
|
errors.add(:agentid, 'cannot be nil when corpid is set') if self[:agentid].blank?
|
37
37
|
else
|
38
|
-
errors
|
38
|
+
errors.add(:base, 'Either appid or corpid must be set')
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
data/lib/wechat.rb
CHANGED
data/lib/wechat/api.rb
CHANGED
@@ -8,6 +8,14 @@ require 'wechat/concern/common'
|
|
8
8
|
|
9
9
|
module Wechat
|
10
10
|
class Api < ApiBase
|
11
|
+
def initialize(appid, secret, token_file, timeout, skip_verify_ssl, jsapi_ticket_file)
|
12
|
+
super()
|
13
|
+
@client = HttpClient.new(Wechat::Api::API_BASE, timeout, skip_verify_ssl)
|
14
|
+
@access_token = Token::PublicAccessToken.new(@client, appid, secret, token_file)
|
15
|
+
@jsapi_ticket = Ticket::PublicJsapiTicket.new(@client, @access_token, jsapi_ticket_file)
|
16
|
+
@qcloud = nil
|
17
|
+
end
|
18
|
+
|
11
19
|
include Concern::Common
|
12
20
|
|
13
21
|
def template_message_send(message)
|
data/lib/wechat/api_base.rb
CHANGED
@@ -2,13 +2,14 @@
|
|
2
2
|
|
3
3
|
module Wechat
|
4
4
|
class ApiBase
|
5
|
-
attr_reader :access_token, :client, :jsapi_ticket
|
5
|
+
attr_reader :access_token, :client, :jsapi_ticket, :qcloud
|
6
6
|
|
7
7
|
API_BASE = 'https://api.weixin.qq.com/cgi-bin/'
|
8
8
|
MP_BASE = 'https://mp.weixin.qq.com/cgi-bin/'
|
9
9
|
WXA_BASE = 'https://api.weixin.qq.com/wxa/'
|
10
10
|
OAUTH2_BASE = 'https://api.weixin.qq.com/sns/'
|
11
11
|
DATACUBE_BASE = 'https://api.weixin.qq.com/datacube/'
|
12
|
+
TCB_BASE = 'https://api.weixin.qq.com/tcb/'
|
12
13
|
QYAPI_BASE = 'https://qyapi.weixin.qq.com/cgi-bin/'
|
13
14
|
|
14
15
|
def callbackip
|
data/lib/wechat/api_loader.rb
CHANGED
@@ -9,9 +9,16 @@ module Wechat
|
|
9
9
|
token_file = options[:token_file] || c.access_token.presence || '/var/tmp/wechat_access_token'
|
10
10
|
js_token_file = options[:js_token_file] || c.jsapi_ticket.presence || '/var/tmp/wechat_jsapi_ticket'
|
11
11
|
type = options[:type] || c.type
|
12
|
+
|
12
13
|
if c.appid && c.secret && token_file.present?
|
13
|
-
|
14
|
-
|
14
|
+
if type == 'mp'
|
15
|
+
qcloud_env = options[:qcloud_env] || c.qcloud_env
|
16
|
+
qcloud_token_file = options[:qcloud_token_file] || c.qcloud_token_file.presence || '/var/tmp/qcloud_access_token'
|
17
|
+
qcloud_token_lifespan = options[:qcloud_token_lifespan] || c.qcloud_token_lifespan
|
18
|
+
Wechat::MpApi.new(c.appid, c.secret, token_file, c.timeout, c.skip_verify_ssl, js_token_file, qcloud_env, qcloud_token_file, qcloud_token_lifespan)
|
19
|
+
else
|
20
|
+
Wechat::Api.new(c.appid, c.secret, token_file, c.timeout, c.skip_verify_ssl, js_token_file)
|
21
|
+
end
|
15
22
|
elsif c.corpid && c.corpsecret && token_file.present?
|
16
23
|
Wechat::CorpApi.new(c.corpid, c.corpsecret, token_file, c.agentid, c.timeout, c.skip_verify_ssl, js_token_file)
|
17
24
|
else
|
@@ -46,11 +53,13 @@ module Wechat
|
|
46
53
|
configs.each do |_, cfg|
|
47
54
|
cfg[:access_token] ||= Rails.root.try(:join, 'tmp/access_token').try(:to_path)
|
48
55
|
cfg[:jsapi_ticket] ||= Rails.root.try(:join, 'tmp/jsapi_ticket').try(:to_path)
|
56
|
+
cfg[:qcloud_token] ||= Rails.root.try(:join, 'tmp/qcloud_token').try(:to_path)
|
49
57
|
end
|
50
58
|
end
|
51
59
|
|
52
60
|
configs.each do |_, cfg|
|
53
61
|
cfg[:timeout] ||= 20
|
62
|
+
cfg[:qcloud_token_lifespan] ||= 7200
|
54
63
|
cfg[:have_session_class] = class_exists?('WechatSession')
|
55
64
|
cfg[:oauth2_cookie_duration] ||= 1.hour
|
56
65
|
end
|
@@ -135,6 +144,9 @@ module Wechat
|
|
135
144
|
skip_verify_ssl: ENV['WECHAT_SKIP_VERIFY_SSL'],
|
136
145
|
encoding_aes_key: ENV['WECHAT_ENCODING_AES_KEY'],
|
137
146
|
jsapi_ticket: ENV['WECHAT_JSAPI_TICKET'],
|
147
|
+
qcloud_env: ENV['WECHAT_QCLOUD_ENV'],
|
148
|
+
qcloud_token_file: ENV['WECHAT_QCLOUD_TOKEN'],
|
149
|
+
qcloud_token_lifespan: ENV['WECHAT_QCLOUD_TOKEN_LIFESPAN'],
|
138
150
|
trusted_domain_fullname: ENV['WECHAT_TRUSTED_DOMAIN_FULLNAME'] }
|
139
151
|
{ default: value }
|
140
152
|
end
|
@@ -3,12 +3,6 @@
|
|
3
3
|
module Wechat
|
4
4
|
module Concern
|
5
5
|
module Common
|
6
|
-
def initialize(appid, secret, token_file, timeout, skip_verify_ssl, jsapi_ticket_file)
|
7
|
-
@client = HttpClient.new(Wechat::Api::API_BASE, timeout, skip_verify_ssl)
|
8
|
-
@access_token = Token::PublicAccessToken.new(@client, appid, secret, token_file)
|
9
|
-
@jsapi_ticket = Ticket::PublicJsapiTicket.new(@client, @access_token, jsapi_ticket_file)
|
10
|
-
end
|
11
|
-
|
12
6
|
def groups
|
13
7
|
get 'groups/get'
|
14
8
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wechat
|
4
|
+
module Concern
|
5
|
+
module Qcloud
|
6
|
+
def invoke_cloud_function(function_name, post_body_params)
|
7
|
+
post 'invokecloudfunction', JSON.generate(post_body_params), params: { env: qcloud.qcloud_env, name: function_name }, base: Wechat::Api::TCB_BASE
|
8
|
+
end
|
9
|
+
|
10
|
+
def qdb_migrate_import(collection_name, file_path, file_type: Wechat::Qcloud::FILE_TYPE_JSON, stop_on_error: false, conflict_mode: Wechat::Qcloud::CONFLICT_MODE_UPSERT)
|
11
|
+
import_params_hash = { env: qcloud.qcloud_env,
|
12
|
+
collection_name: collection_name,
|
13
|
+
file_path: file_path,
|
14
|
+
file_type: file_type,
|
15
|
+
stop_on_error: stop_on_error,
|
16
|
+
conflict_mode: conflict_mode }
|
17
|
+
post 'databasemigrateimport', JSON.generate(import_params_hash), base: Wechat::Api::TCB_BASE
|
18
|
+
end
|
19
|
+
|
20
|
+
def qdb_migrate_export(query, file_path, file_type: Wechat::Qcloud::FILE_TYPE_JSON)
|
21
|
+
export_params_hash = { env: qcloud.qcloud_env,
|
22
|
+
file_path: file_path,
|
23
|
+
file_type: file_type,
|
24
|
+
query: query }
|
25
|
+
post 'databasemigrateexport', JSON.generate(export_params_hash), base: Wechat::Api::TCB_BASE
|
26
|
+
end
|
27
|
+
|
28
|
+
def qdb_migrate_query(job_id)
|
29
|
+
query_info_hash = { env: qcloud.qcloud_env,
|
30
|
+
job_id: job_id }
|
31
|
+
|
32
|
+
post 'databasemigratequeryinfo', JSON.generate(query_info_hash), base: Wechat::Api::TCB_BASE
|
33
|
+
end
|
34
|
+
|
35
|
+
def qdb_update_index(collection_name, create_indexes: [], drop_indexes: [])
|
36
|
+
update_index_params_hash = { env: qcloud.qcloud_env,
|
37
|
+
collection_name: collection_name,
|
38
|
+
create_indexes: create_indexes,
|
39
|
+
drop_indexes: drop_indexes }
|
40
|
+
post 'updateindex', JSON.generate(update_index_params_hash), base: Wechat::Api::TCB_BASE
|
41
|
+
end
|
42
|
+
|
43
|
+
def qdb_collection_add(collection_name)
|
44
|
+
collection_add_params_hash = { env: qcloud.qcloud_env,
|
45
|
+
collection_name: collection_name }
|
46
|
+
post 'databasecollectionadd', JSON.generate(collection_add_params_hash), base: Wechat::Api::TCB_BASE
|
47
|
+
end
|
48
|
+
|
49
|
+
def qdb_collection_delete(collection_name)
|
50
|
+
collection_delete_params_hash = { env: qcloud.qcloud_env,
|
51
|
+
collection_name: collection_name }
|
52
|
+
post 'databasecollectiondelete', JSON.generate(collection_delete_params_hash), base: Wechat::Api::TCB_BASE
|
53
|
+
end
|
54
|
+
|
55
|
+
def qdb_collections(limit: 10, offset: 0)
|
56
|
+
get_collections_params_hash = { env: qcloud.qcloud_env,
|
57
|
+
limit: limit,
|
58
|
+
offset: offset }
|
59
|
+
post 'databasecollectionget', JSON.generate(get_collections_params_hash), base: Wechat::Api::TCB_BASE
|
60
|
+
end
|
61
|
+
|
62
|
+
def qdb_add(add_query)
|
63
|
+
post 'databaseadd', JSON.generate(env: qcloud.qcloud_env, query: add_query), base: Wechat::Api::TCB_BASE
|
64
|
+
end
|
65
|
+
|
66
|
+
def qdb_delete(delete_query)
|
67
|
+
post 'databasedelete', JSON.generate(env: qcloud.qcloud_env, query: delete_query), base: Wechat::Api::TCB_BASE
|
68
|
+
end
|
69
|
+
|
70
|
+
def qdb_update(update_query)
|
71
|
+
post 'databaseupdate', JSON.generate(env: qcloud.qcloud_env, query: update_query), base: Wechat::Api::TCB_BASE
|
72
|
+
end
|
73
|
+
|
74
|
+
def qdb_query(query)
|
75
|
+
post 'databasequery', JSON.generate(env: qcloud.qcloud_env, query: query), base: Wechat::Api::TCB_BASE
|
76
|
+
end
|
77
|
+
|
78
|
+
def qdb_aggregate(aggregate_query)
|
79
|
+
post 'databaseaggregate', JSON.generate(env: qcloud.qcloud_env, query: aggregate_query), base: Wechat::Api::TCB_BASE
|
80
|
+
end
|
81
|
+
|
82
|
+
def qdb_count(count_query)
|
83
|
+
post 'databasecount', JSON.generate(env: qcloud.qcloud_env, query: count_query), base: Wechat::Api::TCB_BASE
|
84
|
+
end
|
85
|
+
|
86
|
+
def tcb_delete_files(fileid_list)
|
87
|
+
post 'batchdeletefile', JSON.generate(env: qcloud.qcloud_env, fileid_list: fileid_list), base: Wechat::Api::TCB_BASE
|
88
|
+
end
|
89
|
+
|
90
|
+
def tcb_download_files(file_list)
|
91
|
+
post 'batchdownloadfile', JSON.generate(env: qcloud.qcloud_env, file_list: file_list), base: Wechat::Api::TCB_BASE
|
92
|
+
end
|
93
|
+
|
94
|
+
def tcb_preflight_upload_file(q_path)
|
95
|
+
post 'uploadfile', JSON.generate(env: qcloud.qcloud_env, path: q_path), base: Wechat::Api::TCB_BASE
|
96
|
+
end
|
97
|
+
|
98
|
+
def tcb_do_upload_file(q_path, upload_url, signature, x_cos_security_token, x_cos_meta_fileid, file)
|
99
|
+
form_file = file.is_a?(HTTP::FormData::File) ? file : HTTP::FormData::File.new(file)
|
100
|
+
form_data = HTTP::FormData.create({ key: q_path,
|
101
|
+
Signature: signature,
|
102
|
+
"x-cos-security-token": x_cos_security_token,
|
103
|
+
'x-cos-meta-fileid': x_cos_meta_fileid,
|
104
|
+
file: form_file })
|
105
|
+
client.httprb.post(upload_url, form: form_data, ssl_context: client.ssl_context)
|
106
|
+
end
|
107
|
+
|
108
|
+
def tcb_upload_file(q_path, file)
|
109
|
+
res = tcb_preflight_upload_file(q_path)
|
110
|
+
tcb_do_upload_file(q_path, res['url'], res['authorization'], res['token'], res['cos_file_id'], file)
|
111
|
+
res
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -5,7 +5,7 @@ module Wechat
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
module ClassMethods
|
8
|
-
attr_accessor :wechat_api_client, :wechat_cfg_account, :token, :appid, :corpid, :agentid, :encrypt_mode, :timeout,
|
8
|
+
attr_accessor :wechat_api_client, :wechat_cfg_account, :token, :appid, :corpid, :agentid, :encrypt_mode, :timeout, :qcloud_token_lifespan,
|
9
9
|
:skip_verify_ssl, :encoding_aes_key, :trusted_domain_fullname, :oauth2_cookie_duration
|
10
10
|
end
|
11
11
|
|
data/lib/wechat/corp_api.rb
CHANGED
@@ -15,6 +15,7 @@ module Wechat
|
|
15
15
|
@access_token = Token::CorpAccessToken.new(@client, appid, secret, token_file)
|
16
16
|
@agentid = agentid
|
17
17
|
@jsapi_ticket = Ticket::CorpJsapiTicket.new(@client, @access_token, jsapi_ticket_file)
|
18
|
+
@qcloud = nil
|
18
19
|
end
|
19
20
|
|
20
21
|
def agent_list
|
@@ -91,7 +92,7 @@ module Wechat
|
|
91
92
|
end
|
92
93
|
|
93
94
|
def department_update(departmentid, name = nil, parentid = nil, order = nil)
|
94
|
-
post 'department/update', JSON.generate({ id: departmentid, name: name, parentid: parentid, order: order }.
|
95
|
+
post 'department/update', JSON.generate({ id: departmentid, name: name, parentid: parentid, order: order }.compact)
|
95
96
|
end
|
96
97
|
|
97
98
|
def department(departmentid = 1)
|
data/lib/wechat/helpers.rb
CHANGED
@@ -24,7 +24,7 @@ module Wechat
|
|
24
24
|
else
|
25
25
|
controller.request.original_url
|
26
26
|
end
|
27
|
-
page_url = page_url.split('#').first
|
27
|
+
page_url = page_url.split('#').first
|
28
28
|
js_hash = api.jsapi_ticket.signature(page_url)
|
29
29
|
|
30
30
|
config_js = <<~WECHAT_CONFIG_JS
|
@@ -39,11 +39,5 @@ module Wechat
|
|
39
39
|
WECHAT_CONFIG_JS
|
40
40
|
javascript_tag config_js, type: 'application/javascript'
|
41
41
|
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def ios?
|
46
|
-
controller.request.user_agent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
|
47
|
-
end
|
48
42
|
end
|
49
43
|
end
|
data/lib/wechat/http_client.rb
CHANGED
@@ -14,7 +14,7 @@ module Wechat
|
|
14
14
|
HTTP.timeout(:global, write: timeout, connect: timeout, read: timeout)
|
15
15
|
end
|
16
16
|
@ssl_context = OpenSSL::SSL::SSLContext.new
|
17
|
-
@ssl_context.ssl_version =
|
17
|
+
@ssl_context.ssl_version = 'TLSv1_2'
|
18
18
|
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE if skip_verify_ssl
|
19
19
|
end
|
20
20
|
|
data/lib/wechat/message.rb
CHANGED
@@ -41,14 +41,14 @@ module Wechat
|
|
41
41
|
|
42
42
|
class NewsArticleBuilder < ArticleBuilder
|
43
43
|
def item(title: 'title', description: nil, pic_url: nil, url: nil)
|
44
|
-
items << { Title: title, Description: description, PicUrl: pic_url, Url: url }.
|
44
|
+
items << { Title: title, Description: description, PicUrl: pic_url, Url: url }.compact
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
class MpNewsArticleBuilder < ArticleBuilder
|
49
49
|
def item(thumb_media_id:, title:, content:, author: nil, content_source_url: nil, digest: nil, show_cover_pic: '0')
|
50
50
|
items << { Thumb_Media_ID: thumb_media_id, Author: author, Title: title, ContentSourceUrl: content_source_url,
|
51
|
-
Content: content, Digest: digest, ShowCoverPic: show_cover_pic }.
|
51
|
+
Content: content, Digest: digest, ShowCoverPic: show_cover_pic }.compact
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -169,7 +169,7 @@ module Wechat
|
|
169
169
|
items = article.items
|
170
170
|
else
|
171
171
|
items = collection.collect do |item|
|
172
|
-
camelize_hash_keys(item.symbolize_keys.slice(:title, :description, :pic_url, :url).
|
172
|
+
camelize_hash_keys(item.symbolize_keys.slice(:title, :description, :pic_url, :url).compact)
|
173
173
|
end
|
174
174
|
end
|
175
175
|
|
@@ -184,7 +184,7 @@ module Wechat
|
|
184
184
|
items = article.items
|
185
185
|
else
|
186
186
|
items = collection.collect do |item|
|
187
|
-
camelize_hash_keys(item.symbolize_keys.slice(:thumb_media_id, :title, :content, :author, :content_source_url, :digest, :show_cover_pic).
|
187
|
+
camelize_hash_keys(item.symbolize_keys.slice(:thumb_media_id, :title, :content, :author, :content_source_url, :digest, :show_cover_pic).compact)
|
188
188
|
end
|
189
189
|
end
|
190
190
|
|
data/lib/wechat/mp_api.rb
CHANGED
@@ -4,11 +4,22 @@ require 'wechat/api_base'
|
|
4
4
|
require 'wechat/http_client'
|
5
5
|
require 'wechat/token/public_access_token'
|
6
6
|
require 'wechat/ticket/public_jsapi_ticket'
|
7
|
+
require 'wechat/qcloud/token'
|
7
8
|
require 'wechat/concern/common'
|
9
|
+
require 'wechat/concern/qcloud'
|
8
10
|
|
9
11
|
module Wechat
|
10
12
|
class MpApi < ApiBase
|
13
|
+
def initialize(appid, secret, token_file, timeout, skip_verify_ssl, jsapi_ticket_file, qcloud_env, qcloud_token_file, qcloud_token_lifespan)
|
14
|
+
super()
|
15
|
+
@client = HttpClient.new(Wechat::Api::API_BASE, timeout, skip_verify_ssl)
|
16
|
+
@access_token = Token::PublicAccessToken.new(@client, appid, secret, token_file)
|
17
|
+
@jsapi_ticket = Ticket::PublicJsapiTicket.new(@client, @access_token, jsapi_ticket_file)
|
18
|
+
@qcloud = Qcloud::Token.new(@client, @access_token, qcloud_env, qcloud_token_file, qcloud_token_lifespan)
|
19
|
+
end
|
20
|
+
|
11
21
|
include Concern::Common
|
22
|
+
include Concern::Qcloud
|
12
23
|
|
13
24
|
def template_message_send(message)
|
14
25
|
post 'message/wxopen/template/send', message.to_json, content_type: :json
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wechat
|
4
|
+
module Qcloud
|
5
|
+
FILE_TYPE_JSON = 1
|
6
|
+
FILE_TYPE_CSV = 2
|
7
|
+
CONFLICT_MODE_INSERT = 1
|
8
|
+
CONFLICT_MODE_UPSERT = 2
|
9
|
+
|
10
|
+
class Token
|
11
|
+
attr_reader :client, :access_token, :qcloud_env, :qcloud_token_file, :qcloud_token_lifespan, :qcloud_token, :qcloud_token_expired_time
|
12
|
+
|
13
|
+
def initialize(client, access_token, qcloud_env, qcloud_token_file, lifespan)
|
14
|
+
@client = client
|
15
|
+
@access_token = access_token
|
16
|
+
@qcloud_env = qcloud_env
|
17
|
+
@qcloud_token_file = qcloud_token_file
|
18
|
+
@qcloud_token_lifespan = lifespan
|
19
|
+
@random_generator = Random.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def token(tries = 2)
|
23
|
+
# Possible two worker running, one worker refresh ticket, other unaware, so must read every time
|
24
|
+
read_qcloud_token_from_store
|
25
|
+
refresh if remain_life_seconds < @random_generator.rand(30..3 * 60)
|
26
|
+
qcloud_token
|
27
|
+
rescue AccessTokenExpiredError
|
28
|
+
access_token.refresh
|
29
|
+
retry unless (tries -= 1).zero?
|
30
|
+
end
|
31
|
+
|
32
|
+
def refresh
|
33
|
+
data = client.post('getqcloudtoken', JSON.generate(lifespan: qcloud_token_lifespan), base: ::Wechat::ApiBase::TCB_BASE, params: { access_token: access_token.token })
|
34
|
+
write_qcloud_token_to_store(data)
|
35
|
+
read_qcloud_token_from_store
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def read_qcloud_token_from_store
|
41
|
+
td = read_qcloud_token
|
42
|
+
@qcloud_token_expired_time = td.fetch('qcloud_token_expired_time').to_i
|
43
|
+
@qcloud_token = td.fetch('token') # return qcloud_token same time
|
44
|
+
rescue JSON::ParserError, Errno::ENOENT, KeyError, TypeError
|
45
|
+
refresh
|
46
|
+
end
|
47
|
+
|
48
|
+
def write_qcloud_token_to_store(qcloud_token_hash)
|
49
|
+
qcloud_token_hash['qcloud_token_expired_time'] = qcloud_token_hash.delete('expired_time')
|
50
|
+
write_qcloud_token(qcloud_token_hash)
|
51
|
+
end
|
52
|
+
|
53
|
+
def read_qcloud_token
|
54
|
+
JSON.parse(File.read(qcloud_token_file))
|
55
|
+
end
|
56
|
+
|
57
|
+
def write_qcloud_token(qcloud_token_hash)
|
58
|
+
File.write(qcloud_token_file, qcloud_token_hash.to_json)
|
59
|
+
end
|
60
|
+
|
61
|
+
def remain_life_seconds
|
62
|
+
qcloud_token_expired_time - Time.now.to_i
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/wechat/responder.rb
CHANGED
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: 0.12.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Skinnyworm
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
spvOK5/LPXWX6ZGc2SR8SH/s7ftYH2EkeM1VUbtemow08NdgCwJ4IG+fRQ9dcrJ+
|
36
36
|
L9TbpLHvVrCe1w8duMqNeUmqj+M1iC/5Zst2vIe14QcOTuAh
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2020-
|
38
|
+
date: 2020-12-28 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: activesupport
|
@@ -105,20 +105,34 @@ dependencies:
|
|
105
105
|
- - ">="
|
106
106
|
- !ruby/object:Gem::Version
|
107
107
|
version: '0'
|
108
|
+
- !ruby/object:Gem::Dependency
|
109
|
+
name: rexml
|
110
|
+
requirement: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
type: :runtime
|
116
|
+
prerelease: false
|
117
|
+
version_requirements: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
108
122
|
- !ruby/object:Gem::Dependency
|
109
123
|
name: rubocop
|
110
124
|
requirement: !ruby/object:Gem::Requirement
|
111
125
|
requirements:
|
112
126
|
- - "~>"
|
113
127
|
- !ruby/object:Gem::Version
|
114
|
-
version: '0
|
128
|
+
version: '1.0'
|
115
129
|
type: :development
|
116
130
|
prerelease: false
|
117
131
|
version_requirements: !ruby/object:Gem::Requirement
|
118
132
|
requirements:
|
119
133
|
- - "~>"
|
120
134
|
- !ruby/object:Gem::Version
|
121
|
-
version: '0
|
135
|
+
version: '1.0'
|
122
136
|
- !ruby/object:Gem::Dependency
|
123
137
|
name: rails
|
124
138
|
requirement: !ruby/object:Gem::Requirement
|
@@ -195,12 +209,14 @@ files:
|
|
195
209
|
- lib/wechat/api_loader.rb
|
196
210
|
- lib/wechat/cipher.rb
|
197
211
|
- lib/wechat/concern/common.rb
|
212
|
+
- lib/wechat/concern/qcloud.rb
|
198
213
|
- lib/wechat/controller_api.rb
|
199
214
|
- lib/wechat/corp_api.rb
|
200
215
|
- lib/wechat/helpers.rb
|
201
216
|
- lib/wechat/http_client.rb
|
202
217
|
- lib/wechat/message.rb
|
203
218
|
- lib/wechat/mp_api.rb
|
219
|
+
- lib/wechat/qcloud/token.rb
|
204
220
|
- lib/wechat/responder.rb
|
205
221
|
- lib/wechat/signature.rb
|
206
222
|
- lib/wechat/ticket/corp_jsapi_ticket.rb
|
@@ -219,7 +235,7 @@ require_paths:
|
|
219
235
|
- lib
|
220
236
|
required_ruby_version: !ruby/object:Gem::Requirement
|
221
237
|
requirements:
|
222
|
-
- - "
|
238
|
+
- - ">="
|
223
239
|
- !ruby/object:Gem::Version
|
224
240
|
version: '2.4'
|
225
241
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
@@ -228,7 +244,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
228
244
|
- !ruby/object:Gem::Version
|
229
245
|
version: '0'
|
230
246
|
requirements: []
|
231
|
-
rubygems_version: 3.
|
247
|
+
rubygems_version: 3.2.3
|
232
248
|
signing_key:
|
233
249
|
specification_version: 4
|
234
250
|
summary: DSL for wechat message handling and API
|
metadata.gz.sig
CHANGED
Binary file
|