wechat 0.6.3 → 0.6.4

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: 9f57875f2dee753674602e98333ae19b6a29c4ed
4
- data.tar.gz: e0c6882f86e379bfd8ad74d31a3c6241cd47f0ae
3
+ metadata.gz: 66ecda4306d9d5a9fde71ae0477d99682fd443a0
4
+ data.tar.gz: 13b71709c26cc139d1be233a0449741eb404adbc
5
5
  SHA512:
6
- metadata.gz: 375da3a164458340900ed8d1ab1b4c864ce3b2f645f18ef19be010a67954018ff5a34da7273e12169c1654673d91c237ea99a633ef63b5630d84f04561e887e9
7
- data.tar.gz: 9dba3994255e0cff1de66e7f125f30b9a6f836f81f98a327fab1180fc940e7fc40ed5169c10ff939264a2e314ae9b3412afbb3a9a8b6bda2920237d43799fa0e
6
+ metadata.gz: 85fb0b5a0745542d5c9e9ec09095125c393192da41335592c58561353c6e5d91cc7eeb112a61c2456ac68cda0768391ae33a65a98aa7f05292abd2cfad78a2fc
7
+ data.tar.gz: 09d88487602a96a6bc1d9b3c7dad3a5f9199c1d8df1f40e96d7b5a5ec6692cc894b4fb071de20ac27a1df42f6536cb17fe691651a044c876c4c117bc80602f17
@@ -1,8 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.6.4 (released at 11/16/2015)
4
+
5
+ * Command mode now display different command set based on enterprise/public account setting
6
+ * Move config logic in command/wechat to ApiLoader class
7
+ * Unsubscribe can only reply plain text 'success' #68
8
+ * Fix 404 qrcode download problem, by @huangxiangdan #69
9
+
3
10
  ## v0.6.3 (released at 11/14/2015)
4
11
 
5
- * Official testing and support public encrypt mode, also fix one cipher bug, many thanks to hlltc #67
12
+ * Official testing and support public encrypt mode, also fix one cipher bug, many thanks to @hlltc #67
6
13
  * hlltc report public account FILE_BASE no longer needs, clean code #67
7
14
  * Media command line reflect recent Tecent json schema change. #67
8
15
 
data/README.md CHANGED
@@ -157,6 +157,46 @@ wechat gems 内部不会检查权限。但因公众号类型不同,和微信
157
157
 
158
158
  ## 使用命令行
159
159
 
160
+ 根据企业号和公众号配置不同,wechat提供了的命令行命令。
161
+
162
+ #### 公众号命令行
163
+
164
+ ```
165
+ $ wechat
166
+ Wechat commands:
167
+ wechat callbackip # 获取微信服务器IP地址
168
+ wechat custom_image [OPENID, IMAGE_PATH] # 发送图片客服消息
169
+ wechat custom_music [OPENID, THUMBNAIL_PATH, MUSIC_URL] # 发送音乐客服消息
170
+ wechat custom_news [OPENID, NEWS_YAML_PATH] # 发送图文客服消息
171
+ wechat custom_text [OPENID, TEXT_MESSAGE] # 发送文字客服消息
172
+ wechat custom_video [OPENID, VIDEO_PATH] # 发送视频客服消息
173
+ wechat custom_voice [OPENID, VOICE_PATH] # 发送语音客服消息
174
+ wechat group_create [GROUP_NAME] # 创建分组
175
+ wechat group_delete [GROUP_ID] # 删除分组
176
+ wechat group_update [GROUP_ID, NEW_GROUP_NAME] # 修改分组名
177
+ wechat groups # 查询所有分组
178
+ wechat material [MEDIA_ID, PATH] # 永久媒体下载
179
+ wechat material_add [MEDIA_TYPE, PATH] # 永久媒体上传
180
+ wechat material_count # 获取永久素材总数
181
+ wechat material_delete [MEDIA_ID] # 删除永久素材
182
+ wechat material_list [TYPE, OFFSET, COUNT] # 获取永久素材列表
183
+ wechat media [MEDIA_ID, PATH] # 媒体下载
184
+ wechat media_create [MEDIA_TYPE, PATH] # 媒体上传
185
+ wechat menu # 当前菜单
186
+ wechat menu_create [MENU_YAML_PATH] # 创建菜单
187
+ wechat menu_delete # 删除菜单
188
+ wechat qrcode_create_limit_scene [SCENE_ID_OR_STR] # 请求永久二维码
189
+ wechat qrcode_create_scene [SCENE_ID, EXPIRE_SECONDS] # 请求临时二维码
190
+ wechat qrcode_download [TICKET, QR_CODE_PIC_PATH] # 通过ticket下载二维码
191
+ wechat template_message [OPENID, TEMPLATE_YAML_PATH] # 模板消息接口
192
+ wechat user [OPEN_ID] # 获取用户基本信息
193
+ wechat user_change_group [OPEN_ID, TO_GROUP_ID] # 移动用户分组
194
+ wechat user_group [OPEN_ID] # 查询用户所在分组
195
+ wechat user_update_remark [OPEN_ID, REMARK] # 设置备注名
196
+ wechat users # 关注者列表
197
+ ```
198
+
199
+ #### 企业号命令行
160
200
  ```
161
201
  $ wechat
162
202
  Wechat commands:
@@ -177,11 +217,7 @@ Wechat commands:
177
217
  wechat department [DEPARTMENT_ID] # 获取部门列表
178
218
  wechat department_create [NAME, PARENT_ID] # 创建部门
179
219
  wechat department_delete [DEPARTMENT_ID] # 删除部门
180
- wechat department_update [DEPARTMENT_ID, NAME] # 更新部门
181
- wechat group_create [GROUP_NAME] # 创建分组
182
- wechat group_delete [GROUP_ID] # 删除分组
183
- wechat group_update [GROUP_ID, NEW_GROUP_NAME] # 修改分组名
184
- wechat groups # 所有用户分组列表
220
+ wechat department_update [DEPARTMENT_ID, NAME] # 更新部门
185
221
  wechat invite_user [USER_ID] # 邀请成员关注
186
222
  wechat material [MEDIA_ID, PATH] # 永久媒体下载
187
223
  wechat material_add [MEDIA_TYPE, PATH] # 永久媒体上传
@@ -193,7 +229,7 @@ Wechat commands:
193
229
  wechat menu # 当前菜单
194
230
  wechat menu_create [MENU_YAML_PATH] # 创建菜单
195
231
  wechat menu_delete # 删除菜单
196
- wechat message_send [OPENID, TEXT_MESSAGE] # 发送文字消息(仅企业号)
232
+ wechat message_send [OPENID, TEXT_MESSAGE] # 发送文字消息
197
233
  wechat qrcode_create_limit_scene [SCENE_ID_OR_STR] # 请求永久二维码
198
234
  wechat qrcode_create_scene [SCENE_ID, EXPIRE_SECONDS] # 请求临时二维码
199
235
  wechat qrcode_download [TICKET, QR_CODE_PIC_PATH] # 通过ticket下载二维码
@@ -201,21 +237,18 @@ Wechat commands:
201
237
  wechat tag_add_department [TAG_ID, PARTY_IDS] # 增加标签部门
202
238
  wechat tag_add_user [TAG_ID, USER_IDS] # 增加标签成员
203
239
  wechat tag_create [TAGNAME, TAG_ID] # 创建标签
204
- wechat tag_del_user [TAG_ID, USER_IDS] # 删除标签成员
205
240
  wechat tag_del_department [TAG_ID, PARTY_IDS] # 删除标签部门
241
+ wechat tag_del_user [TAG_ID, USER_IDS] # 删除标签成员
206
242
  wechat tag_delete [TAG_ID] # 删除标签
207
243
  wechat tag_update [TAG_ID, TAGNAME] # 更新标签名字
208
244
  wechat tags # 获取标签列表
209
245
  wechat template_message [OPENID, TEMPLATE_YAML_PATH] # 模板消息接口
210
246
  wechat user [OPEN_ID] # 获取用户基本信息
211
- wechat user_batchdelete [USER_ID_LIST] # 批量删除成员
212
- wechat user_change_group [OPEN_ID, TO_GROUP_ID] # 移动用户分组
247
+ wechat user_batchdelete [USER_ID_LIST] # 批量删除成员
213
248
  wechat user_delete [USER_ID] # 删除成员
214
- wechat user_group [OPEN_ID] # 查询用户所在分组
215
249
  wechat user_list [DEPARTMENT_ID] # 获取部门成员详情
216
250
  wechat user_simplelist [DEPARTMENT_ID] # 获取部门成员
217
251
  wechat user_update_remark [OPEN_ID, REMARK] # 设置备注名
218
- wechat users # 关注者列表
219
252
  ```
