wechat_public_api 0.1.4 → 0.1.5

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: 98dfee4a07d505f15fb5e2b6c8e34d9210f050ee
4
- data.tar.gz: 9866e3df655cb9cdc1e39a7d8ed33922b012bc9f
3
+ metadata.gz: 8a3c096dfbdce45f98fc5f76ea0681506702410a
4
+ data.tar.gz: bdee8fb5d9c08e57c44c724e2a263006a0373bcc
5
5
  SHA512:
6
- metadata.gz: 912aa2de176603be919d491a4453561abb531b9aa937cbd77b417d7104337594a9af642a0dce0ad3711b14a1035606494a384b441c3290fb3221c97597dd6094
7
- data.tar.gz: 7bd5188cc0c6e69832326a5428e3be01afebe1059df2f32738636b4df79880484471409020794c26c4fa8efbcd274a63df0f92097b2f1962152f24bae11d1aef
6
+ metadata.gz: 8d9a56c7272421292cde50c5b703b8bcaa4fc109bb514eb86759e762dc43b9c2abee65cc8fb5ef06d9fcc7c99cf1a74402d466ae72df8576c69477e0805b4e0d
7
+ data.tar.gz: 67511e46afa3b5fdf425a759b33b5db9864e5f2fb33ceb6fcec8b628a2f7802e439ede3c4e332a5fde1948816848e2486fcfcd4f1f11b315a8f991502ea08597
data/README.md CHANGED
@@ -20,170 +20,14 @@ gem 'wechat_public_api'
20
20
 
21
21
  $ gem install wechat_public_api
22
22
 
23
- ## 三行代码获得 access_token
23
+ ## 0.1.4 版本文档
24
24
 
25
- ```ruby
26
- WechatPublicApi.app_id = 'appid'
27
- WechatPublicApi.app_secret = 'secret'
28
- access_token = WechatPublicApi::AccessToken.get() # access_token
29
- ```
30
- ## API文档
31
-
32
- ### WechatPublicApi模块配置,开启你的新项目
33
-
34
- **参数说明**
35
-
36
- * @param <String> app_id     # 公众号后台->开发->基本配置提供的AppID
37
- * @param <String> app_secret # 公众号后台->开发->基本配置提供的AppSecret
38
- * @param <Boolearn> access_token_cache # 默认false,用于标识是否使用redis缓存查询到的access_token
39
-
40
- 使用`WechatPublicApi`模块封装的方法之前,需要配置 app_id、app_secret和access_token_cache(可选),具体如下:
41
-
42
- ```ruby
43
- WechatPublicApi.app_id = 'wx440415e4c3b4b8f9'
44
- WechatPublicApi.app_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
45
- access_token = WechatPublicApi::AccessToken.get() # access_token
46
- ```
47
-
48
- **注意:** access_token_cache是一个布尔值,用于判断是否需要缓存access_token_cache,默认可不填,即默认不缓存access_token,如需缓存,请依照下方代码设置参数:
49
-
50
- ```ruby
51
- WechatPublicApi.access_token_cache = true
52
- ```
53
-
54
- ### API功能概览
55
-
56
- * 菜单栏操作
57
- * 创建菜单栏:`WechatPublicApi::Menu.create(post_data)`
58
- * 查询菜单栏:`WechatPublicApi::Menu.query()`
59
- * 删除菜单栏:`WechatPublicApi::Menu.delete()`
60
- * 客服消息管理
61
- * 发送文字消息:`WechatPublicApi::Kf.text_message(openid, content)`
62
- * 发送图片消息:`WechatPublicApi::Kf.image_message(openid, media_id)`
63
- * 发送图文消息:`WechatPublicApi::Kf.mpnews_message(openid, media_id)`
64
- * 发送图文消息(点击跳转外链): `WechatPublicApi::Kf.news_message(openid, articles)`
65
- * 发送语音消息:`WechatPublicApi::Kf.voice_message(openid, media_id)`
66
- * 模板消息管理
67
- * 获取模板列表:`WechatPublicApi::Tp.get_all()`
68
- * 删除模板:`WechatPublicApi::Tp.delete(templet_id)`
69
- * 发送普通模板消息(不跳转小程序)`WechatPublicApi::Tp.general_message(openid, templet_id, url, data)`
70
- * 发送跳转小程序的模板消息:`WechatPublicApi::Tp.miniprogram_message(openid, templet_id, url, appid, pagepath, data)`
71
- * 用户管理
72
- * 获取用户基本信息: `WechatPublicApi::User.get_userinfo(openid)`
73
- * 帐号管理
74
- * 获取临时带参二维码: `WechatPublicApi::Account.qrscene(sceneid)`
75
- * 获取永久带参二维码: `WechatPublicApi::Account.qrsrtscene(sceneid)`
76
- * 保存带参二维码到本地: `WechatPublicApi::Account.save_qrcode(path, *filename)`
77
- * 生成短链接:`WechatPublicApi::Account.shorturl(longurl)`
78
- * 素材管理
79
- * 获得临时图片素材的 media_id: `WechatPublicApi::Material.upload_image_media(file_path)`
80
- * 获得永久图片素材的 media_id: `WechatPublicApi::Material.upload_image_material(file_path)`
81
- * 消息加密解密
82
- * 加密: `WechatPublicApi::Aes.encrypt(aes_key, text, app_id)`
83
- * 解密: `WechatPublicApi::Aes.decrypt(key, dicrypted_string)`
84
-
85
- ### 菜单栏操作API
25
+ [0.1.4 版本文档][1]
26
+ [1]:https://github.com/Diyilou/wechat_public_api/blob/master/doc/0.1.4.md "版本:0.1.4"
86
27
 
