wechat 0.8.12 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +9 -0
- data/README-CN.md +69 -0
- data/README.md +68 -0
- data/bin/wechat +22 -3
- data/lib/generators/wechat/config_generator.rb +36 -0
- data/lib/generators/wechat/session_generator.rb +11 -1
- data/lib/generators/wechat/templates/app/models/wechat_config.rb +46 -0
- data/lib/generators/wechat/templates/db/config_migration.rb.erb +40 -0
- data/lib/generators/wechat/templates/db/{migration.rb → session_migration.rb.erb} +1 -1
- data/lib/wechat.rb +4 -0
- data/lib/wechat/api_loader.rb +14 -0
- data/lib/wechat/corp_api.rb +4 -8
- data/lib/wechat/http_client.rb +4 -1
- metadata +9 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1ba8ea75d218bce256ab3ac81dd380747abc5515713f69cfc7353db5c02a3ebb
|
4
|
+
data.tar.gz: 40c60efec124604c7141983de97b121735c45be33213f4395ad7df2c5f967d52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce2ff6717092db5798ab87791acc1ed75465c49a624ad7f7cb946748a3b144d98ff22758d29ed6699744379555bc95a0929358eeb3e19ae668c87b26dd0014b4
|
7
|
+
data.tar.gz: 104a924a1f55c75662b32f41600b81dde58bb33a8bc9c0d377517bb092aff8c72d5c51aa772b22e69c3308bc8523fd424f45a894d9686436358f8afa87cb17e1
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v0.9.0 (released at 4/15/2018)
|
4
|
+
|
5
|
+
* Support multi wechat account dynamically loading from DB. by @tuliren #222
|
6
|
+
* user_create API for enterprise account. #206
|
7
|
+
* Will ignore template_message_send error 43004 by @insub #214
|
8
|
+
* using template with version if the migration version available by @killernova #220
|
9
|
+
* Remove Deprecation oauth2_url
|
10
|
+
* Remove Ruby 2.2 support, add Rails 5.2 and http v3 support
|
11
|
+
|
3
12
|
## v0.8.12 (released at 9/13/2017)
|
4
13
|
|
5
14
|
* Read oauth2_state from ticket store every time to avoid invalid oauth2_state by @xiewenwei #196
|
data/README-CN.md
CHANGED
@@ -66,6 +66,15 @@ rails g wechat:redis_store
|
|
66
66
|
|
67
67
|
Redis存贮相比默认的文件存贮,可以允许Rails应用运行在多台服务器中,如果只有一台服务器,仍然推荐使用默认的文件存贮,另外命令行不会读取Redis存贮的Token或者Ticket。
|
68
68
|
|
69
|
+
启用数据库配置微信账户:
|
70
|
+
|
71
|
+
```console
|
72
|
+
rails g wechat:config
|
73
|
+
rake db:migrate
|
74
|
+
```
|
75
|
+
|
76
|
+
运行后会在数据库中创建 `wechat_configs` 表,用来记录不同微信账户的配置。
|
77
|
+
|
69
78
|
## 配置
|
70
79
|
|
71
80
|
#### 微信的第一次配置
|
@@ -185,10 +194,36 @@ test:
|
|
185
194
|
|
186
195
|
进一步的多账号支持参见[PR 150](https://github.com/Eric-Guo/wechat/pull/150)。
|
187
196
|
|
197
|
+
#### 数据库微信账户配置
|
198
|
+
启用数据库微信配置之后,会生成如下数据表:
|
199
|
+
|
200
|
+
属性 | 类型 | 备注
|
201
|
+
---- | ---- | ----
|
202
|
+
environment | 字串 | 必填。配置对应的运行环境,一般有:`production`、`development`、`test`。比如 `production` 配置仅在生产环境有效。默认为 `development`。
|
203
|
+
account | 字串 | 必填。自定义的微信账户名称。同一 `environment` 下,账户名称不允许重复。
|
204
|
+
enabled | 布尔 | 必填。配置是否生效。默认 `true`。
|
205
|
+
appid | 字串 | 公众号 id。此字段和 `corpid` 两者必填其一。
|
206
|
+
secret | 字串 | 公众号相关配置。当公众号 `appid` 存在时必填。
|
207
|
+
corpid | 字串 | 企业号 id。此字段和 `appid` 两者必填其一。
|
208
|
+
corpsecret | 字串 | 企业号相关配置。当企业号 `corpid` 存在时必填。
|
209
|
+
agentid | 整数 | 企业号相关配置。当企业号 `corpid` 存在时必填。
|
210
|
+
encrypt_mode | 布尔 |
|
211
|
+
encoding_aes_key | 字串 | 当 `encrypt_mode` 为 `true` 时必填。
|
212
|
+
token | 字串 | 必填。
|
213
|
+
access_token | 字串 | 必填。存储 `access token` 文件的路径。
|
214
|
+
jsapi_ticket | 字串 | 必填。存储 `jsapi ticket` 文件的路径。
|
215
|
+
skip_verify_ssl | 布尔
|
216
|
+
timeout | 整数 | 默认值是 20。
|
217
|
+
trusted_domain_fullname | 字串 |
|
218
|
+
|
219
|
+
数据库配置更新后,需要重启服务器或者调用 `Wechat.reload_config!` 载入更新,否则更新不会生效。
|
220
|
+
|
188
221
|
##### 配置优先级
|
189
222
|
|
190
223
|
注意在Rails项目根目录下运行`wechat`命令行工具会优先使用`config/wechat.yml`中的`default`配置,如果失败则使用`~\.wechat.yml`中的配置,以便于在生产环境下管理多个微信账号应用。
|
191
224
|
|
225
|
+
如果启用数据库账户配置,数据库中的账户信息在读入 `wechat.yml` 或环境变量之后被载入。当存在同名账户时,数据库中的配置会覆盖前两者。
|
226
|
+
|
192
227
|
##### 配置微信服务器超时
|
193
228
|
|
194
229
|
微信服务器有时请求会花很长时间,如果不配置,默认为20秒,可视情况配置。
|
@@ -219,6 +254,35 @@ class WechatFirstController < ActionController::Base
|
|
219
254
|
end
|
220
255
|
```
|
221
256
|
|
257
|
+
#### 为每个 request 配置不同的 `appid`
|
258
|
+
|
259
|
+
若需要动态处理不同微信公众号的消息,您需要用数据库存储账户设置,然后调用 `wechat_oauth2` 或者 `Wechat#api`:
|
260
|
+
|
261
|
+
```ruby
|
262
|
+
class WechatReportsController < ApplicationController
|
263
|
+
wechat_api
|
264
|
+
layout 'wechat'
|
265
|
+
|
266
|
+
def index
|
267
|
+
# 通过自定义方法,从 request 中得到微信账户名称
|
268
|
+
account_name = get_account_from_url(request)
|
269
|
+
|
270
|
+
wechat_oauth2('snsapi_base', nil, account_name) do |openid|
|
271
|
+
@current_user = User.find_by(wechat_openid: openid)
|
272
|
+
@articles = @current_user.articles
|
273
|
+
end
|
274
|
+
|
275
|
+
Wechat.api(account_name)
|
276
|
+
end
|
277
|
+
|
278
|
+
private
|
279
|
+
# 预期的 URL: .../wechat/<account-name>/...
|
280
|
+
def get_account_from_url(request)
|
281
|
+
request.original_url.match(/wechat\/(.*)\//)[1]
|
282
|
+
end
|
283
|
+
end
|
284
|
+
```
|
285
|
+
|
222
286
|
#### JS-SDK 支持
|
223
287
|
|
224
288
|
通过JS-SDK可以在HTML网页中控制微信客户端的行为,但必须先注入配置信息,wechat gems提供了帮助方法`wechat_config_js`使这个过程更简单:
|
@@ -395,6 +459,7 @@ Wechat Enterprise Account commands:
|
|
395
459
|
wechat upload_replaceuser [BATCH_USER_CSV_PATH] # 上传文件方式全量覆盖成员
|
396
460
|
wechat user [OPEN_ID] # 获取用户基本信息
|
397
461
|
wechat user_batchdelete [USER_ID_LIST] # 批量删除成员
|
462
|
+
wechat user_create [USER_ID, NAME] # 创建成员
|
398
463
|
wechat user_delete [USER_ID] # 删除成员
|
399
464
|
wechat user_list [DEPARTMENT_ID] # 获取部门成员详情
|
400
465
|
wechat user_simplelist [DEPARTMENT_ID] # 获取部门成员
|
@@ -560,6 +625,10 @@ class WechatReportsController < ApplicationController
|
|
560
625
|
end
|
561
626
|
```
|
562
627
|
|
628
|
+
## 在ActiveJob/Rake tasks中调用有wechat api
|
629
|
+
|
630
|
+
可以通过`Wechat.api`在任意地方使用wechat api的功能。
|
631
|
+
|
563
632
|
## wechat_responder - Rails Responder Controller DSL
|
564
633
|
|
565
634
|
为了在Rails app中响应用户的消息,开发者需要创建一个wechat responder controller. 首先在router中定义
|
data/README.md
CHANGED
@@ -73,6 +73,15 @@ rails g wechat:redis_store
|
|
73
73
|
|
74
74
|
Redis store supports Rails application running in multi-server, no need to enable it if your Rails application is running on one server only, the wechat command won't read the token/ticket stored in Redis.
|
75
75
|
|
76
|
+
Enable database wechat configurations:
|
77
|
+
|
78
|
+
```console
|
79
|
+
rails g wechat:config
|
80
|
+
rake db:migrate
|
81
|
+
```
|
82
|
+
|
83
|
+
After running the migration, a `wechat_configs` table will be created that allows storage of multiple wechat accounts.
|
84
|
+
|
76
85
|
## Configuration
|
77
86
|
|
78
87
|
#### Configure wechat for the first time
|
@@ -198,10 +207,36 @@ test:
|
|
198
207
|
|
199
208
|
For multiple accounts details reference [PR 150](https://github.com/Eric-Guo/wechat/pull/150)
|
200
209
|
|
210
|
+
#### Database wechat account configuration
|
211
|
+
After enabling database account configuration, the following table will be created:
|
212
|
+
|
213
|
+
Attribute | Type | Annotation
|
214
|
+
---- | ---- | ----
|
215
|
+
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`.
|
216
|
+
account | string | Required. Custom wechat account name. Account names must be unique within each environment.
|
217
|
+
enabled | boolean | Required. Whether this configuration is activated. Default to `true`.
|
218
|
+
appid | string | Public account id. Either this attribute or `corpid` must be specified.
|
219
|
+
secret | string | Public account configuration. Required when `appid` exists.
|
220
|
+
corpid | string | Corp account id. Either this attribute or `appid` must be specified.
|
221
|
+
corpsecret | string | Corp account configuration. Required when `corpid` exists.
|
222
|
+
agentid | integer | Corp account configuration. Required when `corpid` exists.
|
223
|
+
encrypt_mode | boolean |
|
224
|
+
encoding_aes_key | string | Required when `encrypt_mode` is `true`.
|
225
|
+
token | string | Required.
|
226
|
+
access_token | string | Required. Path to `access token` storage file.
|
227
|
+
jsapi_ticket | string | Required. Path to `jsapi ticket` storage file.
|
228
|
+
skip_verify_ssl | boolean
|
229
|
+
timeout | integer | Default to 20.
|
230
|
+
trusted_domain_fullname | string |
|
231
|
+
|
232
|
+
After updating database account configurations, you need to restart the server, or call `Wechat.reload_config!` to reload the updates.
|
233
|
+
|
201
234
|
##### Configure priority
|
202
235
|
|
203
236
|
Running `wechat` command in the root folder of Rails application will be using the Rails configuration first (`default` section), if can not find it, will relay on `~\.wechat.yml`, such behavior enables managing more wechat public account and enterprise account without changing your home `~\.wechat.yml` file.
|
204
237
|
|
238
|
+
When database account configuration is enabled, database configurations will be loaded after `yml` configuration file or environment parameters. When configurations with the same account name exist in both database and `yml` file or environment parameter, the one in the database will take precedence.
|
239
|
+
|
205
240
|
##### Wechat server timeout setting
|
206
241
|
|
207
242
|
Stability varies for Tencent wechat server, so setting a long timeout may be needed, default is 20 seconds if not set.
|
@@ -232,6 +267,34 @@ class WechatFirstController < ActionController::Base
|
|
232
267
|
end
|
233
268
|
```
|
234
269
|
|
270
|
+
#### Configure individual request with different `appid`
|
271
|
+
|
272
|
+
If you want the controller to dynamically apply different account configurations for each request, you need to enable database account configuration, and call `wechat_oauth2` or `Wechat#api`:
|
273
|
+
|
274
|
+
```ruby
|
275
|
+
class WechatReportsController < ApplicationController
|
276
|
+
wechat_api
|
277
|
+
layout 'wechat'
|
278
|
+
|
279
|
+
def index
|
280
|
+
account_name = get_account_from_url(request)
|
281
|
+
|
282
|
+
wechat_oauth2('snsapi_base', nil, account_name) do |openid|
|
283
|
+
@current_user = User.find_by(wechat_openid: openid)
|
284
|
+
@articles = @current_user.articles
|
285
|
+
end
|
286
|
+
|
287
|
+
Wechat.api(account_name)
|
288
|
+
end
|
289
|
+
|
290
|
+
private
|
291
|
+
# Expected URL: .../wechat/<account-name>/...
|
292
|
+
def get_account_from_url(request)
|
293
|
+
request.original_url.match(/wechat\/(.*)\//)[1]
|
294
|
+
end
|
295
|
+
end
|
296
|
+
```
|
297
|
+
|
235
298
|
#### JS-SDK helper
|
236
299
|
|
237
300
|
JS-SDK gives you control over Wechat App behavior in html, by injecting a config signature, helper `wechat_config_js` does that in a simple way:
|
@@ -411,6 +474,7 @@ Wechat Enterprise Account commands:
|
|
411
474
|
wechat upload_replaceuser [BATCH_USER_CSV_PATH] # 上传文件方式全量覆盖成员
|
412
475
|
wechat user [OPEN_ID] # 获取用户基本信息
|
413
476
|
wechat user_batchdelete [USER_ID_LIST] # 批量删除成员
|
477
|
+
wechat user_create [USER_ID, NAME] # 创建成员
|
414
478
|
wechat user_delete [USER_ID] # 删除成员
|
415
479
|
wechat user_list [DEPARTMENT_ID] # 获取部门成员详情
|
416
480
|
wechat user_simplelist [DEPARTMENT_ID] # 获取部门成员
|
@@ -575,6 +639,10 @@ class WechatReportsController < ApplicationController
|
|
575
639
|
end
|
576
640
|
```
|
577
641
|
|
642
|
+
## Using wechat api at ActiveJob/Rake tasks
|
643
|
+
|
644
|
+
Using `Wechat.api` to access the wechat api function at any place.
|
645
|
+
|
578
646
|
## wechat_responder - Rails Responder Controller DSL
|
579
647
|
|
580
648
|
In order to respond to the message user sent, Rails developer needs to create a wechat responder controller and define the routing in `routes.rb`
|
data/bin/wechat
CHANGED
@@ -63,7 +63,7 @@ class App < Thor
|
|
63
63
|
end
|
64
64
|
|
65
65
|
desc 'department [DEPARTMENT_ID]', '获取部门列表'
|
66
|
-
def department(departmentid =
|
66
|
+
def department(departmentid = 1)
|
67
67
|
r = wechat_api.department(departmentid)
|
68
68
|
puts "errcode: #{r['errcode']} errmsg: #{r['errmsg']}"
|
69
69
|
puts 'Or# pid id name'
|
@@ -72,6 +72,25 @@ class App < Thor
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
desc 'user_create [USER_ID, NAME]', '创建成员'
|
76
|
+
method_option :departmentid, aliases: '-d', desc: '所属部门id'
|
77
|
+
method_option :mobile, aliases: '-m', desc: '手机号码'
|
78
|
+
method_option :email, aliases: '-e', desc: '邮箱'
|
79
|
+
method_option :weixinid, aliases: '-w', desc: '微信号'
|
80
|
+
def user_create(userid, name)
|
81
|
+
api_opts = options.slice(:departmentid, :mobile, :email, :weixinid)
|
82
|
+
user = { userid: userid, name: name }
|
83
|
+
if api_opts[:departmentid].present?
|
84
|
+
user[:department] = Array(api_opts['departmentid'].to_i)
|
85
|
+
else
|
86
|
+
user[:department] = [1]
|
87
|
+
end
|
88
|
+
user[:mobile] = api_opts[:mobile] if api_opts[:mobile].present?
|
89
|
+
user[:email] = api_opts[:email] if api_opts[:email].present?
|
90
|
+
user[:weixinid] = api_opts[:weixinid] if api_opts[:weixinid].present?
|
91
|
+
puts wechat_api.user_create(user)
|
92
|
+
end
|
93
|
+
|
75
94
|
desc 'user_delete [USER_ID]', '删除成员'
|
76
95
|
def user_delete(userid)
|
77
96
|
puts wechat_api.user_delete(userid)
|
@@ -85,7 +104,7 @@ class App < Thor
|
|
85
104
|
desc 'user_simplelist [DEPARTMENT_ID]', '获取部门成员'
|
86
105
|
method_option :fetch_child, aliases: '-c', desc: '是否递归获取子部门下面的成员', default: 1
|
87
106
|
method_option :status, aliases: '-s', desc: '0 获取全部成员,1 获取已关注成员列表,2 获取禁用成员列表,4 获取未关注成员列表。status可叠加', default: 0
|
88
|
-
def user_simplelist(departmentid =
|
107
|
+
def user_simplelist(departmentid = 1)
|
89
108
|
api_opts = options.slice(:fetch_child, :status)
|
90
109
|
|
91
110
|
r = wechat_api.user_simplelist(departmentid, api_opts[:fetch_child], api_opts[:status])
|
@@ -99,7 +118,7 @@ class App < Thor
|
|
99
118
|
desc 'user_list [DEPARTMENT_ID]', '获取部门成员详情'
|
100
119
|
method_option :fetch_child, aliases: '-c', desc: '是否递归获取子部门下面的成员', default: 0
|
101
120
|
method_option :status, aliases: '-s', desc: '0 获取全部成员,1 获取已关注成员列表,2 获取禁用成员列表,4 获取未关注成员列表。status可叠加', default: 0
|
102
|
-
def user_list(departmentid =
|
121
|
+
def user_list(departmentid = 1)
|
103
122
|
api_opts = options.slice(:fetch_child, :status)
|
104
123
|
|
105
124
|
r = wechat_api.user_list(departmentid, api_opts[:fetch_child], api_opts[:status])
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
module Wechat
|
4
|
+
module Generators
|
5
|
+
class ConfigGenerator < Rails::Generators::Base
|
6
|
+
include ::Rails::Generators::Migration
|
7
|
+
|
8
|
+
desc 'Generate wechat configs in database'
|
9
|
+
source_root File.expand_path('../templates', __FILE__)
|
10
|
+
|
11
|
+
def copy_wechat_config_migration
|
12
|
+
migration_template(
|
13
|
+
'db/config_migration.rb.erb',
|
14
|
+
'db/migrate/create_wechat_configs.rb',
|
15
|
+
{migration_version: migration_version}
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def copy_wechat_config_model
|
20
|
+
template 'app/models/wechat_config.rb'
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def self.next_migration_number(dirname)
|
26
|
+
::ActiveRecord::Generators::Base.next_migration_number(dirname)
|
27
|
+
end
|
28
|
+
|
29
|
+
def migration_version
|
30
|
+
if Rails.version >= '5.0.0'
|
31
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -9,7 +9,11 @@ module Wechat
|
|
9
9
|
source_root File.expand_path('../templates', __FILE__)
|
10
10
|
|
11
11
|
def copy_wechat_sessions_migration
|
12
|
-
migration_template
|
12
|
+
migration_template(
|
13
|
+
'db/session_migration.rb.erb',
|
14
|
+
'db/migrate/create_wechat_sessions.rb',
|
15
|
+
{migration_version: migration_version}
|
16
|
+
)
|
13
17
|
end
|
14
18
|
|
15
19
|
def copy_wechat_session_model
|
@@ -21,6 +25,12 @@ module Wechat
|
|
21
25
|
def self.next_migration_number(dirname)
|
22
26
|
::ActiveRecord::Generators::Base.next_migration_number(dirname)
|
23
27
|
end
|
28
|
+
|
29
|
+
def migration_version
|
30
|
+
if Rails.version >= '5.0.0'
|
31
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
32
|
+
end
|
33
|
+
end
|
24
34
|
end
|
25
35
|
end
|
26
36
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Used by wechat gems, do not rename WechatConfig to other name,
|
2
|
+
# Feel free to inherit from other class like ActiveModel::Model
|
3
|
+
class WechatConfig < ActiveRecord::Base
|
4
|
+
validates :environment, presence: true
|
5
|
+
validates :account, presence: true, uniqueness: { scope: [:environment] }
|
6
|
+
validates :token, presence: true
|
7
|
+
validates :access_token, presence: true
|
8
|
+
validates :jsapi_ticket, presence: true
|
9
|
+
validates :encoding_aes_key, presence: { if: :encrypt_mode? }
|
10
|
+
|
11
|
+
validate :app_config_is_valid
|
12
|
+
|
13
|
+
ATTRIBUTES_TO_REMOVE = %w(environment account created_at updated_at enabled)
|
14
|
+
|
15
|
+
def self.get_all_configs(environment)
|
16
|
+
WechatConfig.where(environment: environment, enabled: true).inject({}) do |hash, config|
|
17
|
+
hash[config.account] = config.build_config_hash
|
18
|
+
hash
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_config_hash
|
23
|
+
self.as_json(except: ATTRIBUTES_TO_REMOVE)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def app_config_is_valid
|
29
|
+
if self[:appid].present?
|
30
|
+
# public account
|
31
|
+
if self[:secret].blank?
|
32
|
+
errors.add(:secret, 'cannot be nil when appid is set')
|
33
|
+
end
|
34
|
+
elsif self[:corpid].present?
|
35
|
+
# corp account
|
36
|
+
if self[:corpsecret].blank?
|
37
|
+
errors.add(:corpsecret, 'cannot be nil when corpid is set')
|
38
|
+
end
|
39
|
+
if self[:agentid].blank?
|
40
|
+
errors.add(:agentid, 'cannot be nil when corpid is set')
|
41
|
+
end
|
42
|
+
else
|
43
|
+
errors[:base] << 'Either appid or corpid must be set'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class CreateWechatConfigs < ActiveRecord::Migration<%= migration_version %>
|
2
|
+
def change
|
3
|
+
create_table :wechat_configs do |t|
|
4
|
+
# config environment, typical values: production, development or test
|
5
|
+
t.string :environment, null: false, default: 'development'
|
6
|
+
# account name
|
7
|
+
t.string :account, null: false
|
8
|
+
# whether this config is activated
|
9
|
+
t.boolean :enabled, default: true
|
10
|
+
|
11
|
+
# public account
|
12
|
+
t.string :appid
|
13
|
+
t.string :secret
|
14
|
+
|
15
|
+
# corp account
|
16
|
+
t.string :corpid
|
17
|
+
t.string :corpsecret
|
18
|
+
t.integer :agentid
|
19
|
+
|
20
|
+
# when encrypt_mode is true, encoding_aes_key must be specified
|
21
|
+
t.boolean :encrypt_mode
|
22
|
+
t.string :encoding_aes_key
|
23
|
+
|
24
|
+
# app token
|
25
|
+
t.string :token, null: false
|
26
|
+
# path to access token storage file
|
27
|
+
t.string :access_token, null: false
|
28
|
+
# path to jsapi ticket storage file
|
29
|
+
t.string :jsapi_ticket, null: false
|
30
|
+
# set to false if RestClient::SSLCertificateNotVerified is thrown
|
31
|
+
t.boolean :skip_verify_ssl, default: true
|
32
|
+
t.integer :timeout, default: 20
|
33
|
+
t.string :trusted_domain_fullname
|
34
|
+
|
35
|
+
t.timestamps null: false
|
36
|
+
end
|
37
|
+
|
38
|
+
add_index :wechat_configs, [:environment, :account], unique: true, length: {environment: 20, account: 100}
|
39
|
+
end
|
40
|
+
end
|
data/lib/wechat.rb
CHANGED
@@ -28,6 +28,10 @@ module Wechat
|
|
28
28
|
@wechat_apis ||= {}
|
29
29
|
@wechat_apis[account.to_sym] ||= ApiLoader.with(account: account)
|
30
30
|
end
|
31
|
+
|
32
|
+
def self.reload_config!
|
33
|
+
ApiLoader.reload_config!
|
34
|
+
end
|
31
35
|
end
|
32
36
|
|
33
37
|
ActionView::Base.send :include, Wechat::Helpers if defined? ActionView::Base
|
data/lib/wechat/api_loader.rb
CHANGED
@@ -24,8 +24,13 @@ module Wechat
|
|
24
24
|
@configs[account.to_sym] || raise("Wechat configuration for #{account} is missing.")
|
25
25
|
end
|
26
26
|
|
27
|
+
def self.reload_config!
|
28
|
+
@configs = loading_config!
|
29
|
+
end
|
30
|
+
|
27
31
|
private_class_method def self.loading_config!
|
28
32
|
configs = config_from_file || config_from_environment
|
33
|
+
configs.merge!(config_from_db)
|
29
34
|
|
30
35
|
configs.symbolize_keys!
|
31
36
|
configs.each do |key, cfg|
|
@@ -57,6 +62,15 @@ module Wechat
|
|
57
62
|
cfg_objs
|
58
63
|
end
|
59
64
|
|
65
|
+
private_class_method def self.config_from_db
|
66
|
+
unless class_exists?('WechatConfig')
|
67
|
+
return {}
|
68
|
+
end
|
69
|
+
|
70
|
+
environment = defined?(::Rails) ? Rails.env.to_s : ENV['RAILS_ENV'] || 'development'
|
71
|
+
WechatConfig.get_all_configs(environment)
|
72
|
+
end
|
73
|
+
|
60
74
|
private_class_method def self.config_from_file
|
61
75
|
if defined?(::Rails)
|
62
76
|
config_file = ENV['WECHAT_CONF_FILE'] || Rails.root.join('config/wechat.yml')
|
data/lib/wechat/corp_api.rb
CHANGED
@@ -2,7 +2,6 @@ require 'wechat/api_base'
|
|
2
2
|
require 'wechat/http_client'
|
3
3
|
require 'wechat/token/corp_access_token'
|
4
4
|
require 'wechat/ticket/corp_jsapi_ticket'
|
5
|
-
require 'cgi'
|
6
5
|
|
7
6
|
module Wechat
|
8
7
|
class CorpApi < ApiBase
|
@@ -33,13 +32,6 @@ module Wechat
|
|
33
32
|
get 'user/getuserinfo', params: { code: code }
|
34
33
|
end
|
35
34
|
|
36
|
-
def oauth2_url(redirect_uri, appid)
|
37
|
-
ActiveSupport::Deprecation.warn('oauth2_url is deprecated. use wechat_oauth2 instead.')
|
38
|
-
|
39
|
-
redirect_uri = CGI.escape(redirect_uri)
|
40
|
-
"https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{appid}&redirect_uri=#{redirect_uri}&response_type=code&scope=snsapi_base#wechat_redirect"
|
41
|
-
end
|
42
|
-
|
43
35
|
def convert_to_openid(userid)
|
44
36
|
post 'user/convert_to_openid', JSON.generate(userid: userid, agentid: agentid)
|
45
37
|
end
|
@@ -52,6 +44,10 @@ module Wechat
|
|
52
44
|
get 'user/authsucc', params: { userid: userid }
|
53
45
|
end
|
54
46
|
|
47
|
+
def user_create(user)
|
48
|
+
post 'user/create', JSON.generate(user)
|
49
|
+
end
|
50
|
+
|
55
51
|
def user_delete(userid)
|
56
52
|
get 'user/delete', params: { userid: userid }
|
57
53
|
end
|
data/lib/wechat/http_client.rb
CHANGED
@@ -8,7 +8,7 @@ module Wechat
|
|
8
8
|
@base = base
|
9
9
|
@httprb = HTTP.timeout(:global, write: timeout, connect: timeout, read: timeout)
|
10
10
|
@ssl_context = OpenSSL::SSL::SSLContext.new
|
11
|
-
@ssl_context.ssl_version = :
|
11
|
+
@ssl_context.ssl_version = :TLSv1
|
12
12
|
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE if skip_verify_ssl
|
13
13
|
end
|
14
14
|
|
@@ -59,6 +59,9 @@ module Wechat
|
|
59
59
|
# 48001, api unauthorized hint, for qrcode creation # 71
|
60
60
|
when 42001, 40014, 40001, 48001
|
61
61
|
raise AccessTokenExpiredError
|
62
|
+
# 43004, require subscribe hint # GH-214
|
63
|
+
when 43004
|
64
|
+
Rails.logger.info "wechat gem template_message_send failure, errcode 43004, errmsg: #{data['errmsg']}"
|
62
65
|
else
|
63
66
|
raise ResponseError.new(data['errcode'], data['errmsg'])
|
64
67
|
end
|
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.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Skinnyworm
|
@@ -31,7 +31,7 @@ cert_chain:
|
|
31
31
|
fGxGnQhzVaW07NKOCRrAZlrF8iqso4JR7Vm9bhFdzxUPLr70njwHLtDS2CHgo1VW
|
32
32
|
1xAjN8ZXXpAmVv7V6cI9RTmQHPu/fFn+E0sG9w==
|
33
33
|
-----END CERTIFICATE-----
|
34
|
-
date:
|
34
|
+
date: 2018-04-15 00:00:00.000000000 Z
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: activesupport
|
@@ -90,7 +90,7 @@ dependencies:
|
|
90
90
|
version: 1.0.4
|
91
91
|
- - "<"
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: '
|
93
|
+
version: '4'
|
94
94
|
type: :runtime
|
95
95
|
prerelease: false
|
96
96
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -100,7 +100,7 @@ dependencies:
|
|
100
100
|
version: 1.0.4
|
101
101
|
- - "<"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
103
|
+
version: '4'
|
104
104
|
- !ruby/object:Gem::Dependency
|
105
105
|
name: rspec-rails
|
106
106
|
requirement: !ruby/object:Gem::Requirement
|
@@ -156,18 +156,21 @@ files:
|
|
156
156
|
- README.md
|
157
157
|
- bin/wechat
|
158
158
|
- lib/action_controller/wechat_responder.rb
|
159
|
+
- lib/generators/wechat/config_generator.rb
|
159
160
|
- lib/generators/wechat/install_generator.rb
|
160
161
|
- lib/generators/wechat/menu_generator.rb
|
161
162
|
- lib/generators/wechat/redis_store_generator.rb
|
162
163
|
- lib/generators/wechat/session_generator.rb
|
163
164
|
- lib/generators/wechat/templates/MENU_README
|
164
165
|
- lib/generators/wechat/templates/app/controllers/wechats_controller.rb
|
166
|
+
- lib/generators/wechat/templates/app/models/wechat_config.rb
|
165
167
|
- lib/generators/wechat/templates/app/models/wechat_session.rb
|
166
168
|
- lib/generators/wechat/templates/config/initializers/wechat_redis_store.rb
|
167
169
|
- lib/generators/wechat/templates/config/wechat.yml
|
168
170
|
- lib/generators/wechat/templates/config/wechat_menu.yml
|
169
171
|
- lib/generators/wechat/templates/config/wechat_menu_android.yml
|
170
|
-
- lib/generators/wechat/templates/db/
|
172
|
+
- lib/generators/wechat/templates/db/config_migration.rb.erb
|
173
|
+
- lib/generators/wechat/templates/db/session_migration.rb.erb
|
171
174
|
- lib/wechat.rb
|
172
175
|
- lib/wechat/api.rb
|
173
176
|
- lib/wechat/api_base.rb
|
@@ -206,7 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
209
|
version: '0'
|
207
210
|
requirements: []
|
208
211
|
rubyforge_project:
|
209
|
-
rubygems_version: 2.6
|
212
|
+
rubygems_version: 2.7.6
|
210
213
|
signing_key:
|
211
214
|
specification_version: 4
|
212
215
|
summary: DSL for wechat message handling and API
|
metadata.gz.sig
CHANGED
Binary file
|