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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b7f55b06f42f4f81535e3eac7cb4030d7850758e
4
- data.tar.gz: 5b8992563a4e96c2e084a2f371601445678a3a8c
3
+ metadata.gz: 24f3a19bb36361d788567cdb400d5a6247753de4
4
+ data.tar.gz: eee12cc2791847bb3a0568d57829b348785d10c8
5
5
  SHA512:
6
- metadata.gz: 602388ebebfda0bba1b5bc2f7cf7601cb313255acdc658902bd3bab5785c52aa23139bdd9bb503d787175012691cccebf0aa17e0637e2aa84f6e251321c43cdb
7
- data.tar.gz: 3700915a52962394b839d77d8b3d6478cdb1df903f5d026910f9bd330755353396c5ae572e199da9f5a8e31bbfe492a0aa4f022bcbc8b7dac50d6f6b268df62f
6
+ metadata.gz: 742d6ed1dbad1e243aea4fce5e289838aee163f858da65d818c82638069e0ecb5a1afd94cb7a9b2689f30867aa4a6c18a8389fe7bdca8e81cae988fedf6dc04e
7
+ data.tar.gz: 8e0f78fedb6bc0cd798d1f8debbab117e3fa8ac642e5c42504d6e2226656b4813fd4ab3685b7092473ebc3ad0964ed416ee5db2b141742b0c70a3839477982a0
@@ -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
 
@@ -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
- file = File.new(batch_party_csv_path)
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
- file = File.new(batch_user_csv_path)
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
- file = File.new(path)
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
- file = File.new(path)
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', file)['media_id']
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', file)['thumb_media_id']
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
 
@@ -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/jsapi_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::JsapiTicket.new(@client, @access_token, jsapi_ticket_file)
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
- post 'material/add_material', { upload: { media: file } }, params: { type: type }
97
+ post_file 'material/add_material', file, params: { type: type }
98
98
  end
99
99
 
100
100
  def material_delete(media_id)
@@ -17,7 +17,7 @@ module Wechat
17
17
  end
18
18
 
19
19
  def media_create(type, file)
20
- post 'media/upload', { upload: { media: file } }, params: { type: type }
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))
@@ -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!(accept: :json)
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
@@ -90,12 +90,12 @@ module Wechat
90
90
  get 'department/list', params: { id: departmentid }
91
91
  end
92
92
 
93
- def user_simplelist(departmentid, fetch_child = 0, status = 0)
94
- get 'user/simplelist', params: { departmentid: departmentid, fetch_child: fetch_child, status: status }
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(departmentid, fetch_child = 0, status = 0)
98
- get 'user/list', params: { departmentid: departmentid, fetch_child: fetch_child, status: status }
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
- post 'material/add_material', { upload: { media: file } }, params: { type: type, agentid: agentid }
155
+ post_file 'material/add_material', file, params: { type: type, agentid: agentid }
156
156
  end
157
157
 
158
158
  def material_delete(media_id)
@@ -164,6 +164,8 @@ module Wechat
164
164
  else
165
165
  render nothing: true, status: 200, content_type: 'text/html'
166
166
  end
167
+
168
+ after_wechat_response(request, response) if respond_to?(:after_wechat_response)
167
169
  end
168
170
 
169
171
  private
@@ -2,8 +2,7 @@ require 'wechat/ticket/jsapi_base'
2
2
 
3
3
  module Wechat
4
4
  module Ticket
5
- class JsapiTicket < JsapiBase
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.0
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-01 00:00:00.000000000 Z
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/jsapi_ticket.rb
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