87
- 1. 自定义菜单查询
28
+ ## 两行代码获得 access_token
88
29
 
89
30
  ```ruby
90
- # no params
91
- # @return
92
- # {
93
- # "menu": {
94
- # "button": [
95
- # {
96
- # "type": "view",
97
- # "name": "",
98
- # "url": "",
99
- # "sub_button": []
100
- # },
101
- # {
102
- # "type": "click",
103
- # "name": "",
104
- # "key": "menu_3",
105
- # "sub_button": []
106
- # }
107
- # ]
108
- # }
109
- # }
110
- #
111
- menu_list = WechatPublicApi::Menu.query()
31
+ wechat_api = WechatPublicApi.new appid: 'xx', app_secret: 'xx', access_token_cache: true
32
+ access_token = wechat_api.get_access_token
112
33
  ```
113
-
114
- 2. 自定义菜单创建
115
-
116
- ```ruby
117
- ###
118
- # create wechat public menu
119
- # @param <json> post_data
120
- #
121
- # => post_data example
122
- # {
123
- # "button": [
124
- # {
125
- # "type": "view",
126
- # "name": "",
127
- # "url": "",
128
- # "sub_button": []
129
- # },
130
- # {
131
- # "type": "click",
132
- # "name": "",
133
- # "key": "menu_3",
134
- # "sub_button": []
135
- # }
136
- # ]
137
- # }
138
- #
139
- # if success
140
- # @return <JSON> {"errcode"=>0, "errmsg"=>"ok"}
141
- # if failed
142
- # @return <JSON> {"errcode"=>40166, "errmsg"=>"...."}
143
- #
144
- status = WechatPublicApi::Menu.create(post_data)
145
- ```
146
-
147
- 3. 自定义菜单删除
148
-
149
- ```ruby
150
- # @return <JSON> {"errcode"=>0, "errmsg"=>"ok"}
151
- status = WechatPublicApi::Menu.delete()
152
- ```
153
-
154
- 菜单栏操作API主要包含以上三个方法,接下来看一个完整示例:
155
-
156
- ```ruby
157
- # 创建菜单栏 -> 查询菜单栏列表
158
- # 初始化配置
159
- WechatPublicApi.app_id = 'wx440415e4c3b4b8f9'
160
- WechatPublicApi.app_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
161
- # 创建菜单栏
162
- post_data = {
163
- "button": [
164
- {
165
- "type": "view",
166
- "name": "",
167
- "url": "",
168
- "sub_button": []
169
- },
170
- {
171
- "type": "click",
172
- "name": "",
173
- "key": "menu_3",
174
- "sub_button": []
175
- }
176
- ]
177
- }
178
- status = WechatPublicApi::Menu.create(post_data)
179
- if status.errcode.to_i == 0 && status.errmsg == 'ok'
180
- # 返回菜单栏列表
181
- menu_list = WechatPublicApi::Menu.query()
182
- end
183
- ```
184
-
185
- **注意:** 菜单栏创建和查询的方法包含了查询access_token
186
-
187
- ### 客服消息管理API
188
-
189
- 待更新... 可参考源代码,注释比较详细
@@ -5,43 +5,41 @@
5
5
  # Wechat number: zmx119966
6
6
  ####################################################
7
7
 
8
- module WechatPublicApi
8
+ class WechatPublicApi
9
9
  module AccessToken
