wechat 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e8ac0d453ab3b09ebc953fc377d87e3e4faaa691
4
- data.tar.gz: db19e37a02a7361aed18294bc10782f276af4bb3
3
+ metadata.gz: f1a9041e7d411063724f87e3a8393a120542e1bf
4
+ data.tar.gz: 1dfa35792fa8f41f9872b00e645196115658308c
5
5
  SHA512:
6
- metadata.gz: c7ed1bc6f07ded18760833ecfc8a19f5daba4ccb8ad0d6e1ed0ce484ef58ae08558c097c37aae5b014101400786d3b76c9a572ef2ce21c3cc56a8c9a3cf71224
7
- data.tar.gz: 205d9c379adec3226e9fa51600ead4905a259133ff724eb49a56d7dec18b14304232a1e75aa92553e4c7048f83837295b2c1ce65c37b2789c40ca1f4fa5e21e3
6
+ metadata.gz: 14df5df5f86412bbb4076095903884c26a8a7942927d3afa5bdb34d2b0d4c65ff330f41fed0bdf38f970f80893117429efd48e531b6a8f9f566b169314cbfc3d
7
+ data.tar.gz: 7daf46b7df72eb76dc8508a6bbc6f575acd44e2beb214d9c81d6cb51bf551591ec0c1a172d942e89e0b65fe92fc5bd713454ccd7a4b93add0a40059500a9fc36
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.3.0 (released at 8/30/2015)
4
+
5
+ * New user group management API
6
+ * Allow transfer to customer service on fallback. #42
7
+ * Read and write access_token properly using file locking, #43
8
+
3
9
  ## v0.2.0 (released at 8/27/2015)
4
10
 
5
11
  * Add wechat enterprise account support
data/README.md CHANGED
@@ -136,18 +136,24 @@ $ wechat
136
136
  Wechat commands:
137
137
  wechat custom_image [OPENID, IMAGE_PATH] # 发送图片客服消息
138
138
  wechat custom_music [OPENID, THUMBNAIL_PATH, MUSIC_URL] # 发送音乐客服消息
139
- wechat custom_news [OPENID, NEWS_YAML_FILE] # 发送图文客服消息
139
+ wechat custom_news [OPENID, NEWS_YAML_PATH] # 发送图文客服消息
140
140
  wechat custom_text [OPENID, TEXT_MESSAGE] # 发送文字客服消息
141
141
  wechat custom_video [OPENID, VIDEO_PATH] # 发送视频客服消息
142
142
  wechat custom_voice [OPENID, VOICE_PATH] # 发送语音客服消息
143
+ wechat group_create [GROUP_NAME] # 创建分组
144
+ wechat group_delete [GROUP_ID] # 删除分组
145
+ wechat group_update [GROUP_ID, NEW_GROUP_NAME] # 修改分组名
146
+ wechat groups # 所有用户分组列表
143
147
  wechat media [MEDIA_ID, PATH] # 媒体下载
144
- wechat media_create [MEDIA_ID, PATH] # 媒体上传
148
+ wechat media_create [MEDIA_TYPE, PATH] # 媒体上传
145
149
  wechat menu # 当前菜单
146
- wechat menu_create [MENU_YAML] # 创建菜单
150
+ wechat menu_create [MENU_YAML_PATH] # 创建菜单
147
151
  wechat menu_delete # 删除菜单
148
152
  wechat message_send [OPENID, TEXT_MESSAGE] # 发送文字消息(仅企业号)
149
- wechat template_message [OPENID, TEMPLATE_YAML_FILE] # 模板消息接口
153
+ wechat template_message [OPENID, TEMPLATE_YAML_PATH] # 模板消息接口
150
154
  wechat user [OPEN_ID] # 查找关注者
155
+ wechat user_change_group [OPEN_ID, TO_GROUP_ID] # 移动用户分组
156
+ wechat user_group [OPEN_ID] # 查询用户所在分组
151
157
  wechat users # 关注者列表
152
158
  ```
153
159
 
@@ -237,7 +243,7 @@ button:
237
243
 
238
244
  ```
239
245
 
