eric_weixin 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bfd1ad73e2c07c9614f92be9fc53ced6059859e9
4
- data.tar.gz: 7658834815335b3723186e52f0546787736de194
3
+ metadata.gz: b91a2c0afb290cba50cce75c285a32de4bee430e
4
+ data.tar.gz: f67c0af9428bb0211ba40747cbc702852d0b4ba8
5
5
  SHA512:
6
- metadata.gz: 84bf69956c75342322bd1f7e0069a33a68a9440a04003b2f9c9aed9407964864cc66f4d534fbdb5e12a8c3348c209d95610cdc1b21581aa937475482b5de43cd
7
- data.tar.gz: 7e6571b876eea85d559b0ca791e8ae1d5c9addde8f8f09e0543aa23dc41ce8be2f6ca57440448c9c3f9d43c53da5073e2648cf865ee661c15e77c80ec1220185
6
+ metadata.gz: 023d60c77b3855d6daec7e27d850bf5de60991df7b111af34920b87b06eb437fe6b180cca91767e606b6b8dee0f49e6bc6b76246de9ce4f1ad83714ce653e609
7
+ data.tar.gz: 884acba9ee05601fdac7d7cd6dc6f59ceb1edeb7bbfef3db0a9f2054b4baf2e6947a89450e8c72a71a578ed32608bd4702c45dbd48b618ac09e2f323a4ea35c4
@@ -14,9 +14,9 @@
14
14
  </component>
15
15
  <component name="NewModuleRootManager">
16
16
  <content url="file://$MODULE_DIR$" />
17
- <orderEntry type="inheritedJdk" />
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
@@ -13,11 +13,11 @@ module EricWeixin
13
13
  # ===参数说明
14
14
  # * ToUserName: 收取方的账号
15
15
  # * FromUserName: 开发者账号
16
- # * news: 文章列表,Weixin::Article 的实例数组
16
+ # * news: 文章列表,EricWeixin::Article 的实例数组
17
17
  # ===示例
18
- # Tools::Weixin::ReplyMessage::get_reply_user_message_image_text ToUserName: 'xx',
18
+ # Tools::EricWeixin::ReplyMessage::get_reply_user_message_image_text ToUserName: 'xx',
19
19
  # FromUserName: 'yy',
20
- # news:[Weixin::ArticleData.new]
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::Weixin::ReplyMessage.get_reply_user_message_text ToUserName: 'xx',
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
- # Tools::Weixin::ReplyMessage::transfer_mult_customer_service ToUserName: 'xxx',
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|
@@ -1,3 +1,3 @@
1
1
  module EricWeixin
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
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
- # Your code goes here...
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.1
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-04 00:00:00.000000000 Z
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: ''