wx_opendata 0.1.1

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 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