wechat 0.16.2 → 0.17.2

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: bc8214345aa67e306a93fb57034de6f8ecc898c630e5abb56f29424b8a360110
4
- data.tar.gz: 7152a97b68aada44c5be152e57dbe55233efabe58124c9d36c73b560b213c51e
3
+ metadata.gz: 116d4ce16cfc0cab641c2f15bbfb112259f55fdc4ef92c802137412cb7bb5302
4
+ data.tar.gz: 12b1d3fa3ec0adfed6df712ee767d6c6a4cd35dad4c6f45cc1cca6791d61fa3f
5
5
  SHA512:
6
- metadata.gz: aed67b12d96ee44e7ab75b8f3fe2bf5170379efd9b94e2d6fab8a92a4a5f99d477ea032a2d1826b3ddc73b195a42ca0f2f72d6a92d27632eb2de0be8c593d62d
7
- data.tar.gz: 7c00e2715896186abfee532190aae993a766fc0a583f41545c62856a4d70554a6a365312a4d0d6e5eeba3e7259f6d552203e0079a70df73ed21677c924a63aa7
6
+ metadata.gz: 4cc56dd5145757fda475a8652c01c58f2e650df30cf9bfe7ac3fc4a5df2917fd82236ade96d29ad69bdccb495f19f223c93e7fe688e11e98621a747ae3efedab
7
+ data.tar.gz: 7b07126c3d6aaae770c2b8bb9c33d133ba489d9387743a2ddcc752e9ba2b89cebcc6203930a447cfcf229e06851af31fe09ff87b2f6cad64740b0c60f5dfd10e
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.17.2 (released at 2023-12-30)
4
+
5
+ * Fix no need the message type restrictions. by @leepood #319
6
+
7
+ ## v0.17.1 (released at 2023-07-28)
8
+
9
+ * Add Record based token support. by @CoolDrinELiu #315
10
+ * Add api shortlink.generate support. by @wikimo #316
11
+ * Add new api & Compatible with WeCom. by @leepood #317
12
+
13
+ ## v0.17.0 yarked
14
+
3
15
  ## v0.16.2 (released at 2022-12-09)
4
16
 
5
17
  * Drop support ruby 2.6 and allow ruby 3.2 will released psych v5.0.0. by @iuhoay #314
data/README-CN.md CHANGED
@@ -89,6 +89,14 @@ rake db:migrate
89
89
 
90
90
  appid/corpid 以及 secret 的配置请阅读下一节
91
91
 
92
+ #### 数据配置模式
93
+ 需要保证传入的 `record` 属性中包含 `access_token`, `token_expires_in`, `got_token_at`。
94
+ ```ruby
95
+ def client
96
+ @client ||= Wechat::Api.new(app_id, app_secret, token_file, network_setting, jsapi_ticket_file, record)
97
+ end
98
+ ```
99
+
92
100
  #### 命令行程序的配置
93
101
 
94
102
  要使用命令行程序,需要在 home 目录中创建一个 `~/.wechat.yml`,包含以下内容。其中 `access_token` 是存放 access_token 的文件位置。