240
- 然后执行命令行
246
+ 然后执行命令行,需确保设置,权限管理中有对此应用的管理权限,否则会报[60011](http://qydev.weixin.qq.com/wiki/index.php?title=%E5%85%A8%E5%B1%80%E8%BF%94%E5%9B%9E%E7%A0%81%E8%AF%B4%E6%98%8E)错。
241
247
 
242
248
  ```
243
249
  $ wechat menu_create menu.yaml
@@ -311,11 +317,10 @@ $ wechat template_message oCfEht9oM*********** template.yml
311
317
  然后创建Controller class, 例如
312
318
 
313
319
  ```ruby
314
-
315
320
  class WechatsController < ApplicationController
316
321
  wechat_responder
317
322
 
318
- # 默认的文字信息responder
323
+ # 默认文字信息responder
319
324
  on :text do |request, content|
320
325
  request.reply.text "echo: #{content}" #Just echo
321
326
  end
@@ -396,10 +401,25 @@ end
396
401
  - :event 响应事件消息, 可以用`:with`参数来匹配事件类型
397
402
  - :fallback 默认响应,当收到的消息无法被其他responder响应时,会使用这个responder.
398
403
 
404
+ ### 多客服消息转发
405
+
406
+ ```ruby
407
+ class WechatsController < ApplicationController
408
+ # 当无任何responder处理用户信息时,转发至客服处理。
409
+ on :fallback, respond: nil do |message|
410
+ message.reply.transfer_customer_service
411
+ end
412
+ end
413
+ ```
414
+
415
+ 注意设置了[多客服消息转发](http://dkf.qq.com/)后,不能再添加`默认文字信息responder`,否则文字消息将得不到转发。
416
+
399
417
  ## Message DSL
400
418
 
401
419
  Wechat 的核心是一个Message DSL,帮助开发者构建各种类型的消息,包括主动推送的和被动响应的。
402
420
  ....
403
421
 
404
422
 
423
+ ## 已知问题
405
424
 
425
+ 企业号接受菜单消息时,Wechat腾讯服务器无法解析部分域名,请使用IP绑定回调URL,用户的普通消息目前不受影响。
data/bin/wechat CHANGED
@@ -37,8 +37,6 @@ HELP
37
37
  end
38
38
  end
39
39
 
40
- private
41
-
42
40
  def self.loading_config
43
41
  config = {}
44
42
 
@@ -64,6 +62,26 @@ HELP
64
62
  package_name 'Wechat'
65
63
  option :toke_file, aliases: '-t', desc: 'File to store access token'
66
64
 
65
+ desc 'groups', '所有用户分组列表'
66
+ def groups
67
+ puts Helper.with(options).groups
68
+ end
69
+
70
+ desc 'group_create [GROUP_NAME]', '创建分组'
71
+ def group_create(group_name)
72
+ puts Helper.with(options).group_create(group_name)
73
+ end
74
+
75
+ desc 'group_update [GROUP_ID, NEW_GROUP_NAME]', '修改分组名'
76
+ def group_update(groupid, new_group_name)
77
+ puts Helper.with(options).group_update(groupid, new_group_name)
78
+ end
79
+
80
+ desc 'group_delete [GROUP_ID]', '删除分组'
81
+ def group_delete(groupid)
82
+ puts Helper.with(options).group_delete(groupid)
83
+ end
84
+
67
85
  desc 'users', '关注者列表'
68
86
  def users
69
87
  puts Helper.with(options).users
@@ -74,6 +92,16 @@ HELP
74
92
  puts Helper.with(options).user(open_id)
75
93
  end
76
94
 
95
+ desc 'user_group [OPEN_ID]', '查询用户所在分组'
96
+ def user_group(openid)
97
+ puts Helper.with(options).user_group(openid)
98
+ end
99
+
100
+ desc 'user_change_group [OPEN_ID, TO_GROUP_ID]', '移动用户分组'
101
+ def user_change_group(openid, to_groupid)
102
+ puts Helper.with(options).user_change_group(openid, to_groupid)
103
+ end
104
+
77
105
  desc 'menu', '当前菜单'
78
106
  def menu
79
107
  puts Helper.with(options).menu
@@ -11,7 +11,7 @@ module Wechat
11
11
 
12
12
  def token
13
13
  begin
14
- @token_data ||= JSON.parse(File.read(token_file))
14
+ @token_data ||= JSON.parse(File.read(token_file, open_args: File::LOCK_SH))
15
15
  created_at = token_data['created_at'].to_i
16
16
  expires_in = token_data['expires_in'].to_i
17
17
  if Time.now.to_i - created_at >= expires_in - 3 * 60
@@ -26,7 +26,7 @@ module Wechat
26
26
  def refresh
27
27
  data = client.get('token', params: { grant_type: 'client_credential', appid: appid, secret: secret })
28
28
  data.merge!(created_at: Time.now.to_i)
29
- File.open(token_file, 'w') { |f| f.write(data.to_json) } if valid_token(data)
29
+ File.write(token_file, data.to_json) if valid_token(data)
30
30
  @token_data = data
31
31
  end
32
32
 
@@ -15,6 +15,22 @@ class Wechat::Api
15
15
  @jsapi_ticket = Wechat::JsapiTicket.new(@client, @access_token, jsapi_ticket_file)
16
16
  end
17
17
 
18
+ def groups
19
+ get('groups/get')
20
+ end
21
+
22
+ def group_create(group_name)
23
+ post 'groups/create', JSON.generate(group: { name: group_name })
24
+ end
25
+
26
+ def group_update(groupid, new_group_name)
27
+ post 'groups/update', JSON.generate(group: { id: groupid, name: new_group_name })
28
+ end
29
+
30
+ def group_delete(groupid)
31
+ post 'groups/delete', JSON.generate(group: { id: groupid })
32
+ end
33
+
18
34
  def users(nextid = nil)
19
35
  params = { params: { next_openid: nextid } } if nextid.present?
20
36
  get('user/get', params || {})
@@ -24,6 +40,14 @@ class Wechat::Api
24
40
  get('user/info', params: { openid: openid })
25
41
  end
26
42
 
43
+ def user_group(openid)
44
+ post 'groups/getid', JSON.generate(openid: openid)
45
+ end
46
+
47
+ def user_change_group(openid, to_groupid)
48
+ post 'groups/members/update', JSON.generate(openid: openid, to_groupid: to_groupid)
49
+ end
50
+
27
51
  def menu
28
52
  get('menu/get')
29
53
  end
@@ -49,7 +49,7 @@ module Wechat
49
49
  # }
50
50
  def signature(url)
51
51
  timestamp = Time.now.to_i
52
- noncestr = generate_noncestr
52
+ noncestr = SecureRandom.base64(16)
53
53
  params = {
54
54
  noncestr: noncestr,
55
55
  timestamp: timestamp,
@@ -70,17 +70,5 @@ module Wechat
70
70
  raise "Response didn't have ticket" if ticket.blank?
71
71
  ticket
72
72
  end
73
-
74
- # 生成随机字符串
75
- # @param Integer length 长度, 默认为16
76
- # @return String
77
- def generate_noncestr(length = 16)
78
- chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
79
- str = ''
80
- 1.upto(length) do |i|
81
- str += chars[rand(chars.length)]
82
- end
83
- str
84
- end
85
73
  end
86
74
  end
@@ -49,8 +49,9 @@ module Wechat
49
49
  Wechat.api.media(message_hash[:MediaId])
50
50
 
51
51
  when :location
52
- message_hash.slice(:Location_X, :Location_Y, :Scale, :Label).inject({}) { |results, value|
53
- results[value[0].to_s.underscore.to_sym] = value[1]; results }
52
+ message_hash.slice(:Location_X, :Location_Y, :Scale, :Label).each_with_object({}) do |value, results|
53
+ results[value[0].to_s.underscore.to_sym] = value[1]
54
+ end
54
55
  else
55
56
  raise "Don't know how to parse message as #{type}"
56
57
  end
@@ -68,6 +69,10 @@ module Wechat
68
69
  update(MsgType: 'text', Content: content)
69
70
  end
70
71
 
72
+ def transfer_customer_service
73
+ update(MsgType: 'transfer_customer_service')
74
+ end
75
+
71
76
  def image(media_id)
72
77
  update(MsgType: 'image', Image: { MediaId: media_id })
73
78
  end
@@ -56,20 +56,19 @@ module Wechat
56
56
  private
57
57
 
58
58
  def match_responders(responders, value)
59
- matched = responders.inject({ scoped: nil, general: nil }) do |matched, responder|
59
+ matched = responders.each_with_object({}) do |responder, memo|
60
60
  condition = responder[:with]
61
61
 
62
62
  if condition.nil?
63
- matched[:general] ||= [responder, value]
64
- next matched
63
+ memo[:general] ||= [responder, value]
64
+ next
65
65
  end
66
66
 
67
67
  if condition.is_a? Regexp
68
- matched[:scoped] ||= [responder] + $LAST_MATCH_INFO.captures if value =~ condition
68
+ memo[:scoped] ||= [responder] + $LAST_MATCH_INFO.captures if value =~ condition
69
69
  else
70
- matched[:scoped] ||= [responder, value] if value == condition
70
+ memo[:scoped] ||= [responder, value] if value == condition
71
71
  end
72
- matched
73
72
  end
74
73
  matched[:scoped] || matched[:general]
75
74
  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.2.0
4
+ version: 0.3.0
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: 2015-08-26 00:00:00.000000000 Z
12
+ date: 2015-08-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails