wechat 0.8.12 → 0.9.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 +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
|