sinatra-wechat 0.0.1 → 0.0.2
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 +4 -4
- data/README.md +9 -10
- data/examples/wechat_example.rb +1 -4
- data/lib/sinatra/version.rb +1 -1
- data/lib/sinatra/wechat.rb +6 -9
- data/sinatra-wechat.gemspec +1 -1
- data/spec/spec_helper.rb +3 -3
- data/spec/wechat_spec.rb +39 -29
- metadata +1 -2
- data/.coveralls.yml +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f5f6095ebdc047a6f9b4ab8e1c18deb9eb5da15
|
4
|
+
data.tar.gz: b1404892968fb949f40caee255de6e2f6a88355a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2cc6dc338939d72ce8115828813fae4e2ccca02652eb026397b435e016fdeeb02a830717dfff0be80ef707d857f21d99bb5b1acb6f1284d8e1bff8ed353e4714
|
7
|
+
data.tar.gz: 5266b028367585f2b96f290e8cd0177ba0aa73be2b987642ae60e284a44d7fecfe3268442511d4876a659ce0cfec33c56e7ac823b5e07a9b07ded6f15dc67753
|
data/README.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# Sinatra Wechat extension
|
2
2
|
[](https://travis-ci.org/luj1985/sinatra-wechat)
|
3
|
+
[](http://badge.fury.io/rb/sinatra-wechat)
|
4
|
+
[](https://coveralls.io/r/luj1985/sinatra-wechat)
|
3
5
|
|
4
|
-
This extension is used to support [Tencent Wechat](https://mp.weixin.qq.com/) development
|
6
|
+
This extension is used to support [Tencent Wechat](https://mp.weixin.qq.com/) rapid development.
|
5
7
|
|
6
8
|
## Installation
|
7
9
|
|
@@ -9,17 +11,15 @@ This extension is used to support [Tencent Wechat](https://mp.weixin.qq.com/) de
|
|
9
11
|
|
10
12
|
# Usage
|
11
13
|
|
12
|
-
|
14
|
+
Below code implement a simple wechat robot, reply text `你好` when message sent by end user contains number `%r{\d+}`.
|
15
|
+
> use `:message_validation => false` to disable wechat message validation, otherwise need to append signature to the URL. The default value of `:message_validation` is `true`
|
13
16
|
|
14
17
|
```ruby
|
15
18
|
# app.rb
|
16
19
|
require 'sinatra'
|
17
20
|
require 'sinatra/wechat'
|
18
21
|
|
19
|
-
|
20
|
-
set :wechat_token, 'test-token'
|
21
|
-
|
22
|
-
wechat('/') {
|
22
|
+
wechat('/', :wechat_token => 'test-token', :message_validation => false) {
|
23
23
|
text(:content => %r{\d+}) {
|
24
24
|
content_type 'application/xml'
|
25
25
|
erb :hello, :locals => request[:wechat_values]
|
@@ -37,13 +37,12 @@ __END__
|
|
37
37
|
</xml>
|
38
38
|
```
|
39
39
|
|
40
|
-
start server:
|
41
|
-
```
|
40
|
+
start web server:
|
41
|
+
```shell
|
42
42
|
$ ruby app.rb
|
43
43
|
```
|
44
44
|
|
45
|
-
|
46
|
-
|
45
|
+
validate it via [cURL](http://curl.haxx.se):
|
47
46
|
```shell
|
48
47
|
$ curl -X POST --data '<xml>
|
49
48
|
<ToUserName>tousername</ToUserName>
|
data/examples/wechat_example.rb
CHANGED
@@ -2,9 +2,6 @@ require 'sinatra'
|
|
2
2
|
require 'sinatra/wechat'
|
3
3
|
require 'nokogiri'
|
4
4
|
|
5
|
-
disable :message_validation
|
6
|
-
set :wechat_token, 'test-token'
|
7
|
-
|
8
5
|
location_event_reply = proc {
|
9
6
|
content_type 'application/xml'
|
10
7
|
values = request[:wechat_values]
|
@@ -20,7 +17,7 @@ location_event_reply = proc {
|
|
20
17
|
builder.to_xml
|
21
18
|
}
|
22
19
|
|
23
|
-
wechat('/wechat') {
|
20
|
+
wechat('/wechat', :wechat_token => 'test-token', :message_validation => false) {
|
24
21
|
location {
|
25
22
|
instance_eval &location_event_reply
|
26
23
|
}
|
data/lib/sinatra/version.rb
CHANGED
data/lib/sinatra/wechat.rb
CHANGED
@@ -6,6 +6,7 @@ module Sinatra
|
|
6
6
|
module Wechat
|
7
7
|
module EndpointActions
|
8
8
|
class WechatDispatcher < ::BlankSlate
|
9
|
+
attr_reader :wechat_token, :verfiy_message
|
9
10
|
def initialize
|
10
11
|
super
|
11
12
|
@message_handlers = {}
|
@@ -34,18 +35,18 @@ module Sinatra
|
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
|
-
def wechat(endpoint = '/', &block)
|
38
|
+
def wechat(endpoint = '/', wechat_token: '', message_validation: true, &block)
|
38
39
|
dispatcher = WechatDispatcher.new
|
39
40
|
dispatcher.instance_eval &block
|
40
41
|
|
41
42
|
get endpoint do
|
42
|
-
halt 403 unless validate_messages
|
43
|
+
halt 403 unless validate_messages(wechat_token) if message_validation
|
43
44
|
content_type 'text/plain'
|
44
45
|
params[:echostr]
|
45
46
|
end
|
46
47
|
|
47
48
|
post endpoint do
|
48
|
-
halt 403 unless validate_messages
|
49
|
+
halt 403 unless validate_messages(wechat_token) if message_validation
|
49
50
|
|
50
51
|
body = request.body.read || ""
|
51
52
|
halt 501 if body.empty?
|
@@ -69,14 +70,10 @@ module Sinatra
|
|
69
70
|
|
70
71
|
def self.registered(app)
|
71
72
|
app.extend(Wechat::EndpointActions)
|
72
|
-
|
73
73
|
app.helpers do
|
74
|
-
|
75
|
-
|
76
|
-
def validate_messages
|
77
|
-
token = settings.wechat_token || ""
|
74
|
+
def validate_messages token
|
78
75
|
raw = [token, params[:timestamp], params[:nonce]].compact.sort.join
|
79
|
-
|
76
|
+
Digest::SHA1.hexdigest(raw) == params[:signature]
|
80
77
|
end
|
81
78
|
end
|
82
79
|
# expose to classic style
|
data/sinatra-wechat.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = "https://github.com/luj1985/sinatra-wechat"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
-
spec.files = `git ls-files -z`.split("\x0") - %w[.gitignore .travis.yml]
|
16
|
+
spec.files = `git ls-files -z`.split("\x0") - %w[.gitignore .travis.yml .coveralls.yml]
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
data/spec/spec_helper.rb
CHANGED
data/spec/wechat_spec.rb
CHANGED
@@ -4,13 +4,11 @@ describe Sinatra::Wechat do
|
|
4
4
|
include Rack::Test::Methods
|
5
5
|
|
6
6
|
it "GET should have message verification" do
|
7
|
-
|
8
7
|
def app
|
9
|
-
|
10
|
-
set :wechat_token, 'test-token'
|
8
|
+
instance = Sinatra.new do
|
11
9
|
register Sinatra::Wechat
|
12
10
|
end
|
13
|
-
|
11
|
+
instance.wechat(:wechat_token => 'test-token') { }
|
14
12
|
end
|
15
13
|
|
16
14
|
get '/'
|
@@ -22,19 +20,26 @@ describe Sinatra::Wechat do
|
|
22
20
|
:echostr => 'echo string'}
|
23
21
|
expect(last_response.status).to eq(200)
|
24
22
|
expect(last_response.body).to eq('echo string')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "Can disable message validation" do
|
26
|
+
def app
|
27
|
+
instance = Sinatra.new do
|
28
|
+
register Sinatra::Wechat
|
29
|
+
end
|
30
|
+
instance.wechat(:message_validation => false) { }
|
31
|
+
end
|
25
32
|
|
26
|
-
@instance.disable :message_validation
|
27
33
|
get '/'
|
28
34
|
expect(last_response.status).to eq(200)
|
29
35
|
end
|
30
36
|
|
31
37
|
it "POST should have message verification" do
|
32
38
|
def app
|
33
|
-
|
34
|
-
set :wechat_token, 'test-token'
|
39
|
+
instance = Sinatra.new do
|
35
40
|
register Sinatra::Wechat
|
36
41
|
end
|
37
|
-
|
42
|
+
instance.wechat(:wechat_token => 'test-token') {
|
38
43
|
text { 'text response' }
|
39
44
|
}
|
40
45
|
end
|
@@ -59,11 +64,10 @@ describe Sinatra::Wechat do
|
|
59
64
|
|
60
65
|
it "can switch wechat endpoint" do
|
61
66
|
def app
|
62
|
-
|
63
|
-
set :wechat_token, 'test-token'
|
67
|
+
instance = Sinatra.new do
|
64
68
|
register Sinatra::Wechat
|
65
69
|
end
|
66
|
-
|
70
|
+
instance.wechat('/wechat', :wechat_token => 'test-token') {
|
67
71
|
image { 'relocated response' }
|
68
72
|
}
|
69
73
|
end
|
@@ -90,11 +94,10 @@ describe Sinatra::Wechat do
|
|
90
94
|
|
91
95
|
it "should accept wechat message push" do
|
92
96
|
def app
|
93
|
-
|
94
|
-
set :wechat_token, 'test-token'
|
97
|
+
instance = Sinatra.new do
|
95
98
|
register Sinatra::Wechat
|
96
99
|
end
|
97
|
-
|
100
|
+
instance.wechat(:wechat_token => 'test-token') {
|
98
101
|
text(:content => %r{regex match}) { 'regex match' }
|
99
102
|
text(lambda {|values| values[:content] == 'function match'}) { 'function match' }
|
100
103
|
text { 'default match' }
|
@@ -191,11 +194,10 @@ describe Sinatra::Wechat do
|
|
191
194
|
|
192
195
|
it "should accept complex match" do
|
193
196
|
def app
|
194
|
-
|
195
|
-
set :wechat_token, 'test-token'
|
197
|
+
instance = Sinatra.new do
|
196
198
|
register Sinatra::Wechat
|
197
199
|
end
|
198
|
-
|
200
|
+
instance.wechat(:wechat_token => 'test-token') {
|
199
201
|
future(lambda {|vs| vs[:to_user_name] == 'test' }, :content => %r{future}, :create_time => '1348831860') {
|
200
202
|
'complex match'
|
201
203
|
}
|
@@ -229,12 +231,11 @@ describe Sinatra::Wechat do
|
|
229
231
|
end
|
230
232
|
|
231
233
|
it "should raise error when invalid condition set" do
|
232
|
-
|
233
|
-
set :wechat_token, 'test-token'
|
234
|
+
instance = Sinatra.new do
|
234
235
|
register Sinatra::Wechat
|
235
236
|
end
|
236
237
|
expect {
|
237
|
-
|
238
|
+
instance.wechat(:wechat_token => 'test-token') {
|
238
239
|
future('invalid condition') { 'complex match' }
|
239
240
|
}
|
240
241
|
}.to raise_exception
|
@@ -242,20 +243,22 @@ describe Sinatra::Wechat do
|
|
242
243
|
|
243
244
|
it "can have multiple endpoint" do
|
244
245
|
def app
|
245
|
-
|
246
|
-
set :wechat_token, 'test-token'
|
246
|
+
instance = Sinatra.new do
|
247
247
|
register Sinatra::Wechat
|
248
248
|
end
|
249
|
-
|
249
|
+
instance.wechat('/wechat1', :wechat_token => 'test-token') {
|
250
250
|
selector = lambda do |values|
|
251
251
|
x = values[:location_x].to_f
|
252
252
|
20 < x && x < 30
|
253
253
|
end
|
254
254
|
location(selector) { 'matched location range' }
|
255
255
|
}
|
256
|
-
|
256
|
+
instance.wechat('/wechat2', :wechat_token => 'test') {
|
257
257
|
text { 'this is another wechat endpoint' }
|
258
258
|
}
|
259
|
+
instance.wechat('/wechat3', :wechat_token => 'unknown', :message_validation => false) {
|
260
|
+
text { 'disable message validation' }
|
261
|
+
}
|
259
262
|
end
|
260
263
|
|
261
264
|
post '/wechat1?timestamp=201407191804&nonce=nonce&signature=9a91a1cea1cb60b87a9abb29dae06dce14721258', <<-EOF
|
@@ -270,13 +273,20 @@ describe Sinatra::Wechat do
|
|
270
273
|
expect(last_response.body).to eq('matched location range')
|
271
274
|
|
272
275
|
|
273
|
-
post '/wechat2?timestamp=201407191804&nonce=nonce&signature=9a91a1cea1cb60b87a9abb29dae06dce14721258',
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
276
|
+
post '/wechat2?timestamp=201407191804&nonce=nonce&signature=9a91a1cea1cb60b87a9abb29dae06dce14721258', '<xml><MsgType>text</MsgType></xml>'
|
277
|
+
expect(last_response.status).to eq(403)
|
278
|
+
|
279
|
+
|
280
|
+
post '/wechat2?timestamp=201407191804&nonce=nonce&signature=8149d14c72f418819b1eaab851aeab2c308f15cc', '<xml><MsgType>text</MsgType></xml>'
|
278
281
|
expect(last_response.status).to eq(200)
|
279
282
|
expect(last_response.body).to eq('this is another wechat endpoint')
|
280
283
|
|
284
|
+
get '/wechat3?echostr=return'
|
285
|
+
expect(last_response).to be_ok
|
286
|
+
expect(last_response.body).to eq('return')
|
287
|
+
|
288
|
+
post '/wechat3', '<xml><MsgType>text</MsgType></xml>'
|
289
|
+
expect(last_response.body).to eq('disable message validation')
|
290
|
+
|
281
291
|
end
|
282
292
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-wechat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lu, Jun
|
@@ -129,7 +129,6 @@ executables: []
|
|
129
129
|
extensions: []
|
130
130
|
extra_rdoc_files: []
|
131
131
|
files:
|
132
|
-
- ".coveralls.yml"
|
133
132
|
- Gemfile
|
134
133
|
- LICENSE
|
135
134
|
- README.md
|
data/.coveralls.yml
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
service_name: travis-ci
|