WeixinRailsMiddleware,顾名思义,是供 Rails 使用的微信中间件。帮助你方便地在 Rails 应用中添加微信功能。
安装: bundle intall
安装最新的版本
gem 'weixin_rails_middleware'
或者安装master最新的代码库更新,注意:可能不稳定
gem 'weixin_rails_middleware', git: "https://github.com/lanrion/weixin_rails_middleware.git"
执行 rails generate weixin_rails_middleware:install
, 会生成:
config/initializers/weixin_rails_middleware.rb
app/decorators/controllers/weixin_rails_middleware/weixin_controller_decorator.rb
适用场合
第一种场合:支持多个公众账号,类似微盟的情况:
前往 config/initializers/weixin_rails_middleware.rb
,
config.public_account_class = "PublicAccount"
注意 PublicAccount 是你保存公众账号的Model名字。
如果使用了第一种场合,则需要跑如下命令:
rails generate weixin_rails_middleware:migration public_account_model_name
例子:rails generate weixin_rails_middleware:migration PublicAccount
会生成如下的Migration:
class AddWeixinSecretKeyAndWeixinTokenToPublicAccounts < ActiveRecord::Migration
def self.up
change_table(:public_accounts) do |t|
t.string :weixin_secret_key
t.string :weixin_token
end
add_index :public_accounts, :weixin_secret_key
add_index :public_accounts, :weixin_token
end
def self.down
# By default, we don't want to make any assumption about how to roll back a migration when your
# model already existed. Please edit below which fields you would like to remove in this migration.
raise ActiveRecord::IrreversibleMigration
end
end
然后执行 rake db:migrate
,生成两个字段到数据库。
另外一方面,同时会向你的 app/models/public_accounts.rb
添加一行代码:
include WeixinRailsMiddleware::AutoGenerateWeixinTokenSecretKey
这行代码的作用在于自动生成 weixin_secret_key 和 weixin_token 两个字段的值,建议不要让用户去填写这两个字段的值,让程序自动生成,如果你想自己定制weixin_secret_key 和 weixin_token 两个字段的值,删除include WeixinRailsMiddleware::AutoGenerateWeixinTokenSecretKey
这行代码即可。
第二种场合:只支持个人公众账号,即不需要把公众账号保存到数据库中:
前往 config/initializers/weixin_rails_middleware.rb
,
config.weixin_token_string = 'c06a2a40256fdeb47ff0c7cc'
config.weixin_secret_string = 'J92Eba24yRpG-s9LGYOA03FcnULHYFYs'
weixin_token_string: 微信Token值;
weixin_secret_string: 微信服务URL配置中,此值用来避免真正使用的Token值暴露在URL上,提高安全性。
默认情况下,在生成 weixin_rails_middleware.rb
时,会使用SecureRandom
自动生成 weixin_token_string 和 weixin_secret_string 的值
所以上述的例子,会生成如下的方案:
URL:http://2e13a461.ngrok.com/weixin/J92Eba24yRpG-s9LGYOA03FcnULHYFYs
Token:c06a2a40256fdeb47ff0c7cc
路由
- 生成微信服务器URL
weixin_engine.weixin_server_url(public_account.weixin_secret_key)
- 举个生成微信服务URL与Token的例子:
@public_account
是你保存的其中一个公众账号的实例:
网站的地址为:
http://2e13a461.ngrok.com
weixin_secret_key
的值为 J92Eba24yRpG-s9LGYOA03FcnULHYFYs
weixin_token
的值为 c06a2a40256fdeb47ff0c7cc
则在app/views/public_accounts/show.html.erb
中:
URL:<%= weixin_engine.weixin_server_url(@public_account.weixin_secret_key) %>
Token:<%= @public_account.weixin_token %>
则会生成:
URL:http://2e13a461.ngrok.com/weixin/J92Eba24yRpG-s9LGYOA03FcnULHYFYs
Token:c06a2a40256fdeb47ff0c7cc
即可复制使用到微信服务器配置中。
配置注意事项
注意: 第一种场合和第二种场合,只能任选一种,如果两种同时配置,会默认使用第二种场合。
业务逻辑实现
前往
app/decorators/controllers/weixin_rails_middleware/weixin_controller_decorator.rb
即为:
# encoding: utf-8
# 1: get weixin xml params
# @weixin_message
# 2: public_account_class instance if you setup, otherwise return nil
# @weixin_public_account
WeixinRailsMiddleware::WeixinController.class_eval do
before_filter :set_keyword, only: :reply
def reply
render xml: send("response_#{@weixin_message.MsgType}_message", {})
end
private
def response_text_message(options={})
reply_text_message("Your Message: #{@keyword}")
end
# <Location_X>23.134521</Location_X>
# <Location_Y>113.358803</Location_Y>
# <Scale>20</Scale>
# <Label><![CDATA[位置信息]]></Label>
def response_location_message(options={})
@lx = @weixin_message.Location_X
@ly = @weixin_message.Location_Y
@scale = @weixin_message.Scale
@label = @weixin_message.Label
reply_text_message("Your Location: #{@lx}, #{@ly}, #{@scale}, #{@label}")
end
# <PicUrl><![CDATA[this is a url]]></PicUrl>
# <MediaId><![CDATA[media_id]]></MediaId>
def response_image_message(options={})
@pic_url = @weixin_message.PicUrl
@media_id = @weixin_message.MediaId # 可以调用多媒体文件下载接口拉取数据。
reply_text_message("回复图片信息")
end
# <Title><![CDATA[公众平台官网链接]]></Title>
# <Description><![CDATA[公众平台官网链接]]></Description>
# <Url><![CDATA[url]]></Url>
def response_link_message(options={})
@title = @weixin_message.Title
@desc = @weixin_message.Description
@url = @weixin_message.Url
reply_text_message("回复链接信息")
end
def response_event_message(options={})
event_type = @weixin_message.Event
case event_type
when "subscribe" # 关注公众账号
if @keyword.present?
# 扫描带参数二维码事件: 1. 用户未关注时,进行关注后的事件推送
return reply_text_message("扫描带参数二维码事件: 1. 用户未关注时,进行关注后的事件推送, keyword: #{@keyword}")
end
reply_text_message("关注公众账号")
when "unsubscribe" # 取消关注
reply_text_message("取消关注")
when "SCAN" # 扫描带参数二维码事件: 2用户已关注时的事件推送
reply_text_message("扫描带参数二维码事件: 2用户已关注时的事件推送, keyword: #{@keyword}")
when "LOCATION" # 上报地理位置事件
@lat = @weixin_message.Latitude
@lgt = @weixin_message.Longitude
@precision = @weixin_message.Precision
reply_text_message("Your Location: #{@lat}, #{@lgt}, #{@precision}")
when "CLICK" # 点击菜单拉取消息时的事件推送
reply_text_message("你点击了: #{@keyword}")
when "VIEW" # 点击菜单跳转链接时的事件推送
reply_text_message("你点击了: #{@keyword}")
else
reply_text_message("处理无法识别的事件")
end
end
# <MediaId><![CDATA[media_id]]></MediaId>
# <Format><![CDATA[Format]]></Format>
def response_voice_message(options={})
@media_id = @weixin_message.MediaId # 可以调用多媒体文件下载接口拉取数据。
@format = @weixin_message.Format
reply_text_message("回复语音信息: #{@keyword}")
end
# <MediaId><![CDATA[media_id]]></MediaId>
# <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
def response_video_message(options={})
@media_id = @weixin_message.MediaId # 可以调用多媒体文件下载接口拉取数据。
# 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
@thumb_media_id = @weixin_message.ThumbMediaId
reply_text_message("回复视频信息")
end
def set_keyword
@keyword = @weixin_message.Content || # 文本消息
@weixin_message.EventKey || # 事件推送
@weixin_message.Recognition # 接收语音识别结果
end
# http://apidock.com/rails/ActionController/Base/default_url_options
def default_url_options(options={})
{ weichat_id: @weixin_message.FromUserName }
end
end
或者猛击, 最新以下面链接内容为主: https://github.com/lanrion/weixin_rails_middleware/blob/master/lib/generators/templates/weixin_controller.rb
里面已经做好了微信所有信息类型的逻辑判断,请再结合微信开发文档来使用。
项目主页
https://github.com/lanrion/weixin_rails_middleware
作者介绍
作者 lanrion,目前专注于云计算中,Paas 平台 Cloud Foundry,分布式架构,数据库。少量业余时间会尝试做一些产品。
喜欢钻牛角尖的家伙,喜欢研究乱七八糟的东西。有任何有关 Ruby and Rails、微信开发、PHP、Java、Nodejs的问题,都可以发邮件一起探讨。微信号:dht_ruby
编辑 SegmentFault