wechat 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -1
- data/README-CN.md +16 -9
- data/README.md +19 -12
- data/bin/wechat +8 -20
- data/lib/wechat/api.rb +3 -3
- data/lib/wechat/api_base.rb +7 -1
- data/lib/wechat/client.rb +12 -1
- data/lib/wechat/corp_api.rb +5 -5
- data/lib/wechat/responder.rb +2 -0
- data/lib/wechat/ticket/{jsapi_ticket.rb → public_jsapi_ticket.rb} +1 -2
- metadata +4 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24f3a19bb36361d788567cdb400d5a6247753de4
|
4
|
+
data.tar.gz: eee12cc2791847bb3a0568d57829b348785d10c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 742d6ed1dbad1e243aea4fce5e289838aee163f858da65d818c82638069e0ecb5a1afd94cb7a9b2689f30867aa4a6c18a8389fe7bdca8e81cae988fedf6dc04e
|
7
|
+
data.tar.gz: 8e0f78fedb6bc0cd798d1f8debbab117e3fa8ac642e5c42504d6e2226656b4813fd4ab3685b7092473ebc3ad0964ed416ee5db2b141742b0c70a3839477982a0
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,17 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v0.7.1 (released at 1/11/2016)
|
4
|
+
|
5
|
+
* Fix after using http, upload file function break. #78
|
6
|
+
* Add callback function after_wechat_response support. by @zfben #79
|
7
|
+
* Should using department_id instead of departmentid at enterprise api: user_simplelist/user_list.
|
8
|
+
|
3
9
|
## v0.7.0 (released at 1/1/2016)
|
4
10
|
|
5
|
-
* Using [http](https://github.com/httprb/http) instead of rest-client for performance reason.
|
11
|
+
* Using [http](https://github.com/httprb/http) instead of rest-client for performance reason. (not support upload file yet)
|
12
|
+
|
13
|
+
## v0.6.9 (released at 1/6/2016)
|
14
|
+
|
6
15
|
* Fix token refresh bug on multi worker. #76
|
7
16
|
* Rewrite the token relative code to add more storage support in future.
|
8
17
|
|
data/README-CN.md
CHANGED
@@ -79,16 +79,16 @@ default: &default
|
|
79
79
|
token: "app_token"
|
80
80
|
access_token: "/var/tmp/wechat_access_token"
|
81
81
|
|
82
|
-
production:
|
82
|
+
production:
|
83
83
|
appid: <%= ENV['WECHAT_APPID'] %>
|
84
84
|
secret: <%= ENV['WECHAT_APP_SECRET'] %>
|
85
85
|
token: <%= ENV['WECHAT_TOKEN'] %>
|
86
86
|
access_token: <%= ENV['WECHAT_ACCESS_TOKEN'] %>
|
87
87
|
|
88
|
-
development:
|
88
|
+
development:
|
89
89
|
<<: *default
|
90
90
|
|
91
|
-
test:
|
91
|
+
test:
|
92
92
|
<<: *default
|
93
93
|
```
|
94
94
|
|
@@ -149,11 +149,11 @@ Wechat服务器有报道曾出现[RestClient::SSLCertificateNotVerified](http://
|
|
149
149
|
```ruby
|
150
150
|
class WechatFirstController < ActionController::Base
|
151
151
|
wechat_responder appid: "app1", secret: "secret1", token: "token1", access_token: Rails.root.join("tmp/access_token1")
|
152
|
-
|
152
|
+
|
153
153
|
on :text, with:"help", respond: "help content"
|
154
154
|
end
|
155
155
|
```
|
156
|
-
|
156
|
+
|
157
157
|
#### jssdk 支持
|
158
158
|
|
159
159
|
jssdk 使用前需通过config接口注入权限验证配置, 所需参数可以通过 signature 方法获取:
|
@@ -354,7 +354,7 @@ articles:
|
|
354
354
|
然后执行命令行
|
355
355
|
|
356
356
|
```
|
357
|
-
$ wechat custom_news oCfEht9oM*********** articles.yml
|
357
|
+
$ wechat custom_news oCfEht9oM*********** articles.yml
|
358
358
|
|
359
359
|
```
|
360
360
|
|
@@ -368,7 +368,7 @@ template:
|
|
368
368
|
url: "http://weixin.qq.com/download"
|
369
369
|
topcolor: "#FF0000"
|
370
370
|
data:
|
371
|
-
first:
|
371
|
+
first:
|
372
372
|
value: "你好,你已报名成功"
|
373
373
|
color: "#0A0A0A"
|
374
374
|
keynote1:
|
@@ -405,7 +405,7 @@ $ wechat template_message oCfEht9oM*********** template.yml
|
|
405
405
|
```ruby
|
406
406
|
class WechatsController < ActionController::Base
|
407
407
|
wechat_responder
|
408
|
-
|
408
|
+
|
409
409
|
# 默认文字信息responder
|
410
410
|
on :text do |request, content|
|
411
411
|
request.reply.text "echo: #{content}" #Just echo
|
@@ -522,6 +522,13 @@ class WechatsController < ActionController::Base
|
|
522
522
|
|
523
523
|
# 当无任何responder处理用户信息时,使用这个responder处理
|
524
524
|
on :fallback, respond: 'fallback message'
|
525
|
+
|
526
|
+
# 如果你要在微信回复后增加一些操作,可以用 after_wechat_response(req, res)
|
527
|
+
# private
|
528
|
+
#
|
529
|
+
# def after_wechat_response(req, res)
|
530
|
+
# WechatLog.create req: req, res: res
|
531
|
+
# end
|
525
532
|
end
|
526
533
|
```
|
527
534
|
|
@@ -557,7 +564,7 @@ class WechatsController < ActionController::Base
|
|
557
564
|
# 当无任何responder处理用户信息时,转发至客服处理。
|
558
565
|
on :fallback do |message|
|
559
566
|
message.reply.transfer_customer_service
|
560
|
-
end
|
567
|
+
end
|
561
568
|
end
|
562
569
|
```
|
563
570
|
|
data/README.md
CHANGED
@@ -17,7 +17,7 @@ WeChat gem trying to helping Rails developer to integrated [enterprise account](
|
|
17
17
|
|
18
18
|
`wechat` command share the same API in console, so you can interactive with wechat server quickly, without starting up web environment/code.
|
19
19
|
|
20
|
-
A responder DSL can used in Rails controller, so giving a event based interface to handler message sent by end user from wechat server.
|
20
|
+
A responder DSL can used in Rails controller, so giving a event based interface to handler message sent by end user from wechat server.
|
21
21
|
|
22
22
|
Wechat provide OAuth2.0 as authentication service and possible to intergrated with devise/other authorization gems, [omniauth-wechat-oauth2](https://github.com/skinnyworm/omniauth-wechat-oauth2) is a good start
|
23
23
|
|
@@ -88,16 +88,16 @@ default: &default
|
|
88
88
|
token: "app_token"
|
89
89
|
access_token: "/var/tmp/wechat_access_token"
|
90
90
|
|
91
|
-
production:
|
91
|
+
production:
|
92
92
|
appid: <%= ENV['WECHAT_APPID'] %>
|
93
93
|
secret: <%= ENV['WECHAT_APP_SECRET'] %>
|
94
94
|
token: <%= ENV['WECHAT_TOKEN'] %>
|
95
95
|
access_token: <%= ENV['WECHAT_ACCESS_TOKEN'] %>
|
96
96
|
|
97
|
-
development:
|
97
|
+
development:
|
98
98
|
<<: *default
|
99
99
|
|
100
|
-
test:
|
100
|
+
test:
|
101
101
|
<<: *default
|
102
102
|
```
|
103
103
|
|
@@ -161,11 +161,11 @@ Rare case, you may want to hosting more than one wechat enterprise/public accoun
|
|
161
161
|
```ruby
|
162
162
|
class WechatFirstController < ActionController::Base
|
163
163
|
wechat_responder appid: "app1", secret: "secret1", token: "token1", access_token: Rails.root.join("tmp/access_token1")
|
164
|
-
|
164
|
+
|
165
165
|
on :text, with:"help", respond: "help content"
|
166
166
|
end
|
167
167
|
```
|
168
|
-
|
168
|
+
|
169
169
|
#### JS-SDK helper
|
170
170
|
|
171
171
|
JS-SDK enable you control wechat behavior in your web page, but need inject a config with signature methods first, you can obtain those signature hash via below
|
@@ -182,7 +182,7 @@ wechat gems won't handle any privilege exception. (except token time out, but it
|
|
182
182
|
|
183
183
|
The available API is different between public account and enterprise account, so wechat gems provide different set of command.
|
184
184
|
|
185
|
-
Feel safe if you can not read Chinese in the comments, it's keep there in order to copy & find in official document more easier.
|
185
|
+
Feel safe if you can not read Chinese in the comments, it's keep there in order to copy & find in official document more easier.
|
186
186
|
|
187
187
|
#### Public account command line
|
188
188
|
|
@@ -367,7 +367,7 @@ articles:
|
|
367
367
|
After that, can running command:
|
368
368
|
|
369
369
|
```
|
370
|
-
$ wechat custom_news oCfEht9oM*********** articles.yml
|
370
|
+
$ wechat custom_news oCfEht9oM*********** articles.yml
|
371
371
|
|
372
372
|
```
|
373
373
|
|
@@ -381,7 +381,7 @@ template:
|
|
381
381
|
url: "http://weixin.qq.com/download"
|
382
382
|
topcolor: "#FF0000"
|
383
383
|
data:
|
384
|
-
first:
|
384
|
+
first:
|
385
385
|
value: "Hello, you successfully registed"
|
386
386
|
color: "#0A0A0A"
|
387
387
|
keynote1:
|
@@ -535,10 +535,17 @@ class WechatsController < ActionController::Base
|
|
535
535
|
|
536
536
|
# Any not match above will fail to below
|
537
537
|
on :fallback, respond: 'fallback message'
|
538
|
+
|
539
|
+
# If you need do something after response, you should add after_wechat_response(req, res)
|
540
|
+
# private
|
541
|
+
#
|
542
|
+
# def after_wechat_response(req, res)
|
543
|
+
# WechatLog.create req: req, res: res
|
544
|
+
# end
|
538
545
|
end
|
539
546
|
```
|
540
547
|
|
541
|
-
So the importent statement is only `wechat_responder`, all other is just a DSL:
|
548
|
+
So the importent statement is only `wechat_responder`, all other is just a DSL:
|
542
549
|
|
543
550
|
```
|
544
551
|
on <message_type> do |message|
|
@@ -571,13 +578,13 @@ class WechatsController < ActionController::Base
|
|
571
578
|
# When no other responder can handle incoming message, will transfer to human customer service.
|
572
579
|
on :fallback do |message|
|
573
580
|
message.reply.transfer_customer_service
|
574
|
-
end
|
581
|
+
end
|
575
582
|
end
|
576
583
|
```
|
577
584
|
|
578
585
|
Caution: do not setting default text responder if you want to using [multiply human customer service](http://dkf.qq.com/), other will lead text message can not transfer.
|
579
586
|
|
580
|
-
|
587
|
+
|
581
588
|
## Known Issue
|
582
589
|
|
583
590
|
* Sometime, enterprise account can not receive the menu message due to Tencent server can not resolved the DNS, so using IP as a callback URL more stable, but it's never happen for user sent text message.
|
data/bin/wechat
CHANGED
@@ -173,8 +173,7 @@ class App < Thor
|
|
173
173
|
|
174
174
|
desc 'upload_replaceparty [BATCH_PARTY_CSV_PATH]', '上传文件方式全量覆盖部门'
|
175
175
|
def upload_replaceparty(batch_party_csv_path)
|
176
|
-
|
177
|
-
media_id = wechat_api.media_create('file', file)['media_id']
|
176
|
+
media_id = wechat_api.media_create('file', batch_party_csv_path)['media_id']
|
178
177
|
job_id = wechat_api.batch_replaceparty(media_id)['jobid']
|
179
178
|
puts "running job_id: #{job_id}"
|
180
179
|
puts wechat_api.batch_job_result(job_id)
|
@@ -192,8 +191,7 @@ class App < Thor
|
|
192
191
|
|
193
192
|
desc 'upload_replaceuser [BATCH_USER_CSV_PATH]', '上传文件方式全量覆盖成员'
|
194
193
|
def upload_replaceuser(batch_user_csv_path)
|
195
|
-
|
196
|
-
media_id = wechat_api.media_create('file', file)['media_id']
|
194
|
+
media_id = wechat_api.media_create('file', batch_user_csv_path)['media_id']
|
197
195
|
job_id = wechat_api.batch_replaceuser(media_id)['jobid']
|
198
196
|
puts "running job_id: #{job_id}"
|
199
197
|
puts wechat_api.batch_job_result(job_id)
|
@@ -321,8 +319,7 @@ class App < Thor
|
|
321
319
|
|
322
320
|
desc 'media_create [MEDIA_TYPE, PATH]', '媒体上传'
|
323
321
|
def media_create(type, path)
|
324
|
-
|
325
|
-
puts wechat_api.media_create(type, file)
|
322
|
+
puts wechat_api.media_create(type, path)
|
326
323
|
end
|
327
324
|
|
328
325
|
desc 'material [MEDIA_ID, PATH]', '永久媒体下载'
|
@@ -334,8 +331,7 @@ class App < Thor
|
|
334
331
|
|
335
332
|
desc 'material_add [MEDIA_TYPE, PATH]', '永久媒体上传'
|
336
333
|
def material_add(type, path)
|
337
|
-
|
338
|
-
puts wechat_api.material_add(type, file)
|
334
|
+
puts wechat_api.material_add(type, path)
|
339
335
|
end
|
340
336
|
|
341
337
|
desc 'material_delete [MEDIA_ID]', '删除永久素材'
|
@@ -370,19 +366,15 @@ class App < Thor
|
|
370
366
|
|
371
367
|
desc 'custom_image [OPENID, IMAGE_PATH]', '发送图片客服消息'
|
372
368
|
def custom_image(openid, image_path)
|
373
|
-
file = File.new(image_path)
|
374
369
|
api = wechat_api
|
375
|
-
|
376
|
-
media_id = api.media_create('image', file)['media_id']
|
370
|
+
media_id = api.media_create('image', image_path)['media_id']
|
377
371
|
puts api.custom_message_send Wechat::Message.to(openid).image(media_id)
|
378
372
|
end
|
379
373
|
|
380
374
|
desc 'custom_voice [OPENID, VOICE_PATH]', '发送语音客服消息'
|
381
375
|
def custom_voice(openid, voice_path)
|
382
|
-
file = File.new(voice_path)
|
383
376
|
api = wechat_api
|
384
|
-
|
385
|
-
media_id = api.media_create('voice', file)['media_id']
|
377
|
+
media_id = api.media_create('voice', voice_path)['media_id']
|
386
378
|
puts api.custom_message_send Wechat::Message.to(openid).voice(media_id)
|
387
379
|
end
|
388
380
|
|
@@ -390,11 +382,9 @@ class App < Thor
|
|
390
382
|
method_option :title, aliases: '-h', desc: '视频标题'
|
391
383
|
method_option :description, aliases: '-d', desc: '视频描述'
|
392
384
|
def custom_video(openid, video_path)
|
393
|
-
file = File.new(video_path)
|
394
385
|
api = wechat_api
|
395
|
-
|
396
386
|
api_opts = options.slice(:title, :description)
|
397
|
-
media_id = api.media_create('video',
|
387
|
+
media_id = api.media_create('video', video_path)['media_id']
|
398
388
|
puts api.custom_message_send Wechat::Message.to(openid).video(media_id, api_opts)
|
399
389
|
end
|
400
390
|
|
@@ -403,11 +393,9 @@ class App < Thor
|
|
403
393
|
method_option :description, aliases: '-d', desc: '音乐描述'
|
404
394
|
method_option :HQ_music_url, aliases: '-u', desc: '高质量音乐URL链接'
|
405
395
|
def custom_music(openid, thumbnail_path, music_url)
|
406
|
-
file = File.new(thumbnail_path)
|
407
396
|
api = wechat_api
|
408
|
-
|
409
397
|
api_opts = options.slice(:title, :description, :HQ_music_url)
|
410
|
-
thumb_media_id = api.media_create('thumb',
|
398
|
+
thumb_media_id = api.media_create('thumb', thumbnail_path)['thumb_media_id']
|
411
399
|
puts api.custom_message_send Wechat::Message.to(openid).music(thumb_media_id, music_url, api_opts)
|
412
400
|
end
|
413
401
|
|
data/lib/wechat/api.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'wechat/api_base'
|
2
2
|
require 'wechat/client'
|
3
3
|
require 'wechat/token/public_access_token'
|
4
|
-
require 'wechat/ticket/
|
4
|
+
require 'wechat/ticket/public_jsapi_ticket'
|
5
5
|
|
6
6
|
module Wechat
|
7
7
|
class Api < ApiBase
|
@@ -11,7 +11,7 @@ module Wechat
|
|
11
11
|
def initialize(appid, secret, token_file, timeout, skip_verify_ssl, jsapi_ticket_file)
|
12
12
|
@client = Client.new(API_BASE, timeout, skip_verify_ssl)
|
13
13
|
@access_token = Token::PublicAccessToken.new(@client, appid, secret, token_file)
|
14
|
-
@jsapi_ticket = Ticket::
|
14
|
+
@jsapi_ticket = Ticket::PublicJsapiTicket.new(@client, @access_token, jsapi_ticket_file)
|
15
15
|
end
|
16
16
|
|
17
17
|
def groups
|
@@ -94,7 +94,7 @@ module Wechat
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def material_add(type, file)
|
97
|
-
|
97
|
+
post_file 'material/add_material', file, params: { type: type }
|
98
98
|
end
|
99
99
|
|
100
100
|
def material_delete(media_id)
|
data/lib/wechat/api_base.rb
CHANGED
@@ -17,7 +17,7 @@ module Wechat
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def media_create(type, file)
|
20
|
-
|
20
|
+
post_file 'media/upload', file, params: { type: type }
|
21
21
|
end
|
22
22
|
|
23
23
|
protected
|
@@ -34,6 +34,12 @@ module Wechat
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
def post_file(path, file, headers = {})
|
38
|
+
with_access_token(headers[:params]) do |params|
|
39
|
+
client.post_file path, file, headers.merge(params: params)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
37
43
|
def with_access_token(params = {}, tries = 2)
|
38
44
|
params ||= {}
|
39
45
|
yield(params.merge(access_token: access_token.token))
|
data/lib/wechat/client.rb
CHANGED
@@ -25,12 +25,23 @@ module Wechat
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
def post_file(path, file, post_header = {})
|
29
|
+
request(path, post_header) do |url, header|
|
30
|
+
params = header.delete(:params)
|
31
|
+
HTTP.headers(header)
|
32
|
+
.post(url, params: params,
|
33
|
+
form: { media: HTTP::FormData::File.new(file),
|
34
|
+
hack: 'X' }, # Existing here for http-form_data 1.0.1 handle single param improperly
|
35
|
+
ssl_context: ssl_context)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
28
39
|
private
|
29
40
|
|
30
41
|
def request(path, header = {}, &_block)
|
31
42
|
url = "#{header.delete(:base) || base}#{path}"
|
32
43
|
as = header.delete(:as)
|
33
|
-
header.merge!(
|
44
|
+
header.merge!('Accept' => 'application/json')
|
34
45
|
response = yield(url, header)
|
35
46
|
|
36
47
|
fail "Request not OK, response status #{response.status}" if response.status != 200
|
data/lib/wechat/corp_api.rb
CHANGED
@@ -90,12 +90,12 @@ module Wechat
|
|
90
90
|
get 'department/list', params: { id: departmentid }
|
91
91
|
end
|
92
92
|
|
93
|
-
def user_simplelist(
|
94
|
-
get 'user/simplelist', params: {
|
93
|
+
def user_simplelist(department_id, fetch_child = 0, status = 0)
|
94
|
+
get 'user/simplelist', params: { department_id: department_id, fetch_child: fetch_child, status: status }
|
95
95
|
end
|
96
96
|
|
97
|
-
def user_list(
|
98
|
-
get 'user/list', params: {
|
97
|
+
def user_list(department_id, fetch_child = 0, status = 0)
|
98
|
+
get 'user/list', params: { department_id: department_id, fetch_child: fetch_child, status: status }
|
99
99
|
end
|
100
100
|
|
101
101
|
def tag_create(tagname, tagid = nil)
|
@@ -152,7 +152,7 @@ module Wechat
|
|
152
152
|
end
|
153
153
|
|
154
154
|
def material_add(type, file)
|
155
|
-
|
155
|
+
post_file 'material/add_material', file, params: { type: type, agentid: agentid }
|
156
156
|
end
|
157
157
|
|
158
158
|
def material_delete(media_id)
|
data/lib/wechat/responder.rb
CHANGED
@@ -2,8 +2,7 @@ require 'wechat/ticket/jsapi_base'
|
|
2
2
|
|
3
3
|
module Wechat
|
4
4
|
module Ticket
|
5
|
-
class
|
6
|
-
# refresh jsapi ticket
|
5
|
+
class PublicJsapiTicket < JsapiBase
|
7
6
|
def refresh
|
8
7
|
data = client.get('ticket/getticket', params: { access_token: access_token.token, type: 'jsapi' })
|
9
8
|
write_ticket_to_file(data)
|
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.7.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Skinnyworm
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-01-
|
12
|
+
date: 2016-01-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -136,7 +136,7 @@ files:
|
|
136
136
|
- lib/wechat/signature.rb
|
137
137
|
- lib/wechat/ticket/corp_jsapi_ticket.rb
|
138
138
|
- lib/wechat/ticket/jsapi_base.rb
|
139
|
-
- lib/wechat/ticket/
|
139
|
+
- lib/wechat/ticket/public_jsapi_ticket.rb
|
140
140
|
- lib/wechat/token/access_token_base.rb
|
141
141
|
- lib/wechat/token/corp_access_token.rb
|
142
142
|
- lib/wechat/token/public_access_token.rb
|
@@ -144,13 +144,7 @@ homepage: https://github.com/Eric-Guo/wechat
|
|
144
144
|
licenses:
|
145
145
|
- MIT
|
146
146
|
metadata: {}
|
147
|
-
post_install_message:
|
148
|
-
*****WECHAT BREAK CHANGE*****
|
149
|
-
1. Scan 2D barcode using new syntax `on :scan, with: 'BINDING_QR_CODE' `
|
150
|
-
instead of previous `on :event, with: 'BINDING_QR_CODE' `.
|
151
|
-
2. Batch job using new syntax `on :batch_job, with: 'replace_user' `
|
152
|
-
instead of previous `on :event, with: 'replace_user' `.
|
153
|
-
*****************************
|
147
|
+
post_install_message:
|
154
148
|
rdoc_options: []
|
155
149
|
require_paths:
|
156
150
|
- lib
|