220
253
 
221
254
  ### 使用场景
@@ -449,7 +482,7 @@ class WechatsController < ApplicationController
449
482
 
450
483
  # 当用户取消关注订阅
451
484
  on :event, with: 'unsubscribe' do |request|
452
- request.reply.text "#{request[:FromUserName]} can not receive this message"
485
+ request.reply.success # user can not receive this message
453
486
  end
454
487
 
455
488
  # 成员进入应用的事件推送
data/bin/wechat CHANGED
@@ -12,316 +12,284 @@ require 'active_support/core_ext'
12
12
  require 'active_support/json'
13
13
  require 'fileutils'
14
14
  require 'yaml'
15
+ require 'wechat/api_loader'
15
16
 
16
17
  class App < Thor
17
- class Helper
18
- def self.with(options)
19
- config = loading_config
20
-
21
- appid = config['appid']
22
- secret = config['secret']
23
- corpid = config['corpid']
24
- corpsecret = config['corpsecret']
25
- token_file = options[:toke_file] || config['access_token'] || '/var/tmp/wechat_access_token'
26
- agentid = config['agentid']
27
- skip_verify_ssl = config['skip_verify_ssl']
28
-
29
- if appid.present? && secret.present? && token_file.present?
30
- Wechat::Api.new(appid, secret, token_file, skip_verify_ssl)
31
- elsif corpid.present? && corpsecret.present? && token_file.present?
32
- Wechat::CorpApi.new(corpid, corpsecret, token_file, agentid, skip_verify_ssl)
33
- else
34
- puts <<-HELP
35
- Need create ~/.wechat.yml with wechat appid and secret
36
- or running at rails root folder so wechat can read config/wechat.yml
37
- HELP
38
- exit 1
39
- end
40
- end
41
-
42
- def self.loading_config
43
- config = {}
44
-
45
- rails_config_file = File.join(Dir.getwd, 'config/wechat.yml')
46
- home_config_file = File.join(Dir.home, '.wechat.yml')
47
-
48
- if File.exist?(rails_config_file)
49
- config = YAML.load(ERB.new(File.read(rails_config_file)).result)['default']
50
- if config.present? && (config['appid'] || config['corpid'])
51
- puts 'Using rails project config/wechat.yml default setting...'
52
- else
53
- config = {}
54
- end
55
- end
18
+ package_name 'Wechat'
19
+ option :toke_file, aliases: '-t', desc: 'File to store access token'
56
20
 
57
- if config.blank? && File.exist?(home_config_file)
58
- config = YAML.load ERB.new(File.read(home_config_file)).result
59
- end
60
- config
21
+ attr_reader :wechat_api_client
22
+ no_commands do
23
+ def wechat_api
24
+ @wechat_api_client ||= Wechat::ApiLoader.with(options)
61
25
  end
62
26
  end
63
27
 
64
- package_name 'Wechat'
65
- option :toke_file, aliases: '-t', desc: 'File to store access token'
66
-
67
28
  desc 'callbackip', '获取微信服务器IP地址'
68
29
  def callbackip
69
- puts Helper.with(options).callbackip
30
+ puts wechat_api.callbackip
70
31
  end
71
32
 
72
33
  desc 'qrcode_download [TICKET, QR_CODE_PIC_PATH]', '通过ticket下载二维码'
73
34
  def qrcode_download(ticket, qr_code_pic_path)
74
- tmp_file = Helper.with(options).qrcode(ticket)
35
+ tmp_file = wechat_api.qrcode(ticket)
75
36
  FileUtils.mv(tmp_file.path, qr_code_pic_path)
76
37
  puts 'File downloaded'
77
38
  end
78
39
 
