wx_opendata 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +6 -0
- data/lib/wx_opendata/service.rb +137 -0
- data/lib/wx_opendata/token.rb +59 -0
- data/lib/wx_opendata/version.rb +3 -0
- data/lib/wx_opendata.rb +14 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/wx_opendata_spec.rb +66 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1699ef3c57e9e4189e2c371b5c47905e9d331321
|
4
|
+
data.tar.gz: 42749163d3b371025c129d23fb7a93b6e787ab55
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 063d446971c3127d3ff93fff01dac39902c75700eac5d0b031a560009fc35681bff4f297d2e1c75d373906d3c85a4d11ba55c1e0d816b77e474feb2a381e3981
|
7
|
+
data.tar.gz: 402202ff4258eae20d649c66e47e779b036c79ac3c61a38fc1902cd073dd0fcfde5ef9f15b9a1d760c87a4f6e5a03375a043a01431ecbb8d19e384023bbe3214
|
data/Rakefile
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'mime/types'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module WxOpendata
|
6
|
+
BASE_URL = 'https://api.weixin.qq.com/'.freeze
|
7
|
+
class Service
|
8
|
+
attr_accessor :content_type
|
9
|
+
|
10
|
+
# 发送模板消息
|
11
|
+
def send_template_message(token, params)
|
12
|
+
raise InvalidParametersError unless params[:touser] && params[:template_id] && params[:form_id]
|
13
|
+
url = "cgi-bin/message/wxopen/template/send?access_token=#{token}"
|
14
|
+
touser = params[:touser]
|
15
|
+
template_id = params[:template_id]
|
16
|
+
form_id = params[:form_id]
|
17
|
+
page = params[:page] || 'pages/index/main'
|
18
|
+
data = params[:data] || { keyword1: { value: 'Test Message Template' } }
|
19
|
+
emphasis_keyword = params[:emphasis_keyword] || "keyword1.DATA"
|
20
|
+
p = { touser: touser, template_id: template_id, form_id: form_id, page: page, data: data, emphasis_keyword: emphasis_keyword }
|
21
|
+
jsondata = post(url, p)
|
22
|
+
begin
|
23
|
+
raise ErrCodeError, 'template_id不正确' if jsondata['errcode'] == 40037
|
24
|
+
raise ErrCodeError, 'form_id不正确,或者过期' if jsondata['errcode'] == 41028
|
25
|
+
raise ErrCodeError, 'form_id已被使用' if jsondata['errcode'] == 41029
|
26
|
+
raise ErrCodeError, 'page不正确' if jsondata['errcode'] == 41030
|
27
|
+
raise ErrCodeError, '接口调用超过限额(目前默认每个帐号日调用限额为100万)' if jsondata['errcode'] == 45009
|
28
|
+
jsondata['errcode'] == 0
|
29
|
+
rescue ErrCodeError => e
|
30
|
+
p "#{e.class}: #{e.message}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# 检查一段文本是否含有违法违规内容
|
35
|
+
def msg_sec_check(token, content)
|
36
|
+
url = "wxa/msg_sec_check?access_token=#{token}"
|
37
|
+
p = { content: content }
|
38
|
+
jsondata = post(url, p)
|
39
|
+
return true if jsondata['errcode'] == 0
|
40
|
+
return false if jsondata['errcode'] == 87014
|
41
|
+
end
|
42
|
+
|
43
|
+
# 校验一张图片是否含有违法违规内容
|
44
|
+
def img_sec_check
|
45
|
+
end
|
46
|
+
|
47
|
+
# 创建被分享动态消息的 activity_id
|
48
|
+
def create_activity_id(token)
|
49
|
+
url = "cgi-bin/message/wxopen/activityid/create?access_token=#{token}"
|
50
|
+
jsondata = get(url)
|
51
|
+
raise ServiceNotAvailableError if jsondata['errcode'] != 0
|
52
|
+
jsondata['activity_id']
|
53
|
+
end
|
54
|
+
|
55
|
+
# 获取小程序二维码,适用于需要的码数量较少的业务场景
|
56
|
+
def create_wx_aqrcode(token, params = {})
|
57
|
+
url = "cgi-bin/wxaapp/createwxaqrcode?access_token=#{token}"
|
58
|
+
path = params[:path] || 'pages/index/main'
|
59
|
+
width = params[:width] || 430
|
60
|
+
p = { path: path, width: width }
|
61
|
+
data = post(url, p)
|
62
|
+
raise InvalidCredentialError if data['errcode'] == 45029
|
63
|
+
tmpfile(data)
|
64
|
+
end
|
65
|
+
|
66
|
+
# 获取小程序码,适用于需要的码数量较少的业务场景
|
67
|
+
def get_wx_acode(token, params = {})
|
68
|
+
url = "wxa/getwxacode?access_token=#{token}"
|
69
|
+
path = params[:path] || 'pages/index/main'
|
70
|
+
width = params[:width] || 430
|
71
|
+
auto_color = params[:auto_color] || false
|
72
|
+
line_color = params[:line_color] || {"r": 0,"g": 0,"b": 0}
|
73
|
+
is_hyaline = params[:is_hyaline] || true
|
74
|
+
p = { path: path, width: width, auto_color: auto_color, line_color: line_color, is_hyaline: is_hyaline }
|
75
|
+
data = post(url, p)
|
76
|
+
raise InvalidCredentialError if data['errcode'] == 45029
|
77
|
+
tmpfile(data)
|
78
|
+
end
|
79
|
+
|
80
|
+
# 获取小程序码,适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制。
|
81
|
+
def get_wx_acode_unlimit(token, params = {})
|
82
|
+
url = "wxa/getwxacodeunlimit?access_token=#{token}"
|
83
|
+
scene = params[:scene] || 'api'
|
84
|
+
page = params[:page] || 'pages/index/main'
|
85
|
+
width = params[:width] || 430
|
86
|
+
auto_color = params[:auto_color] || false
|
87
|
+
line_color = params[:line_color] || {"r": 0,"g": 0,"b": 0}
|
88
|
+
is_hyaline = params[:is_hyaline] || true
|
89
|
+
p = { scene: scene, page: page, width: width, auto_color: auto_color, line_color: line_color, is_hyaline: is_hyaline }
|
90
|
+
data = post(url, p)
|
91
|
+
raise InvalidCredentialError if data['errcode'] == 45009 || data['errcode'] == 41030
|
92
|
+
tmpfile(data)
|
93
|
+
end
|
94
|
+
|
95
|
+
# 下发小程序和公众号统一的服务消息
|
96
|
+
def send_uniform_message
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
protected
|
101
|
+
def get(url)
|
102
|
+
url = BASE_URL + url
|
103
|
+
resp = RestClient.get url
|
104
|
+
format_result(resp)
|
105
|
+
end
|
106
|
+
|
107
|
+
def post(url, params)
|
108
|
+
url = BASE_URL + url
|
109
|
+
resp = RestClient.post url, params.to_json, {accept: :json}
|
110
|
+
format_result(resp)
|
111
|
+
end
|
112
|
+
|
113
|
+
def format_result(resp)
|
114
|
+
@content_type = resp.headers[:content_type]
|
115
|
+
if resp.headers[:content_type].include? "application/json".freeze
|
116
|
+
JSON.parse resp.body
|
117
|
+
else
|
118
|
+
resp.body
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def current_req_type
|
123
|
+
@content_type
|
124
|
+
end
|
125
|
+
|
126
|
+
def tmpfile(data)
|
127
|
+
tmpname = (Time.now.to_i + rand(1000...9999)).to_s
|
128
|
+
ext = '.' + MIME::Types[current_req_type].first.extensions.first
|
129
|
+
f = Tempfile.new([tmpname, ext], Dir.tmpdir)
|
130
|
+
# f.binmode
|
131
|
+
f.write(data)
|
132
|
+
f.flush
|
133
|
+
f.path
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module WxOpendata
|
2
|
+
|
3
|
+
WX_ACCESS_TOKEN = 'https://api.weixin.qq.com/cgi-bin/token'.freeze
|
4
|
+
|
5
|
+
class Token
|
6
|
+
attr_reader :appid, :secret, :token_file, :access_token, :token_expires_in, :store_token_at
|
7
|
+
|
8
|
+
def initialize(appid, appsecret, token_file)
|
9
|
+
@appid = appid
|
10
|
+
@appsecret = appsecret
|
11
|
+
@token_file = token_file
|
12
|
+
@random_generator = Random.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def token
|
16
|
+
read_token_from_cache
|
17
|
+
refresh_token if remain_seconds < @random_generator.rand(30..3 * 60)
|
18
|
+
access_token
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def refresh_token
|
24
|
+
url = "#{WX_ACCESS_TOKEN}?grant_type=client_credential&appid=#{@appid}&secret=#{@appsecret}"
|
25
|
+
resp = RestClient.get url
|
26
|
+
store_token_to_cache(resp.body)
|
27
|
+
read_token_from_cache
|
28
|
+
end
|
29
|
+
|
30
|
+
def read_token_from_cache
|
31
|
+
token = read_token
|
32
|
+
@token_expires_in = token.fetch('expires_in').to_i
|
33
|
+
@store_token_at = token.fetch('store_token_at').to_i
|
34
|
+
@access_token = token.fetch('access_token')
|
35
|
+
rescue JSON::ParserError, Errno::ENOENT, KeyError, TypeError => e
|
36
|
+
refresh_token
|
37
|
+
end
|
38
|
+
|
39
|
+
def store_token_to_cache(token)
|
40
|
+
token_hash = JSON.parse token
|
41
|
+
raise InvalidCredentialError unless token_hash['access_token']
|
42
|
+
token_hash['store_token_at'.freeze] = Time.now.to_i
|
43
|
+
write_token(token_hash.to_json)
|
44
|
+
end
|
45
|
+
|
46
|
+
def write_token(token)
|
47
|
+
File.write(token_file, token)
|
48
|
+
end
|
49
|
+
|
50
|
+
def read_token
|
51
|
+
JSON.parse File.read(token_file)
|
52
|
+
end
|
53
|
+
|
54
|
+
def remain_seconds
|
55
|
+
token_expires_in - (Time.now.to_i - store_token_at.to_i)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
data/lib/wx_opendata.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "wx_opendata/version"
|
2
|
+
require 'wx_opendata/service'
|
3
|
+
require 'wx_opendata/token'
|
4
|
+
|
5
|
+
module WxOpendata
|
6
|
+
class AccessTokenExpiredError < StandardError; end
|
7
|
+
class InvalidCredentialError < StandardError; end
|
8
|
+
class ServiceNotAvailableError < StandardError; end
|
9
|
+
class InvalidParametersError < StandardError; end
|
10
|
+
class ErrCodeError < StandardError; end
|
11
|
+
|
12
|
+
class<< self
|
13
|
+
end
|
14
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "wx_opendata"
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
# Enable flags like --only-failures and --next-failure
|
6
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
7
|
+
|
8
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
9
|
+
config.disable_monkey_patching!
|
10
|
+
|
11
|
+
config.expect_with :rspec do |c|
|
12
|
+
c.syntax = :expect
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
appid = ''
|
3
|
+
appsecret = ''
|
4
|
+
token_file = '/tmp/weapp_access_token'
|
5
|
+
tk = WxOpendata::Token.new(appid, appsecret, token_file)
|
6
|
+
service = WxOpendata::Service.new
|
7
|
+
|
8
|
+
RSpec.describe WxOpendata do
|
9
|
+
it "1. should return corrent length access_token" do
|
10
|
+
token = tk.token
|
11
|
+
expect(token.size).to be > 120
|
12
|
+
end
|
13
|
+
|
14
|
+
it "2. should return activity id" do
|
15
|
+
token = tk.token
|
16
|
+
activity_id = service.create_activity_id(token)
|
17
|
+
expect(activity_id.size).to be > 10
|
18
|
+
end
|
19
|
+
|
20
|
+
it '3.1 should return get_wx_acode_unlimit pic path' do
|
21
|
+
token = tk.token
|
22
|
+
pic = service.get_wx_acode_unlimit(token, { width: 100, scene: 'uid=12345678' })
|
23
|
+
expect(pic).to include('/var')
|
24
|
+
end
|
25
|
+
|
26
|
+
it '3.2 should return get_wx_acode pic path' do
|
27
|
+
token = tk.token
|
28
|
+
pic = service.get_wx_acode(token)
|
29
|
+
expect(pic).to include('/var')
|
30
|
+
end
|
31
|
+
|
32
|
+
it '3.3 should return create_wx_aqrcode pic path' do
|
33
|
+
token = tk.token
|
34
|
+
pic = service.create_wx_aqrcode(token)
|
35
|
+
expect(pic).to include('/var')
|
36
|
+
end
|
37
|
+
|
38
|
+
it '4. should return ok if content is: Mot最棒' do
|
39
|
+
token = tk.token
|
40
|
+
isOk = service.msg_sec_check(token, "Mot最棒")
|
41
|
+
expect(isOk).to eq(true)
|
42
|
+
end
|
43
|
+
it '5.1 should return risky content if content is: 特3456书yuuo莞6543李zxcz蒜7782法fgnv级' do
|
44
|
+
token = tk.token
|
45
|
+
isOk = service.msg_sec_check(token, "特3456书yuuo莞6543李zxcz蒜7782法fgnv级")
|
46
|
+
expect(isOk).to eq(false)
|
47
|
+
end
|
48
|
+
|
49
|
+
it '5.2 should return risky content if content is: 完2347全dfji试3726测asad感3847知qwez到' do
|
50
|
+
token = tk.token
|
51
|
+
isOk = service.msg_sec_check(token, "完2347全dfji试3726测asad感3847知qwez到")
|
52
|
+
expect(isOk).to eq(false)
|
53
|
+
end
|
54
|
+
|
55
|
+
# it '6. send message template to user and should return ok' do
|
56
|
+
# isOk = service.send_template_message(token, {
|
57
|
+
# touser: '',
|
58
|
+
# template_id: '',
|
59
|
+
# form_id: '',
|
60
|
+
# data: {
|
61
|
+
# },
|
62
|
+
# emphasis_keyword: ''
|
63
|
+
# })
|
64
|
+
# expect(isOk).to eq(true)
|
65
|
+
# end
|
66
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wx_opendata
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mot_Wu
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-03-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.0.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.0.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: activesupport
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: bundler
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.15'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.15'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rake
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '10.0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '10.0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rspec
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '3.0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '3.0'
|
89
|
+
description: This is a gem for weapp open data API.小程序开放数据API
|
90
|
+
email:
|
91
|
+
- motevans412@gmail.com
|
92
|
+
executables: []
|
93
|
+
extensions: []
|
94
|
+
extra_rdoc_files: []
|
95
|
+
files:
|
96
|
+
- Rakefile
|
97
|
+
- lib/wx_opendata.rb
|
98
|
+
- lib/wx_opendata/service.rb
|
99
|
+
- lib/wx_opendata/token.rb
|
100
|
+
- lib/wx_opendata/version.rb
|
101
|
+
- spec/spec_helper.rb
|
102
|
+
- spec/wx_opendata_spec.rb
|
103
|
+
homepage: https://github.com/mozillo/wx_opendata
|
104
|
+
licenses:
|
105
|
+
- MIT
|
106
|
+
metadata:
|
107
|
+
allowed_push_host: https://rubygems.org
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 2.6.12
|
125
|
+
signing_key:
|
126
|
+
specification_version: 4
|
127
|
+
summary: This is a gem for weapp open data API.小程序开放数据API
|
128
|
+
test_files:
|
129
|
+
- spec/spec_helper.rb
|
130
|
+
- spec/wx_opendata_spec.rb
|