wx_opendata 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -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
@@ -0,0 +1,3 @@
1
+ module WxOpendata
2
+ VERSION = "0.1.1"
3
+ end
@@ -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
@@ -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