79
- desc 'groups', '所有用户分组列表'
80
- def groups
81
- puts Helper.with(options).groups
82
- end
83
-
84
- desc 'group_create [GROUP_NAME]', '创建分组'
85
- def group_create(group_name)
86
- puts Helper.with(options).group_create(group_name)
87
- end
88
-
89
- desc 'group_update [GROUP_ID, NEW_GROUP_NAME]', '修改分组名'
90
- def group_update(groupid, new_group_name)
91
- puts Helper.with(options).group_update(groupid, new_group_name)
92
- end
40
+ if Wechat::ApiLoader.with(options).is_a?(Wechat::CorpApi)
41
+ desc 'department_create [NAME, PARENT_ID]', '创建部门'
42
+ method_option :parentid, aliases: '-p', desc: '父亲部门id。根部门id为1'
43
+ def department_create(name)
44
+ api_opts = options.slice(:parentid)
45
+ puts wechat_api.department_create(name, api_opts[:parentid] || '1')
46
+ end
93
47
 
94
- desc 'group_delete [GROUP_ID]', '删除分组'
95
- def group_delete(groupid)
96
- puts Helper.with(options).group_delete(groupid)
97
- end
48
+ desc 'department_delete [DEPARTMENT_ID]', '删除部门'
49
+ def department_delete(departmentid)
50
+ puts wechat_api.department_delete(departmentid)
51
+ end
98
52
 
99
- desc 'department_create [NAME, PARENT_ID]', '创建部门'
100
- method_option :parentid, aliases: '-p', desc: '父亲部门id。根部门id为1'
101
- def department_create(name)
102
- api_opts = options.slice(:parentid)
103
- puts Helper.with(options).department_create(name, api_opts[:parentid] || '1')
104
- end
53
+ desc 'department_update [DEPARTMENT_ID, NAME]', '更新部门'
54
+ method_option :parentid, aliases: '-p', desc: '父亲部门id。根部门id为1', default: nil
55
+ method_option :order, aliases: '-o', desc: '在父部门中的次序值。order值小的排序靠前。', default: nil
56
+ def department_update(departmentid, name)
57
+ api_opts = options.slice(:parentid, :order)
58
+ puts wechat_api.department_update(departmentid, name, api_opts[:parentid], api_opts[:order])
59
+ end
105
60
 
106
- desc 'department_delete [DEPARTMENT_ID]', '删除部门'
107
- def department_delete(departmentid)
108
- puts Helper.with(options).department_delete(departmentid)
109
- end
61
+ desc 'department [DEPARTMENT_ID]', '获取部门列表'
62
+ def department(departmentid = 0)
63
+ r = wechat_api.department(departmentid)
64
+ puts "errcode: #{r['errcode']} errmsg: #{r['errmsg']}"
65
+ puts 'Or# pid id name'
66
+ r['department'].sort_by { |d| d['order'].to_i + d['parentid'].to_i * 1000 } .each do |i|
67
+ puts format('%3d %3d %3d %s', i['order'], i['parentid'], i['id'], i['name'])
68
+ end
69
+ end
110
70
 
111
- desc 'department_update [DEPARTMENT_ID, NAME]', '更新部门'
112
- method_option :parentid, aliases: '-p', desc: '父亲部门id。根部门id为1', default: nil
113
- method_option :order, aliases: '-o', desc: '在父部门中的次序值。order值小的排序靠前。', default: nil
114
- def department_update(departmentid, name)
115
- api_opts = options.slice(:parentid, :order)
116
- puts Helper.with(options).department_update(departmentid, name, api_opts[:parentid], api_opts[:order])
117
- end
71
+ desc 'user_delete [USER_ID]', '删除成员'
72
+ def user_delete(userid)
73
+ puts wechat_api.user_delete(userid)
74
+ end
118
75
 
119
- desc 'department [DEPARTMENT_ID]', '获取部门列表'
120
- def department(departmentid = 0)
121
- r = Helper.with(options).department(departmentid)
122
- puts "errcode: #{r['errcode']} errmsg: #{r['errmsg']}"
123
- puts 'Or# pid id name'
124
- r['department'].sort_by { |d| d['order'].to_i + d['parentid'].to_i * 1000 } .each do |i|
125
- puts format('%3d %3d %3d %s', i['order'], i['parentid'], i['id'], i['name'])
76
+ desc 'user_batchdelete [USER_ID_LIST]', '批量删除成员'
77
+ def user_batchdelete(useridlist)
78
+ puts wechat_api.user_batchdelete(useridlist.split(','))
126
79
  end
127
- end
128
80
 
129
- desc 'user_simplelist [DEPARTMENT_ID]', '获取部门成员'
130
- method_option :fetch_child, aliases: '-c', desc: '是否递归获取子部门下面的成员', default: 1
131
- method_option :status, aliases: '-s', desc: '0 获取全部成员,1 获取已关注成员列表,2 获取禁用成员列表,4 获取未关注成员列表。status可叠加', default: 0
132
- def user_simplelist(departmentid = 0)
133
- api_opts = options.slice(:fetch_child, :status)
81
+ desc 'user_simplelist [DEPARTMENT_ID]', '获取部门成员'
82
+ method_option :fetch_child, aliases: '-c', desc: '是否递归获取子部门下面的成员', default: 1
83
+ method_option :status, aliases: '-s', desc: '0 获取全部成员,1 获取已关注成员列表,2 获取禁用成员列表,4 获取未关注成员列表。status可叠加', default: 0
84
+ def user_simplelist(departmentid = 0)
85
+ api_opts = options.slice(:fetch_child, :status)
86
+
87
+ r = wechat_api.user_simplelist(departmentid, api_opts[:fetch_child], api_opts[:status])
88
+ puts "errcode: #{r['errcode']} errmsg: #{r['errmsg']}"
89
+ puts " userid Name #{' ' * 20} department_ids"
90
+ r['userlist'].sort_by { |d| d['userid'] } .each do |i|
91
+ puts format('%7s %-25s %-14s', i['userid'], i['name'], i['department'])
92
+ end
93
+ end
134
94
 