data/README.md CHANGED
@@ -97,6 +97,14 @@ URL address for wechat created by running `rails g wechat:install` is `http://yo
97
97
 
98
98
  How to setup appid/corpid and secret see below section.
99
99
 
100
+ #### Configure wechat by record-based mode
101
+ Make sure the `record` attributes include `access_token`, `token_expires_in`, `got_token_at`.
102
+ ```ruby
103
+ def client
104
+ @client ||= Wechat::Api.new(app_id, app_secret, token_file, network_setting, jsapi_ticket_file, record)
105
+ end
106
+ ```
107
+
100
108
  #### Configure for command line
101
109
 
102
110
  To use standalone `wechat` command, you need to create configuration file `~/.wechat.yml` and include content below for public account. The `access_token` will be written to file `/var/tmp/wechat_access_token`.
data/bin/wechat CHANGED
@@ -236,6 +236,12 @@ class App < Thor
236
236
  puts wechat_api.wxa_generate_urllink(body_hash)
237
237
  end
238
238
 
239
+ desc 'wxa_generate_shortlink [PATH]', '获取小程序 Short Link'
240
+ def wxa_generate_shortlink(url, title = '', is_permanent = false)
241
+ body_hash = { page_url: url, page_title: title, is_permanent: is_permanent}
242
+ puts wechat_api.wxa_generate_shortlink(body_hash)
243
+ end
244
+
239
245
  desc 'media_uploadnews [MPNEWS_YAML_PATH]', '上传图文消息素材'
240
246
  def media_uploadnews(mpnews_yaml_path)
241
247
  mpnew = Wechat::ApiLoader.load_yaml(File.read(mpnews_yaml_path))
@@ -4,7 +4,7 @@
4
4
  # Feel free to inherit from other class like ActiveModel::Model
5
5
  class WechatSession < ActiveRecord::Base
6
6
  validates :openid, presence: true, uniqueness: true
7
- serialize :hash_store, Hash
7
+ serialize :hash_store, type: Hash
8
8
 
9
9
  # called by wechat gems when user request session
10
10
  def self.find_or_initialize_session(request_message)
data/lib/wechat/api.rb CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Wechat
4
4
  class Api < ApiBase
5
- def initialize(appid, secret, token_file, network_setting, jsapi_ticket_file)
5
+ def initialize(appid, secret, token_file, network_setting, jsapi_ticket_file, record = nil)
6
6
  super()
7
7
  @client = HttpClient.new(Wechat::Api::API_BASE, network_setting)
8
- @access_token = Token::PublicAccessToken.new(@client, appid, secret, token_file)
8
+ @access_token = Token::PublicAccessToken.new(@client, appid, secret, token_file, record)
9
9
  @jsapi_ticket = Ticket::PublicJsapiTicket.new(@client, @access_token, jsapi_ticket_file)
10
10
  @qcloud = nil
11
11
  end
@@ -124,7 +124,7 @@ module Wechat
124
124
  return config
125
125
  end
126
126
  end
127
- return resolve_config_file(home_config_file, nil) if File.exist?(home_config_file)
127
+ resolve_config_file(home_config_file, nil) if File.exist?(home_config_file)
128
128
  end
129
129
  end
130
130
 
@@ -88,6 +88,11 @@ module Wechat
88
88
  post 'message/mass/get', JSON.generate(msg_id: msg_id)
89
89
  end
90
90
 
91
+ def wxa_get_user_phone_number(code)
92
+ # https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/phone-number/getPhoneNumber.html
93
+ post 'business/getuserphonenumber', JSON.generate(code: code), base: Wechat::Api::WXA_BASE
94
+ end
95
+
91
96
  def wxa_get_wxacode(path, width = 430)
92
97
  post 'getwxacode', JSON.generate(path: path, width: width), base: Wechat::Api::WXA_BASE
93
98
  end
@@ -109,6 +114,10 @@ module Wechat
109
114
  post 'generate_urllink', JSON.generate(body_hash), base: Wechat::Api::WXA_BASE
110
115
  end
111
116
 
117
+ def wxa_generate_shortlink(body_hash)
118
+ post 'genwxashortlink', JSON.generate(body_hash), base: Wechat::Api::WXA_BASE
119
+ end
120
+
112
121
  def menu
113
122
  get 'menu/get'
114
123
  end
@@ -13,6 +13,11 @@ module Wechat
13
13
  @qcloud = nil
14
14
  end
15
15
 
16
+ def get_externalcontact(external_userid, cursor = nil)
17
+ # https://developer.work.weixin.qq.com/document/path/92114
18
+ get 'externalcontact/get', params: { external_userid: external_userid, cursor: cursor }
19
+ end
20
+
16
21
  def agent_list
17
22
  get 'agent/list'
18
23
  end
@@ -27,9 +27,12 @@ module Wechat
27
27
  page_url = page_url.split('#').first
28
28
  js_hash = api.jsapi_ticket.signature(page_url)
29
29
 
30
+ # Field `beta` please check https://developer.work.weixin.qq.com/document/path/90514#%E6%AD%A5%E9%AA%A4%E4%BA%8C%EF%BC%9A%E9%80%9A%E8%BF%87config%E6%8E%A5%E5%8F%A3%E6%B3%A8%E5%85%A5%E6%9D%83%E9%99%90%E9%AA%8C%E8%AF%81%E9%85%8D%E7%BD%AE
31
+
30
32
  config_js = <<~WECHAT_CONFIG_JS
31
33
  wx.config({
32
- debug: #{config_options[:debug]},
34
+ beta: #{config_options[:beta] || false},
35
+ debug: #{config_options[:debug] || false},
33
36
  appId: "#{app_id}",
34
37
  timestamp: "#{js_hash[:timestamp]}",
35
38
  nonceStr: "#{js_hash[:noncestr]}",
@@ -19,8 +19,6 @@ module Wechat
19
19
  attr_accessor :account_from_request
20
20
 
21
21
  def on(message_type, with: nil, respond: nil, &block)
22
- raise 'Unknow message type' unless %i[text image voice video shortvideo link event click view scan batch_job location label_location fallback].include?(message_type)
23
-
24
22
  config = respond.nil? ? {} : { respond: respond }
25
23
  config[:proc] = block if block_given?
26
24
 
@@ -3,13 +3,14 @@
3
3
  module Wechat
4
4
  module Token
5
5
  class AccessTokenBase
6
- attr_reader :client, :appid, :secret, :token_file, :access_token, :token_life_in_seconds, :got_token_at
6
+ attr_reader :client, :appid, :secret, :token_file, :access_token, :token_life_in_seconds, :got_token_at, :record
7
7
 
8
- def initialize(client, appid, secret, token_file)
8
+ def initialize(client, appid, secret, token_file, record = nil)
9
9
  @appid = appid
10
10
  @secret = secret
11
11
  @client = client
12
12
  @token_file = token_file
13
+ @record = record
13
14
  @random_generator = Random.new
14
15
  end
15
16
 
@@ -40,16 +41,57 @@ module Wechat
40
41
  end
41
42
 
42
43
  def read_token
43
- JSON.parse(File.read(token_file))
44
+ if record_based_token?
45
+ throw_error_if_missing_attributes!
46
+
47
+ {
48
+ 'access_token' => record.access_token,
49
+ 'got_token_at' => record.got_token_at,
50
+ 'token_expires_in' => record.token_expires_in
51
+ }
52
+ else
53
+ JSON.parse(File.read(token_file))
54
+ end
44
55
  end
45
56
 
46
57
  def write_token(token_hash)
47
- File.write(token_file, token_hash.to_json)
58
+ if record_based_token?
59
+ write_token_to_record(token_hash)
60
+ else
61
+ File.write(token_file, token_hash.to_json)
62
+ end
48
63
  end
49
64
 
50
65
  def remain_life_seconds
51
66
  token_life_in_seconds - (Time.now.to_i - got_token_at)
52
67
  end
68
+
69
+ private
70
+
71
+ def record_based_token?
72
+ record.present?
73
+ end
74
+
75
+ def write_token_to_record(token_hash)
76
+ throw_error_if_missing_attributes!
77
+
78
+ record.access_token = token_hash['access_token']
79
+ record.token_expires_in = token_hash['token_expires_in']
80
+ record.got_token_at = Time.now
81
+ record.save || record.save(validate: false)
82
+ end
83
+
84
+ def missing_necessary_attributes?
85
+ return true unless record.respond_to?(:access_token)
86
+ return true unless record.respond_to?(:token_expires_in)
87
+ return true unless record.respond_to?(:got_token_at)
88
+
89
+ false
90
+ end
91
+
92
+ def throw_error_if_missing_attributes!
93
+ raise "Missing attributes #access_token or #token_expires_in or #got_token_at in #{record.class.name}" if missing_necessary_attributes?
94
+ end
53
95
  end
54
96
  end
55
97
  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.16.2
4
+ version: 0.17.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Skinnyworm
@@ -13,30 +13,30 @@ cert_chain:
13
13
  -----BEGIN CERTIFICATE-----
14
14
  MIIEeDCCAuCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMRMwEQYDVQQDDAplcmlj
15
15
  Lmd1b2N6MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNj
16
- b20wHhcNMjIxMjA5MDcyMTE1WhcNMjMxMjA5MDcyMTE1WjBBMRMwEQYDVQQDDApl
16
+ b20wHhcNMjMxMjMwMDgzMDQ1WhcNMjQxMjI5MDgzMDQ1WjBBMRMwEQYDVQQDDApl
17
17
  cmljLmd1b2N6MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
18
- FgNjb20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC6jGarls5mU792
19
- leWot9tWKXnnvVnj1oUPea8M77PpHcYMVmjUTkjgsrKiOFNv2nAjUIDrUaLJvuKi
20
- 95zZYLIT3uWqI9QvSSDr+rs4HyIDcXuWWB89GpKN5WgyCVel6V9X5PN0C5hIiz8T
21
- ThW7ZqkS8mTmHm2micL8/lmnelpxj9EjCin7xOCvebB9pdA7Y0kXMLbnRq4QK2lB
22
- O2YRbLvYKWOQfO/sqLlwFsNWMNkj5ZROIqmKRvOHQdchox2RfBNsWRZ7XH8tTW1L
23
- cqx95dI2qC6Xg+IHjN4Wc6n+Ak1KENlVjI4mGcuk+34d1S9gaZT8vW/cYcL30Nbg
24
- AAUQvS4AQ8gmAkk1+oNs+725QLBprbnSN5PJr9VQiDteNHHkY5ugjndeAByOGy8h
25
- /TgV4tBZQ0IT37ZRDcP4dayFMm2DVjS4uU7RUXLgc8sdOGeMmsFwdz9QrBPGeKsV
26
- 4+dXjrzzUvwRX4K21mx4ZSP9eSOscOEuzRIRTnab0GniDhkkHc8CAwEAAaN7MHkw
27
- CQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFPGkToJNhoEfhsOYqnTH
28
- MZDYyjQtMB8GA1UdEQQYMBaBFGVyaWMuZ3VvY3pAZ21haWwuY29tMB8GA1UdEgQY
29
- MBaBFGVyaWMuZ3VvY3pAZ21haWwuY29tMA0GCSqGSIb3DQEBCwUAA4IBgQCdTl5T
30
- qfcrbo4KdgZM84ZbeiUIXcRy/chbfQfPZ/qPp7qKARLxRJINmaqt/bP+RrlQypEe
31
- 1EIYhbxLGo1TvpbRFuADUhZjGZ8Vaa+bgPfj8Dxa71ow5dF9nrqidddV7qjmk57F
32
- klOrOl+99Ryx01OAdlxGZqz/VrHrzbhQNtiUl2BYnosZLddYPTzuhNLe72eIypkY
33
- synsOqoXRuegCtO4sSGSvRV79/GyN0jqtptpa61MaxgYG13+P8QwXeTo2Ro86ZAJ
34
- h+KBs65p0MiFHl6zc2oany9Pk0kqs50TDKOCT7ZdSxz5xes0SvTi3mmX3XemjQhm
35
- qNb+5zsj4Kn5auKYA7GupfLYKS/dYt4EIfNKhSEHgkVFdVPxSAQ73UAWsndINTTA
36
- HjK18j09PoL9vWMUtyez2xpxlRDA+bEkF74AEVwMYozjP8VNM1ERTG+8kROuQjGV
37
- aWhGk3yVuHjmlBvfDpPqmux3ulWXnvHulcYiPxETh/m3PUfIKMTHydjAz88=
18
+ FgNjb20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDvLvsV0dygCIpJ
19
+ fi58762MvuxkFod1TEHkx2kmGbdazIrnS5uR1/H3dw+TY8tPp0/AdD4LYw2JOJy/
20
+ 2T9LUAO5HRBFRVfQEBqpEiIix8TK1uu62Ba9DKBng0y+2hpcdMnQE7xgri8QN1QA
21
+ xg9z7P7tRCCI/x8IEFI+2DNTVZqI20a3OniliWiGc+GE9/H7uYR3VvFxQyCrPGsR
22
+ 09Hp0FvjYQbkNoRznhNd+IqXs9t9AkaUqhuAzPMQYA3YVil8VWUJGVCaIYT6itUy
23
+ M7fIMjwZkUHLZJfikqzJB2n4R91huTb3BfEUMjJ2gonuVUjsmgrpk5kzKIkr3Z49
24
+ K/3PW6lt6sCKeBxqKUq7KGejND0QhH85Jn/RBJf5iLc8YX8IvjonsF+mDahnhQcH
25
+ qFavtYkmcTwCr6EjrsY5kR/XgxKfyB5r8QYkqhrGI84w9RhI9crmLEW0wC8ByZj0
26
+ m5D5wn/0b91hNmoqvkQyH2H5UCB9lo1CljRCb2/YefMg+s9iyrcCAwEAAaN7MHkw
27
+ CQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJ38163LBZjvmEfRWTXp
28
+ ZjFNx8ndMB8GA1UdEQQYMBaBFGVyaWMuZ3VvY3pAZ21haWwuY29tMB8GA1UdEgQY
29
+ MBaBFGVyaWMuZ3VvY3pAZ21haWwuY29tMA0GCSqGSIb3DQEBCwUAA4IBgQDin3tk
30
+ EDZowoDU06C8CLFfnGX3PYT43c+dJi52L3mAEDilLirmoq/H8xbq9bxyCpofJj/b
31
+ Wyn+Ada+OjWvSRTdRHHd/w2MPNTiTaRhKi5w1xbLxJndjIKDsAWYIYX5vdryfjBJ
32
+ UngqW5Imxx4jzWCpvFAA1XfV2J/WD3IKRBhSECCslzTEBYwcJaj0UHmYJofMOJEh
33
+ f5Fsu5w3dXOBtmUzN9G2dgssmY8ldEtuSkj8USjsW1aWAEmfnDpQH1YSnA2uLo7d
34
+ 9cDmklPUoOO15i9Yjv+rYoWAqHFzPBUxUnuy/lIJSFTR0bD9b2+JuCSRvY95glad
35
+ lNKyXpZe/w2kofm5cSyoSF3TxeHKn29tQl8zgo2mwtuz042QSVcIw+5Q5wcmZpXL
36
+ uxhUIIN2A+qeUxOIoO9VfGAX5Q+cQ4J+EpKkDovIHaG0tJdNoA9EABD8yMMHgWgw
37
+ q9fk/nu08SjME28EsSxW0oLUQq1vHNKWUyZuHtihd0yBYGRJH7xdZivkUOs=
38
38
  -----END CERTIFICATE-----
39
- date: 2022-12-09 00:00:00.000000000 Z
39
+ date: 2023-12-30 00:00:00.000000000 Z
40
40
  dependencies:
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activesupport
@@ -162,42 +162,42 @@ dependencies:
162
162
  requirements:
163
163
  - - "~>"
164
164
  - !ruby/object:Gem::Version
165
- version: '5.1'
165
+ version: '6.0'
166
166
  type: :development
167
167
  prerelease: false
168
168
  version_requirements: !ruby/object:Gem::Requirement
169
169
  requirements:
170
170
  - - "~>"
171
171
  - !ruby/object:Gem::Version
172
- version: '5.1'
172
+ version: '6.0'
173
173
  - !ruby/object:Gem::Dependency
174
174
  name: rspec-mocks
175
175
  requirement: !ruby/object:Gem::Requirement
176
176
  requirements:
177
- - - '='
177
+ - - "~>"
178
178
  - !ruby/object:Gem::Version
179
- version: 3.10.2
179
+ version: '3.12'
180
180
  type: :development
181
181
  prerelease: false
182
182
  version_requirements: !ruby/object:Gem::Requirement
183
183
  requirements:
184
- - - '='
184
+ - - "~>"
185
185
  - !ruby/object:Gem::Version
186
- version: 3.10.2
186
+ version: '3.12'
187
187
  - !ruby/object:Gem::Dependency
188
188
  name: sqlite3
189
189
  requirement: !ruby/object:Gem::Requirement
190
190
  requirements:
191
191
  - - "~>"
192
192
  - !ruby/object:Gem::Version
193
- version: '1.4'
193
+ version: '1.5'
194
194
  type: :development
195
195
  prerelease: false
196
196
  version_requirements: !ruby/object:Gem::Requirement
197
197
  requirements:
198
198
  - - "~>"
199
199
  - !ruby/object:Gem::Version
200
- version: '1.4'
200
+ version: '1.5'
201
201
  description: API, command and message handling for WeChat in Rails
202
202
  email: eric.guocz@gmail.com
203
203
  executables:
@@ -257,8 +257,8 @@ licenses:
257
257
  metadata:
258
258
  bug_tracker_uri: https://github.com/Eric-Guo/wechat/issues
259
259
  changelog_uri: https://github.com/Eric-Guo/wechat/releases
260
- documentation_uri: https://github.com/Eric-Guo/wechat/tree/v0.16.2#readme
261
- source_code_uri: https://github.com/Eric-Guo/wechat/tree/v0.16.2
260
+ documentation_uri: https://github.com/Eric-Guo/wechat/tree/v0.17.2#readme
261
+ source_code_uri: https://github.com/Eric-Guo/wechat/tree/v0.17.2
262
262
  rubygems_mfa_required: 'true'
263
263
  post_install_message:
264
264
  rdoc_options: []
@@ -273,9 +273,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
273
273
  requirements:
274
274
  - - ">="
275
275
  - !ruby/object:Gem::Version
276
- version: 1.8.11
276
+ version: 3.1.6
277
277
  requirements: []
278
- rubygems_version: 3.3.26
278
+ rubygems_version: 3.5.3
279
279
  signing_key:
280
280
  specification_version: 4
281
281
  summary: DSL for wechat message handling and API
metadata.gz.sig CHANGED
Binary file