weixin_authorize 1.6.3 → 1.6.4
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/.gitignore +1 -0
- data/.travis.yml +1 -1
- data/Gemfile +0 -12
- data/README.md +8 -3
- data/lib/weixin_authorize.rb +22 -10
- data/lib/weixin_authorize/api/custom.rb +37 -0
- data/lib/weixin_authorize/api/groups.rb +11 -0
- data/lib/weixin_authorize/api/mass.rb +18 -16
- data/lib/weixin_authorize/api/media.rb +13 -0
- data/lib/weixin_authorize/api/oauth.rb +15 -3
- data/lib/weixin_authorize/api/user.rb +2 -2
- data/lib/weixin_authorize/client.rb +20 -11
- data/lib/weixin_authorize/handler/exceptions.rb +2 -4
- data/lib/weixin_authorize/handler/global_code.rb +39 -1
- data/lib/weixin_authorize/token/redis_store.rb +5 -2
- data/lib/weixin_authorize/version.rb +1 -1
- data/spec/api/custom_spec.rb +12 -3
- data/spec/api/groups_spec.rb +25 -5
- data/spec/api/media_spec.rb +13 -1
- data/spec/spec_helper.rb +8 -9
- data/weixin_authorize.gemspec +15 -1
- metadata +101 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c62ee0327cea856b56ef05e830a8f86ccf630b7
|
4
|
+
data.tar.gz: fbca80ea0873544e0ec14da9dec434546658cef1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3383868121cf735194d4b19df846f8f421329ddcd9f52ec079c888a1e7e38486e94a60055910f24a6548183ed07b4b0533beb21317a6c95c6e997581a6738d05
|
7
|
+
data.tar.gz: 6efe789d011da30d79986fd8110f93735265ae7897c6a585749e6212f1d29fd2b6026c812a404e3637634641dd0404f8de71ff0be831b94cbf120bbacff20052
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,17 +1,5 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
group :test, :development do
|
4
|
-
gem "rspec"
|
5
|
-
gem 'redis-namespace'
|
6
|
-
gem 'simplecov', '~> 0.7.1', :require => false
|
7
|
-
gem "codeclimate-test-reporter", require: nil
|
8
|
-
gem 'coveralls', require: false
|
9
|
-
# For debugger
|
10
|
-
gem "pry-rails"
|
11
|
-
|
12
|
-
gem "pry-byebug"
|
13
|
-
end
|
14
|
-
|
15
3
|
# Specify your gem's dependencies in weixin_authorize.gemspec
|
16
4
|
gemspec
|
17
5
|
|
data/README.md
CHANGED
@@ -13,6 +13,10 @@ Support using [Redis](http://redis.io) to store `access_token`
|
|
13
13
|
|
14
14
|
[JS SDK](https://github.com/lanrion/weixin_authorize/wiki/js-sdk)
|
15
15
|
|
16
|
+
## 支持自助实现API
|
17
|
+
|
18
|
+
详情见:https://github.com/lanrion/weixin_authorize/wiki/diy-your-api
|
19
|
+
|
16
20
|
## 已经完成API
|
17
21
|
|
18
22
|
* 客服消息
|
@@ -25,8 +29,9 @@ Support using [Redis](http://redis.io) to store `access_token`
|
|
25
29
|
* 群发消息
|
26
30
|
* 多媒体管理
|
27
31
|
* JS SDK(ticket支持缓存)
|
32
|
+
* 更多请查看测试例子
|
28
33
|
|
29
|
-
## V2.0开发中:
|
34
|
+
## V2.0开发中:
|
30
35
|
https://github.com/lanrion/weixin_authorize/milestones/v2.0-dev
|
31
36
|
|
32
37
|
1. 重构API实现,调用方式
|
@@ -42,7 +47,7 @@ Go to https://github.com/lanrion/weixin_authorize/issues/2, apply a weixin sandb
|
|
42
47
|
|
43
48
|
https://github.com/lanrion/weixin_authorize/blob/master/spec/spec_helper.rb
|
44
49
|
|
45
|
-
change your infos:
|
50
|
+
change your infos:
|
46
51
|
|
47
52
|
```ruby
|
48
53
|
ENV["APPID"]="wxe371e0960de5426a"
|
@@ -64,4 +69,4 @@ then run `rspec .`
|
|
64
69
|
|
65
70
|
如果你觉得我的gem对你有帮助,欢迎打赏支持,:smile:
|
66
71
|
|
67
|
-

|
data/lib/weixin_authorize.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
require "rest-client"
|
2
2
|
require "carrierwave"
|
3
|
-
|
3
|
+
if defined? Yajl
|
4
|
+
require 'yajl/json_gem'
|
5
|
+
else
|
6
|
+
require "json"
|
7
|
+
end
|
8
|
+
require "erb"
|
4
9
|
|
5
10
|
require "weixin_authorize/carrierwave/weixin_uploader"
|
6
11
|
require "weixin_authorize/config"
|
@@ -23,21 +28,26 @@ module WeixinAuthorize
|
|
23
28
|
autoload(:RedisStore, "weixin_authorize/js_ticket/redis_store")
|
24
29
|
end
|
25
30
|
|
26
|
-
OK_MSG = "ok"
|
27
|
-
OK_CODE = 0
|
28
|
-
GRANT_TYPE = "client_credential"
|
31
|
+
OK_MSG = "ok".freeze
|
32
|
+
OK_CODE = 0.freeze
|
33
|
+
GRANT_TYPE = "client_credential".freeze
|
34
|
+
# 用于标记endpoint可以直接使用url作为完整请求API
|
35
|
+
CUSTOM_ENDPOINT = "custom_endpoint".freeze
|
29
36
|
|
30
37
|
class << self
|
31
38
|
|
32
|
-
def http_get_without_token(url,
|
39
|
+
def http_get_without_token(url, url_params={}, endpoint="plain")
|
33
40
|
get_api_url = endpoint_url(endpoint, url)
|
34
|
-
load_json(resource(get_api_url).get(params:
|
41
|
+
load_json(resource(get_api_url).get(params: url_params))
|
35
42
|
end
|
36
43
|
|
37
|
-
def http_post_without_token(url,
|
44
|
+
def http_post_without_token(url, post_body={}, url_params={}, endpoint="plain")
|
38
45
|
post_api_url = endpoint_url(endpoint, url)
|
39
|
-
|
40
|
-
|
46
|
+
# to json if invoke "plain"
|
47
|
+
if endpoint == "plain" || endpoint == CUSTOM_ENDPOINT
|
48
|
+
post_body = JSON.dump(post_body)
|
49
|
+
end
|
50
|
+
load_json(resource(post_api_url).post(post_body, params: url_params))
|
41
51
|
end
|
42
52
|
|
43
53
|
def resource(url)
|
@@ -46,13 +56,15 @@ module WeixinAuthorize
|
|
46
56
|
|
47
57
|
# return hash
|
48
58
|
def load_json(string)
|
49
|
-
result_hash = JSON.parse(string)
|
59
|
+
result_hash = JSON.parse(string.force_encoding("UTF-8").gsub(/[\u0011-\u001F]/, ""))
|
50
60
|
code = result_hash.delete("errcode")
|
51
61
|
en_msg = result_hash.delete("errmsg")
|
52
62
|
ResultHandler.new(code, en_msg, result_hash)
|
53
63
|
end
|
54
64
|
|
55
65
|
def endpoint_url(endpoint, url)
|
66
|
+
# 此处为了应对第三方开发者如果自助对接接口时,URL不规范的情况下,可以直接使用URL当为endpoint
|
67
|
+
return url if endpoint == CUSTOM_ENDPOINT
|
56
68
|
send("#{endpoint}_endpoint") + url
|
57
69
|
end
|
58
70
|
|
@@ -3,6 +3,8 @@ module WeixinAuthorize
|
|
3
3
|
module Api
|
4
4
|
module Custom
|
5
5
|
|
6
|
+
CUSTOM_SERVICE = "https://api.weixin.qq.com/customservice".freeze
|
7
|
+
|
6
8
|
# 发送文本消息
|
7
9
|
# {
|
8
10
|
# "touser":"OPENID",
|
@@ -108,6 +110,41 @@ module WeixinAuthorize
|
|
108
110
|
http_post(custom_base_url, message)
|
109
111
|
end
|
110
112
|
|
113
|
+
# 官方示例:{endtime: 1439571890, pageindex: 1, pagesize: 10, starttime: 1438707864}
|
114
|
+
# options:
|
115
|
+
# page_index: 查询第几页,从1开始
|
116
|
+
# page_size: 每页大小,每页最多拉取50条
|
117
|
+
CUSTOM_RECORD_URL = "#{CUSTOM_SERVICE}/msgrecord/getrecord".freeze
|
118
|
+
def get_custom_msg_record(start_time, end_time, options={})
|
119
|
+
start_time, end_time = start_time.to_i, end_time.to_i
|
120
|
+
page_index = options[:page_index] || 1
|
121
|
+
page_size = options[:page_size] || 50
|
122
|
+
option = {
|
123
|
+
endtime: end_time,
|
124
|
+
starttime: start_time,
|
125
|
+
pageindex: page_index,
|
126
|
+
pagesize: page_size
|
127
|
+
}
|
128
|
+
http_post(CUSTOM_RECORD_URL, option, {}, CUSTOM_ENDPOINT)
|
129
|
+
end
|
130
|
+
|
131
|
+
# 客服接口创建会话
|
132
|
+
# POST数据示例如下:
|
133
|
+
# {
|
134
|
+
# "kf_account" : "test1@test",
|
135
|
+
# "openid" : "OPENID",
|
136
|
+
# "text" : "这是一段附加信息"
|
137
|
+
# }
|
138
|
+
KF_SESSION_URL = "#{CUSTOM_SERVICE}/kfsession/create".freeze
|
139
|
+
def create_kf_session(account, open_id, text)
|
140
|
+
post_body = {
|
141
|
+
kf_account: account,
|
142
|
+
openid: open_id,
|
143
|
+
text: text
|
144
|
+
}
|
145
|
+
http_post(KF_SESSION_URL, post_body, {}, CUSTOM_ENDPOINT)
|
146
|
+
end
|
147
|
+
|
111
148
|
private
|
112
149
|
|
113
150
|
# https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN
|
@@ -38,6 +38,17 @@ module WeixinAuthorize
|
|
38
38
|
http_post(group_url, {openid: openid, to_groupid: to_groupid})
|
39
39
|
end
|
40
40
|
|
41
|
+
# 批量移动用户分组
|
42
|
+
def batch_update_group_for_openids(openids, group_id)
|
43
|
+
group_url = "#{group_base_url}/members/batchupdate"
|
44
|
+
http_post(group_url, {openid_list: openids, to_groupid: group_id})
|
45
|
+
end
|
46
|
+
|
47
|
+
def delete_group(group_id)
|
48
|
+
group_url = "#{group_base_url}/delete"
|
49
|
+
http_post(group_url, {group: {id: group_id}})
|
50
|
+
end
|
51
|
+
|
41
52
|
private
|
42
53
|
|
43
54
|
def group_base_url
|
@@ -3,12 +3,12 @@ module WeixinAuthorize
|
|
3
3
|
module Api
|
4
4
|
module Mass
|
5
5
|
|
6
|
-
MSG_TYPE = ["mpnews", "image", "text", "voice", "mpvideo"]
|
6
|
+
MSG_TYPE = ["mpnews", "image", "text", "voice", "mpvideo"].freeze
|
7
7
|
|
8
8
|
# media_info= {"media_id" media_id}
|
9
9
|
# https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=ACCESS_TOKEN
|
10
10
|
def mass_with_group(group_id, media_info, msgtype="mpnews", is_to_all=false)
|
11
|
-
group_option = {
|
11
|
+
group_option = {filter: {group_id: group_id, is_to_all: is_to_all}}
|
12
12
|
media = generate_media(msgtype, media_info, group_option)
|
13
13
|
|
14
14
|
mass_url = "#{mass_base_url}/sendall"
|
@@ -19,7 +19,7 @@ module WeixinAuthorize
|
|
19
19
|
# if mpvideo,
|
20
20
|
# media_info= {"media_id" => media_id, "title" => "title", "description" => "description"}
|
21
21
|
def mass_with_openids(openids, media_info, msgtype="mpnews")
|
22
|
-
openid_option = {
|
22
|
+
openid_option = {touser: openids}
|
23
23
|
media = generate_media(msgtype, media_info, openid_option)
|
24
24
|
mass_url = "#{mass_base_url}/send"
|
25
25
|
http_post(mass_url, media)
|
@@ -29,13 +29,13 @@ module WeixinAuthorize
|
|
29
29
|
# 另外,删除群发消息只能删除图文消息和视频消息,其他类型的消息一经发送,无法删除。
|
30
30
|
def mass_delete_with_msgid(msg_id)
|
31
31
|
mass_url = "#{mass_base_url}/delete"
|
32
|
-
http_post(mass_url, {
|
32
|
+
http_post(mass_url, {msg_id: msg_id})
|
33
33
|
end
|
34
34
|
|
35
35
|
# 预览接口【订阅号与服务号认证后均可用】
|
36
|
-
def mass_preview(openid, media_info,
|
37
|
-
openid_option = {
|
38
|
-
media = generate_media(
|
36
|
+
def mass_preview(openid, media_info, msg_type="mpnews")
|
37
|
+
openid_option = {touser: openid}
|
38
|
+
media = generate_media(msg_type, media_info, openid_option)
|
39
39
|
mass_url = "#{mass_base_url}/preview"
|
40
40
|
http_post(mass_url, media)
|
41
41
|
end
|
@@ -52,22 +52,24 @@ module WeixinAuthorize
|
|
52
52
|
"/message/mass"
|
53
53
|
end
|
54
54
|
|
55
|
-
def generate_media(
|
56
|
-
|
57
|
-
|
55
|
+
def generate_media(msg_type, media_info, option)
|
56
|
+
msg_type = msg_type.to_s
|
57
|
+
if not MSG_TYPE.include?(msg_type)
|
58
|
+
raise MediaTypeException, "#{msg_type} is a invalid msg_type"
|
59
|
+
end
|
58
60
|
{
|
59
|
-
|
60
|
-
"msgtype" =>
|
61
|
+
msg_type => convert_media_info(msg_type, media_info),
|
62
|
+
"msgtype" => msg_type
|
61
63
|
}.merge(option)
|
62
64
|
end
|
63
65
|
|
64
66
|
# 如果用户填写的media信息,是字符串,则转换来符合的数据结构,如果 是hash,则直接使用用户的结构。
|
65
|
-
def convert_media_info(
|
67
|
+
def convert_media_info(msg_type, media_info)
|
66
68
|
if media_info.is_a?(String)
|
67
|
-
if
|
68
|
-
return {
|
69
|
+
if msg_type == "text"
|
70
|
+
return {content: media_info}
|
69
71
|
else
|
70
|
-
return {
|
72
|
+
return {media_id: media_info}
|
71
73
|
end
|
72
74
|
end
|
73
75
|
media_info
|
@@ -68,6 +68,19 @@ module WeixinAuthorize
|
|
68
68
|
http_post("#{media_base_url}/uploadvideo", video_msg)
|
69
69
|
end
|
70
70
|
|
71
|
+
# 上传图文消息内的图片获取URL
|
72
|
+
# https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
|
73
|
+
#
|
74
|
+
# return:
|
75
|
+
# {
|
76
|
+
# "url": "http://mmbiz.qpic.cn/mmbiz/gLO17UPS6FS2xsypf378iaNhWacZ1G1UplZYWEYfwvuU6Ont96b1roYs CNFwaRrSaKTPCUdBK9DgEHicsKwWCBRQ/0"
|
77
|
+
# }
|
78
|
+
def upload_image(image)
|
79
|
+
file = process_file(image)
|
80
|
+
upload_image_url = "#{media_base_url}/uploadimg"
|
81
|
+
http_post(upload_image_url, {media: file}, {type: 'image'}, 'file')
|
82
|
+
end
|
83
|
+
|
71
84
|
private
|
72
85
|
|
73
86
|
def media_base_url
|
@@ -3,6 +3,13 @@ module WeixinAuthorize
|
|
3
3
|
module Api
|
4
4
|
module Oauth
|
5
5
|
|
6
|
+
# 网站应用微信登录授权URL
|
7
|
+
# 文档:http://t.cn/RyZVWEY
|
8
|
+
def qrcode_authorize_url(redirect_uri, scope="snsapi_login", state="web_wx_login")
|
9
|
+
uri = encode_url(redirect_uri)
|
10
|
+
WeixinAuthorize.open_endpoint("/connect/qrconnect?appid=#{app_id}&redirect_uri=#{uri}&response_type=code&scope=#{scope}&state=#{state}#wechat_redirect")
|
11
|
+
end
|
12
|
+
|
6
13
|
# 应用授权作用域: scope
|
7
14
|
# snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),
|
8
15
|
# snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
|
@@ -11,9 +18,8 @@ module WeixinAuthorize
|
|
11
18
|
|
12
19
|
# 如果用户点击同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=STATE
|
13
20
|
def authorize_url(redirect_uri, scope="snsapi_base", state="weixin")
|
14
|
-
|
15
|
-
|
16
|
-
WeixinAuthorize.open_endpoint("/connect/oauth2/authorize?appid=#{app_id}&redirect_uri=#{redirect_uri}&response_type=code&scope=#{scope}&state=#{state}#wechat_redirect")
|
21
|
+
uri = encode_url(redirect_uri)
|
22
|
+
WeixinAuthorize.open_endpoint("/connect/oauth2/authorize?appid=#{app_id}&redirect_uri=#{uri}&response_type=code&scope=#{scope}&state=#{state}#wechat_redirect")
|
17
23
|
end
|
18
24
|
|
19
25
|
# 首先请注意,这里通过code换取的网页授权access_token,与基础支持中的access_token不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。
|
@@ -33,6 +39,12 @@ module WeixinAuthorize
|
|
33
39
|
WeixinAuthorize.http_get_without_token("/sns/userinfo?access_token=#{oauth_token}&openid=#{openid}&lang=#{lang}", {}, "api")
|
34
40
|
end
|
35
41
|
|
42
|
+
private
|
43
|
+
|
44
|
+
def encode_url(uri)
|
45
|
+
ERB::Util.url_encode(uri)
|
46
|
+
end
|
47
|
+
|
36
48
|
end
|
37
49
|
end
|
38
50
|
end
|
@@ -29,11 +29,11 @@ module WeixinAuthorize
|
|
29
29
|
# }
|
30
30
|
def update_remark(openid, remark)
|
31
31
|
update_url = "/user/info/updateremark"
|
32
|
-
|
32
|
+
post_body = {
|
33
33
|
openid: openid,
|
34
34
|
remark: remark
|
35
35
|
}
|
36
|
-
http_post(update_url,
|
36
|
+
http_post(update_url, post_body)
|
37
37
|
end
|
38
38
|
|
39
39
|
private
|
@@ -1,9 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require "monitor"
|
2
3
|
require "redis"
|
3
4
|
require 'digest/md5'
|
4
5
|
module WeixinAuthorize
|
5
6
|
|
6
7
|
class Client
|
8
|
+
|
9
|
+
include MonitorMixin
|
10
|
+
|
7
11
|
include Api::User
|
8
12
|
include Api::Menu
|
9
13
|
include Api::Custom
|
@@ -15,24 +19,29 @@ module WeixinAuthorize
|
|
15
19
|
include Api::Template
|
16
20
|
|
17
21
|
attr_accessor :app_id, :app_secret, :expired_at # Time.now + expires_in
|
18
|
-
attr_accessor :access_token, :redis_key
|
22
|
+
attr_accessor :access_token, :redis_key, :custom_access_token
|
19
23
|
attr_accessor :jsticket, :jsticket_expired_at, :jsticket_redis_key
|
20
24
|
|
21
|
-
|
22
|
-
|
25
|
+
# options: redis_key, custom_access_token
|
26
|
+
def initialize(app_id, app_secret, options={})
|
27
|
+
@app_id = app_id
|
23
28
|
@app_secret = app_secret
|
24
29
|
@jsticket_expired_at = @expired_at = Time.now.to_i
|
25
|
-
@redis_key
|
30
|
+
@redis_key = security_redis_key(options[:redis_key] || "weixin_#{app_id}")
|
26
31
|
@jsticket_redis_key = security_redis_key("js_sdk_#{app_id}")
|
32
|
+
@custom_access_token = options[:custom_access_token]
|
33
|
+
super() # Monitor#initialize
|
27
34
|
end
|
28
35
|
|
29
36
|
# return token
|
30
37
|
def get_access_token
|
31
|
-
|
38
|
+
return custom_access_token if !custom_access_token.nil?
|
39
|
+
synchronize{ token_store.access_token }
|
32
40
|
end
|
33
41
|
|
34
42
|
# 检查appid和app_secret是否有效。
|
35
43
|
def is_valid?
|
44
|
+
return true if !custom_access_token.nil?
|
36
45
|
token_store.valid?
|
37
46
|
end
|
38
47
|
|
@@ -62,14 +71,14 @@ module WeixinAuthorize
|
|
62
71
|
end
|
63
72
|
|
64
73
|
# 暴露出:http_get,http_post两个方法,方便第三方开发者扩展未开发的微信API。
|
65
|
-
def http_get(url,
|
66
|
-
|
67
|
-
WeixinAuthorize.http_get_without_token(url,
|
74
|
+
def http_get(url, url_params={}, endpoint="plain")
|
75
|
+
url_params = url_params.merge(access_token_param)
|
76
|
+
WeixinAuthorize.http_get_without_token(url, url_params, endpoint)
|
68
77
|
end
|
69
78
|
|
70
|
-
def http_post(url,
|
71
|
-
|
72
|
-
WeixinAuthorize.http_post_without_token(url,
|
79
|
+
def http_post(url, post_body={}, url_params={}, endpoint="plain")
|
80
|
+
url_params = access_token_param.merge(url_params)
|
81
|
+
WeixinAuthorize.http_post_without_token(url, post_body, url_params, endpoint)
|
73
82
|
end
|
74
83
|
|
75
84
|
private
|
@@ -83,7 +83,45 @@ module WeixinAuthorize
|
|
83
83
|
46004 => "不存在的用户",
|
84
84
|
47001 => "解析JSON/XML内容错误",
|
85
85
|
48001 => "api功能未授权",
|
86
|
-
50001 => "用户未授权该api"
|
86
|
+
50001 => "用户未授权该api",
|
87
|
+
50002 => "用户受限,可能是违规后接口被封禁",
|
88
|
+
61451 => "参数错误(invalid parameter)",
|
89
|
+
61452 => "无效客服账号(invalid kf_account)",
|
90
|
+
61453 => "客服帐号已存在(kf_account exsited)",
|
91
|
+
61454 => "客服帐号名长度超过限制(仅允许10个英文字符,不包括@及@后的公众号的微信号)(invalid kf_acount length)",
|
92
|
+
61455 => "客服帐号名包含非法字符(仅允许英文+数字)(illegal character in kf_account)",
|
93
|
+
61456 => "客服帐号个数超过限制(10个客服账号)(kf_account count exceeded)",
|
94
|
+
61457 => "无效头像文件类型(invalid file type)",
|
95
|
+
61450 => "系统错误(system error)",
|
96
|
+
61500 => "日期格式错误",
|
97
|
+
61501 => "日期范围错误",
|
98
|
+
9001001 => "POST数据参数不合法",
|
99
|
+
9001002 => "远端服务不可用",
|
100
|
+
9001003 => "Ticket不合法",
|
101
|
+
9001004 => "获取摇周边用户信息失败",
|
102
|
+
9001005 => "获取商户信息失败",
|
103
|
+
9001006 => "获取OpenID失败",
|
104
|
+
9001007 => "上传文件缺失",
|
105
|
+
9001008 => "上传素材的文件类型不合法",
|
106
|
+
9001009 => "上传素材的文件尺寸不合法",
|
107
|
+
9001010 => "上传失败",
|
108
|
+
9001020 => "帐号不合法",
|
109
|
+
9001021 => "已有设备激活率低于50%,不能新增设备",
|
110
|
+
9001022 => "设备申请数不合法,必须为大于0的数字",
|
111
|
+
9001023 => "已存在审核中的设备ID申请",
|
112
|
+
9001024 => "一次查询设备ID数量不能超过50",
|
113
|
+
9001025 => "设备ID不合法",
|
114
|
+
9001026 => "页面ID不合法",
|
115
|
+
9001027 => "页面参数不合法",
|
116
|
+
9001028 => "一次删除页面ID数量不能超过10",
|
117
|
+
9001029 => "页面已应用在设备中,请先解除应用关系再删除",
|
118
|
+
9001030 => "一次查询页面ID数量不能超过50",
|
119
|
+
9001031 => "时间区间不合法",
|
120
|
+
9001032 => "保存设备与页面的绑定关系参数错误",
|
121
|
+
9001033 => "门店ID不合法",
|
122
|
+
9001034 => "设备备注信息过长",
|
123
|
+
9001035 => "设备申请参数不合法",
|
124
|
+
9001036 => "查询起始值begin不合法"
|
87
125
|
}unless defined?(GLOBAL_CODES)
|
88
126
|
|
89
127
|
end
|
@@ -14,8 +14,11 @@ module WeixinAuthorize
|
|
14
14
|
|
15
15
|
def refresh_token
|
16
16
|
super
|
17
|
-
weixin_redis.hmset(
|
18
|
-
|
17
|
+
weixin_redis.hmset(
|
18
|
+
client.redis_key, "access_token",
|
19
|
+
client.access_token, "expired_at",
|
20
|
+
client.expired_at
|
21
|
+
)
|
19
22
|
weixin_redis.expireat(client.redis_key, client.expired_at.to_i-10) # 提前10秒超时
|
20
23
|
end
|
21
24
|
|
data/spec/api/custom_spec.rb
CHANGED
@@ -42,17 +42,26 @@ describe WeixinAuthorize::Api::Custom do
|
|
42
42
|
|
43
43
|
it "#send_video_custom" do
|
44
44
|
pending("The test must have a media_id")
|
45
|
-
this_should_not_get_executed
|
46
45
|
end
|
47
46
|
|
48
47
|
it "#send_music_custom" do
|
49
48
|
pending("The test must have a media_id")
|
50
|
-
this_should_not_get_executed
|
51
49
|
end
|
52
50
|
|
53
51
|
it "#send_voice_custom" do
|
54
52
|
pending("The test must have a media_id")
|
55
|
-
|
53
|
+
end
|
54
|
+
|
55
|
+
it "#get_custom_msg_record" do
|
56
|
+
option = {pageindex: 1, pagesize: 10}
|
57
|
+
response = $client.get_custom_msg_record(Time.now - 10.days, Time.now, option)
|
58
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
59
|
+
expect(response.result.keys).to eq(["recordlist", "retcode"])
|
60
|
+
end
|
61
|
+
|
62
|
+
it "#create_kf_session" do
|
63
|
+
response = $client.create_kf_session("test1@test", ENV["APPID"], "test kfsession")
|
64
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
56
65
|
end
|
57
66
|
|
58
67
|
end
|
data/spec/api/groups_spec.rb
CHANGED
@@ -8,18 +8,35 @@ describe WeixinAuthorize::Api::Groups do
|
|
8
8
|
"test group_name_2"
|
9
9
|
end
|
10
10
|
|
11
|
+
let(:groups) do
|
12
|
+
$client.groups
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:last_group_id) do
|
16
|
+
groups.result["groups"][-1]["id"]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "#delete all group step by step" do
|
20
|
+
group_ids = groups.result["groups"].collect{|group|group["id"]}
|
21
|
+
group_ids.each do |group_id|
|
22
|
+
res = $client.delete_group(group_id)
|
23
|
+
if res.code.to_s != "45009"
|
24
|
+
expect(res.code).to eq(WeixinAuthorize::OK_CODE)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
11
29
|
it "create a group" do
|
12
30
|
response = $client.create_group(group_name)
|
13
31
|
if response.code == WeixinAuthorize::OK_CODE
|
14
32
|
expect(response.result["group"]["name"]).to eq(group_name)
|
15
33
|
else
|
16
34
|
expect(response.code).to eq(-1)
|
17
|
-
puts "
|
35
|
+
puts "WEIXIN says: system error"
|
18
36
|
end
|
19
37
|
end
|
20
38
|
|
21
39
|
it "get groups" do
|
22
|
-
groups = $client.groups
|
23
40
|
expect(groups.result["groups"][-1]["name"]).to eq(group_name)
|
24
41
|
end
|
25
42
|
|
@@ -32,7 +49,7 @@ describe WeixinAuthorize::Api::Groups do
|
|
32
49
|
response = $client.create_group(group_name)
|
33
50
|
if response.code != WeixinAuthorize::OK_CODE
|
34
51
|
expect(response.code).to eq(-1)
|
35
|
-
puts "
|
52
|
+
puts "WEIXIN says: system error"
|
36
53
|
else
|
37
54
|
expect(response.result["group"]["name"]).to eq(group_name)
|
38
55
|
response = $client.update_group_name(response.result["group"]["id"], group_name_2)
|
@@ -43,12 +60,15 @@ describe WeixinAuthorize::Api::Groups do
|
|
43
60
|
end
|
44
61
|
|
45
62
|
it "#update_group_for_openid" do
|
46
|
-
groups = $client.groups
|
47
|
-
last_group_id = groups.result["groups"][-1]["id"]
|
48
63
|
$client.update_group_for_openid(ENV["OPENID"], last_group_id)
|
49
64
|
group = $client.get_group_for(ENV["OPENID"])
|
50
65
|
expect(group.result["groupid"]).to eq(last_group_id)
|
51
66
|
$client.update_group_for_openid(ENV["OPENID"], 0)
|
52
67
|
end
|
53
68
|
|
69
|
+
it "#batch update group for openids" do
|
70
|
+
res = $client.batch_update_group_for_openids([ENV["OPENID"]], last_group_id)
|
71
|
+
expect(res.code).to eq(WeixinAuthorize::OK_CODE)
|
72
|
+
end
|
73
|
+
|
54
74
|
end
|
data/spec/api/media_spec.rb
CHANGED
@@ -17,13 +17,25 @@ describe WeixinAuthorize::Api::Media do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
let(:remote_png_path) do
|
20
|
-
"https://ruby-china-files.b0.upaiyun.com/
|
20
|
+
"https://ruby-china-files.b0.upaiyun.com/photo/5982eaaa64f467d9dbda03ad4f40ea27.png"
|
21
21
|
end
|
22
22
|
|
23
23
|
let(:remote_jpg_path) do
|
24
24
|
"http://g.hiphotos.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=ce55457e4334970a537e187df4a3baad/03087bf40ad162d99455ef4d13dfa9ec8b13632762d0ed14.jpg"
|
25
25
|
end
|
26
26
|
|
27
|
+
it "can upload a jpg image and get url" do
|
28
|
+
response = $client.upload_image(image_jpg_file)
|
29
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
30
|
+
expect(response.result.keys).to eq(["url"])
|
31
|
+
end
|
32
|
+
|
33
|
+
it "can upload a png image and get url" do
|
34
|
+
response = $client.upload_image(remote_png_path)
|
35
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
36
|
+
expect(response.result.keys).to eq(["url"])
|
37
|
+
end
|
38
|
+
|
27
39
|
it "can upload a jpg File image" do
|
28
40
|
response = $client.upload_media(image_jpg_file, "image")
|
29
41
|
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
data/spec/spec_helper.rb
CHANGED
@@ -15,7 +15,6 @@
|
|
15
15
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
16
16
|
require "rspec"
|
17
17
|
require "weixin_authorize"
|
18
|
-
require 'yajl/json_gem'
|
19
18
|
require "redis"
|
20
19
|
require "redis-namespace"
|
21
20
|
|
@@ -25,17 +24,17 @@ require "codeclimate-test-reporter"
|
|
25
24
|
|
26
25
|
require "pry-rails"
|
27
26
|
|
28
|
-
Coveralls.wear!
|
27
|
+
# Coveralls.wear!
|
29
28
|
|
30
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
31
|
-
|
32
|
-
|
33
|
-
]
|
29
|
+
# SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
30
|
+
# SimpleCov::Formatter::HTMLFormatter,
|
31
|
+
# Coveralls::SimpleCov::Formatter
|
32
|
+
# ]
|
34
33
|
|
35
|
-
SimpleCov.start
|
34
|
+
# SimpleCov.start
|
36
35
|
|
37
|
-
ENV['CODECLIMATE_REPO_TOKEN'] = "c91fecbbd9e414e7cc3ad7a7d99207145de0ac65a3368de09e8c19295343d399"
|
38
|
-
CodeClimate::TestReporter.start
|
36
|
+
# ENV['CODECLIMATE_REPO_TOKEN'] = "c91fecbbd9e414e7cc3ad7a7d99207145de0ac65a3368de09e8c19295343d399"
|
37
|
+
# CodeClimate::TestReporter.start
|
39
38
|
|
40
39
|
# If you want test, change your weixin test profile
|
41
40
|
ENV["APPID"]="wx986f04063d341d04"
|
data/weixin_authorize.gemspec
CHANGED
@@ -26,9 +26,23 @@ Gem::Specification.new do |spec|
|
|
26
26
|
|
27
27
|
# A streaming JSON parsing and encoding library for Ruby (C bindings to yajl)
|
28
28
|
# https://github.com/brianmario/yajl-ruby
|
29
|
-
|
29
|
+
# yajl-ruby 不支持 jruby
|
30
|
+
if RUBY_PLATFORM == 'java'
|
31
|
+
spec.add_dependency "json"
|
32
|
+
else
|
33
|
+
spec.add_dependency "yajl-ruby", ">= 1.2.0"
|
34
|
+
end
|
30
35
|
|
31
36
|
spec.add_development_dependency "bundler"
|
32
37
|
spec.add_development_dependency "rake"
|
38
|
+
spec.add_development_dependency "rspec"
|
39
|
+
spec.add_development_dependency "redis-namespace"
|
40
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
41
|
+
spec.add_development_dependency "simplecov", "~> 0.10.0"
|
42
|
+
spec.add_development_dependency 'coveralls', '~> 0.8.2'
|
43
|
+
spec.add_development_dependency 'pry-rails'
|
44
|
+
if RUBY_PLATFORM != 'java'
|
45
|
+
spec.add_development_dependency 'pry-byebug'
|
46
|
+
end
|
33
47
|
|
34
48
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: weixin_authorize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- lanrion
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -108,6 +108,104 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: redis-namespace
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: codeclimate-test-reporter
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: simplecov
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 0.10.0
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.10.0
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: coveralls
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 0.8.2
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 0.8.2
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: pry-rails
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: pry-byebug
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
111
209
|
description: weixin api authorize access_token
|
112
210
|
email:
|
113
211
|
- huaitao-deng@foxmail.com
|
@@ -201,3 +299,4 @@ test_files:
|
|
201
299
|
- spec/api/template_spec.rb
|
202
300
|
- spec/api/user_spec.rb
|
203
301
|
- spec/spec_helper.rb
|
302
|
+
has_rdoc:
|