135
- r = Helper.with(options).user_simplelist(departmentid, api_opts[:fetch_child], api_opts[:status])
136
- puts "errcode: #{r['errcode']} errmsg: #{r['errmsg']}"
137
- puts " userid Name #{' ' * 20} department_ids"
138
- r['userlist'].sort_by { |d| d['userid'] } .each do |i|
139
- puts format('%7s %-25s %-14s', i['userid'], i['name'], i['department'])
95
+ desc 'user_list [DEPARTMENT_ID]', '获取部门成员详情'
96
+ method_option :fetch_child, aliases: '-c', desc: '是否递归获取子部门下面的成员', default: 0
97
+ method_option :status, aliases: '-s', desc: '0 获取全部成员,1 获取已关注成员列表,2 获取禁用成员列表,4 获取未关注成员列表。status可叠加', default: 0
98
+ def user_list(departmentid = 0)
99
+ api_opts = options.slice(:fetch_child, :status)
100
+
101
+ r = wechat_api.user_list(departmentid, api_opts[:fetch_child], api_opts[:status])
102
+ puts "errcode: #{r['errcode']} errmsg: #{r['errmsg']}"
103
+ puts " userid Name #{' ' * 15} department_ids position mobile #{' ' * 5}gender email #{' ' * 10}weixinid status extattr"
104
+ r['userlist'].sort_by { |d| d['userid'] } .each do |i|
105
+ puts format('%7s %-20s %-14s %-8s %-11s %-6s %-15s %-15s %-6s %s',
106
+ i['userid'], i['name'], i['department'], i['position'], i['mobile'],
107
+ i['gender'], i['email'], i['weixinid'], i['status'], i['extattr'])
108
+ end
140
109
  end
141
- end
142
110
 
143
- desc 'user_list [DEPARTMENT_ID]', '获取部门成员详情'
144
- method_option :fetch_child, aliases: '-c', desc: '是否递归获取子部门下面的成员', default: 0
145
- method_option :status, aliases: '-s', desc: '0 获取全部成员,1 获取已关注成员列表,2 获取禁用成员列表,4 获取未关注成员列表。status可叠加', default: 0
146
- def user_list(departmentid = 0)
147
- api_opts = options.slice(:fetch_child, :status)
111
+ desc 'invite_user [USER_ID]', '邀请成员关注'
112
+ def invite_user(userid)
113
+ puts wechat_api.invite_user(userid)
114
+ end
148
115
 
149
- r = Helper.with(options).user_list(departmentid, api_opts[:fetch_child], api_opts[:status])
150
- puts "errcode: #{r['errcode']} errmsg: #{r['errmsg']}"
151
- puts " userid Name #{' ' * 15} department_ids position mobile #{' ' * 5}gender email #{' ' * 10}weixinid status extattr"
152
- r['userlist'].sort_by { |d| d['userid'] } .each do |i|
153
- puts format('%7s %-20s %-14s %-8s %-11s %-6s %-15s %-15s %-6s %s',
154
- i['userid'], i['name'], i['department'], i['position'], i['mobile'],
155
- i['gender'], i['email'], i['weixinid'], i['status'], i['extattr'])
116
+ desc 'tag_create [TAGNAME, TAG_ID]', '创建标签'
117
+ method_option :tagid, aliases: '-id', desc: '整型,指定此参数时新增的标签会生成对应的标签id,不指定时则以目前最大的id自增'
118
+ def tag_create(name)
119
+ api_opts = options.slice(:tagid)
120
+ puts wechat_api.tag_create(name, api_opts[:tagid])
156
121
  end
157
- end
158
122
 
159
- desc 'tag_create [TAGNAME, TAG_ID]', '创建标签'
160
- method_option :tagid, aliases: '-id', desc: '整型,指定此参数时新增的标签会生成对应的标签id,不指定时则以目前最大的id自增'
161
- def tag_create(name)
162
- api_opts = options.slice(:tagid)
163
- puts Helper.with(options).tag_create(name, api_opts[:tagid])
164
- end
123
+ desc 'tag_update [TAG_ID, TAGNAME]', '更新标签名字'
124
+ def tag_update(tagid, tagname)
125
+ puts wechat_api.tag_update(tagid, tagname)
126
+ end
165
127
 
166
- desc 'tag_update [TAG_ID, TAGNAME]', '更新标签名字'
167
- def tag_update(tagid, tagname)
168
- puts Helper.with(options).tag_update(tagid, tagname)
169
- end
128
+ desc 'tag_delete [TAG_ID]', '删除标签'
129
+ def tag_delete(tagid)
130
+ puts wechat_api.tag_delete(tagid)
131
+ end
170
132
 
171
- desc 'tag_delete [TAG_ID]', '删除标签'
172
- def tag_delete(tagid)
173
- puts Helper.with(options).tag_delete(tagid)
174
- end
133
+ desc 'tag [TAG_ID]', '获取标签成员'
134
+ def tag(tagid)
135
+ puts wechat_api.tag(tagid)
136
+ end
175
137
 
176
- desc 'tags', '获取标签列表'
177
- def tags
178
- puts Helper.with(options).tags
179
- end
138
+ desc 'tag_add_user [TAG_ID, USER_IDS]', '增加标签成员'
139
+ def tag_add_user(tagid, userids)
140
+ puts wechat_api.tag_add_user(tagid, userids.split(','))
141
+ end
180
142
 
181
- desc 'tag [TAG_ID]', '获取标签成员'
182
- def tag(tagid)
183
- puts Helper.with(options).tag(tagid)
184
- end
143
+ desc 'tag_add_department [TAG_ID, PARTY_IDS]', '增加标签部门'
144
+ def tag_add_department(tagid, partyids)
145
+ puts wechat_api.tag_add_user(tagid, nil, partyids.split(','))
146
+ end
185
147
 
186
- desc 'tag_add_user [TAG_ID, USER_IDS]', '增加标签成员'
187
- def tag_add_user(tagid, userids)
188
- puts Helper.with(options).tag_add_user(tagid, userids.split(','))
189
- end
148
+ desc 'tag_del_user [TAG_ID, USER_IDS]', '删除标签成员'
149
+ def tag_del_user(tagid, userids)
150
+ puts wechat_api.tag_del_user(tagid, userids.split(','))
151
+ end
190
152
 
191
- desc 'tag_add_department [TAG_ID, PARTY_IDS]', '增加标签部门'
192
- def tag_add_department(tagid, partyids)
193
- puts Helper.with(options).tag_add_user(tagid, nil, partyids.split(','))
194
- end
153
+ desc 'tag_del_department [TAG_ID, PARTY_IDS]', '删除标签部门'
154
+ def tag_del_department(tagid, partyids)
155
+ puts wechat_api.tag_del_user(tagid, nil, partyids.split(','))
156
+ end
195
157
 
