weixin_authorize_905 1.6.5
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 +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/.travis.yml +11 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +72 -0
- data/Rakefile +1 -0
- data/lib/weixin_authorize.rb +97 -0
- data/lib/weixin_authorize/api.rb +3 -0
- data/lib/weixin_authorize/api/custom.rb +176 -0
- data/lib/weixin_authorize/api/data_cube.rb +8 -0
- data/lib/weixin_authorize/api/groups.rb +60 -0
- data/lib/weixin_authorize/api/mass.rb +80 -0
- data/lib/weixin_authorize/api/media.rb +149 -0
- data/lib/weixin_authorize/api/menu.rb +36 -0
- data/lib/weixin_authorize/api/oauth.rb +50 -0
- data/lib/weixin_authorize/api/qrcode.rb +62 -0
- data/lib/weixin_authorize/api/template.rb +34 -0
- data/lib/weixin_authorize/api/user.rb +69 -0
- data/lib/weixin_authorize/carrierwave/weixin_uploader.rb +4 -0
- data/lib/weixin_authorize/client.rb +95 -0
- data/lib/weixin_authorize/config.rb +35 -0
- data/lib/weixin_authorize/handler.rb +3 -0
- data/lib/weixin_authorize/handler/exceptions.rb +5 -0
- data/lib/weixin_authorize/handler/global_code.rb +127 -0
- data/lib/weixin_authorize/handler/result_handler.rb +52 -0
- data/lib/weixin_authorize/js_ticket/object_store.rb +21 -0
- data/lib/weixin_authorize/js_ticket/redis_store.rb +41 -0
- data/lib/weixin_authorize/js_ticket/store.rb +40 -0
- data/lib/weixin_authorize/token/object_store.rb +25 -0
- data/lib/weixin_authorize/token/redis_store.rb +38 -0
- data/lib/weixin_authorize/token/store.rb +72 -0
- data/lib/weixin_authorize/version.rb +3 -0
- data/spec/1_fetch_access_token_spec.rb +43 -0
- data/spec/2_fetch_jsticket_spec.rb +10 -0
- data/spec/api/custom_spec.rb +71 -0
- data/spec/api/groups_spec.rb +74 -0
- data/spec/api/mass_spec.rb +70 -0
- data/spec/api/media_spec.rb +82 -0
- data/spec/api/medias/favicon.ico +0 -0
- data/spec/api/medias/ruby-logo.jpg +0 -0
- data/spec/api/menu_spec.rb +26 -0
- data/spec/api/qrcode_spec.rb +22 -0
- data/spec/api/template_spec.rb +40 -0
- data/spec/api/user_spec.rb +26 -0
- data/spec/spec_helper.rb +130 -0
- data/weixin_authorize.gemspec +48 -0
- metadata +301 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module WeixinAuthorize
|
3
|
+
module Api
|
4
|
+
module Mass
|
5
|
+
|
6
|
+
MSG_TYPE = ["mpnews", "image", "text", "voice", "mpvideo"].freeze
|
7
|
+
|
8
|
+
# media_info= {"media_id" media_id}
|
9
|
+
# https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=ACCESS_TOKEN
|
10
|
+
def mass_with_group(group_id, media_info, msgtype="mpnews", is_to_all=false)
|
11
|
+
group_option = {filter: {group_id: group_id, is_to_all: is_to_all}}
|
12
|
+
media = generate_media(msgtype, media_info, group_option)
|
13
|
+
|
14
|
+
mass_url = "#{mass_base_url}/sendall"
|
15
|
+
http_post(mass_url, media)
|
16
|
+
end
|
17
|
+
|
18
|
+
# https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=ACCESS_TOKEN
|
19
|
+
# if mpvideo,
|
20
|
+
# media_info= {"media_id" => media_id, "title" => "title", "description" => "description"}
|
21
|
+
def mass_with_openids(openids, media_info, msgtype="mpnews")
|
22
|
+
openid_option = {touser: openids}
|
23
|
+
media = generate_media(msgtype, media_info, openid_option)
|
24
|
+
mass_url = "#{mass_base_url}/send"
|
25
|
+
http_post(mass_url, media)
|
26
|
+
end
|
27
|
+
|
28
|
+
# 请注意,只有已经发送成功的消息才能删除删除消息只是将消息的图文详情页失效,已经收到的用户,还是能在其本地看到消息卡片。
|
29
|
+
# 另外,删除群发消息只能删除图文消息和视频消息,其他类型的消息一经发送,无法删除。
|
30
|
+
def mass_delete_with_msgid(msg_id)
|
31
|
+
mass_url = "#{mass_base_url}/delete"
|
32
|
+
http_post(mass_url, {msg_id: msg_id})
|
33
|
+
end
|
34
|
+
|
35
|
+
# 预览接口【订阅号与服务号认证后均可用】
|
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
|
+
mass_url = "#{mass_base_url}/preview"
|
40
|
+
http_post(mass_url, media)
|
41
|
+
end
|
42
|
+
|
43
|
+
# 查询群发消息发送状态【订阅号与服务号认证后均可用】
|
44
|
+
def mass_get_status(msg_id)
|
45
|
+
mass_url = "#{mass_base_url}/get"
|
46
|
+
http_post(mass_url, {"msg_id" => msg_id})
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def mass_base_url
|
52
|
+
"/message/mass"
|
53
|
+
end
|
54
|
+
|
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
|
60
|
+
{
|
61
|
+
msg_type => convert_media_info(msg_type, media_info),
|
62
|
+
"msgtype" => msg_type
|
63
|
+
}.merge(option)
|
64
|
+
end
|
65
|
+
|
66
|
+
# 如果用户填写的media信息,是字符串,则转换来符合的数据结构,如果 是hash,则直接使用用户的结构。
|
67
|
+
def convert_media_info(msg_type, media_info)
|
68
|
+
if media_info.is_a?(String)
|
69
|
+
if msg_type == "text"
|
70
|
+
return {content: media_info}
|
71
|
+
else
|
72
|
+
return {media_id: media_info}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
media_info
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module WeixinAuthorize
|
4
|
+
module Api
|
5
|
+
module Media
|
6
|
+
# 上传多媒体文件
|
7
|
+
# http请求方式: POST/FORM
|
8
|
+
# http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
|
9
|
+
# 支持传路径或者文件类型
|
10
|
+
def upload_media(media, media_type)
|
11
|
+
file = process_file(media)
|
12
|
+
upload_media_url = "#{media_base_url}/upload"
|
13
|
+
http_post(upload_media_url, {media: file}, {type: media_type}, "file")
|
14
|
+
end
|
15
|
+
|
16
|
+
# 目前仅仅把下载链接返回给第三方开发者,由第三方开发者处理下载
|
17
|
+
def download_media_url(media_id)
|
18
|
+
download_media_url = WeixinAuthorize.endpoint_url("file", "#{media_base_url}/get")
|
19
|
+
params = URI.encode_www_form("access_token" => get_access_token,
|
20
|
+
"media_id" => media_id)
|
21
|
+
download_media_url += "?#{params}"
|
22
|
+
download_media_url
|
23
|
+
end
|
24
|
+
|
25
|
+
# 上传图文消息素材, 主要用于群发消息接口
|
26
|
+
# {
|
27
|
+
# "articles": [
|
28
|
+
# {
|
29
|
+
# "thumb_media_id":"mwvBelOXCFZiq2OsIU-p",
|
30
|
+
# "author":"xxx",
|
31
|
+
# "title":"Happy Day",
|
32
|
+
# "content_source_url":"www.qq.com",
|
33
|
+
# "content":"content",
|
34
|
+
# "digest":"digest"
|
35
|
+
# },
|
36
|
+
# {
|
37
|
+
# "thumb_media_id":"mwvBelOXCFZiq2OsIU-p",
|
38
|
+
# "author":"xxx",
|
39
|
+
# "title":"Happy Day",
|
40
|
+
# "content_source_url":"www.qq.com",
|
41
|
+
# "content":"content",
|
42
|
+
# "digest":"digest"
|
43
|
+
# }
|
44
|
+
# ]
|
45
|
+
# }
|
46
|
+
# Option: author, content_source_url
|
47
|
+
def upload_mass_news(news=[])
|
48
|
+
upload_news_url = "#{media_base_url}/uploadnews"
|
49
|
+
http_post(upload_news_url, {articles: news})
|
50
|
+
end
|
51
|
+
|
52
|
+
# media_id: 需通过基础支持中的上传下载多媒体文件来得到
|
53
|
+
# https://file.api.weixin.qq.com/cgi-bin/media/uploadvideo?access_token=ACCESS_TOKEN
|
54
|
+
|
55
|
+
# return:
|
56
|
+
# {
|
57
|
+
# "type":"video",
|
58
|
+
# "media_id":"IhdaAQXuvJtGzwwc0abfXnzeezfO0NgPK6AQYShD8RQYMTtfzbLdBIQkQziv2XJc",
|
59
|
+
# "created_at":1398848981
|
60
|
+
# }
|
61
|
+
def upload_mass_video(media_id, title="", desc="")
|
62
|
+
video_msg = {
|
63
|
+
"media_id" => media_id,
|
64
|
+
"title" => title,
|
65
|
+
"description" => desc
|
66
|
+
}
|
67
|
+
|
68
|
+
http_post("#{media_base_url}/uploadvideo", video_msg)
|
69
|
+
end
|
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
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def media_base_url
|
87
|
+
"/media"
|
88
|
+
end
|
89
|
+
|
90
|
+
def process_file(media)
|
91
|
+
return media if media.is_a?(File) && jpep?(media)
|
92
|
+
|
93
|
+
media_url = media
|
94
|
+
uploader = WeixinUploader.new
|
95
|
+
|
96
|
+
if http?(media_url) # remote
|
97
|
+
uploader.download!(media_url.to_s)
|
98
|
+
else # local
|
99
|
+
media_file = media.is_a?(File) ? media : File.new(media_url)
|
100
|
+
uploader.cache!(media_file)
|
101
|
+
end
|
102
|
+
file = process_media(uploader)
|
103
|
+
CarrierWave.clean_cached_files! # clear last one day cache
|
104
|
+
file
|
105
|
+
end
|
106
|
+
|
107
|
+
def process_media(uploader)
|
108
|
+
uploader = covert(uploader)
|
109
|
+
uploader.file.to_file
|
110
|
+
end
|
111
|
+
|
112
|
+
# JUST ONLY FOR JPG IMAGE
|
113
|
+
def covert(uploader)
|
114
|
+
# image process
|
115
|
+
unless (uploader.file.content_type =~ /image/).nil?
|
116
|
+
if !jpep?(uploader.file)
|
117
|
+
require "mini_magick"
|
118
|
+
# covert to jpeg
|
119
|
+
image = MiniMagick::Image.open(uploader.path)
|
120
|
+
image.format("jpg")
|
121
|
+
uploader.cache!(File.open(image.path))
|
122
|
+
image.destroy! # remove /tmp from MinMagick generate
|
123
|
+
end
|
124
|
+
end
|
125
|
+
uploader
|
126
|
+
end
|
127
|
+
|
128
|
+
def http?(uri)
|
129
|
+
return false if !uri.is_a?(String)
|
130
|
+
uri = URI.parse(uri)
|
131
|
+
uri.scheme =~ /^https?$/
|
132
|
+
end
|
133
|
+
|
134
|
+
def jpep?(file)
|
135
|
+
content_type = if file.respond_to?(:content_type)
|
136
|
+
file.content_type
|
137
|
+
else
|
138
|
+
content_type(file.path)
|
139
|
+
end
|
140
|
+
!(content_type =~ /jpeg/).nil?
|
141
|
+
end
|
142
|
+
|
143
|
+
def content_type(media_path)
|
144
|
+
MIME::Types.type_for(media_path).first.content_type
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module WeixinAuthorize
|
3
|
+
module Api
|
4
|
+
module Menu
|
5
|
+
|
6
|
+
# 自定义菜单查询接口
|
7
|
+
# https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN
|
8
|
+
def menu
|
9
|
+
get_menu_url = "#{menu_base_url}/get"
|
10
|
+
http_get(get_menu_url)
|
11
|
+
end
|
12
|
+
|
13
|
+
# 自定义菜单删除接口
|
14
|
+
# https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN
|
15
|
+
def delete_menu
|
16
|
+
delete_menu_url = "#{menu_base_url}/delete"
|
17
|
+
http_get(delete_menu_url)
|
18
|
+
end
|
19
|
+
|
20
|
+
# 自定义菜单创建接口
|
21
|
+
# https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
|
22
|
+
def create_menu(menu)
|
23
|
+
menu = JSON.load(menu) if menu.is_a?(String)
|
24
|
+
create_menu_url = "#{menu_base_url}/create"
|
25
|
+
http_post(create_menu_url, menu)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def menu_base_url
|
31
|
+
"/menu"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module WeixinAuthorize
|
3
|
+
module Api
|
4
|
+
module Oauth
|
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
|
+
|
13
|
+
# 应用授权作用域: scope
|
14
|
+
# snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),
|
15
|
+
# snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
|
16
|
+
# default is snsapi_base
|
17
|
+
# state 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值
|
18
|
+
|
19
|
+
# 如果用户点击同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=STATE
|
20
|
+
def authorize_url(redirect_uri, scope="snsapi_base", state="weixin")
|
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")
|
23
|
+
end
|
24
|
+
|
25
|
+
# 首先请注意,这里通过code换取的网页授权access_token,与基础支持中的access_token不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。
|
26
|
+
|
27
|
+
# 微信通过请求 #authorize_url 方法后,会返回一个code到redirect_uri中
|
28
|
+
def get_oauth_access_token(code)
|
29
|
+
WeixinAuthorize.http_get_without_token("/sns/oauth2/access_token?appid=#{app_id}&secret=#{app_secret}&code=#{code}&grant_type=authorization_code", {}, "api")
|
30
|
+
end
|
31
|
+
|
32
|
+
# refresh_token: 填写通过access_token获取到的refresh_token参数
|
33
|
+
def refresh_oauth2_token(refresh_token)
|
34
|
+
WeixinAuthorize.http_get_without_token("/sns/oauth2/refresh_token?appid=#{app_id}&grant_type=refresh_token&refresh_token=#{refresh_token}", {}, "api")
|
35
|
+
end
|
36
|
+
|
37
|
+
# 如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。
|
38
|
+
def get_oauth_userinfo(openid, oauth_token, lang="zh_CN")
|
39
|
+
WeixinAuthorize.http_get_without_token("/sns/userinfo?access_token=#{oauth_token}&openid=#{openid}&lang=#{lang}", {}, "api")
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def encode_url(uri)
|
45
|
+
ERB::Util.url_encode(uri)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module WeixinAuthorize
|
3
|
+
module Api
|
4
|
+
module Qrcode
|
5
|
+
# http://mp.weixin.qq.com/wiki/index.php?title=生成带参数的二维码
|
6
|
+
|
7
|
+
# 临时二维码
|
8
|
+
def create_qr_scene(scene_id, expire_seconds=1800)
|
9
|
+
qrcode_infos = {action_name: "QR_SCENE", expire_seconds: expire_seconds}
|
10
|
+
qrcode_infos.merge!(action_info(scene_id))
|
11
|
+
http_post(qrcode_base_url, qrcode_infos)
|
12
|
+
end
|
13
|
+
|
14
|
+
# 临时字符串参数二维码
|
15
|
+
def create_qr_str_scene(options, expire_seconds=1800)
|
16
|
+
scene_str = options[:scene_str]
|
17
|
+
qrcode_infos = {action_name: "QR_STR_SCENE", expire_seconds: expire_seconds}
|
18
|
+
qrcode_infos.merge!(action_info(nil, scene_str))
|
19
|
+
http_post(qrcode_base_url, qrcode_infos)
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
# 永久二维码
|
24
|
+
# options: scene_id, scene_str
|
25
|
+
def create_qr_limit_scene(options)
|
26
|
+
scene_id = options[:scene_id]
|
27
|
+
qrcode_infos = {action_name: "QR_LIMIT_SCENE"}
|
28
|
+
qrcode_infos.merge!(action_info(scene_id))
|
29
|
+
http_post(qrcode_base_url, qrcode_infos)
|
30
|
+
end
|
31
|
+
|
32
|
+
# 为永久的字符串参数值
|
33
|
+
# options: scene_str
|
34
|
+
def create_qr_limit_str_scene(options)
|
35
|
+
scene_str = options[:scene_str]
|
36
|
+
qrcode_infos = {action_name: "QR_LIMIT_STR_SCENE"}
|
37
|
+
qrcode_infos.merge!(action_info(nil, scene_str))
|
38
|
+
http_post(qrcode_base_url, qrcode_infos)
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# 通过ticket换取二维码, 直接访问即可显示!
|
43
|
+
def qr_code_url(ticket)
|
44
|
+
WeixinAuthorize.mp_endpoint("/showqrcode?ticket=#{ticket}")
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def qrcode_base_url
|
50
|
+
"/qrcode/create"
|
51
|
+
end
|
52
|
+
|
53
|
+
def action_info(scene_id, scene_str=nil)
|
54
|
+
scene_info = {}
|
55
|
+
scene_info[:scene_id] = scene_id if !scene_id.nil?
|
56
|
+
scene_info[:scene_str] = scene_str if !scene_str.nil?
|
57
|
+
{action_info: {scene: scene_info}}
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module WeixinAuthorize
|
3
|
+
module Api
|
4
|
+
module Template
|
5
|
+
|
6
|
+
# 设置所属行业
|
7
|
+
# 需要选择公众账号服务所处的2个行业,每月可更改1次所选行业;
|
8
|
+
# 初始化行业时,传入两个,每月更改时,传入一个即可。
|
9
|
+
def set_template_industry(industry_id1, industry_id2="")
|
10
|
+
industries = {industry_id1: industry_id1}
|
11
|
+
if industry_id2 != ""
|
12
|
+
industries.merge!({industry_id2: industry_id2})
|
13
|
+
end
|
14
|
+
http_post("/template/api_set_industry", industries)
|
15
|
+
end
|
16
|
+
|
17
|
+
# 获得模板ID
|
18
|
+
# code: 模板库中模板的编号,有“TM**”和“OPENTMTM**”等形式
|
19
|
+
def add_template(code)
|
20
|
+
http_post("/template/api_add_template", template_id_short: code)
|
21
|
+
end
|
22
|
+
|
23
|
+
# 发送模板消息
|
24
|
+
def send_template_msg(touser, template_id, url, topcolor, data)
|
25
|
+
msg = {
|
26
|
+
touser: touser, template_id: template_id,
|
27
|
+
url: url, topcolor: topcolor, data: data
|
28
|
+
}
|
29
|
+
http_post("/message/template/send", msg)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module WeixinAuthorize
|
3
|
+
module Api
|
4
|
+
module User
|
5
|
+
|
6
|
+
# 获取用户基本信息
|
7
|
+
# https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
|
8
|
+
# lang: zh_CN, zh_TW, en
|
9
|
+
def user(openid, lang="zh_CN")
|
10
|
+
user_info_url = "#{user_base_url}/info"
|
11
|
+
http_get(user_info_url, {openid: openid, lang: lang})
|
12
|
+
end
|
13
|
+
|
14
|
+
# 批量获取用户基本信息
|
15
|
+
# https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN
|
16
|
+
# POST数据格式:JSON
|
17
|
+
# POST数据例子:
|
18
|
+
# {
|
19
|
+
# "user_list": [
|
20
|
+
# {
|
21
|
+
# "openid": "otvxTs4dckWG7imySrJd6jSi0CWE",
|
22
|
+
# "lang": "zh-CN"
|
23
|
+
# },
|
24
|
+
# {
|
25
|
+
# "openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg",
|
26
|
+
# "lang": "zh-CN"
|
27
|
+
# }
|
28
|
+
# ]
|
29
|
+
# }
|
30
|
+
def users(user_list)
|
31
|
+
user_info_batchget_url = "#{user_base_url}/info/batchget"
|
32
|
+
post_body = user_list
|
33
|
+
http_post(user_info_batchget_url, post_body)
|
34
|
+
end
|
35
|
+
|
36
|
+
# 获取关注者列表
|
37
|
+
# https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
|
38
|
+
def followers(next_openid="")
|
39
|
+
followers_url = "#{user_base_url}/get"
|
40
|
+
http_get(followers_url, {next_openid: next_openid})
|
41
|
+
end
|
42
|
+
|
43
|
+
# 设置备注名
|
44
|
+
# http请求方式: POST(请使用https协议)
|
45
|
+
# https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token=ACCESS_TOKEN
|
46
|
+
# POST数据格式:JSON
|
47
|
+
# POST数据例子:
|
48
|
+
# {
|
49
|
+
# "openid":"oDF3iY9ffA-hqb2vVvbr7qxf6A0Q",
|
50
|
+
# "remark":"pangzi"
|
51
|
+
# }
|
52
|
+
def update_remark(openid, remark)
|
53
|
+
update_url = "/user/info/updateremark"
|
54
|
+
post_body = {
|
55
|
+
openid: openid,
|
56
|
+
remark: remark
|
57
|
+
}
|
58
|
+
http_post(update_url, post_body)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def user_base_url
|
64
|
+
"/user"
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|