10
- class << self
11
-
12
- ###
13
- # 获取 access_token
14
- # 判断access_token_cache,决定是否需要缓存数据
15
- # @return <string> nil or access_token
16
- def get()
17
- appid = WechatPublicApi.app_id
18
- secret = WechatPublicApi.app_secret
19
- access_token_cache = WechatPublicApi.access_token_cache
20
-
21
- unless access_token_cache
22
- response = HTTParty.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=#{appid}&secret=#{secret}").body
23
- response_body = (JSON.parse response)
24
-
25
- # 抛出异常
26
- throw response_body['errmsg'] unless response_body['access_token']
27
-
28
- return response_body['access_token']
29
- end
30
-
31
- _cache_key = "#{appid}_access_token"
32
- _cached_access_token = $redis.get _cache_key
33
- if _cached_access_token == nil or _cached_access_token == ''
34
- response = HTTParty.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=#{appid}&secret=#{secret}").body
35
- response_body = (JSON.parse response)
36
-
37
- # 抛出异常
38
- throw response_body['errmsg'] unless response_body['access_token']
39
-
40
- _cached_access_token = response_body['access_token']
41
- $redis.set _cache_key, _cached_access_token, ex: 2.minutes
42
- end
43
- _cached_access_token
10
+
11
+ ###
12
+ # 获取 access_token
13
+ # 判断access_token_cache,决定是否需要缓存数据
14
+ # @return <string> nil or access_token
15
+ def get_access_token()
16
+ appid = @app_id
17
+ secret = @app_secret
18
+ access_token_cache = @access_token_cache
19
+
20
+ unless access_token_cache
21
+ response = HTTParty.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=#{appid}&secret=#{secret}").body
22
+ response_body = (JSON.parse response)
23
+
24
+ # 抛出异常
25
+ throw response_body['errmsg'] unless response_body['access_token']
26
+
27
+ return response_body['access_token']
28
+ end
29
+
30
+ _cache_key = "#{appid}_access_token"
31
+ _cached_access_token = $redis.get _cache_key
32
+ if _cached_access_token == nil or _cached_access_token == ''
33
+ response = HTTParty.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=#{appid}&secret=#{secret}").body
34
+ response_body = (JSON.parse response)
35
+
36
+ # 抛出异常
37
+ throw response_body['errmsg'] unless response_body['access_token']
38
+
39
+ _cached_access_token = response_body['access_token']
40
+ $redis.set _cache_key, _cached_access_token, ex: 2.minutes
44
41
  end
42
+ _cached_access_token
45
43
  end
46
44
  end
47
45
  end
@@ -5,115 +5,108 @@
5
5
  # Wechat number: zmx119966
6
6
  ####################################################
7
7
 
8
- require "wechat_public_api/access_token"
9
-
10
- module WechatPublicApi
8
+ class WechatPublicApi
11
9
  module Account
12
- class << self
10
+ ###
11
+ # 获取临时场景带惨二维码,30天有效
12
+ # @param <int> sceneid -- 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)
13
+ # @return <string> url -- 二维码网址
14
+ #
15
+ def get_qrscene(sceneid)
16
+ access_token = get_access_token()
13
17
 
14
- ###
15
- # 获取临时场景带惨二维码,30天有效
16
- # @param <int> sceneid -- 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)
17
- # @return <string> url -- 二维码网址
18
- #
19
- def qrscene(sceneid)
20
- access_token = AccessToken.get()
18
+ # 获取ticket
19
+ uri = URI.parse("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=#{access_token}")
20
+ post_data = {
21
+ 'expire_seconds' => 2592000,
22
+ 'action_name' => 'QR_SCENE',
23
+ 'action_info' => {'scene' => {'scene_id' => sceneid}}}
24
+ http = Net::HTTP.new(uri.host, uri.port)
25
+ http.use_ssl = true
26
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
27
+ request = Net::HTTP::Post.new("/cgi-bin/qrcode/create?access_token=#{access_token}")
28
+ request.add_field('Content-Type', 'application/json')
29
+ request.body = post_data.to_json
30
+ response = http.request(request)
31
+ content = JSON.parse(response.body)
32
+ ticket = content['ticket']
21
33
 
22
- # 获取ticket
23
- uri = URI.parse("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=#{access_token}")
24
- post_data = {
25
- 'expire_seconds' => 2592000,
26
- 'action_name' => 'QR_SCENE',
27
- 'action_info' => {'scene' => {'scene_id' => sceneid}}}
28
- http = Net::HTTP.new(uri.host, uri.port)
29
- http.use_ssl = true
30
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
31
- request = Net::HTTP::Post.new("/cgi-bin/qrcode/create?access_token=#{access_token}")
32
- request.add_field('Content-Type', 'application/json')
33
- request.body = post_data.to_json
34
- response = http.request(request)
35
- content = JSON.parse(response.body)
36
- ticket = content['ticket']
34
+ # 通过ticket换取二维码
35
+ "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=#{ticket}"
36
+ end
37
37
 