196
- desc 'tag_del_user [TAG_ID, USER_IDS]', '删除标签成员'
197
- def tag_del_user(tagid, userids)
198
- puts Helper.with(options).tag_del_user(tagid, userids.split(','))
199
- end
158
+ desc 'tags', '获取标签列表'
159
+ def tags
160
+ puts wechat_api.tags
161
+ end
200
162
 
201
- desc 'tag_del_department [TAG_ID, PARTY_IDS]', '删除标签部门'
202
- def tag_del_department(tagid, partyids)
203
- puts Helper.with(options).tag_del_user(tagid, nil, partyids.split(','))
204
- end
163
+ desc 'batch_job_result [JOB_ID]', '获取异步任务结果'
164
+ def batch_job_result(job_id)
165
+ puts wechat_api.batch_job_result(job_id)
166
+ end
205
167
 
206
- desc 'agent_list', '获取应用概况列表'
207
- def agent_list
208
- r = Helper.with(options).agent_list
209
- puts "errcode: #{r['errcode']} errmsg: #{r['errmsg']}"
210
- puts 'ag# name square_logo_url round_logo_url'
211
- r['agentlist'].sort_by { |d| d['agentid'] } .each do |i|
212
- puts format('%3d %s %s %s', i['agentid'], i['name'], i['square_logo_url'], i['round_logo_url'])
168
+ desc 'batch_replaceparty [BATCH_PARTY_CSV_MEDIA_ID]', '全量覆盖部门'
169
+ def batch_replaceparty(batch_party_csv_media_id)
170
+ puts wechat_api.batch_replaceparty(batch_party_csv_media_id)
213
171
  end
214
- end
215
172
 
216
- desc 'agent [AGENT_ID]', '获取企业号应用详情'
217
- def agent(agentid)
218
- r = Helper.with(options).agent(agentid)
219
- puts "agentid: #{r['agentid']} errcode: #{r['errcode']} errmsg: #{r['errmsg']}"
220
- puts "name: #{r['name']}"
221
- puts "description: #{r['description']}"
222
- puts " square_logo_url: #{r['square_logo_url']}"
223
- puts " round_logo_url: #{r['round_logo_url']}"
224
- puts "allow_userinfos: #{r['allow_userinfos']}"
225
- puts "allow_partys: #{r['allow_partys']}"
226
- puts "allow_tags: #{r['allow_tags']}"
227
- puts "close: #{r['close']} redirect_domain: #{r['redirect_domain']}"
228
- puts "report_location_flag: #{r['report_location_flag']} isreportuser: #{r['isreportuser']} isreportenter: #{r['isreportenter']}"
229
- end
173
+ desc 'batch_syncuser [SYNC_USER_CSV_MEDIA_ID]', '增量更新成员'
174
+ def batch_syncuser(sync_user_csv_media_id)
175
+ puts wechat_api.batch_syncuser(sync_user_csv_media_id)
176
+ end
230
177
 
231
- desc 'users', '关注者列表'
232
- def users
233
- puts Helper.with(options).users
234
- end
178
+ desc 'batch_replaceuser [BATCH_USER_CSV_MEDIA_ID]', '全量覆盖成员'
179
+ def batch_replaceuser(batch_user_csv_media_id)
180
+ puts wechat_api.batch_replaceuser(batch_user_csv_media_id)
181
+ end
235
182
 
236
- desc 'user [OPEN_ID]', '获取用户基本信息'
237
- def user(open_id)
238
- puts Helper.with(options).user(open_id)
239
- end
183
+ desc 'convert_to_openid [USER_ID]', 'userid转换成openid'
184
+ def convert_to_openid(userid)
185
+ puts wechat_api.convert_to_openid(userid)
186
+ end
240
187
 
241
- desc 'convert_to_openid [USER_ID]', 'userid转换成openid'
242
- def convert_to_openid(userid)
243
- puts Helper.with(options).convert_to_openid(userid)
244
- end
188
+ desc 'agent_list', '获取应用概况列表'
189
+ def agent_list
190
+ r = wechat_api.agent_list
191
+ puts "errcode: #{r['errcode']} errmsg: #{r['errmsg']}"
192
+ puts 'ag# name square_logo_url round_logo_url'
193
+ r['agentlist'].sort_by { |d| d['agentid'] } .each do |i|
194
+ puts format('%3d %s %s %s', i['agentid'], i['name'], i['square_logo_url'], i['round_logo_url'])
195
+ end
196
+ end
245
197
 
246
- desc 'invite_user [USER_ID]', '邀请成员关注'
247
- def invite_user(userid)
248
- puts Helper.with(options).invite_user(userid)
249
- end
198
+ desc 'agent [AGENT_ID]', '获取企业号应用详情'
199
+ def agent(agentid)
200
+ r = wechat_api.agent(agentid)
201
+ puts "agentid: #{r['agentid']} errcode: #{r['errcode']} errmsg: #{r['errmsg']}"
202
+ puts "name: #{r['name']}"
203
+ puts "description: #{r['description']}"
204
+ puts " square_logo_url: #{r['square_logo_url']}"
205
+ puts " round_logo_url: #{r['round_logo_url']}"
206
+ puts "allow_userinfos: #{r['allow_userinfos']}"
207
+ puts "allow_partys: #{r['allow_partys']}"
208
+ puts "allow_tags: #{r['allow_tags']}"
209
+ puts "close: #{r['close']} redirect_domain: #{r['redirect_domain']}"
210
+ puts "report_location_flag: #{r['report_location_flag']} isreportuser: #{r['isreportuser']} isreportenter: #{r['isreportenter']}"
211
+ end
250
212
 
251
- desc 'user_delete [USER_ID]', '删除成员'
252
- def user_delete(userid)
253
- puts Helper.with(options).user_delete(userid)
254
- end
213
+ desc 'message_send [OPENID, TEXT_MESSAGE]', '发送文字消息'
214
+ def message_send(openid, text_message)
215
+ puts wechat_api.message_send openid, text_message
216
+ end
217
+ else
218
+ desc 'group_create [GROUP_NAME]', '创建分组'
219
+ def group_create(group_name)
220
+ puts wechat_api.group_create(group_name)
221
+ end
255
222
 
