simple_wx 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +289 -6
- data/lib/simple_wx.rb +3 -1
- data/lib/simple_wx/access_token.rb +0 -9
- data/lib/simple_wx/base.rb +8 -0
- data/lib/simple_wx/media.rb +19 -0
- data/lib/simple_wx/menu.rb +1 -10
- data/lib/simple_wx/message.rb +9 -3
- data/lib/simple_wx/messages/music_message.rb +30 -0
- data/lib/simple_wx/messages/news_message.rb +34 -0
- data/lib/simple_wx/messages/video_message.rb +28 -0
- data/lib/simple_wx/messages/voice_message.rb +23 -0
- data/lib/simple_wx/o_auth.rb +5 -1
- data/lib/simple_wx/signaturer.rb +29 -5
- data/lib/simple_wx/template.rb +43 -0
- data/lib/simple_wx/user_info.rb +3 -3
- data/lib/simple_wx/version.rb +1 -1
- data/simple_wx.gemspec +4 -2
- metadata +44 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14016b04930e8e82a6567edf4e861aa1eaca0c4a
|
4
|
+
data.tar.gz: a5a501f857ad54af51b08c5702abd877ec61c86a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c75e4bd577a24851e7f3e100a482fa6eb359c3b8cf6a8e3e6c40c6ebeadabe315c494cc61ed5f30eafaa720a9365f4fb68ef9efd0d1f80e3525f5aff7cc8693
|
7
|
+
data.tar.gz: 1f02bd359dc7233884eed0b72d8b6f7deb504954fb6c1c120c7bbb9b582e5a5803844f4f0168bf68b25e0b363d20bc2385454274faedf25f7d4812d3327efd03
|
data/README.md
CHANGED
@@ -1,16 +1,48 @@
|
|
1
|
-
|
1
|
+
|
2
|
+
# SimpleWx
|
3
|
+
|
4
|
+
Ruby Api for Micro Message(WeiXin 微信)Public(公众)Platform.
|
5
|
+
|
6
|
+
[微信公众平台开发文档](http://mp.weixin.qq.com/wiki/home/index.html)
|
7
|
+
|
8
|
+
------
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
### Step 1
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem 'simple_wx'
|
2
18
|
```
|
3
|
-
WeixinSetting = YAML.load_file(File.join "#{Rails.root}", "config", "weixin.yml")[Rails.env || "development"]
|
4
19
|
|
20
|
+
### Step 2
|
21
|
+
|
22
|
+
在 `config/initailizers/` 目录下添加文件 `simple_wx.rb`:
|
23
|
+
|
24
|
+
```ruby
|
5
25
|
module SimpleWx
|
6
|
-
|
26
|
+
# 配置微信参数
|
27
|
+
# 配置日志对象
|
28
|
+
# 配置 Redis,用来存放 access_token 和 jsapi_ticket
|
29
|
+
|
30
|
+
# @@weixin_config = YAML.load_file(File.join "#{Rails.root}", "config", "weixin.yml")
|
31
|
+
@@weixin_config = { "app_id"=>"app_id",
|
32
|
+
"app_secret"=>"app_secret",
|
33
|
+
"serial_no"=>"gh_xxxxxxxx(微信号)",
|
34
|
+
"token"=>"verify_token"
|
35
|
+
}
|
7
36
|
@@logger = Rails.logger
|
8
37
|
@@redis = Redis::Objects.redis
|
9
38
|
end
|
10
39
|
```
|
11
40
|
|
12
|
-
|
13
|
-
|
41
|
+
### Optional
|
42
|
+
|
43
|
+
选择配置 `config/weixin.yml`:
|
44
|
+
|
45
|
+
```ruby
|
14
46
|
development:
|
15
47
|
app_id: app_id
|
16
48
|
app_secret: app_secret
|
@@ -19,4 +51,255 @@
|
|
19
51
|
|
20
52
|
production:
|
21
53
|
# ...
|
22
|
-
```
|
54
|
+
```
|
55
|
+
|
56
|
+
配置 helper 方法,生成 jsapi 签名参数 `application_helper.rb`:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
def weixin_jsapi_signature_params
|
60
|
+
SimpleWx::Signaturer.jsapi_signature_gen url: url
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
------
|
65
|
+
|
66
|
+
## Usage
|
67
|
+
|
68
|
+
### Signaturer
|
69
|
+
|
70
|
+
验证微信消息签名
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
signer = SimpleWx::Signaturer.new timestamp: params[:timestamp], nonce: params[:nonce]
|
74
|
+
if signer.sign params[:signature]
|
75
|
+
render text: params[:echostr]
|
76
|
+
else
|
77
|
+
# ...
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
生成 jsapi 签名参数
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
SimpleWx::Signaturer.jsapi_signature_gen url: url
|
85
|
+
```
|
86
|
+
|
87
|
+
------
|
88
|
+
|
89
|
+
### AccessToken
|
90
|
+
|
91
|
+
保存在 Redis 中,保存 30 mins
|
92
|
+
|
93
|
+
get access_token
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
SimpleWx::AccessToken.access_token
|
97
|
+
```
|
98
|
+
|
99
|
+
get 微信服务器ip
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
SimpleWx::AccessToken.server_ip
|
103
|
+
```
|
104
|
+
|
105
|
+
get jsapi_ticket
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
SimpleWx::AccessToken.jsapi_ticket
|
109
|
+
```
|
110
|
+
|
111
|
+
------
|
112
|
+
|
113
|
+
### Menu
|
114
|
+
|
115
|
+
查看、生成、删除菜单,buttons 参数为 hash,格式参照微信文档
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
SimpleWx::Menu.show
|
119
|
+
SimpleWx::Menu.create(buttons) # 返回 true/false
|
120
|
+
SimpleWx::Menu.create!(buttons) # 强制报错
|
121
|
+
SimpleWx::Menu.delete # 返回 true/false
|
122
|
+
SimpleWx::Menu.delete!
|
123
|
+
```
|
124
|
+
|
125
|
+
------
|
126
|
+
|
127
|
+
### OAuth
|
128
|
+
|
129
|
+
生成微信回调链接
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
SimpleWx::OAuth.generate_auth_link "url", "state", "snsapi_userinfo/snsapi_base"
|
133
|
+
```
|
134
|
+
|
135
|
+
获取 `OAuth` 的 `access_token` 及相关参数
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
auth = SimpleWx::OAuth.new(code: "code")
|
139
|
+
result_json = auth.get_access_token
|
140
|
+
```
|
141
|
+
|
142
|
+
`access_token` 返回的基本参数会赋值给实例属性
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
auth.access_token == result_json["access_token"]
|
146
|
+
# => true
|
147
|
+
```
|
148
|
+
|
149
|
+
检查 `access_token` 是否过期
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
auth.access_token_valid?
|
153
|
+
=> true/false
|
154
|
+
```
|
155
|
+
|
156
|
+
查看 `access_token` 过期时间
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
auth.expires_in
|
160
|
+
# => 7200
|
161
|
+
```
|
162
|
+
|
163
|
+
刷新 `access_token`
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
result_json = auth.refresh_token
|
167
|
+
auth.access_token == result_json["access_token"]
|
168
|
+
auth.access_token_valid?
|
169
|
+
# => true
|
170
|
+
```
|
171
|
+
|
172
|
+
通过 OAuth 信息获取用户信息,返回信息格式见微信文档
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
auth.get_user_info
|
176
|
+
```
|
177
|
+
|
178
|
+
------
|
179
|
+
|
180
|
+
### UserInfo
|
181
|
+
|
182
|
+
获取用户信息一般接口
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
@user_info = SimpleWx::UserInfo.new(access_token: "token", openid: "openid")
|
186
|
+
```
|
187
|
+
|
188
|
+
获取用户信息 OAuth 接口
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
o_auth = SimpleWx::OAuth.new("code")
|
192
|
+
o_auth.get_access_token
|
193
|
+
SimpleWx::UserInfo.get_auth_info(o_auth: o_auth)
|
194
|
+
```
|
195
|
+
|
196
|
+
------
|
197
|
+
|
198
|
+
### Message
|
199
|
+
|
200
|
+
通过客服接口发送
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
message_params = {openid: "to_user", content: "content"}
|
204
|
+
SimpleWx::Messages::TextMessage.send_json!(message_params)
|
205
|
+
SimpleWx::Messages::TextMessage.send_json(message_params)
|
206
|
+
```
|
207
|
+
|
208
|
+
直接返回给微信
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
message_params = {openid: "to_user", content: "content"}
|
212
|
+
render xml: SimpleWx::Messages::TextMessage.to_xml(message_params)
|
213
|
+
```
|
214
|
+
|
215
|
+
使用对象方式
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
msg = SimpleWx::Messages::TextMessage.new openid: "to_user", content: "content"
|
219
|
+
msg.send_json
|
220
|
+
msg.to_xml
|
221
|
+
```
|
222
|
+
|
223
|
+
信息对象列举:
|
224
|
+
|
225
|
+
```ruby
|
226
|
+
msg = SimpleWx::Messages::TextMessage.new openid: "to_user", content: "content"
|
227
|
+
msg = SimpleWx::Messages::ImageMessage.new openid: "to_user", media_id: "media_id"
|
228
|
+
msg = SimpleWx::Messages::VoiceMessage.new openid: "to_user", media_id: "media_id"
|
229
|
+
video = { title: 'title', media_id: 'media_id', description: 'desc' }
|
230
|
+
msg = SimpleWx::Messages::VideoMessage.new openid: "to_user", video: video
|
231
|
+
|
232
|
+
music = { title: 'title', description: 'desc', music_url: 'url', hq_music_url: 'hq_url', thumb_media_id: 'thumb_media_id' }
|
233
|
+
msg = SimpleWx::Messages::MusicMessage.new openid: "to_user", music: music
|
234
|
+
|
235
|
+
# 图文信息必须使用数组包围
|
236
|
+
articles = [{title: 'title1', description: 'desc1', url: 'url1', picurl: 'picurl1'}, {title: 'title2', ..., picurl: 'picurl2'}, ...]
|
237
|
+
msg = SimpleWx::Messages::NewsMessage.new openid: "to_user", articles: articles
|
238
|
+
```
|
239
|
+
|
240
|
+
------
|
241
|
+
|
242
|
+
### Template
|
243
|
+
|
244
|
+
改变行业id
|
245
|
+
|
246
|
+
```ruby
|
247
|
+
SimpleWx::Template.set_industry id1, id2
|
248
|
+
```
|
249
|
+
|
250
|
+
获取模板id
|
251
|
+
|
252
|
+
```ruby
|
253
|
+
SimpleWx::Template.get_template_id(template_id_short: "TM00015")
|
254
|
+
```
|
255
|
+
|
256
|
+
发送模板信息
|
257
|
+
|
258
|
+
```ruby
|
259
|
+
params = {
|
260
|
+
openid: openid,
|
261
|
+
template_id: "JrneF1SO3wo1K3qG1GL-zplmJpvxFsrIeBWPFYKIBB4",
|
262
|
+
url: open_url,
|
263
|
+
topcolor: "#FF0000",
|
264
|
+
data: {
|
265
|
+
...
|
266
|
+
}
|
267
|
+
}
|
268
|
+
SimpleWx::Template.send_json(params)
|
269
|
+
```
|
270
|
+
|
271
|
+
------
|
272
|
+
|
273
|
+
### Media
|
274
|
+
|
275
|
+
获取临时素材
|
276
|
+
|
277
|
+
```ruby
|
278
|
+
SimpleWx::Media.get_media(media_id: "media_id")
|
279
|
+
```
|
280
|
+
|
281
|
+
获取永久素材
|
282
|
+
|
283
|
+
```ruby
|
284
|
+
SimpleWx::Media.get_material(media_id: "media_id")
|
285
|
+
```
|
286
|
+
|
287
|
+
------
|
288
|
+
|
289
|
+
### Base
|
290
|
+
|
291
|
+
上面所有的方法都能使用__类方法__和__实例方法__实现。
|
292
|
+
使用实例的方式,能获得一个 error 参数,检查微信接口是否有错误码返回。
|
293
|
+
error 在每次请求微信API时都会刷新.
|
294
|
+
|
295
|
+
eg.
|
296
|
+
|
297
|
+
```ruby
|
298
|
+
at = SimpleWx::AccessToken.new
|
299
|
+
at.access_token
|
300
|
+
if at.error.present?
|
301
|
+
...
|
302
|
+
end
|
303
|
+
```
|
304
|
+
|
305
|
+
------
|
data/lib/simple_wx.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'redis'
|
3
3
|
require 'yell'
|
4
|
+
require 'nokogiri'
|
4
5
|
|
5
6
|
module SimpleWx
|
6
7
|
@@weixin_config = {}
|
@@ -26,6 +27,7 @@ require 'simple_wx/o_auth'
|
|
26
27
|
require 'simple_wx/access_token'
|
27
28
|
require 'simple_wx/menu'
|
28
29
|
require 'simple_wx/user_info'
|
30
|
+
require 'simple_wx/media'
|
29
31
|
require 'simple_wx/message'
|
30
32
|
require 'simple_wx/messages/text_message'
|
31
33
|
require 'simple_wx/messages/image_message'
|
@@ -33,4 +35,4 @@ require 'simple_wx/messages/news_message'
|
|
33
35
|
require 'simple_wx/messages/video_message'
|
34
36
|
require 'simple_wx/messages/voice_message'
|
35
37
|
require 'simple_wx/messages/music_message'
|
36
|
-
|
38
|
+
require 'simple_wx/template'
|
data/lib/simple_wx/base.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
module SimpleWx
|
2
|
+
class Media < Base
|
3
|
+
def initialize options
|
4
|
+
@access_token = options[:access_token] || AccessToken.access_token
|
5
|
+
@media_id = options[:media_id]
|
6
|
+
end
|
7
|
+
|
8
|
+
def get_media
|
9
|
+
url = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=#{@access_token}&media_id=#{@media_id}"
|
10
|
+
RestClient.get url
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_material
|
14
|
+
url = "https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=#{@access_token}"
|
15
|
+
response = RestClient.post(url, JSON.generate(media_id: @media_id))
|
16
|
+
errcode_check(JSON.parse(response))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/simple_wx/menu.rb
CHANGED
@@ -34,8 +34,7 @@ module SimpleWx
|
|
34
34
|
def show
|
35
35
|
url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=#{@access_token}"
|
36
36
|
response = RestClient.get url
|
37
|
-
|
38
|
-
@menus = response_json["menu"]
|
37
|
+
errcode_check(JSON.parse(response))
|
39
38
|
end
|
40
39
|
|
41
40
|
def create menu_hash
|
@@ -61,13 +60,5 @@ module SimpleWx
|
|
61
60
|
@raise_flag ||= true
|
62
61
|
delete
|
63
62
|
end
|
64
|
-
|
65
|
-
def self.method_missing m, *args
|
66
|
-
if instance_methods.include? m.to_sym
|
67
|
-
self.new.send(m, *args)
|
68
|
-
else
|
69
|
-
super
|
70
|
-
end
|
71
|
-
end
|
72
63
|
end
|
73
64
|
end
|
data/lib/simple_wx/message.rb
CHANGED
@@ -2,8 +2,8 @@ module SimpleWx
|
|
2
2
|
class Message < Base
|
3
3
|
attr_accessor :openid, :json, :xml
|
4
4
|
def initialize options
|
5
|
-
@openid = options
|
6
|
-
@access_token = options
|
5
|
+
@openid = options[:openid]
|
6
|
+
@access_token = options[:access_token] || AccessToken.access_token
|
7
7
|
@custom_msg_url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=#{@access_token}"
|
8
8
|
@json = {}
|
9
9
|
@xml = {}
|
@@ -50,10 +50,16 @@ module SimpleWx
|
|
50
50
|
builder.send(k) do
|
51
51
|
recursively_xml(builder, v)
|
52
52
|
end
|
53
|
+
elsif v.is_a? Array
|
54
|
+
builder.send(k) do
|
55
|
+
v.each do |item|
|
56
|
+
recursively_xml(builder, item)
|
57
|
+
end
|
58
|
+
end
|
53
59
|
else
|
54
60
|
builder.send(k, v)
|
55
61
|
end
|
56
62
|
end
|
57
63
|
end
|
58
64
|
end
|
59
|
-
end
|
65
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module SimpleWx
|
2
|
+
module Messages
|
3
|
+
class MusicMessage < Message
|
4
|
+
def initialize options
|
5
|
+
super
|
6
|
+
@music = options[:music]
|
7
|
+
end
|
8
|
+
|
9
|
+
def send_json
|
10
|
+
@json[:msgtype] = "music"
|
11
|
+
@json[:music] = @music
|
12
|
+
SimpleWx.logger.info("SimpleWxLog:#{self.class.name} -- #{@openid} -- #{json}")
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_xml
|
17
|
+
@xml["MsgType"] = "music"
|
18
|
+
@xml["Music"] = {
|
19
|
+
"Title" => @music[:title],
|
20
|
+
"Description" => @music[:description],
|
21
|
+
"MusicUrl" => @music[:music_url],
|
22
|
+
"HQMusicUrl" => @music[:hq_music_url],
|
23
|
+
"ThumbMediaId" => @music[:thumb_media_id]
|
24
|
+
}
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SimpleWx
|
2
|
+
module Messages
|
3
|
+
class NewsMessage < Message
|
4
|
+
def initialize options
|
5
|
+
super
|
6
|
+
@articles = options[:articles]
|
7
|
+
end
|
8
|
+
|
9
|
+
def send_json
|
10
|
+
@json[:msgtype] = "news"
|
11
|
+
@json[:news] = { articles: @articles }
|
12
|
+
SimpleWx.logger.info("SimpleWxLog:#{self.class.name} -- #{@openid} -- #{json}")
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_xml
|
17
|
+
@xml["MsgType"] = "news"
|
18
|
+
@xml["ArticleCount"] = @articles.size
|
19
|
+
@xml["Articles"] = @articles.map do |item|
|
20
|
+
{
|
21
|
+
"item" =>
|
22
|
+
{
|
23
|
+
"Title" => item[:title],
|
24
|
+
"Description" => item[:description],
|
25
|
+
"PicUrl" => item[:picurl],
|
26
|
+
"Url" => item[:url]
|
27
|
+
}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SimpleWx
|
2
|
+
module Messages
|
3
|
+
class VideoMessage < Message
|
4
|
+
def initialize options
|
5
|
+
super
|
6
|
+
@video = options[:video]
|
7
|
+
end
|
8
|
+
|
9
|
+
def send_json
|
10
|
+
@json[:msgtype] = "video"
|
11
|
+
@json[:video] = @video
|
12
|
+
SimpleWx.logger.info("SimpleWxLog:#{self.class.name} -- #{@openid} -- #{json}")
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_xml
|
17
|
+
@xml["MsgType"] = "video"
|
18
|
+
@xml["Video"] = {
|
19
|
+
"MediaId" => @video[:media_id],
|
20
|
+
"Title" => @video[:title],
|
21
|
+
"Description" => @video[:description],
|
22
|
+
}
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SimpleWx
|
2
|
+
module Messages
|
3
|
+
class VoiceMessage < Message
|
4
|
+
def initialize options
|
5
|
+
super
|
6
|
+
@media_id = options[:media_id]
|
7
|
+
end
|
8
|
+
|
9
|
+
def send_json
|
10
|
+
@json[:msgtype] = "voice"
|
11
|
+
@json[:voice] = { media_id: @media_id }
|
12
|
+
SimpleWx.logger.info("SimpleWxLog:#{self.class.name} -- #{@openid} -- #{json}")
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_xml
|
17
|
+
@xml["MsgType"] = "voice"
|
18
|
+
@xml["Voice"] = { "MediaId" => @media_id }
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/simple_wx/o_auth.rb
CHANGED
@@ -43,7 +43,11 @@ module SimpleWx
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def get_user_info
|
46
|
-
|
46
|
+
if @scope == "snsapi_base"
|
47
|
+
UserInfo.get_base_info(openid: @openid)
|
48
|
+
else
|
49
|
+
UserInfo.get_auth_info(o_auth: self)
|
50
|
+
end
|
47
51
|
end
|
48
52
|
|
49
53
|
def access_token_valid?
|
data/lib/simple_wx/signaturer.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'securerandom'
|
1
2
|
module SimpleWx
|
2
3
|
class Signaturer < Base
|
3
4
|
|
@@ -11,20 +12,43 @@ module SimpleWx
|
|
11
12
|
# end
|
12
13
|
|
13
14
|
def initialize options = {}
|
14
|
-
@timestamp = options
|
15
|
-
@nonce = options
|
15
|
+
@timestamp = options[:timestamp] || Time.now.to_i
|
16
|
+
@nonce = options[:nonce] || SecureRandom.urlsafe_base64
|
16
17
|
@token = SimpleWx.weixin_config["token"] #TODO 没有就raise错误,用method_missing
|
17
18
|
end
|
18
19
|
|
19
20
|
def sign signture
|
20
21
|
@sort_array = [@timestamp, @nonce, @token].sort
|
21
|
-
|
22
|
+
encrypt_str = @sort_array.join
|
23
|
+
signture == sha1_encrypt(encrypt_str)
|
24
|
+
end
|
25
|
+
|
26
|
+
def jsapi_signature_gen url
|
27
|
+
params = {
|
28
|
+
'jsapi_ticket' => AccessToken.jsapi_ticket,
|
29
|
+
'noncestr' => @nonce,
|
30
|
+
'timestamp' => @timestamp,
|
31
|
+
'url' => url.split('#', 2).first
|
32
|
+
}
|
33
|
+
params = Hash[params.sort]
|
34
|
+
encrypt_str = params.to_a.map { |a, b| "#{a}=#{b}" }.join('&')
|
35
|
+
signature = sha1_encrypt(encrypt_str)
|
36
|
+
{
|
37
|
+
'appId' => SimpleWx.weixin_config["app_id"],
|
38
|
+
'timestamp' => @timestamp,
|
39
|
+
'nonceStr' => @nonce,
|
40
|
+
'signature' => signature
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.jsapi_signature_gen options
|
45
|
+
url = options.delete(:url)
|
46
|
+
self.new(options).jsapi_signature_gen url
|
22
47
|
end
|
23
48
|
|
24
49
|
private
|
25
50
|
|
26
|
-
def sha1_encrypt
|
27
|
-
encrypt_str = @sort_array.join
|
51
|
+
def sha1_encrypt encrypt_str
|
28
52
|
Digest::SHA1.hexdigest(encrypt_str)
|
29
53
|
end
|
30
54
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module SimpleWx
|
2
|
+
class Template < Message
|
3
|
+
attr_reader :template_id
|
4
|
+
|
5
|
+
def initialize options
|
6
|
+
super
|
7
|
+
@access_token = options[:access_token] || AccessToken.access_token
|
8
|
+
@template_id_short = options[:template_id_short]
|
9
|
+
@template_id = options[:template_id]
|
10
|
+
@url = options[:url]
|
11
|
+
@topcolor = options[:topcolor]
|
12
|
+
@data = options[:data]
|
13
|
+
end
|
14
|
+
|
15
|
+
undef_method :to_xml
|
16
|
+
|
17
|
+
def get_template_id
|
18
|
+
url = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=#{@access_token}"
|
19
|
+
response = RestClient.post(url, JSON.generate({template_id_short: @template_id_short}))
|
20
|
+
response_json = errcode_check(JSON.parse(response))
|
21
|
+
@template_id = response_json["template_id"]
|
22
|
+
end
|
23
|
+
|
24
|
+
def send_json
|
25
|
+
set_json
|
26
|
+
@json["template_id"] = @template_id
|
27
|
+
@json["url"] = @url
|
28
|
+
@json["topcolor"] = @topcolor
|
29
|
+
@json["data"] = @data
|
30
|
+
url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=#{@access_token}"
|
31
|
+
response = RestClient.post(url, JSON.generate(@json))
|
32
|
+
errcode_check(JSON.parse(response))
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.set_industry id1 ,id2
|
36
|
+
url = "https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=#{@access_token}"
|
37
|
+
response = RestClient.post(url, JSON.generate({industry_id1: id1, industry_id2: id2}))
|
38
|
+
errcode_check(JSON.parse(response))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
data/lib/simple_wx/user_info.rb
CHANGED
@@ -9,12 +9,12 @@ module SimpleWx
|
|
9
9
|
# instance_of_oauth.get_access_token
|
10
10
|
# user_info_hsh = SimpleWx::UserInfo.get_auth_info(o_auth: instance_of_oauth)
|
11
11
|
#
|
12
|
-
# user_info_hsh = SimpleWx::UserInfo.
|
12
|
+
# user_info_hsh = SimpleWx::UserInfo.get_base_info(access_token: "token", openid: "openid")
|
13
13
|
#
|
14
14
|
# ---------- instance-methods -----------
|
15
15
|
#
|
16
16
|
# @user_info = SimpleWx::UserInfo.new(access_token: "token", openid: "openid")
|
17
|
-
# user_info_hsh = @user_info.
|
17
|
+
# user_info_hsh = @user_info.get_base_info
|
18
18
|
# if @user_info.error.present?
|
19
19
|
# ...
|
20
20
|
# end
|
@@ -26,7 +26,7 @@ module SimpleWx
|
|
26
26
|
@access_token = options[:access_token] || AccessToken.access_token
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
29
|
+
def get_base_info
|
30
30
|
url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=#{@access_token}&openid=#{@openid}&lang=zh_CN"
|
31
31
|
response = RestClient.get url
|
32
32
|
errcode_check(JSON.parse(response))
|
data/lib/simple_wx/version.rb
CHANGED
data/simple_wx.gemspec
CHANGED
@@ -17,8 +17,10 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_dependency '
|
21
|
-
spec.add_dependency '
|
20
|
+
spec.add_dependency 'rest-client', '>= 1.6.1'
|
21
|
+
spec.add_dependency 'redis', '>= 2.0.0'
|
22
|
+
spec.add_dependency 'yell', '>= 1.2.0'
|
23
|
+
spec.add_dependency 'nokogiri', '>= 1.4.4'
|
22
24
|
|
23
25
|
spec.add_development_dependency "bundler", "~> 1.6"
|
24
26
|
|
metadata
CHANGED
@@ -1,43 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_wx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott1743
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rest-client
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.6.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.6.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: redis
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 2.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 2.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: yell
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.2.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.2.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.4.4
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.4.4
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: bundler
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -65,12 +93,18 @@ files:
|
|
65
93
|
- lib/simple_wx.rb
|
66
94
|
- lib/simple_wx/access_token.rb
|
67
95
|
- lib/simple_wx/base.rb
|
96
|
+
- lib/simple_wx/media.rb
|
68
97
|
- lib/simple_wx/menu.rb
|
69
98
|
- lib/simple_wx/message.rb
|
70
99
|
- lib/simple_wx/messages/image_message.rb
|
100
|
+
- lib/simple_wx/messages/music_message.rb
|
101
|
+
- lib/simple_wx/messages/news_message.rb
|
71
102
|
- lib/simple_wx/messages/text_message.rb
|
103
|
+
- lib/simple_wx/messages/video_message.rb
|
104
|
+
- lib/simple_wx/messages/voice_message.rb
|
72
105
|
- lib/simple_wx/o_auth.rb
|
73
106
|
- lib/simple_wx/signaturer.rb
|
107
|
+
- lib/simple_wx/template.rb
|
74
108
|
- lib/simple_wx/user_info.rb
|
75
109
|
- lib/simple_wx/version.rb
|
76
110
|
- simple_wx.gemspec
|