eric_weixin 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.idea/eric_weixin.iml +2 -2
- data/eric_weixin.gemspec +11 -2
- data/lib/eric_weixin/app/controllers/weixin/weixin_controller.rb +27 -0
- data/lib/eric_weixin/app/model/access_token.rb +45 -0
- data/lib/eric_weixin/app/model/article.rb +17 -0
- data/lib/eric_weixin/app/model/article_news.rb +8 -0
- data/lib/eric_weixin/app/model/news.rb +52 -0
- data/lib/eric_weixin/app/model/public_account.rb +185 -0
- data/lib/eric_weixin/app/model/reply_message_rule.rb +109 -0
- data/lib/eric_weixin/app/model/weixin_user.rb +89 -0
- data/lib/eric_weixin/app/views/eric_weixin/weixin/aa.erb +1 -0
- data/lib/eric_weixin/reply_message.rb +5 -5
- data/lib/eric_weixin/version.rb +1 -1
- data/lib/eric_weixin.rb +14 -1
- metadata +143 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b91a2c0afb290cba50cce75c285a32de4bee430e
|
4
|
+
data.tar.gz: f67c0af9428bb0211ba40747cbc702852d0b4ba8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 023d60c77b3855d6daec7e27d850bf5de60991df7b111af34920b87b06eb437fe6b180cca91767e606b6b8dee0f49e6bc6b76246de9ce4f1ad83714ce653e609
|
7
|
+
data.tar.gz: 884acba9ee05601fdac7d7cd6dc6f59ceb1edeb7bbfef3db0a9f2054b4baf2e6947a89450e8c72a71a578ed32608bd4702c45dbd48b618ac09e2f323a4ea35c4
|
data/.idea/eric_weixin.iml
CHANGED
@@ -14,9 +14,9 @@
|
|
14
14
|
</component>
|
15
15
|
<component name="NewModuleRootManager">
|
16
16
|
<content url="file://$MODULE_DIR$" />
|
17
|
-
<orderEntry type="
|
17
|
+
<orderEntry type="jdk" jdkName="RVM: ruby-2.0.0-p481 [eric_tools]" jdkType="RUBY_SDK" />
|
18
18
|
<orderEntry type="sourceFolder" forTests="false" />
|
19
|
-
<orderEntry type="library" scope="PROVIDED" name="bundler (v1.6.2, RVM: ruby-2.0.0-p481) [gem]" level="application" />
|
19
|
+
<orderEntry type="library" scope="PROVIDED" name="bundler (v1.6.2, RVM: ruby-2.0.0-p481 [eric_tools]) [gem]" level="application" />
|
20
20
|
</component>
|
21
21
|
</module>
|
22
22
|
|
data/eric_weixin.gemspec
CHANGED
@@ -19,6 +19,15 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
-
spec.add_development_dependency "rake"
|
23
|
-
spec.add_development_dependency 'nokogiri'
|
22
|
+
spec.add_development_dependency "rake", '~> 0'
|
23
|
+
spec.add_development_dependency 'nokogiri', '~> 0'
|
24
|
+
spec.add_development_dependency 'rest-client', '~> 0'
|
25
|
+
spec.add_development_dependency 'activerecord', '~> 4.1', '>= 4.1.4'
|
26
|
+
spec.add_development_dependency 'rails', '~> 4.1', '>= 4.1.4'
|
27
|
+
spec.add_development_dependency 'actionpack', '~> 4.1', '>= 4.1.4'
|
28
|
+
spec.add_development_dependency 'activesupport', '~> 4.1', '>= 4.1.4'
|
29
|
+
spec.add_development_dependency 'actionview', '~> 4.1', '>= 4.1.4'
|
30
|
+
|
31
|
+
spec.add_development_dependency 'eric_tools', '~> 0.0.4'
|
32
|
+
|
24
33
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "pp"
|
2
|
+
module EricWeixin
|
3
|
+
class WeixinController < ActionController::Base
|
4
|
+
layout "cms/base"
|
5
|
+
|
6
|
+
# 第一次接入时,用于微信服务器验证开者服务器的真实性。
|
7
|
+
def index
|
8
|
+
render :text => params[:echostr]
|
9
|
+
end
|
10
|
+
|
11
|
+
def reply
|
12
|
+
request_body = request.body.read
|
13
|
+
weixin_secret_key = ::EricWeixin::PublicAccount.get_secret params[:app_id]
|
14
|
+
|
15
|
+
"message from wechat: ".to_logger
|
16
|
+
request_body.to_logger
|
17
|
+
weixin_message = MultiXml.parse(request_body).deep_symbolize_keys[:xml]
|
18
|
+
|
19
|
+
message = ::EricWeixin::ReplyMessageRule.process_rule(weixin_message, weixin_secret_key)
|
20
|
+
render xml: message
|
21
|
+
end
|
22
|
+
|
23
|
+
def aa
|
24
|
+
@ee = 12
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module EricWeixin
|
2
|
+
class AccessToken < ActiveRecord::Base
|
3
|
+
require "rest-client"
|
4
|
+
self.table_name = "weixin_access_tokens"
|
5
|
+
|
6
|
+
|
7
|
+
# 获取有效的Token
|
8
|
+
# 参数为: weixin_secret_key
|
9
|
+
# ::EricWeixin::AccessToken.get_valid_access_token weixin_secret_key: 'bba7ba32bf3e1a60edd8bd8903ce33e5'
|
10
|
+
def self.get_valid_access_token options
|
11
|
+
::EricWeixin::AccessToken.transaction do
|
12
|
+
access_token = ::EricWeixin::AccessToken.where(weixin_secret_key: options[:weixin_secret_key]).first
|
13
|
+
if access_token.blank?
|
14
|
+
public_account = ::EricWeixin::PublicAccount.find_by_weixin_secret_key(options[:weixin_secret_key]).first
|
15
|
+
access_token = ::EricWeixin::AccessToken.new :weixin_secret_key => options[:weixin_secret_key],
|
16
|
+
:access_token => get_new_token(options[:weixin_secret_key]),
|
17
|
+
:expired_at => Time.now.to_i + 2*60*60,
|
18
|
+
:public_account_id => public_account.id
|
19
|
+
access_token.save!
|
20
|
+
end
|
21
|
+
|
22
|
+
if Time.now.to_i > (access_token.expired_at.to_i - 30)
|
23
|
+
access_token.access_token = get_new_token(options[:weixin_secret_key])
|
24
|
+
access_token.expired_at = Time.now.to_i + 2*60*60
|
25
|
+
access_token.save!
|
26
|
+
end
|
27
|
+
access_token.reload
|
28
|
+
access_token.access_token
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
private
|
34
|
+
#::EricWeixin::AccessToken.get_new_token 'bba7ba32bf3e1a60edd8bd8903ce33e5'
|
35
|
+
def self.get_new_token secret_key
|
36
|
+
account = ::EricWeixin::PublicAccount.where(:weixin_secret_key => secret_key).first
|
37
|
+
BusinessException.raise 'account 不存在' if account.blank?
|
38
|
+
response = RestClient.get "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=#{account.weixin_app_id}&secret=#{account.weixin_secret_key}"
|
39
|
+
JSON.parse(response)["access_token"]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class EricWeixin::Article < ActiveRecord::Base
|
2
|
+
self.table_name = "weixin_articles"
|
3
|
+
validates_presence_of :title, :pic_url, :link_url
|
4
|
+
has_many :weixin_article_newses, :class_name => '::EricWeixin::ArticleNews', foreign_key: "weixin_article_id"
|
5
|
+
has_many :weixin_news_datas, :class_name => '::EricWeixin::NewsData', through: :weixin_article_newses
|
6
|
+
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def create_article_data options
|
10
|
+
::EricWeixin::Article.transaction do
|
11
|
+
article = ::EricWeixin::Article.new(options)
|
12
|
+
article.save!
|
13
|
+
article
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class EricWeixin::ArticleNews < ActiveRecord::Base
|
2
|
+
self.table_name = 'weixin_article_news'
|
3
|
+
belongs_to :weixin_article, :class_name => '::EricWeixin::Article', :foreign_key => 'weixin_article_id'
|
4
|
+
belongs_to :weixin_newses, :class_name => '::EricWeixin::News', :foreign_key => 'weixin_news_id'
|
5
|
+
accepts_nested_attributes_for :weixin_newses
|
6
|
+
|
7
|
+
|
8
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class EricWeixin::News < ActiveRecord::Base
|
2
|
+
self.table_name = "weixin_news"
|
3
|
+
has_many :weixin_article_newses, :class_name => '::EricWeixin::ArticleNews', foreign_key: "weixin_news_id"
|
4
|
+
has_many :weixin_articles, -> { order "sort" }, :class_name => '::EricWeixin::Article', through: :weixin_article_newses
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
def generate_news_data
|
9
|
+
articles = []
|
10
|
+
self.weixin_articles.each do |article_data|
|
11
|
+
article = generate_article(article_data.title, article_data.desc, article_data.pic_url, article_data.link_url)
|
12
|
+
articles << article
|
13
|
+
end
|
14
|
+
articles
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def create_news_datas(options, weixin_article_data_ids, weixin_article_data_sort)
|
19
|
+
::EricWeixin::News.transaction do
|
20
|
+
news_data = ::EricWeixin::News.new
|
21
|
+
news_data.update_attributes(options)
|
22
|
+
news_data.weixin_articles.clear
|
23
|
+
weixin_article_data_ids.each do |article_data_id|
|
24
|
+
article_data = ::EricWeixin::Article.find(article_data_id)
|
25
|
+
if (!article_data.blank?) && (!news_data.weixin_articles.include?(article_data))
|
26
|
+
::EricWeixin::ArticleNews.create! weixin_article_id: article_data_id, weixin_news_id: news_data.id, sort: weixin_article_data_sort[article_data_id].first
|
27
|
+
end
|
28
|
+
end
|
29
|
+
news_data.save!
|
30
|
+
news_data
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def update_news_datas(id, options, weixin_article_data_ids, weixin_article_data_sort)
|
36
|
+
::EricWeixin::News.transaction do
|
37
|
+
news_data = ::EricWeixin::News.find(id)
|
38
|
+
news_data.update(options)
|
39
|
+
news_data.weixin_articles.clear
|
40
|
+
weixin_article_data_ids.each do |article_data_id|
|
41
|
+
article_data = ::EricWeixin::Article.find(article_data_id)
|
42
|
+
if (!article_data.blank?) && (!news_data.weixin_articles.include?(article_data))
|
43
|
+
::EricWeixin::ArticleNews.create! weixin_article_id: article_data_id, weixin_news_id: news_data.id, sort: weixin_article_data_sort[article_data_id].first
|
44
|
+
end
|
45
|
+
end
|
46
|
+
news_data.save!
|
47
|
+
news_data
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
module EricWeixin
|
2
|
+
class PublicAccount < ActiveRecord::Base
|
3
|
+
require "rest-client"
|
4
|
+
self.table_name = "weixin_public_accounts"
|
5
|
+
has_many :weixin_users, :class_name => 'WeixinUser', foreign_key: "weixin_public_account_id"
|
6
|
+
|
7
|
+
|
8
|
+
def self.get_secret app_id
|
9
|
+
account = ::EricWeixin::PublicAccount.where(weixin_app_id: app_id).first
|
10
|
+
account.weixin_secret_key
|
11
|
+
end
|
12
|
+
|
13
|
+
#::EricWeixin::PublicAccount.first.get_user_data_from_weixin_api 'osyUtswoeJ9d7p16RdpC5grOeukQ'
|
14
|
+
#返回Hash信息
|
15
|
+
def get_user_data_from_weixin_api openid
|
16
|
+
token = ::EricWeixin::AccessToken.get_valid_access_token weixin_secret_key: self.weixin_secret_key
|
17
|
+
response = RestClient.get "https://api.weixin.qq.com/cgi-bin/user/info?access_token=#{token}&openid=#{openid}&lang=zh_CN"
|
18
|
+
response = JSON.parse response.body
|
19
|
+
response["nickname"] = CGI::escape(response["nickname"]) if not response["nickname"].blank?
|
20
|
+
response
|
21
|
+
end
|
22
|
+
|
23
|
+
#::EricWeixin::PublicAccount.first.weixin_menus
|
24
|
+
def weixin_menus
|
25
|
+
token = ::EricWeixin::AccessToken.get_valid_access_token weixin_secret_key: self.weixin_secret_key
|
26
|
+
response = RestClient.get "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=#{token}"
|
27
|
+
response = JSON.parse response.body
|
28
|
+
response['menu']
|
29
|
+
end
|
30
|
+
#
|
31
|
+
# ::EricWeixin::PublicAccount.first.create_menu '{
|
32
|
+
# "button":[
|
33
|
+
# {
|
34
|
+
# "name":"俱乐部2",
|
35
|
+
# "sub_button":[
|
36
|
+
#
|
37
|
+
# {
|
38
|
+
# "type":"click",
|
39
|
+
# "name":"节目介绍",
|
40
|
+
# "key":"V1001_PROGRAMME_INTRODUCTION"
|
41
|
+
# }]
|
42
|
+
# },
|
43
|
+
# {
|
44
|
+
# "type":"view",
|
45
|
+
# "name":"创意社区",
|
46
|
+
# "url":"http://m.wsq.qq.com/264164362"
|
47
|
+
# },
|
48
|
+
# {
|
49
|
+
# "name":"辣妈奶爸",
|
50
|
+
# "sub_button":[
|
51
|
+
# {
|
52
|
+
# "type":"click",
|
53
|
+
# "name":"百家言",
|
54
|
+
# "key":"V1001_BAIJIAYAN"
|
55
|
+
# },
|
56
|
+
# {
|
57
|
+
# "type":"view",
|
58
|
+
# "name":"辣妈养成记",
|
59
|
+
# "url":"http://m.wsq.qq.com/264164362/t/32"
|
60
|
+
# },
|
61
|
+
# {
|
62
|
+
# "type":"view",
|
63
|
+
# "name":"奶爸集中营4",
|
64
|
+
# "url":"http://m.wsq.qq.com/264164362/t/35"
|
65
|
+
# }]
|
66
|
+
# }]
|
67
|
+
# }'
|
68
|
+
def create_menu menu_json
|
69
|
+
::EricWeixin::PublicAccount.transaction do
|
70
|
+
self.menu_json = menu_json
|
71
|
+
self.save!
|
72
|
+
token = ::EricWeixin::AccessToken.get_valid_access_token weixin_secret_key: self.weixin_secret_key
|
73
|
+
response = RestClient.post "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=#{token}", menu_json
|
74
|
+
response = JSON.parse response.body
|
75
|
+
BusinessException.raise response["errmsg"] if response["errcode"].to_i!=0
|
76
|
+
pp response
|
77
|
+
return 0
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# ::EricWeixin::PublicAccount.first.rebuild_users
|
82
|
+
def rebuild_users next_openid = nil
|
83
|
+
token = ::EricWeixin::AccessToken.get_valid_access_token weixin_secret_key: self.weixin_secret_key
|
84
|
+
response = if next_openid.blank?
|
85
|
+
RestClient.get "https://api.weixin.qq.com/cgi-bin/user/get?access_token=#{token}"
|
86
|
+
else
|
87
|
+
RestClient.get "https://api.weixin.qq.com/cgi-bin/user/get?access_token=#{token}&next_openid=#{next_openid}"
|
88
|
+
end
|
89
|
+
response = JSON.parse response.body
|
90
|
+
if response["count"].to_i > 0
|
91
|
+
response["data"]["openid"].each do |openid|
|
92
|
+
::EricWeixin::WeixinUser.create_weixin_user self.weixin_secret_key, openid
|
93
|
+
end
|
94
|
+
tmp_next_openid = response["next_openid"]
|
95
|
+
self.rebuild_users tmp_next_openid unless tmp_next_openid.blank?
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
GLOBAL_CODES = {
|
101
|
+
-1 => "系统繁忙",
|
102
|
+
0 => "请求成功",
|
103
|
+
40001 => "获取access_token时AppSecret错误,或者access_token无效",
|
104
|
+
40002 => "不合法的凭证类型",
|
105
|
+
40003 => "不合法的OpenID",
|
106
|
+
40004 => "不合法的媒体文件类型",
|
107
|
+
40005 => "不合法的文件类型",
|
108
|
+
40006 => "不合法的文件大小",
|
109
|
+
40007 => "不合法的媒体文件id",
|
110
|
+
40008 => "不合法的消息类型",
|
111
|
+
40009 => "不合法的图片文件大小",
|
112
|
+
40010 => "不合法的语音文件大小",
|
113
|
+
40011 => "不合法的视频文件大小",
|
114
|
+
40012 => "不合法的缩略图文件大小",
|
115
|
+
40013 => "不合法的APPID",
|
116
|
+
40014 => "不合法的access_token",
|
117
|
+
40015 => "不合法的菜单类型",
|
118
|
+
40016 => "不合法的按钮个数",
|
119
|
+
40017 => "不合法的按钮个数",
|
120
|
+
40018 => "不合法的按钮名字长度",
|
121
|
+
40019 => "不合法的按钮KEY长度",
|
122
|
+
40020 => "不合法的按钮URL长度",
|
123
|
+
40021 => "不合法的菜单版本号",
|
124
|
+
40022 => "不合法的子菜单级数",
|
125
|
+
40023 => "不合法的子菜单按钮个数",
|
126
|
+
40024 => "不合法的子菜单按钮类型",
|
127
|
+
40025 => "不合法的子菜单按钮名字长度",
|
128
|
+
40026 => "不合法的子菜单按钮KEY长度",
|
129
|
+
40027 => "不合法的子菜单按钮URL长度",
|
130
|
+
40028 => "不合法的自定义菜单使用用户",
|
131
|
+
40029 => "不合法的oauth_code",
|
132
|
+
40030 => "不合法的refresh_token",
|
133
|
+
40031 => "不合法的openid列表",
|
134
|
+
40032 => "不合法的openid列表长度",
|
135
|
+
40033 => "不合法的请求字符,不能包含xxxx格式的字符",
|
136
|
+
40035 => "不合法的参数",
|
137
|
+
40038 => "不合法的请求格式",
|
138
|
+
40039 => "不合法的URL长度",
|
139
|
+
40050 => "不合法的分组id",
|
140
|
+
40051 => "分组名字不合法",
|
141
|
+
41001 => "缺少access_token参数",
|
142
|
+
41002 => "缺少appid参数",
|
143
|
+
41003 => "缺少refresh_token参数",
|
144
|
+
41004 => "缺少secret参数",
|
145
|
+
41005 => "缺少多媒体文件数据",
|
146
|
+
41006 => "缺少media_id参数",
|
147
|
+
41007 => "缺少子菜单数据",
|
148
|
+
41008 => "缺少oauth code",
|
149
|
+
41009 => "缺少openid",
|
150
|
+
42001 => "access_token超时",
|
151
|
+
42002 => "refresh_token超时",
|
152
|
+
42003 => "oauth_code超时",
|
153
|
+
43001 => "需要GET请求",
|
154
|
+
43002 => "需要POST请求",
|
155
|
+
43003 => "需要HTTPS请求",
|
156
|
+
43004 => "需要接收者关注",
|
157
|
+
43005 => "需要好友关系",
|
158
|
+
44001 => "多媒体文件为空",
|
159
|
+
44002 => "POST的数据包为空",
|
160
|
+
44003 => "图文消息内容为空",
|
161
|
+
44004 => "文本消息内容为空",
|
162
|
+
45001 => "多媒体文件大小超过限制",
|
163
|
+
45002 => "消息内容超过限制",
|
164
|
+
45003 => "标题字段超过限制",
|
165
|
+
45004 => "描述字段超过限制",
|
166
|
+
45005 => "链接字段超过限制",
|
167
|
+
45006 => "图片链接字段超过限制",
|
168
|
+
45007 => "语音播放时间超过限制",
|
169
|
+
45008 => "图文消息超过限制",
|
170
|
+
45009 => "接口调用超过限制",
|
171
|
+
45010 => "创建菜单个数超过限制",
|
172
|
+
45015 => "回复时间超过限制",
|
173
|
+
45016 => "系统分组,不允许修改",
|
174
|
+
45017 => "分组名字过长",
|
175
|
+
45018 => "分组数量超过上限",
|
176
|
+
46001 => "不存在媒体数据",
|
177
|
+
46002 => "不存在的菜单版本",
|
178
|
+
46003 => "不存在的菜单数据",
|
179
|
+
46004 => "不存在的用户",
|
180
|
+
47001 => "解析JSON/XML内容错误",
|
181
|
+
48001 => "api功能未授权",
|
182
|
+
50001 => "用户未授权该api"
|
183
|
+
}
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
class EricWeixin::ReplyMessageRule < ActiveRecord::Base
|
2
|
+
self.table_name = 'weixin_reply_message_rules'
|
3
|
+
scope :valid, -> { where(:is_valid => true) }
|
4
|
+
belongs_to :weixin_public_account, :class_name => '::EricWeixin::PublicAccount', foreign_key: "weixin_public_account_id"
|
5
|
+
delegate :name, to: :weixin_public_account, prefix: true, allow_nil: true
|
6
|
+
|
7
|
+
KEY_WORD_TYPE_LABEL = {"keyword" => '字符', 'regularexpr' => '正则表达式'}
|
8
|
+
REPLY_TYPE_LABEL = {"text" => '静态字符串', 'wx_function' => '动态运行', 'news' => '多图文'}
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def create_reply_message_rule options
|
13
|
+
options = get_arguments_options options, [:weixin_public_account_id, :key_word, :reply_message, :key_word_type, :order, :reply_type], is_valid: true
|
14
|
+
::EricWeixin::ReplyMessageRule.transaction do
|
15
|
+
reply_message_rule = ::EricWeixin::ReplyMessageRule.new options
|
16
|
+
public_account = ::EricWeixin::PublicAccount.find(options[:weixin_public_account_id])
|
17
|
+
reply_message_rule.weixin_app_id = public_account.weixin_app_id
|
18
|
+
reply_message_rule.weixin_secret_key = public_account.weixin_secret_key
|
19
|
+
reply_message_rule.save!
|
20
|
+
reply_message_rule
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def update_reply_message_rule(rule_id, options)
|
25
|
+
options = get_arguments_options options, [:weixin_public_account_id, :key_word, :reply_message, :key_word_type, :order, :reply_type, :is_valid]
|
26
|
+
EricWeixin::ReplyMessageRule.transaction do
|
27
|
+
rule = EricWeixin::ReplyMessageRule.find(rule_id)
|
28
|
+
rule.update_attributes(options)
|
29
|
+
public_account = ::EricWeixin::PublicAccount.find(options[:weixin_public_account_id])
|
30
|
+
rule.weixin_app_id = public_account.weixin_app_id
|
31
|
+
rule.weixin_secret_key = public_account.weixin_secret_key
|
32
|
+
rule.save!
|
33
|
+
rule
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def process_rule(receive_message, secret_key)
|
38
|
+
business_type = "#{receive_message[:MsgType]}~#{receive_message[:Event]}"
|
39
|
+
|
40
|
+
|
41
|
+
reply_message = case business_type
|
42
|
+
#订阅
|
43
|
+
when /event~subscribe/
|
44
|
+
result = ::Weixin::Process.subscribe receive_message
|
45
|
+
if result == true
|
46
|
+
::EricWeixin::WeixinUser.create_weixin_user secret_key, receive_message[:FromUserName]
|
47
|
+
match_key_words 'subscribe', secret_key, receive_message
|
48
|
+
else
|
49
|
+
result
|
50
|
+
end
|
51
|
+
when /event~unsubscribe/
|
52
|
+
result = ::Weixin::Process.unsubscribe receive_message
|
53
|
+
if result == true
|
54
|
+
::EricWeixin::WeixinUser.create_weixin_user secret_key, receive_message[:FromUserName]
|
55
|
+
match_key_words 'unsubscribe', secret_key, receive_message
|
56
|
+
else
|
57
|
+
result
|
58
|
+
end
|
59
|
+
when /event~CLICK/
|
60
|
+
result = ::Weixin::Process.click_event receive_message[:EventKey], receive_message
|
61
|
+
if result == true
|
62
|
+
match_key_words receive_message[:EventKey], secret_key, receive_message
|
63
|
+
else
|
64
|
+
result
|
65
|
+
end
|
66
|
+
when /text~/
|
67
|
+
result = ::Weixin::Process.text_event receive_message[:Content], receive_message
|
68
|
+
if result == true
|
69
|
+
match_key_words receive_message[:Content], secret_key, receive_message
|
70
|
+
else
|
71
|
+
result
|
72
|
+
end
|
73
|
+
else
|
74
|
+
result = ::Weixin::Process.another_event receive_message
|
75
|
+
if result == true
|
76
|
+
match_key_words 'unknow~words', secret_key, receive_message
|
77
|
+
else
|
78
|
+
result
|
79
|
+
end
|
80
|
+
end
|
81
|
+
"message_to_wechat:".to_logger
|
82
|
+
reply_message.to_logger
|
83
|
+
reply_message
|
84
|
+
end
|
85
|
+
|
86
|
+
def match_key_words wx_key_word, secret_key, receive_message
|
87
|
+
matched_rule = EricWeixin::ReplyMessageRule.order(order: :desc).
|
88
|
+
where(:key_word => wx_key_word, :weixin_secret_key => secret_key).first
|
89
|
+
if matched_rule.nil?
|
90
|
+
return EricWeixin::ReplyMessage::transfer_mult_customer_service ToUserName: receive_message[:FromUserName],
|
91
|
+
FromUserName: receive_message[:ToUserName]
|
92
|
+
end
|
93
|
+
reply_msg = case matched_rule.reply_type
|
94
|
+
when "text"
|
95
|
+
EricWeixin::ReplyMessage.get_reply_user_message_text ToUserName: receive_message[:FromUserName],
|
96
|
+
FromUserName: receive_message[:ToUserName],
|
97
|
+
Content: matched_rule.reply_message
|
98
|
+
when "news"
|
99
|
+
weixin_news = ::EricWeixin::News.find_by_match_key matched_rule.reply_message
|
100
|
+
EricWeixin::ReplyMessage::get_reply_user_message_image_text ToUserName: receive_message[:FromUserName],
|
101
|
+
FromUserName: receive_message[:ToUserName],
|
102
|
+
news: weixin_news.weixin_articles
|
103
|
+
when "wx_function"
|
104
|
+
Weixin::WeixinAutoReplyFunctions.send(matched_rule.reply_message, {:key_word => wx_key_word, :receive_message => receive_message})
|
105
|
+
end
|
106
|
+
reply_msg
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
class EricWeixin::WeixinUser < ActiveRecord::Base
|
2
|
+
belongs_to :member_info
|
3
|
+
belongs_to :weixin_public_account, :class_name => '::EricWeixin::PublicAccount', :foreign_key => 'weixin_public_account_id'
|
4
|
+
validates_uniqueness_of :openid, scope: :weixin_secret_key
|
5
|
+
validates_presence_of :openid, :weixin_secret_key, :weixin_public_account
|
6
|
+
|
7
|
+
def nickname
|
8
|
+
CGI::unescape(self.attributes["nickname"])
|
9
|
+
end
|
10
|
+
|
11
|
+
def follow_status
|
12
|
+
self.subscribe.to_i == 1
|
13
|
+
end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
17
|
+
##
|
18
|
+
# ===业务说明:创建、更新微信用户
|
19
|
+
# * 微信用户在关注、取消关注时更新用户信息。
|
20
|
+
# * 当用户关注微信时,创建用户。
|
21
|
+
# * 当用户取消关注时,把用户标记为取消关注,同时更新用户的最新信息(包含用户名等)
|
22
|
+
# ===参数说明
|
23
|
+
# * secret_key::公众账号的secret_key,其值取决于公众账号的设置。
|
24
|
+
# * openid::用户的openid,微信服务器传送过来。
|
25
|
+
# ===调用方法
|
26
|
+
# EricWeixin::WeixinUser.create_weixin_user 'adsfkj', 'sdfdf'
|
27
|
+
# EricWeixin::WeixinUser.create_weixin_user 'adsfkj', 'sdfdf'
|
28
|
+
# ====返回
|
29
|
+
# 正常情况下返回当前微信用户 <tt>::EricWeixin::WeixinUser</tt>,抛出异常时错误查看异常信息。
|
30
|
+
def create_weixin_user(secret_key, openid)
|
31
|
+
public_account = ::Weixin::PublicAccount.find_by_weixin_secret_key(secret_key)
|
32
|
+
::Weixin::ReplyMessageRule.transaction do
|
33
|
+
weixin_user = ::EricWeixin::WeixinUser.where(openid: openid, weixin_secret_key: secret_key).first
|
34
|
+
if weixin_user.blank?
|
35
|
+
weixin_user = ::EricWeixin::WeixinUser.new openid: openid,
|
36
|
+
weixin_secret_key: secret_key,
|
37
|
+
weixin_public_account_id: public_account.id
|
38
|
+
weixin_user.save!
|
39
|
+
end
|
40
|
+
wx_user_data = public_account.get_user_data_from_weixin_api openid
|
41
|
+
weixin_user.update_attributes(wx_user_data)
|
42
|
+
weixin_user
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def export_users_to_csv(weixin_secret_key)
|
48
|
+
require 'csv'
|
49
|
+
weixin_users = ::EricWeixin::WeixinUser.where(weixin_secret_key: weixin_secret_key)
|
50
|
+
CSV.generate do |csv|
|
51
|
+
csv << ["订阅状态", "openid", "昵称", "性别", "语言", "城市", "省份", "国家", "订阅时间"]
|
52
|
+
weixin_users.each do |weixin_user|
|
53
|
+
user_fields = []
|
54
|
+
user_fields << (weixin_user.follow_status ? '订阅': '取消订阅')
|
55
|
+
user_fields << weixin_user.openid
|
56
|
+
user_fields << weixin_user.nickname
|
57
|
+
user_fields << case weixin_user.sex when 1 then '男' when 2 then '女' else '未知' end
|
58
|
+
user_fields << case weixin_user.language when 'zh_CN' then '简体中文' when 'zh_TW' then '繁体中文' when 'en' then '英文' else '其它' end
|
59
|
+
user_fields << weixin_user.city
|
60
|
+
user_fields << weixin_user.province
|
61
|
+
user_fields << weixin_user.country
|
62
|
+
user_fields << Time.at(weixin_user.subscribe_time.to_i).chinese_format
|
63
|
+
csv << user_fields
|
64
|
+
end
|
65
|
+
csv
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
#绑定会员
|
71
|
+
def connect_member(options)
|
72
|
+
openid = options[:openid]
|
73
|
+
user_name = options[:username]
|
74
|
+
password = options[:password]
|
75
|
+
|
76
|
+
::EricWeixin::WeixinUser.transaction do
|
77
|
+
member_info = MemberInfo.where(user_name: user_name, password: password).first
|
78
|
+
BusinessException.raise '该会员不存在' if member_info.blank?
|
79
|
+
|
80
|
+
weixin_user = ::EricWeixin::WeixinUser.find_by_openid(openid)
|
81
|
+
BusinessException.raise '该微信用户不存在' if weixin_user.blank?
|
82
|
+
|
83
|
+
weixin_user.member_info = member_info
|
84
|
+
weixin_user.save!
|
85
|
+
member_info
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%=@ee%>
|
@@ -13,11 +13,11 @@ module EricWeixin
|
|
13
13
|
# ===参数说明
|
14
14
|
# * ToUserName: 收取方的账号
|
15
15
|
# * FromUserName: 开发者账号
|
16
|
-
# * news: 文章列表,
|
16
|
+
# * news: 文章列表,EricWeixin::Article 的实例数组
|
17
17
|
# ===示例
|
18
|
-
# Tools::
|
18
|
+
# Tools::EricWeixin::ReplyMessage::get_reply_user_message_image_text ToUserName: 'xx',
|
19
19
|
# FromUserName: 'yy',
|
20
|
-
# news:[
|
20
|
+
# news:[EricWeixin::ArticleData.new]
|
21
21
|
def self.get_reply_user_message_image_text options
|
22
22
|
xml = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
|
23
23
|
xml.send(:xml) {
|
@@ -49,7 +49,7 @@ module EricWeixin
|
|
49
49
|
# * FromUserName: 开发者账号
|
50
50
|
# * Content: 回复的消息内容
|
51
51
|
# ===示例
|
52
|
-
# Tools::
|
52
|
+
# Tools::EricWeixin::ReplyMessage.get_reply_user_message_text ToUserName: 'xx',
|
53
53
|
# FromUserName: 'yy',
|
54
54
|
# Content: 'haha'
|
55
55
|
def self.get_reply_user_message_text options
|
@@ -70,7 +70,7 @@ module EricWeixin
|
|
70
70
|
# * ToUserName: 收取方的账号
|
71
71
|
# * FromUserName: 开发者账号
|
72
72
|
# ===示例
|
73
|
-
#
|
73
|
+
# EricWeixin::ReplyMessage::transfer_mult_customer_service ToUserName: 'xxx',
|
74
74
|
# FromUserName: 'yyyy',
|
75
75
|
def self.transfer_mult_customer_service options
|
76
76
|
xml = Nokogiri::XML::Builder.new(:encoding => 'utf-8') do |xml|
|
data/lib/eric_weixin/version.rb
CHANGED
data/lib/eric_weixin.rb
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
require "eric_weixin/version"
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/eric_weixin/app/model/access_token.rb'
|
4
|
+
require File.dirname(__FILE__) + '/eric_weixin/app/model/article.rb'
|
5
|
+
require File.dirname(__FILE__) + '/eric_weixin/app/model/article_news.rb'
|
6
|
+
require File.dirname(__FILE__) + '/eric_weixin/app/model/news.rb'
|
7
|
+
require File.dirname(__FILE__) + '/eric_weixin/app/model/public_account.rb'
|
8
|
+
require File.dirname(__FILE__) + '/eric_weixin/app/model/reply_message_rule.rb'
|
9
|
+
require File.dirname(__FILE__) + '/eric_weixin/app/model/weixin_user.rb'
|
2
10
|
require File.dirname(__FILE__) + '/eric_weixin/reply_message.rb'
|
3
11
|
|
12
|
+
|
13
|
+
require File.dirname(__FILE__) + '/eric_weixin/app/controllers/weixin/weixin_controller'
|
14
|
+
|
15
|
+
|
4
16
|
module EricWeixin
|
5
|
-
#
|
17
|
+
# 把gem目录放作为视图目录
|
18
|
+
ActionController::Base.append_view_path(File.dirname(__FILE__) + '/eric_weixin/app/views')
|
6
19
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eric_weixin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 刘晓琦
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -28,30 +28,158 @@ dependencies:
|
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: nokogiri
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rest-client
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
53
60
|
- !ruby/object:Gem::Version
|
54
61
|
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activerecord
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.1'
|
76
|
+
- - '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 4.1.4
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '4.1'
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 4.1.4
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rails
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ~>
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '4.1'
|
96
|
+
- - '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 4.1.4
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ~>
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '4.1'
|
106
|
+
- - '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: 4.1.4
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: actionpack
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ~>
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '4.1'
|
116
|
+
- - '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 4.1.4
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '4.1'
|
126
|
+
- - '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: 4.1.4
|
129
|
+
- !ruby/object:Gem::Dependency
|
130
|
+
name: activesupport
|
131
|
+
requirement: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ~>
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '4.1'
|
136
|
+
- - '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 4.1.4
|
139
|
+
type: :development
|
140
|
+
prerelease: false
|
141
|
+
version_requirements: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ~>
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '4.1'
|
146
|
+
- - '>='
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: 4.1.4
|
149
|
+
- !ruby/object:Gem::Dependency
|
150
|
+
name: actionview
|
151
|
+
requirement: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ~>
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '4.1'
|
156
|
+
- - '>='
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: 4.1.4
|
159
|
+
type: :development
|
160
|
+
prerelease: false
|
161
|
+
version_requirements: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ~>
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '4.1'
|
166
|
+
- - '>='
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: 4.1.4
|
169
|
+
- !ruby/object:Gem::Dependency
|
170
|
+
name: eric_tools
|
171
|
+
requirement: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - ~>
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: 0.0.4
|
176
|
+
type: :development
|
177
|
+
prerelease: false
|
178
|
+
version_requirements: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ~>
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: 0.0.4
|
55
183
|
description: 微信插件
|
56
184
|
email:
|
57
185
|
- ericliu@ikidstv.com
|
@@ -72,6 +200,15 @@ files:
|
|
72
200
|
- Rakefile
|
73
201
|
- eric_weixin.gemspec
|
74
202
|
- lib/eric_weixin.rb
|
203
|
+
- lib/eric_weixin/app/controllers/weixin/weixin_controller.rb
|
204
|
+
- lib/eric_weixin/app/model/access_token.rb
|
205
|
+
- lib/eric_weixin/app/model/article.rb
|
206
|
+
- lib/eric_weixin/app/model/article_news.rb
|
207
|
+
- lib/eric_weixin/app/model/news.rb
|
208
|
+
- lib/eric_weixin/app/model/public_account.rb
|
209
|
+
- lib/eric_weixin/app/model/reply_message_rule.rb
|
210
|
+
- lib/eric_weixin/app/model/weixin_user.rb
|
211
|
+
- lib/eric_weixin/app/views/eric_weixin/weixin/aa.erb
|
75
212
|
- lib/eric_weixin/reply_message.rb
|
76
213
|
- lib/eric_weixin/version.rb
|
77
214
|
homepage: ''
|