256
- desc 'user_batchdelete [USER_ID_LIST]', '批量删除成员'
257
- def user_batchdelete(useridlist)
258
- puts Helper.with(options).user_batchdelete(useridlist.split(','))
259
- end
223
+ desc 'groups', '查询所有分组'
224
+ def groups
225
+ puts wechat_api.groups
226
+ end
260
227
 
261
- desc 'batch_job_result [JOB_ID]', '获取异步任务结果'
262
- def batch_job_result(job_id)
263
- puts Helper.with(options).batch_job_result(job_id)
264
- end
228
+ desc 'user_group [OPEN_ID]', '查询用户所在分组'
229
+ def user_group(openid)
230
+ puts wechat_api.user_group(openid)
231
+ end
265
232
 
266
- desc 'batch_replaceparty [BATCH_PARTY_CSV_MEDIA_ID]', '全量覆盖部门'
267
- def batch_replaceparty(batch_party_csv_media_id)
268
- puts Helper.with(options).batch_replaceparty(batch_party_csv_media_id)
269
- end
233
+ desc 'group_update [GROUP_ID, NEW_GROUP_NAME]', '修改分组名'
234
+ def group_update(groupid, new_group_name)
235
+ puts wechat_api.group_update(groupid, new_group_name)
236
+ end
270
237
 
271
- desc 'batch_syncuser [SYNC_USER_CSV_MEDIA_ID]', '增量更新成员'
272
- def batch_syncuser(sync_user_csv_media_id)
273
- puts Helper.with(options).batch_syncuser(sync_user_csv_media_id)
274
- end
238
+ desc 'user_change_group [OPEN_ID, TO_GROUP_ID]', '移动用户分组'
239
+ def user_change_group(openid, to_groupid)
240
+ puts wechat_api.user_change_group(openid, to_groupid)
241
+ end
275
242
 
276
- desc 'batch_replaceuser [BATCH_USER_CSV_MEDIA_ID]', '全量覆盖成员'
277
- def batch_replaceuser(batch_user_csv_media_id)
278
- puts Helper.with(options).batch_replaceuser(batch_user_csv_media_id)
279
- end
243
+ desc 'group_delete [GROUP_ID]', '删除分组'
244
+ def group_delete(groupid)
245
+ puts wechat_api.group_delete(groupid)
246
+ end
280
247
 
281
- desc 'user_group [OPEN_ID]', '查询用户所在分组'
282
- def user_group(openid)
283
- puts Helper.with(options).user_group(openid)
248
+ desc 'users', '关注者列表'
249
+ def users
250
+ puts wechat_api.users
251
+ end
284
252
  end
285
253
 
286
- desc 'user_change_group [OPEN_ID, TO_GROUP_ID]', '移动用户分组'
287
- def user_change_group(openid, to_groupid)
288
- puts Helper.with(options).user_change_group(openid, to_groupid)
254
+ desc 'user [OPEN_ID]', '获取用户基本信息'
255
+ def user(open_id)
256
+ puts wechat_api.user(open_id)
289
257
  end
290
258
 
291
259
  desc 'user_update_remark [OPEN_ID, REMARK]', '设置备注名'
292
260
  def user_update_remark(openid, remark)
293
- puts Helper.with(options).user_update_remark(openid, remark)
261
+ puts wechat_api.user_update_remark(openid, remark)
294
262
  end
295
263
 
296
264
  desc 'qrcode_create_scene [SCENE_ID, EXPIRE_SECONDS]', '请求临时二维码'
297
265
  def qrcode_create_scene(scene_id, expire_seconds = 604800)
298
- puts Helper.with(options).qrcode_create_scene(scene_id, expire_seconds)
266
+ puts wechat_api.qrcode_create_scene(scene_id, expire_seconds)
299
267
  end
300
268
 
301
269
  desc 'qrcode_create_limit_scene [SCENE_ID_OR_STR]', '请求永久二维码'
302
270
  def qrcode_create_limit_scene(scene_id_or_str)
303
- puts Helper.with(options).qrcode_create_limit_scene(scene_id_or_str)
271
+ puts wechat_api.qrcode_create_limit_scene(scene_id_or_str)
304
272
  end
305
273
 
306
274
  desc 'menu', '当前菜单'
307
275
  def menu
308
- puts Helper.with(options).menu
276
+ puts wechat_api.menu
309
277
  end
310
278
 
311
279
  desc 'menu_delete', '删除菜单'
312
280
  def menu_delete
313
- puts 'Menu deleted' if Helper.with(options).menu_delete
281
+ puts 'Menu deleted' if wechat_api.menu_delete
314
282
  end
315
283
 
316
284
  desc 'menu_create [MENU_YAML_PATH]', '创建菜单'
317
285
  def menu_create(menu_yaml_path)
318
286
  menu = YAML.load(File.read(menu_yaml_path))
319
- puts 'Menu created' if Helper.with(options).menu_create(menu)
287
+ puts 'Menu created' if wechat_api.menu_create(menu)
320
288
  end
321
289
 
322
290
  desc 'media [MEDIA_ID, PATH]', '媒体下载'
323
291
  def media(media_id, path)
324
- tmp_file = Helper.with(options).media(media_id)
292
+ tmp_file = wechat_api.media(media_id)
325
293
  FileUtils.mv(tmp_file.path, path)
326
294
  puts 'File downloaded'
327
295
  end
@@ -329,12 +297,12 @@ HELP
329
297
  desc 'media_create [MEDIA_TYPE, PATH]', '媒体上传'
330
298
  def media_create(type, path)
331
299
  file = File.new(path)
332
- puts Helper.with(options).media_create(type, file)
300
+ puts wechat_api.media_create(type, file)
333
301
  end
334
302
 
335
303
  desc 'material [MEDIA_ID, PATH]', '永久媒体下载'
336
304
  def material(media_id, path)
337
- tmp_file = Helper.with(options).material(media_id)
305
+ tmp_file = wechat_api.material(media_id)
338
306
  FileUtils.mv(tmp_file.path, path)
339
307
  puts 'File downloaded'
340
308
  end
@@ -342,46 +310,43 @@ HELP
342
310
  desc 'material_add [MEDIA_TYPE, PATH]', '永久媒体上传'
343
311
  def material_add(type, path)
344
312
  file = File.new(path)
345
- puts Helper.with(options).material_add(type, file)
313
+ puts wechat_api.material_add(type, file)
346
314
  end
347
315
 