38
- # 通过ticket换取二维码
39
- url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' + ticket
40
- url
41
- end
38
+ ###
39
+ # 获取永久二维码
40
+ # @param <int> sceneid -- 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)
41
+ # @return <string> url -- 二维码网址
42
+ #
43
+ def get_qrsrtscene(sceneid)
44
+ access_token = get_access_token()
42
45
 
43
- ###
44
- # 获取永久二维码
45
- # @param <int> sceneid -- 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)
46
- # @return <string> url -- 二维码网址
47
- #
48
- def qrsrtscene(sceneid)
49
- access_token = AccessToken.get()
46
+ # 获取ticket
47
+ uri = URI.parse("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=#{access_token}")
48
+ post_data = {
49
+ 'action_name' => 'QR_LIMIT_STR_SCENE',
50
+ 'action_info' => {'scene' => {'scene_id' => sceneid}}}
51
+ http = Net::HTTP.new(uri.host, uri.port)
52
+ http.use_ssl = true
53
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
54
+ request = Net::HTTP::Post.new("/cgi-bin/qrcode/create?access_token=#{access_token}")
55
+ request.add_field('Content-Type', 'application/json')
56
+ request.body = post_data.to_json
57
+ response = http.request(request)
58
+ content = JSON.parse(response.body)
59
+ ticket = content['ticket']
50
60
 
51
- # 获取ticket
52
- uri = URI.parse("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=#{access_token}")
53
- post_data = {
54
- 'action_name' => 'QR_LIMIT_STR_SCENE',
55
- 'action_info' => {'scene' => {'scene_id' => sceneid}}}
56
- http = Net::HTTP.new(uri.host, uri.port)
57
- http.use_ssl = true
58
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
59
- request = Net::HTTP::Post.new("/cgi-bin/qrcode/create?access_token=#{access_token}")
60
- request.add_field('Content-Type', 'application/json')
61
- request.body = post_data.to_json
62
- response = http.request(request)
63
- content = JSON.parse(response.body)
64
- ticket = content['ticket']
61
+ # 通过ticket换取二维码
62
+ "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=#{ticket}"
63
+ end
65
64
 
66
- # 通过ticket换取二维码
67
- url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' + ticket
68
- url
65
+ ###
66
+ # 保存带参数二维码到指定位置
67
+ # @param <string> path -- 例如: "#{Rails.root}/public/qrcode"
68
+ # @param <string> filename -- 文件名,可选参数,默认不填写则使用时间戳+随机数的方式命名
69
+ #
70
+ # @return <string> path -- 二维码的保存路径
71
+ def save_qrcode(path, *filename)
72
+ # 判断是否需要新建文件
73
+ unless File.exist?(path)
74
+ FileUtils.makedirs(path)
69
75
  end
70
76
 
71
- ###
72
- # 保存带参数二维码到指定位置
73
- # @param <string> path -- 例如: "#{Rails.root}/public/qrcode"
74
- # @param <string> filename -- 文件名,可选参数,默认不填写则使用时间戳+随机数的方式命名
75
- #
76
- # @return <string> path -- 二维码的保存路径
77
- def save_qrcode(path, *filename)
78
- # 判断是否需要新建文件
79
- unless File.exist?(path)
80
- FileUtils.makedirs(path)
81
- end
82
-
83
- if filename
84
- path = "#{path}/#{filename}"
85
- else
86
- path = "#{path}/#{Time.now.to_i.to_s}_#{rand 1000.9999}"
87
- end
88
-
89
- File.open(path, 'wb') do |f|
90
- f.write(HTTParty.get(url).body)
91
- end
77
+ if filename
78
+ path = "#{path}/#{filename}"
79
+ else
80
+ path = "#{path}/#{Time.now.to_i.to_s}_#{rand 1000.9999}"
81
+ end
92
82
 
93
- path
83
+ File.open(path, 'wb') do |f|
84
+ f.write(HTTParty.get(url).body)
94
85
  end
95
86
 
