wechat_public_api 0.1.1 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +45 -0
- data/README.md +165 -19
- data/lib/wechat_public_api.rb +5 -0
- data/lib/wechat_public_api/access_token.rb +8 -1
- data/lib/wechat_public_api/account.rb +119 -0
- data/lib/wechat_public_api/aes.rb +44 -0
- data/lib/wechat_public_api/kf_message.rb +5 -5
- data/lib/wechat_public_api/material.rb +53 -0
- data/lib/wechat_public_api/menu.rb +4 -4
- data/lib/wechat_public_api/templet_message.rb +1 -1
- data/lib/wechat_public_api/user.rb +46 -0
- data/lib/wechat_public_api/utils.rb +15 -0
- data/lib/wechat_public_api/version.rb +1 -1
- data/wechat_public_api-0.1.1.gem +0 -0
- data/wechat_public_api-0.1.2.gem +0 -0
- data/wechat_public_api.gemspec +2 -2
- metadata +12 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98dfee4a07d505f15fb5e2b6c8e34d9210f050ee
|
4
|
+
data.tar.gz: 9866e3df655cb9cdc1e39a7d8ed33922b012bc9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 912aa2de176603be919d491a4453561abb531b9aa937cbd77b417d7104337594a9af642a0dce0ad3711b14a1035606494a384b441c3290fb3221c97597dd6094
|
7
|
+
data.tar.gz: 7bd5188cc0c6e69832326a5428e3be01afebe1059df2f32738636b4df79880484471409020794c26c4fa8efbcd274a63df0f92097b2f1962152f24bae11d1aef
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
wechat_public_api (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
domain_name (0.5.20180417)
|
10
|
+
unf (>= 0.0.5, < 1.0.0)
|
11
|
+
http-cookie (1.0.3)
|
12
|
+
domain_name (~> 0.5)
|
13
|
+
httparty (0.16.2)
|
14
|
+
multi_xml (>= 0.5.2)
|
15
|
+
json (2.1.0)
|
16
|
+
mime-types (3.1)
|
17
|
+
mime-types-data (~> 3.2015)
|
18
|
+
mime-types-data (3.2016.0521)
|
19
|
+
multi_xml (0.6.0)
|
20
|
+
netrc (0.11.0)
|
21
|
+
rake (10.5.0)
|
22
|
+
redis (4.0.1)
|
23
|
+
rest-client (2.0.2)
|
24
|
+
http-cookie (>= 1.0.2, < 2.0)
|
25
|
+
mime-types (>= 1.16, < 4.0)
|
26
|
+
netrc (~> 0.8)
|
27
|
+
unf (0.1.4)
|
28
|
+
unf_ext
|
29
|
+
unf_ext (0.0.7.5)
|
30
|
+
|
31
|
+
PLATFORMS
|
32
|
+
ruby
|
33
|
+
|
34
|
+
DEPENDENCIES
|
35
|
+
bundler (~> 1.16)
|
36
|
+
httparty
|
37
|
+
json
|
38
|
+
rake (~> 10.0)
|
39
|
+
redis
|
40
|
+
rest-client
|
41
|
+
unf_ext (~> 0.0.7.5)
|
42
|
+
wechat_public_api!
|
43
|
+
|
44
|
+
BUNDLED WITH
|
45
|
+
1.16.1
|
data/README.md
CHANGED
@@ -1,43 +1,189 @@
|
|
1
|
-
#
|
1
|
+
# 简介
|
2
2
|
|
3
|
-
|
3
|
+
基于ruby的微信公众号开发的API,包含对微信公众号菜单栏、客服消息、模板消息、帐号管理等接口的封装。
|
4
4
|
|
5
|
-
|
5
|
+
API长期更新维护,建议使用最新版本。
|
6
6
|
|
7
|
-
##
|
7
|
+
## 安装
|
8
8
|
|
9
|
-
|
9
|
+
添加 Gemfile:
|
10
10
|
|
11
11
|
```ruby
|
12
12
|
gem 'wechat_public_api'
|
13
13
|
```
|
14
14
|
|
15
|
-
|
15
|
+
执行 bundle:
|
16
16
|
|
17
|
-
$ bundle
|
17
|
+
$ bundle install
|
18
18
|
|
19
|
-
|
19
|
+
或者直接通过 gem 安装:
|
20
20
|
|
21
21
|
$ gem install wechat_public_api
|
22
22
|
|
23
|
-
##
|
23
|
+
## 三行代码获得 access_token
|
24
24
|
|
25
|
-
|
25
|
+
```ruby
|
26
|
+
WechatPublicApi.app_id = 'appid'
|
27
|
+
WechatPublicApi.app_secret = 'secret'
|
28
|
+
access_token = WechatPublicApi::AccessToken.get() # access_token
|
29
|
+
```
|
30
|
+
## API文档
|
31
|
+
|
32
|
+
### WechatPublicApi模块配置,开启你的新项目
|
33
|
+
|
34
|
+
**参数说明**
|
35
|
+
|
36
|
+
* @param <String> app_id # 公众号后台->开发->基本配置提供的AppID
|
37
|
+
* @param <String> app_secret # 公众号后台->开发->基本配置提供的AppSecret
|
38
|
+
* @param <Boolearn> access_token_cache # 默认false,用于标识是否使用redis缓存查询到的access_token
|
39
|
+
|
40
|
+
使用`WechatPublicApi`模块封装的方法之前,需要配置 app_id、app_secret和access_token_cache(可选),具体如下:
|
26
41
|
|
27
|
-
|
42
|
+
```ruby
|
43
|
+
WechatPublicApi.app_id = 'wx440415e4c3b4b8f9'
|
44
|
+
WechatPublicApi.app_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
45
|
+
access_token = WechatPublicApi::AccessToken.get() # access_token
|
46
|
+
```
|
28
47
|
|
29
|
-
|
48
|
+
**注意:** access_token_cache是一个布尔值,用于判断是否需要缓存access_token_cache,默认可不填,即默认不缓存access_token,如需缓存,请依照下方代码设置参数:
|
30
49
|
|
31
|
-
|
50
|
+
```ruby
|
51
|
+
WechatPublicApi.access_token_cache = true
|
52
|
+
```
|
32
53
|
|
33
|
-
|
54
|
+
### API功能概览
|
55
|
+
|
56
|
+
* 菜单栏操作
|
57
|
+
* 创建菜单栏:`WechatPublicApi::Menu.create(post_data)`
|
58
|
+
* 查询菜单栏:`WechatPublicApi::Menu.query()`
|
59
|
+
* 删除菜单栏:`WechatPublicApi::Menu.delete()`
|
60
|
+
* 客服消息管理
|
61
|
+
* 发送文字消息:`WechatPublicApi::Kf.text_message(openid, content)`
|
62
|
+
* 发送图片消息:`WechatPublicApi::Kf.image_message(openid, media_id)`
|
63
|
+
* 发送图文消息:`WechatPublicApi::Kf.mpnews_message(openid, media_id)`
|
64
|
+
* 发送图文消息(点击跳转外链): `WechatPublicApi::Kf.news_message(openid, articles)`
|
65
|
+
* 发送语音消息:`WechatPublicApi::Kf.voice_message(openid, media_id)`
|
66
|
+
* 模板消息管理
|
67
|
+
* 获取模板列表:`WechatPublicApi::Tp.get_all()`
|
68
|
+
* 删除模板:`WechatPublicApi::Tp.delete(templet_id)`
|
69
|
+
* 发送普通模板消息(不跳转小程序)`WechatPublicApi::Tp.general_message(openid, templet_id, url, data)`
|
70
|
+
* 发送跳转小程序的模板消息:`WechatPublicApi::Tp.miniprogram_message(openid, templet_id, url, appid, pagepath, data)`
|
71
|
+
* 用户管理
|
72
|
+
* 获取用户基本信息: `WechatPublicApi::User.get_userinfo(openid)`
|
73
|
+
* 帐号管理
|
74
|
+
* 获取临时带参二维码: `WechatPublicApi::Account.qrscene(sceneid)`
|
75
|
+
* 获取永久带参二维码: `WechatPublicApi::Account.qrsrtscene(sceneid)`
|
76
|
+
* 保存带参二维码到本地: `WechatPublicApi::Account.save_qrcode(path, *filename)`
|
77
|
+
* 生成短链接:`WechatPublicApi::Account.shorturl(longurl)`
|
78
|
+
* 素材管理
|
79
|
+
* 获得临时图片素材的 media_id: `WechatPublicApi::Material.upload_image_media(file_path)`
|
80
|
+
* 获得永久图片素材的 media_id: `WechatPublicApi::Material.upload_image_material(file_path)`
|
81
|
+
* 消息加密解密
|
82
|
+
* 加密: `WechatPublicApi::Aes.encrypt(aes_key, text, app_id)`
|
83
|
+
* 解密: `WechatPublicApi::Aes.decrypt(key, dicrypted_string)`
|
84
|
+
|
85
|
+
### 菜单栏操作API
|
86
|
+
|
87
|
+
1. 自定义菜单查询
|
34
88
|
|
35
|
-
|
89
|
+
```ruby
|
90
|
+
# no params
|
91
|
+
# @return
|
92
|
+
# {
|
93
|
+
# "menu": {
|
94
|
+
# "button": [
|
95
|
+
# {
|
96
|
+
# "type": "view",
|
97
|
+
# "name": "",
|
98
|
+
# "url": "",
|
99
|
+
# "sub_button": []
|
100
|
+
# },
|
101
|
+
# {
|
102
|
+
# "type": "click",
|
103
|
+
# "name": "",
|
104
|
+
# "key": "menu_3",
|
105
|
+
# "sub_button": []
|
106
|
+
# }
|
107
|
+
# ]
|
108
|
+
# }
|
109
|
+
# }
|
110
|
+
#
|
111
|
+
menu_list = WechatPublicApi::Menu.query()
|
112
|
+
```
|
36
113
|
|
37
|
-
|
114
|
+
2. 自定义菜单创建
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
###
|
118
|
+
# create wechat public menu
|
119
|
+
# @param <json> post_data
|
120
|
+
#
|
121
|
+
# => post_data example
|
122
|
+
# {
|
123
|
+
# "button": [
|
124
|
+
# {
|
125
|
+
# "type": "view",
|
126
|
+
# "name": "",
|
127
|
+
# "url": "",
|
128
|
+
# "sub_button": []
|
129
|
+
# },
|
130
|
+
# {
|
131
|
+
# "type": "click",
|
132
|
+
# "name": "",
|
133
|
+
# "key": "menu_3",
|
134
|
+
# "sub_button": []
|
135
|
+
# }
|
136
|
+
# ]
|
137
|
+
# }
|
138
|
+
#
|
139
|
+
# if success
|
140
|
+
# @return <JSON> {"errcode"=>0, "errmsg"=>"ok"}
|
141
|
+
# if failed
|
142
|
+
# @return <JSON> {"errcode"=>40166, "errmsg"=>"...."}
|
143
|
+
#
|
144
|
+
status = WechatPublicApi::Menu.create(post_data)
|
145
|
+
```
|
146
|
+
|
147
|
+
3. 自定义菜单删除
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
# @return <JSON> {"errcode"=>0, "errmsg"=>"ok"}
|
151
|
+
status = WechatPublicApi::Menu.delete()
|
152
|
+
```
|
153
|
+
|
154
|
+
菜单栏操作API主要包含以上三个方法,接下来看一个完整示例:
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
# 创建菜单栏 -> 查询菜单栏列表
|
158
|
+
# 初始化配置
|
159
|
+
WechatPublicApi.app_id = 'wx440415e4c3b4b8f9'
|
160
|
+
WechatPublicApi.app_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
161
|
+
# 创建菜单栏
|
162
|
+
post_data = {
|
163
|
+
"button": [
|
164
|
+
{
|
165
|
+
"type": "view",
|
166
|
+
"name": "",
|
167
|
+
"url": "",
|
168
|
+
"sub_button": []
|
169
|
+
},
|
170
|
+
{
|
171
|
+
"type": "click",
|
172
|
+
"name": "",
|
173
|
+
"key": "menu_3",
|
174
|
+
"sub_button": []
|
175
|
+
}
|
176
|
+
]
|
177
|
+
}
|
178
|
+
status = WechatPublicApi::Menu.create(post_data)
|
179
|
+
if status.errcode.to_i == 0 && status.errmsg == 'ok'
|
180
|
+
# 返回菜单栏列表
|
181
|
+
menu_list = WechatPublicApi::Menu.query()
|
182
|
+
end
|
183
|
+
```
|
38
184
|
|
39
|
-
|
185
|
+
**注意:** 菜单栏创建和查询的方法包含了查询access_token
|
40
186
|
|
41
|
-
|
187
|
+
### 客服消息管理API
|
42
188
|
|
43
|
-
|
189
|
+
待更新... 可参考源代码,注释比较详细
|
data/lib/wechat_public_api.rb
CHANGED
@@ -3,6 +3,11 @@ require "wechat_public_api/menu"
|
|
3
3
|
require "wechat_public_api/kf_message"
|
4
4
|
require "wechat_public_api/templet_message"
|
5
5
|
require "wechat_public_api/access_token"
|
6
|
+
require "wechat_public_api/accout"
|
7
|
+
require "wechat_public_api/aes"
|
8
|
+
require "wechat_public_api/utils"
|
9
|
+
require "wechat_public_api/user"
|
10
|
+
require "wechat_public_api/material"
|
6
11
|
|
7
12
|
module WechatPublicApi
|
8
13
|
class << self
|
@@ -21,6 +21,10 @@ module WechatPublicApi
|
|
21
21
|
unless access_token_cache
|
22
22
|
response = HTTParty.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=#{appid}&secret=#{secret}").body
|
23
23
|
response_body = (JSON.parse response)
|
24
|
+
|
25
|
+
# 抛出异常
|
26
|
+
throw response_body['errmsg'] unless response_body['access_token']
|
27
|
+
|
24
28
|
return response_body['access_token']
|
25
29
|
end
|
26
30
|
|
@@ -29,7 +33,10 @@ module WechatPublicApi
|
|
29
33
|
if _cached_access_token == nil or _cached_access_token == ''
|
30
34
|
response = HTTParty.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=#{appid}&secret=#{secret}").body
|
31
35
|
response_body = (JSON.parse response)
|
32
|
-
|
36
|
+
|
37
|
+
# 抛出异常
|
38
|
+
throw response_body['errmsg'] unless response_body['access_token']
|
39
|
+
|
33
40
|
_cached_access_token = response_body['access_token']
|
34
41
|
$redis.set _cache_key, _cached_access_token, ex: 2.minutes
|
35
42
|
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
#####################################################
|
2
|
+
# 微信公众号帐号管理 (带参二维码获得)
|
3
|
+
# Created by zhangmingxin
|
4
|
+
# Date: 2018-05-18
|
5
|
+
# Wechat number: zmx119966
|
6
|
+
####################################################
|
7
|
+
|
8
|
+
require "wechat_public_api/access_token"
|
9
|
+
|
10
|
+
module WechatPublicApi
|
11
|
+
module Account
|
12
|
+
class << self
|
13
|
+
|
14
|
+
###
|
15
|
+
# 获取临时场景带惨二维码,30天有效
|
16
|
+
# @param <int> sceneid -- 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)
|
17
|
+
# @return <string> url -- 二维码网址
|
18
|
+
#
|
19
|
+
def qrscene(sceneid)
|
20
|
+
access_token = AccessToken.get()
|
21
|
+
|
22
|
+
# 获取ticket
|
23
|
+
uri = URI.parse("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=#{access_token}")
|
24
|
+
post_data = {
|
25
|
+
'expire_seconds' => 2592000,
|
26
|
+
'action_name' => 'QR_SCENE',
|
27
|
+
'action_info' => {'scene' => {'scene_id' => sceneid}}}
|
28
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
29
|
+
http.use_ssl = true
|
30
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
31
|
+
request = Net::HTTP::Post.new("/cgi-bin/qrcode/create?access_token=#{access_token}")
|
32
|
+
request.add_field('Content-Type', 'application/json')
|
33
|
+
request.body = post_data.to_json
|
34
|
+
response = http.request(request)
|
35
|
+
content = JSON.parse(response.body)
|
36
|
+
ticket = content['ticket']
|
37
|
+
|
38
|
+
# 通过ticket换取二维码
|
39
|
+
url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' + ticket
|
40
|
+
url
|
41
|
+
end
|
42
|
+
|
43
|
+
###
|
44
|
+
# 获取永久二维码
|
45
|
+
# @param <int> sceneid -- 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)
|
46
|
+
# @return <string> url -- 二维码网址
|
47
|
+
#
|
48
|
+
def qrsrtscene(sceneid)
|
49
|
+
access_token = AccessToken.get()
|
50
|
+
|
51
|
+
# 获取ticket
|
52
|
+
uri = URI.parse("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=#{access_token}")
|
53
|
+
post_data = {
|
54
|
+
'action_name' => 'QR_LIMIT_STR_SCENE',
|
55
|
+
'action_info' => {'scene' => {'scene_id' => sceneid}}}
|
56
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
57
|
+
http.use_ssl = true
|
58
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
59
|
+
request = Net::HTTP::Post.new("/cgi-bin/qrcode/create?access_token=#{access_token}")
|
60
|
+
request.add_field('Content-Type', 'application/json')
|
61
|
+
request.body = post_data.to_json
|
62
|
+
response = http.request(request)
|
63
|
+
content = JSON.parse(response.body)
|
64
|
+
ticket = content['ticket']
|
65
|
+
|
66
|
+
# 通过ticket换取二维码
|
67
|
+
url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' + ticket
|
68
|
+
url
|
69
|
+
end
|
70
|
+
|
71
|
+
###
|
72
|
+
# 保存带参数二维码到指定位置
|
73
|
+
# @param <string> path -- 例如: "#{Rails.root}/public/qrcode"
|
74
|
+
# @param <string> filename -- 文件名,可选参数,默认不填写则使用时间戳+随机数的方式命名
|
75
|
+
#
|
76
|
+
# @return <string> path -- 二维码的保存路径
|
77
|
+
def save_qrcode(path, *filename)
|
78
|
+
# 判断是否需要新建文件
|
79
|
+
unless File.exist?(path)
|
80
|
+
FileUtils.makedirs(path)
|
81
|
+
end
|
82
|
+
|
83
|
+
if filename
|
84
|
+
path = "#{path}/#{filename}"
|
85
|
+
else
|
86
|
+
path = "#{path}/#{Time.now.to_i.to_s}_#{rand 1000.9999}"
|
87
|
+
end
|
88
|
+
|
89
|
+
File.open(path, 'wb') do |f|
|
90
|
+
f.write(HTTParty.get(url).body)
|
91
|
+
end
|
92
|
+
|
93
|
+
path
|
94
|
+
end
|
95
|
+
|
96
|
+
###
|
97
|
+
# @param <string> longurl -- 需要被压缩的url
|
98
|
+
#
|
99
|
+
# @return <json> shorturl -- 返回短链接 {"errcode":0,"errmsg":"ok","short_url":"http:\/\/w.url.cn\/s\/AvCo6Ih"}
|
100
|
+
# if false
|
101
|
+
# @return {"errcode":40013,"errmsg":"invalid appid"}
|
102
|
+
#
|
103
|
+
def shorturl(longurl)
|
104
|
+
access_token = AccessToken.get()
|
105
|
+
uri = URI.parse("https://api.weixin.qq.com/cgi-bin/shorturl?access_token=#{access_token}")
|
106
|
+
post_data = {action: "long2short", long_url: longurl}
|
107
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
108
|
+
http.use_ssl = true
|
109
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
110
|
+
request = Net::HTTP::Post.new("/cgi-bin/shorturl?access_token=#{access_token}")
|
111
|
+
request.add_field('Content-Type', 'application/json')
|
112
|
+
request.body = post_data.to_json
|
113
|
+
response = http.request(request)
|
114
|
+
|
115
|
+
JSON.parse(response.body)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#####################################################
|
2
|
+
# 消息加密解密
|
3
|
+
# Created by zhangmingxin
|
4
|
+
# Date: 2018-05-18
|
5
|
+
# Wechat number: zmx119966
|
6
|
+
####################################################
|
7
|
+
|
8
|
+
require "wechat_public_api/access_token"
|
9
|
+
module WechatPublicApi
|
10
|
+
module Aes
|
11
|
+
class << self
|
12
|
+
|
13
|
+
# 解密
|
14
|
+
def decrypt(key, dicrypted_string)
|
15
|
+
cipher = OpenSSL::Cipher::AES.new(256, :CBC)
|
16
|
+
cipher.decrypt
|
17
|
+
cipher.key = key
|
18
|
+
cipher.iv = '0000000000000000'
|
19
|
+
cipher.padding = 0
|
20
|
+
cipher.update(dicrypted_string) << cipher.final
|
21
|
+
end
|
22
|
+
|
23
|
+
# 加密
|
24
|
+
def encrypt(aes_key, text, app_id)
|
25
|
+
text = text.force_encoding("ASCII-8BIT")
|
26
|
+
random = SecureRandom.hex(8)
|
27
|
+
msg_len = [text.length].pack("N")
|
28
|
+
text = "#{random}#{msg_len}#{text}#{app_id}"
|
29
|
+
text = WxAuth.encode(text)
|
30
|
+
text = handle_cipher(:encrypt, aes_key, text)
|
31
|
+
Base64.encode64(text)
|
32
|
+
end
|
33
|
+
|
34
|
+
def handle_cipher(action, aes_key, text)
|
35
|
+
cipher = OpenSSL::Cipher.new('AES-256-CBC')
|
36
|
+
cipher.send(action)
|
37
|
+
cipher.padding = 0
|
38
|
+
cipher.key = aes_key
|
39
|
+
cipher.iv = aes_key[0...16]
|
40
|
+
cipher.update(text) + cipher.final
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -29,7 +29,7 @@ module WechatPublicApi
|
|
29
29
|
#
|
30
30
|
# @param <JSON> message
|
31
31
|
#
|
32
|
-
def
|
32
|
+
def post_customer_message(message)
|
33
33
|
# get access_token
|
34
34
|
access_token = AccessToken.get()
|
35
35
|
|
@@ -49,7 +49,7 @@ module WechatPublicApi
|
|
49
49
|
# @param <string> content -- 需要发送的客服消息内容
|
50
50
|
#
|
51
51
|
# 发送文字消息
|
52
|
-
def
|
52
|
+
def text_message(openid, content)
|
53
53
|
|
54
54
|
custom_message = {
|
55
55
|
touser: openid,
|
@@ -68,7 +68,7 @@ module WechatPublicApi
|
|
68
68
|
# @param <string> media_id -- 发送的图片/语音/视频/图文消息(点击跳转到图文消息页)的媒体ID
|
69
69
|
#
|
70
70
|
# 发送图片消息
|
71
|
-
def
|
71
|
+
def image_message(openid, media_id)
|
72
72
|
|
73
73
|
custom_message = {
|
74
74
|
touser: openid,
|
@@ -116,7 +116,7 @@ module WechatPublicApi
|
|
116
116
|
# ]
|
117
117
|
#
|
118
118
|
# 发送图文消息(点击跳转到外链)
|
119
|
-
def
|
119
|
+
def news_message(openid, articles)
|
120
120
|
custom_message = {
|
121
121
|
touser: openid,
|
122
122
|
msgtype: 'news',
|
@@ -132,7 +132,7 @@ module WechatPublicApi
|
|
132
132
|
end
|
133
133
|
|
134
134
|
# 发送语音消息
|
135
|
-
def
|
135
|
+
def voice_message(openid, media_id)
|
136
136
|
|
137
137
|
custom_message = {
|
138
138
|
touser: openid,
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#####################################################
|
2
|
+
# 微信公众号素材管理
|
3
|
+
# Created by zhangmingxin
|
4
|
+
# Date: 2018-05-18
|
5
|
+
# Wechat number: zmx119966
|
6
|
+
####################################################
|
7
|
+
|
8
|
+
require "wechat_public_api/access_token"
|
9
|
+
|
10
|
+
module WechatPublicApi
|
11
|
+
module Material
|
12
|
+
class << self
|
13
|
+
|
14
|
+
###
|
15
|
+
# 获得临时图片素材的 media_id
|
16
|
+
# @param <string> file_path -- 图片素材的路径
|
17
|
+
#
|
18
|
+
# @return <json> {"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789}
|
19
|
+
# if false
|
20
|
+
# @return <json> {"errcode":40004,"errmsg":"invalid media type"}
|
21
|
+
#
|
22
|
+
def upload_image_media(file_path)
|
23
|
+
# request access_token
|
24
|
+
access_token = AccessToken.get()
|
25
|
+
response = RestClient.post('https://api.weixin.qq.com/cgi-bin/media/upload',
|
26
|
+
{
|
27
|
+
access_token: access_token,
|
28
|
+
type: 'image',
|
29
|
+
media: File.new(file_path, 'rb')})
|
30
|
+
JSON.parse(response)
|
31
|
+
end
|
32
|
+
|
33
|
+
###
|
34
|
+
# 新增永久图片素材
|
35
|
+
# @param <string> file_path -- 图片素材的路径
|
36
|
+
#
|
37
|
+
# @return <json> {"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789}
|
38
|
+
# if false
|
39
|
+
# @return <json> {"errcode":40004,"errmsg":"invalid media type"}
|
40
|
+
#
|
41
|
+
def upload_image_material(file_path)
|
42
|
+
# request access_token
|
43
|
+
access_token = AccessToken.get()
|
44
|
+
response = RestClient.post('https://api.weixin.qq.com/cgi-bin/material/add_material',
|
45
|
+
{
|
46
|
+
access_token: access_token,
|
47
|
+
type: 'image',
|
48
|
+
media: File.new(file_path, 'rb')})
|
49
|
+
JSON.parse(response)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -17,7 +17,7 @@ module WechatPublicApi
|
|
17
17
|
#
|
18
18
|
# => post_data example
|
19
19
|
# {
|
20
|
-
#
|
20
|
+
# "button": [
|
21
21
|
# {
|
22
22
|
# "type": "view",
|
23
23
|
# "name": "",
|
@@ -41,9 +41,9 @@ module WechatPublicApi
|
|
41
41
|
def create(post_data)
|
42
42
|
# request access_token
|
43
43
|
access_token = AccessToken.get()
|
44
|
+
post_data = post_data.to_json.gsub(/\\u([0-9a-z]{4})/) {|s| [$1.to_i(16)].pack("U")}
|
44
45
|
|
45
46
|
uri = URI.parse("https://api.weixin.qq.com/cgi-bin/menu/create?access_token=#{access_token}")
|
46
|
-
post_data = post_data
|
47
47
|
http = Net::HTTP.new(uri.host, uri.port)
|
48
48
|
http.use_ssl = true
|
49
49
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
@@ -58,7 +58,7 @@ module WechatPublicApi
|
|
58
58
|
def query()
|
59
59
|
# request access_token
|
60
60
|
access_token = AccessToken.get()
|
61
|
-
response = HTTParty.get("https://api.weixin.qq.com/cgi-bin/menu/get?access_token
|
61
|
+
response = HTTParty.get("https://api.weixin.qq.com/cgi-bin/menu/get?access_token=#{access_token}").body
|
62
62
|
(JSON.parse response)
|
63
63
|
end
|
64
64
|
|
@@ -69,7 +69,7 @@ module WechatPublicApi
|
|
69
69
|
def delete()
|
70
70
|
# request access_token
|
71
71
|
access_token = AccessToken.get()
|
72
|
-
response = HTTParty.get("https://api.weixin.qq.com/cgi-bin/menu/delete?access_token
|
72
|
+
response = HTTParty.get("https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=#{access_token}").body
|
73
73
|
(JSON.parse response)
|
74
74
|
end
|
75
75
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#####################################################
|
2
|
+
# 公众号用户管理
|
3
|
+
# Created by zhangmingxin
|
4
|
+
# Date: 2018-05-18
|
5
|
+
# Wechat number: zmx119966
|
6
|
+
####################################################
|
7
|
+
|
8
|
+
require "wechat_public_api/access_token"
|
9
|
+
|
10
|
+
module WechatPublicApi
|
11
|
+
module User
|
12
|
+
class << self
|
13
|
+
|
14
|
+
# 获取用户信息
|
15
|
+
# @return <JSON>
|
16
|
+
# {
|
17
|
+
# "subscribe": 1,
|
18
|
+
# "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M",
|
19
|
+
# "nickname": "Band",
|
20
|
+
# "sex": 1,
|
21
|
+
# "language": "zh_CN",
|
22
|
+
# "city": "广州",
|
23
|
+
# "province": "广东",
|
24
|
+
# "country": "中国",
|
25
|
+
# "headimgurl":"http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
|
26
|
+
# "subscribe_time": 1382694957,
|
27
|
+
# "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
|
28
|
+
# "remark": "",
|
29
|
+
# "groupid": 0,
|
30
|
+
# "tagid_list":[128,2],
|
31
|
+
# "subscribe_scene": "ADD_SCENE_QR_CODE",
|
32
|
+
# "qr_scene": 98765,
|
33
|
+
# "qr_scene_str": ""
|
34
|
+
# }
|
35
|
+
#
|
36
|
+
# if failed
|
37
|
+
# {"errcode":40013,"errmsg":"invalid appid"}
|
38
|
+
#
|
39
|
+
def get_userinfo(openid)
|
40
|
+
# request access_token
|
41
|
+
access_token = AccessToken.get()
|
42
|
+
JSON.parse HTTParty.get("https://api.weixin.qq.com/cgi-bin/user/info?access_token=#{access_token}&openid=#{openid}&lang=zh_CN").body
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#####################################################
|
2
|
+
# 基于微信公众号的小工具,公用
|
3
|
+
# Created by zhangmingxin
|
4
|
+
# Date: 2018-05-18
|
5
|
+
# Wechat number: zmx119966
|
6
|
+
####################################################
|
7
|
+
|
8
|
+
require "wechat_public_api/access_token"
|
9
|
+
module WechatPublicApi
|
10
|
+
module Utils
|
11
|
+
class << self
|
12
|
+
# Todo
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
Binary file
|
Binary file
|
data/wechat_public_api.gemspec
CHANGED
@@ -6,10 +6,10 @@ require "wechat_public_api/version"
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "wechat_public_api"
|
8
8
|
spec.version = WechatPublicApi::VERSION
|
9
|
-
spec.authors = ["张明鑫"]
|
9
|
+
spec.authors = ["张明鑫 wechat number: zmx119966"]
|
10
10
|
spec.email = ["mnzmx_z@163.com"]
|
11
11
|
|
12
|
-
spec.summary = %q{微信公众号开发API
|
12
|
+
spec.summary = %q{微信公众号开发API,包含对微信公众号菜单栏、客服消息、模板消息、帐号管理等接口的封装,API长期更新维护,建议使用最新版本.}
|
13
13
|
spec.description = %q{}
|
14
14
|
spec.homepage = "https://github.com/Diyilou/wechat_public_api.git"
|
15
15
|
spec.license = "MIT"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wechat_public_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- 张明鑫
|
7
|
+
- '张明鑫 wechat number: zmx119966'
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- ".gitignore"
|
119
119
|
- CODE_OF_CONDUCT.md
|
120
120
|
- Gemfile
|
121
|
+
- Gemfile.lock
|
121
122
|
- LICENSE.txt
|
122
123
|
- README.md
|
123
124
|
- Rakefile
|
@@ -125,10 +126,17 @@ files:
|
|
125
126
|
- bin/setup
|
126
127
|
- lib/wechat_public_api.rb
|
127
128
|
- lib/wechat_public_api/access_token.rb
|
129
|
+
- lib/wechat_public_api/account.rb
|
130
|
+
- lib/wechat_public_api/aes.rb
|
128
131
|
- lib/wechat_public_api/kf_message.rb
|
132
|
+
- lib/wechat_public_api/material.rb
|
129
133
|
- lib/wechat_public_api/menu.rb
|
130
134
|
- lib/wechat_public_api/templet_message.rb
|
135
|
+
- lib/wechat_public_api/user.rb
|
136
|
+
- lib/wechat_public_api/utils.rb
|
131
137
|
- lib/wechat_public_api/version.rb
|
138
|
+
- wechat_public_api-0.1.1.gem
|
139
|
+
- wechat_public_api-0.1.2.gem
|
132
140
|
- wechat_public_api.gemspec
|
133
141
|
homepage: https://github.com/Diyilou/wechat_public_api.git
|
134
142
|
licenses:
|
@@ -153,5 +161,5 @@ rubyforge_project:
|
|
153
161
|
rubygems_version: 2.5.2.1
|
154
162
|
signing_key:
|
155
163
|
specification_version: 4
|
156
|
-
summary: 微信公众号开发API
|
164
|
+
summary: 微信公众号开发API,包含对微信公众号菜单栏、客服消息、模板消息、帐号管理等接口的封装,API长期更新维护,建议使用最新版本.
|
157
165
|
test_files: []
|