348
316
  desc 'material_delete [MEDIA_ID]', '删除永久素材'
349
317
  def material_delete(media_id)
350
- puts Helper.with(options).material_delete(media_id)
318
+ puts wechat_api.material_delete(media_id)
351
319
  end
352
320
 
353
321
  desc 'material_count', '获取永久素材总数'
354
322
  def material_count
355
- puts Helper.with(options).material_count
323
+ puts wechat_api.material_count
356
324
  end
357
325
 
358
326
  desc 'material_list [TYPE, OFFSET, COUNT]', '获取永久素材列表'
359
327
  def material_list(type, offset, count)
360
- r = Helper.with(options).material_list(type, offset, count)
328
+ r = wechat_api.material_list(type, offset, count)
361
329
  if %w(image voice video file).include?(type)
362
330
  puts "errcode: #{r['errcode']} errmsg: #{r['errmsg']} total_count: #{r['total_count']} item_count: #{r['item_count']}"
363
- r['item'].each do |i|
364
- puts "#{i['media_id']} #{i['name']} #{Time.at(i['update_time'].to_i)}"
331
+ if wechat_api.is_a?(Wechat::CorpApi)
332
+ r['itemlist'].each { |i| puts "#{i['media_id']} #{i['filename']} #{Time.at(i['update_time'].to_i)}" }
333
+ else
334
+ r['item'].each { |i| puts "#{i['media_id']} #{i['name']} #{Time.at(i['update_time'].to_i)}" }
365
335
  end
366
336
  else
367
337
  puts r
368
338
  end
369
339
  end
370
340
 
371
- desc 'message_send [OPENID, TEXT_MESSAGE]', '发送文字消息(仅企业号)'
372
- def message_send(openid, text_message)
373
- puts Helper.with(options).message_send openid, text_message
374
- end
375
-
376
341
  desc 'custom_text [OPENID, TEXT_MESSAGE]', '发送文字客服消息'
377
342
  def custom_text(openid, text_message)
378
- puts Helper.with(options).custom_message_send Wechat::Message.to(openid).text(text_message)
343
+ puts wechat_api.custom_message_send Wechat::Message.to(openid).text(text_message)
379
344
  end
380
345
 
381
346
  desc 'custom_image [OPENID, IMAGE_PATH]', '发送图片客服消息'
382
347
  def custom_image(openid, image_path)
383
348
  file = File.new(image_path)
384
- api = Helper.with(options)
349
+ api = wechat_api
385
350
 
386
351
  media_id = api.media_create('image', file)['media_id']
387
352
  puts api.custom_message_send Wechat::Message.to(openid).image(media_id)
@@ -390,7 +355,7 @@ HELP
390
355
  desc 'custom_voice [OPENID, VOICE_PATH]', '发送语音客服消息'
391
356
  def custom_voice(openid, voice_path)
392
357
  file = File.new(voice_path)
393
- api = Helper.with(options)
358
+ api = wechat_api
394
359
 
395
360
  media_id = api.media_create('voice', file)['media_id']
396
361
  puts api.custom_message_send Wechat::Message.to(openid).voice(media_id)
@@ -401,7 +366,7 @@ HELP
401
366
  method_option :description, aliases: '-d', desc: '视频描述'
402
367
  def custom_video(openid, video_path)
403
368
  file = File.new(video_path)
404
- api = Helper.with(options)
369
+ api = wechat_api
405
370
 
406
371
  api_opts = options.slice(:title, :description)
407
372
  media_id = api.media_create('video', file)['media_id']
@@ -414,7 +379,7 @@ HELP
414
379
  method_option :HQ_music_url, aliases: '-u', desc: '高质量音乐URL链接'
415
380
  def custom_music(openid, thumbnail_path, music_url)
416
381
  file = File.new(thumbnail_path)
417
- api = Helper.with(options)
382
+ api = wechat_api
418
383
 
419
384
  api_opts = options.slice(:title, :description, :HQ_music_url)
420
385
  thumb_media_id = api.media_create('thumb', file)['thumb_media_id']
@@ -424,13 +389,13 @@ HELP
424
389
  desc 'custom_news [OPENID, NEWS_YAML_PATH]', '发送图文客服消息'
425
390
  def custom_news(openid, news_yaml_path)
426
391
  articles = YAML.load(File.read(news_yaml_path))
427
- puts Helper.with(options).custom_message_send Wechat::Message.to(openid).news(articles['articles'])
392
+ puts wechat_api.custom_message_send Wechat::Message.to(openid).news(articles['articles'])
428
393
  end
429
394
 
430
395
  desc 'template_message [OPENID, TEMPLATE_YAML_PATH]', '模板消息接口'
431
396
  def template_message(openid, template_yaml_path)
432
397
  template = YAML.load(File.read(template_yaml_path))
433
- puts Helper.with(options).template_message_send Wechat::Message.to(openid).template(template['template'])
398
+ puts wechat_api.template_message_send Wechat::Message.to(openid).template(template['template'])
434
399
  end
435
400
  end
436
401
 
@@ -81,7 +81,7 @@ class WechatsController < ApplicationController
81
81
  end
82
82
 
83
83
  on :event, with: 'unsubscribe' do |request|
84
- request.reply.text "#{request[:FromUserName]} can not receive this message"
84
+ request.reply.success # user can not receive this message
85
85
  end
86
86
 
87
87
  # When user enter the app / agent app
@@ -1,3 +1,4 @@
1
+ require 'wechat/api_loader'
1
2
  require 'wechat/api'
2
3
  require 'wechat/corp_api'
3
4
  require 'action_controller/wechat_responder'
@@ -19,18 +20,7 @@ module Wechat
19
20
  attr_reader :config
20
21
 
21
22
  def self.config
22
- @config ||= begin
23
- if defined? Rails
24
- config_file = Rails.root.join('config/wechat.yml')
25
- config = YAML.load(ERB.new(File.new(config_file).read).result)[Rails.env] if File.exist?(config_file)
26
- end
27
-
28
- config ||= config_from_environment
29
- config.symbolize_keys!
30
- config[:access_token] ||= Rails.root.join('tmp/access_token').to_s
31
- config[:jsapi_ticket] ||= Rails.root.join('tmp/jsapi_ticket').to_s
32
- OpenStruct.new(config)
33
- end
23
+ @config ||= ApiLoader.loading_config
34
24
  end