96
- ###
97
- # @param <string> longurl -- 需要被压缩的url
98
- #
99
- # @return <json> shorturl -- 返回短链接 {"errcode":0,"errmsg":"ok","short_url":"http:\/\/w.url.cn\/s\/AvCo6Ih"}
100
- # if false
101
- # @return {"errcode":40013,"errmsg":"invalid appid"}
102
- #
103
- def shorturl(longurl)
104
- access_token = AccessToken.get()
105
- uri = URI.parse("https://api.weixin.qq.com/cgi-bin/shorturl?access_token=#{access_token}")
106
- post_data = {action: "long2short", long_url: longurl}
107
- http = Net::HTTP.new(uri.host, uri.port)
108
- http.use_ssl = true
109
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
110
- request = Net::HTTP::Post.new("/cgi-bin/shorturl?access_token=#{access_token}")
111
- request.add_field('Content-Type', 'application/json')
112
- request.body = post_data.to_json
113
- response = http.request(request)
87
+ path
88
+ end
114
89
 
115
- JSON.parse(response.body)
116
- end
90
+ ###
91
+ # @param <string> longurl -- 需要被压缩的url
92
+ #
93
+ # @return <json> shorturl -- 返回短链接 {"errcode":0,"errmsg":"ok","short_url":"http:\/\/w.url.cn\/s\/AvCo6Ih"}
94
+ # if false
95
+ # @return {"errcode":40013,"errmsg":"invalid appid"}
96
+ #
97
+ def get_shorturl(longurl)
98
+ access_token = get_access_token()
99
+ uri = URI.parse("https://api.weixin.qq.com/cgi-bin/shorturl?access_token=#{access_token}")
100
+ post_data = {action: "long2short", long_url: longurl}
101
+ http = Net::HTTP.new(uri.host, uri.port)
102
+ http.use_ssl = true
103
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
104
+ request = Net::HTTP::Post.new("/cgi-bin/shorturl?access_token=#{access_token}")
105
+ request.add_field('Content-Type', 'application/json')
106
+ request.body = post_data.to_json
107
+ response = http.request(request)
108
+
109
+ JSON.parse(response.body)
117
110
  end
118
111
  end
119
112
  end
@@ -5,40 +5,37 @@
5
5
  # Wechat number: zmx119966
6
6
  ####################################################
7
7
 
8
- require "wechat_public_api/access_token"
9
- module WechatPublicApi
8
+ class WechatPublicApi
10
9
  module Aes
11
- class << self
12
-
13
- # 解密
14
- def decrypt(key, dicrypted_string)
15
- cipher = OpenSSL::Cipher::AES.new(256, :CBC)
16
- cipher.decrypt
17
- cipher.key = key
18
- cipher.iv = '0000000000000000'
19
- cipher.padding = 0
20
- cipher.update(dicrypted_string) << cipher.final
21
- end
10
+ # 解密
11
+ def decrypt(key, dicrypted_string)
12
+ cipher = OpenSSL::Cipher::AES.new(256, :CBC)
13
+ cipher.decrypt
14
+ cipher.key = key
15
+ cipher.iv = '0000000000000000'
16
+ cipher.padding = 0
17
+ cipher.update(dicrypted_string) << cipher.final
18
+ end
22
19
 
23
- # 加密
24
- def encrypt(aes_key, text, app_id)
25
- text = text.force_encoding("ASCII-8BIT")
26
- random = SecureRandom.hex(8)
27
- msg_len = [text.length].pack("N")
28
- text = "#{random}#{msg_len}#{text}#{app_id}"
29
- text = WxAuth.encode(text)
30
- text = handle_cipher(:encrypt, aes_key, text)
31
- Base64.encode64(text)
32
- end
20
+ # 加密
21
+ def encrypt(aes_key, text, app_id)
22
+ text = text.force_encoding("ASCII-8BIT")
23
+ random = SecureRandom.hex(8)
24
+ msg_len = [text.length].pack("N")
25
+ text = "#{random}#{msg_len}#{text}#{app_id}"
26
+ text = WxAuth.encode(text)
27
+ text = handle_cipher(:encrypt, aes_key, text)
28
+ Base64.encode64(text)
29
+ end
33
30
 
34
- def handle_cipher(action, aes_key, text)
35
- cipher = OpenSSL::Cipher.new('AES-256-CBC')
36
- cipher.send(action)
37
- cipher.padding = 0
38
- cipher.key = aes_key
39
- cipher.iv = aes_key[0...16]
40
- cipher.update(text) + cipher.final
41
- end
31
+ private
32
+ def handle_cipher(action, aes_key, text)
33
+ cipher = OpenSSL::Cipher.new('AES-256-CBC')
34
+ cipher.send(action)
35
+ cipher.padding = 0
36
+ cipher.key = aes_key
37
+ cipher.iv = aes_key[0...16]
38
+ cipher.update(text) + cipher.final
42
39
  end
43
40
  end
44
41
  end