35
25
 
36
26
  def self.api
@@ -40,19 +30,4 @@ module Wechat
40
30
  @api ||= Api.new(config.appid, config.secret, config.access_token, config.skip_verify_ssl, config.jsapi_ticket)
41
31
  end
42
32
  end
43
-
44
- private
45
-
46
- def self.config_from_environment
47
- { appid: ENV['WECHAT_APPID'],
48
- secret: ENV['WECHAT_SECRET'],
49
- corpid: ENV['WECHAT_CORPID'],
50
- corpsecret: ENV['WECHAT_CORPSECRET'],
51
- agentid: ENV['WECHAT_AGENTID'],
52
- token: ENV['WECHAT_TOKEN'],
53
- access_token: ENV['WECHAT_ACCESS_TOKEN'],
54
- encrypt_mode: ENV['WECHAT_ENCRYPT_MODE'],
55
- skip_verify_ssl: ENV['WECHAT_SKIP_VERIFY_SSL'],
56
- encoding_aes_key: ENV['WECHAT_ENCODING_AES_KEY'] }
57
- end
58
33
  end
@@ -1,5 +1,3 @@
1
- require 'cgi'
2
-
3
1
  module Wechat
4
2
  class ApiBase
5
3
  attr_reader :access_token, :client
@@ -11,7 +9,7 @@ module Wechat
11
9
  end
12
10
 
13
11
  def qrcode(ticket)
14
- client.get 'showqrcode', ticket: CGI.escape(ticket), base: MP_BASE, as: :file
12
+ client.get 'showqrcode', params: { ticket: ticket }, base: MP_BASE, as: :file
15
13
  end
16
14
 
17
15
  def media(media_id)
@@ -0,0 +1,65 @@
1
+ module Wechat
2
+ class ApiLoader
3
+ def self.with(options)
4
+ c = loading_config
5
+
6
+ token_file = options[:toke_file] || c.access_token || '/var/tmp/wechat_access_token'
7
+
8
+ if c.appid && c.secret && token_file.present?
9
+ Wechat::Api.new(c.appid, c.secret, token_file, c.skip_verify_ssl)
10
+ elsif c.corpid && c.corpsecret && token_file.present?
11
+ Wechat::CorpApi.new(c.corpid, c.corpsecret, token_file, c.agentid, c.skip_verify_ssl)
12
+ else
13
+ puts <<-HELP
14
+ Need create ~/.wechat.yml with wechat appid and secret
15
+ or running at rails root folder so wechat can read config/wechat.yml
16
+ HELP
17
+ exit 1
18
+ end
19
+ end
20
+
21
+ def self.loading_config
22
+ if defined?(::Rails)
23
+ config_file = Rails.root.join('config/wechat.yml')
24
+ config = YAML.load(ERB.new(File.read(config_file)).result)[Rails.env] if File.exist?(config_file)
25
+ else
26
+ rails_config_file = File.join(Dir.getwd, 'config/wechat.yml')
27
+ home_config_file = File.join(Dir.home, '.wechat.yml')
28
+
29
+ if File.exist?(rails_config_file)
30
+ config = YAML.load(ERB.new(File.read(rails_config_file)).result)['default']
31
+ if config.present? && (config['appid'] || config['corpid'])
32
+ puts 'Using rails project config/wechat.yml default setting...'
33
+ else
34
+ config = {}
35
+ end
36
+ end
37
+
38
+ if config.blank? && File.exist?(home_config_file)
39
+ config = YAML.load ERB.new(File.read(home_config_file)).result
40
+ end
41
+ end
42
+
43
+ config ||= config_from_environment
44
+ if defined?(::Rails)
45
+ config[:access_token] ||= Rails.root.join('tmp/access_token').to_s
46
+ config[:jsapi_ticket] ||= Rails.root.join('tmp/jsapi_ticket').to_s
47
+ end
48
+ config.symbolize_keys!
49
+ OpenStruct.new(config)
50
+ end
51
+
52
+ def self.config_from_environment
53
+ { appid: ENV['WECHAT_APPID'],
54
+ secret: ENV['WECHAT_SECRET'],
55
+ corpid: ENV['WECHAT_CORPID'],
56
+ corpsecret: ENV['WECHAT_CORPSECRET'],
57
+ agentid: ENV['WECHAT_AGENTID'],
58
+ token: ENV['WECHAT_TOKEN'],
59
+ access_token: ENV['WECHAT_ACCESS_TOKEN'],
60
+ encrypt_mode: ENV['WECHAT_ENCRYPT_MODE'],
61
+ skip_verify_ssl: ENV['WECHAT_SKIP_VERIFY_SSL'],
62
+ encoding_aes_key: ENV['WECHAT_ENCODING_AES_KEY'] }
63
+ end
64
+ end
65
+ end
@@ -73,6 +73,10 @@ module Wechat
73
73
  update(MsgType: 'transfer_customer_service')
74
74
  end
75
75
 
76
+ def success
77
+ update(MsgType: 'success')
78
+ end
79
+
76
80
  def image(media_id)
77
81
  update(MsgType: 'image', Image: { MediaId: media_id })
78
82
  end
@@ -200,7 +200,11 @@ module Wechat
200
200
  end
201
201
 
202
202
  def process_response(response)
203
- msg = response.to_xml
203
+ if response[:MsgType] == 'success'
204
+ msg = 'success'
205
+ else
206
+ msg = response.to_xml
207
+ end
204
208
 
205
209
  if self.class.encrypt_mode
206
210
  encrypt = Base64.strict_encode64(encrypt(pack(msg, @app_id), self.class.encoding_aes_key))
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.6.3
4
+ version: 0.6.4
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-11-13 00:00:00.000000000 Z
12
+ date: 2015-11-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -39,6 +39,20 @@ dependencies:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: 1.6.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: thor
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
42
56
  - !ruby/object:Gem::Dependency
43
57
  name: rest-client
44
58
  requirement: !ruby/object:Gem::Requirement
@@ -101,6 +115,7 @@ files:
101
115
  - lib/wechat/access_token.rb
102
116
  - lib/wechat/api.rb
103
117
  - lib/wechat/api_base.rb
118
+ - lib/wechat/api_loader.rb
104
119
  - lib/wechat/cipher.rb
105
120
  - lib/wechat/client.rb
106
121
  - lib/wechat/corp_api.rb