weixin_rails_middleware 1.0.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3460a9d1f7aa1a3e99fdc92ce50d3b225553a999
4
+ data.tar.gz: 045d5b32cbbe7ac1ad175d08d27495dd60360f5c
5
+ SHA512:
6
+ metadata.gz: 985aa7b06a951dda574c72500ecec59a2dd001ac82eef9af4c1e3b6e583188da06604b39e24f100a54a0c5d9e2116edc275c4dcac6ae1c9b3527d7e825fc9f01
7
+ data.tar.gz: a2c2ef8e8899dec3945310add57afbc0f8bd798e31c83f3ae150d9e7523f12b39c2eff5a97ea13db888e65a80b9b16aeaa74016cccf37bb8f911402eae7efa9a
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'WeixinRailsMiddleware'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,4 @@
1
+ module WeixinRailsMiddleware
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,63 @@
1
+ module WeixinRailsMiddleware
2
+ class WeixinController < ApplicationController
3
+
4
+ include WeixinMessageHelper
5
+
6
+ skip_before_filter :verify_authenticity_token
7
+ before_action :check_weixin_params, only: [:index, :reply]
8
+
9
+ def index
10
+ render text: params[:echostr]
11
+ end
12
+
13
+ def reply
14
+ end
15
+
16
+ protected
17
+
18
+ def check_weixin_params
19
+ if check_weixin_token_valid?
20
+ if !is_hexdigest?
21
+ render text: "Forbidden", status: 403
22
+ end
23
+ end
24
+ end
25
+
26
+ # check the token from Weixin Service is exist in local store.
27
+ def check_weixin_token_valid?
28
+ if WeixinRailsMiddleware.config.token_string.blank?
29
+ if token_model_instance.blank?
30
+ render text: "Forbidden", status: 403
31
+ return false
32
+ end
33
+ else
34
+ if current_weixin_token != WeixinRailsMiddleware.config.token_string
35
+ render text: "Forbidden", status: 403
36
+ return false
37
+ end
38
+ end
39
+ true
40
+ end
41
+
42
+ def is_hexdigest?
43
+ signature = params[:signature] || ''
44
+ timestamp = params[:timestamp] || ''
45
+ nonce = params[:nonce] || ''
46
+ current_signature = Digest::SHA1.hexdigest([current_weixin_token, timestamp, nonce].sort.join)
47
+ return true if current_signature == signature
48
+ false
49
+ end
50
+
51
+ def current_weixin_token
52
+ @weixin_token = params[:weixin_token]
53
+ end
54
+
55
+ def token_model_instance
56
+ token_model = WeixinRailsMiddleware.config.token_model_class
57
+ token_column = WeixinRailsMiddleware.config.token_column
58
+ token_model_instance = token_model.where("#{token_column}" => current_weixin_token).first
59
+ token_model_instance
60
+ end
61
+
62
+ end
63
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,4 @@
1
+ WeixinRailsMiddleware::Engine.routes.draw do
2
+ get 'weixin/:weixin_token', to: 'weixin#index'
3
+ post 'weixin/:weixin_token', to: 'weixin#reply'
4
+ end
@@ -0,0 +1,20 @@
1
+ # Use this hook to configure WeixinRailsMiddleware bahaviors.
2
+ WeixinRailsMiddleware.configure do |config|
3
+
4
+ ## NOTE:
5
+ ## if you config all them, it will use `token_string` default
6
+ ##
7
+ # Th FIRST configure
8
+ # if you config `token_model`, it will use it to find_by_weixin_token
9
+ # you must config a column name, `weixin_token` default
10
+ # config.token_model = "" # ActiveRecord subclass or other ORM subclass
11
+ # config.token_column = "weixin_token"
12
+
13
+ # OR the SECOND configure
14
+ # if you config `token_string`, so it will directly use it
15
+ # config.token_string = "token string"
16
+
17
+ # router
18
+ config.engine_path = "/"
19
+
20
+ end
@@ -0,0 +1,27 @@
1
+ WeixinRailsMiddleware::WeixinController.class_eval do
2
+
3
+ def reply
4
+ # Get the current_message
5
+ current_message = current_weixin_message
6
+
7
+ case current_message.MsgType
8
+ when 'text'
9
+ # text message handler
10
+ # render xml: reply_text_message("ToUserName", "FromUserName", "your Message")
11
+ when 'image'
12
+ # image message handler
13
+ when 'location'
14
+ # location message handler
15
+ when 'link'
16
+ # link message handler
17
+ when 'event'
18
+ # event messge handler
19
+ when 'voice'
20
+ # voice message handler
21
+ when 'video'
22
+ # video message handler
23
+ else
24
+ render xml: reply_text_message(current_message.ToUserName, current_message.FromUserName, 'Unknow message')
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ # Rails::Generators::Base dont need a name
2
+ # Rails::Generators::NamedBase need a name
3
+ module WeixinRailsMiddleware
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path('../../templates', __FILE__)
7
+
8
+ desc 'Creates a Dashing initializer for your application.'
9
+
10
+ def install
11
+ route 'mount WeixinRailsMiddleware::Engine, at: WeixinRailsMiddleware.config.engine_path'
12
+ end
13
+
14
+ def copy_initializer
15
+ template 'initializer.rb', 'config/initializers/weixin_rails_middleware.rb'
16
+ end
17
+
18
+ def configure_application
19
+ application <<-APP
20
+ config.to_prepare do
21
+ # Load application's model / class decorators
22
+ Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c|
23
+ Rails.configuration.cache_classes ? require(c) : load(c)
24
+ end
25
+ end
26
+ APP
27
+ end
28
+
29
+ def copy_decorators
30
+ template 'weixin_controller.rb', 'app/decorators/controllers/weixin_rails_middleware/weixin_controller_decorator.rb'
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :weixin_rails_middleware do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,27 @@
1
+ require "weixin_rails_middleware/engine"
2
+ require "weixin_rails_middleware/configuration"
3
+ require "weixin_rails_middleware/message"
4
+ require "weixin_rails_middleware/reply_message"
5
+ require "weixin_rails_middleware/weixin_message_helper"
6
+
7
+ module WeixinRailsMiddleware
8
+
9
+ DEFAULT_TOKEN_COLUMN_NAME = "weixin_token".freeze
10
+ DEFAULT_ENGINE_PATH = "/weixin_rails".freeze
11
+
12
+ class << self
13
+
14
+ attr_accessor :configuration
15
+
16
+ def config
17
+ self.configuration ||= Configuration.new
18
+ end
19
+
20
+ def configure
21
+ yield config if block_given?
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+
@@ -0,0 +1,22 @@
1
+ module WeixinRailsMiddleware
2
+ class Configuration
3
+ # use 'token_model': if the token is saved in SomeModel, then find token by it
4
+ # use 'token_string': if the token is a String, just use it,
5
+ attr_accessor :token_model, :token_column, :token_string, :engine_path
6
+
7
+ def initialize
8
+ @engine_path = DEFAULT_ENGINE_PATH
9
+ @token_column = DEFAULT_TOKEN_COLUMN_NAME
10
+ end
11
+
12
+ def token_model_class
13
+ raise "You need to config `token_model` in config/initializers/weixin_rails_middleware.rb" if token_model.blank?
14
+ token_model_c = token_model.constantize
15
+ unless token_model_c.table_exists?
16
+ raise "You don't have #{token_model_c.table_name} table"
17
+ end
18
+ token_model_c
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ module WeixinRailsMiddleware
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace WeixinRailsMiddleware
4
+ end
5
+ end
@@ -0,0 +1,160 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # ref: https://github.com/wolfg1969/rack-weixin/lib/weixin/model.rb
3
+ require 'roxml'
4
+ require 'multi_xml'
5
+ require 'ostruct'
6
+
7
+ module WeixinRailsMiddleware
8
+
9
+ class Message
10
+
11
+ def initialize(hash)
12
+ @source = OpenStruct.new(hash)
13
+ end
14
+
15
+ def method_missing(method, *args, &block)
16
+ @source.send(method, *args, &block)
17
+ end
18
+
19
+ def CreateTime
20
+ @source.CreateTime.to_i
21
+ end
22
+
23
+ def MsgId
24
+ @source.MsgId.to_i
25
+ end
26
+
27
+ def Message.factory(xml)
28
+ hash = MultiXml.parse(xml)['xml']
29
+ case hash['MsgType']
30
+ when 'text'
31
+ TextMessage.new(hash)
32
+ when 'image'
33
+ ImageMessage.new(hash)
34
+ when 'location'
35
+ LocationMessage.new(hash)
36
+ when 'link'
37
+ LinkMessage.new(hash)
38
+ when 'event'
39
+ EventMessage.new(hash)
40
+ when 'voice'
41
+ VoiceMessage.new(hash)
42
+ when 'video'
43
+ VideoMessage.new(hash)
44
+ else
45
+ raise ArgumentError, 'Unknown Message'
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+ # <xml>
52
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
53
+ # <FromUserName><![CDATA[fromUser]]></FromUserName>
54
+ # <CreateTime>1348831860</CreateTime>
55
+ # <MsgType><![CDATA[text]]></MsgType>
56
+ # <Content><![CDATA[this is a test]]></Content>
57
+ # <MsgId>1234567890123456</MsgId>
58
+ # </xml>
59
+ TextMessage = Class.new(Message)
60
+
61
+ # <xml>
62
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
63
+ # <FromUserName><![CDATA[fromUser]]></FromUserName>
64
+ # <CreateTime>1348831860</CreateTime>
65
+ # <MsgType><![CDATA[image]]></MsgType>
66
+ # <PicUrl><![CDATA[this is a url]]></PicUrl>
67
+ # <MsgId>1234567890123456</MsgId>
68
+ # </xml>
69
+ ImageMessage = Class.new(Message)
70
+
71
+ # <xml>
72
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
73
+ # <FromUserName><![CDATA[fromUser]]></FromUserName>
74
+ # <CreateTime>1351776360</CreateTime>
75
+ # <MsgType><![CDATA[link]]></MsgType>
76
+ # <Title><![CDATA[公众平台官网链接]]></Title>
77
+ # <Description><![CDATA[公众平台官网链接]]></Description>
78
+ # <Url><![CDATA[url]]></Url>
79
+ # <MsgId>1234567890123456</MsgId>
80
+ # </xml>
81
+ LinkMessage = Class.new(Message)
82
+
83
+ # <xml>
84
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
85
+ # <FromUserName><![CDATA[FromUser]]></FromUserName>
86
+ # <CreateTime>123456789</CreateTime>
87
+ # <MsgType><![CDATA[event]]></MsgType>
88
+ # <Event><![CDATA[EVENT]]></Event>
89
+ # <EventKey><![CDATA[EVENTKEY]]></EventKey>
90
+ # </xml>
91
+ EventMessage = Class.new(Message)
92
+
93
+ # <xml>
94
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
95
+ # <FromUserName><![CDATA[fromUser]]></FromUserName>
96
+ # <CreateTime>1351776360</CreateTime>
97
+ # <MsgType><![CDATA[location]]></MsgType>
98
+ # <Location_X>23.134521</Location_X>
99
+ # <Location_Y>113.358803</Location_Y>
100
+ # <Scale>20</Scale>
101
+ # <Label><![CDATA[位置信息]]></Label>
102
+ # <MsgId>1234567890123456</MsgId>
103
+ # </xml>
104
+ class LocationMessage < Message
105
+
106
+ def Location_X
107
+ @source.Location_X.to_f
108
+ end
109
+
110
+ def Location_Y
111
+ @source.Location_Y.to_f
112
+ end
113
+
114
+ def Scale
115
+ @source.Scale.to_i
116
+ end
117
+ end
118
+
119
+ # <xml>
120
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
121
+ # <FromUserName><![CDATA[fromUser]]></FromUserName>
122
+ # <CreateTime>1376632760</CreateTime>
123
+ # <MsgType><![CDATA[voice]]></MsgType>
124
+ # <MediaId><![CDATA[Qyb0tgux6QLjhL6ipvFZJ-kUt2tcQtkn0BU365Vt3wUAtqfGam4QpZU35RXVhv6G]]></MediaId>
125
+ # <Format><![CDATA[amr]]></Format>
126
+ # <MsgId>5912592682802219078</MsgId>
127
+ # <Recognition><![CDATA[]]></Recognition>
128
+ # </xml>
129
+ class VoiceMessage < Message
130
+
131
+ def MediaId
132
+ @source.MediaId
133
+ end
134
+
135
+ def Format
136
+ @source.Format
137
+ end
138
+ end
139
+
140
+ # <xml>
141
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
142
+ # <FromUserName><![CDATA[fromUser]]></FromUserName>
143
+ # <CreateTime>1376632994</CreateTime>
144
+ # <MsgType><![CDATA[video]]></MsgType>
145
+ # <MediaId><![CDATA[TAAGb6iS5LcZR1d5ICiZTWGWi6-Upic9tlWDpAKcNJA]]></MediaId>
146
+ # <ThumbMediaId><![CDATA[U-xulPW4kq6KKMWFNaBSPc65Bcgr7Qopwex0DfCeyQs]]></ThumbMediaId>
147
+ # <MsgId>5912593687824566343</MsgId>
148
+ # </xml>
149
+ class VideoMessage < Message
150
+
151
+ def MediaId
152
+ @source.MediaId
153
+ end
154
+
155
+ def ThumbMediaId
156
+ @source.ThumbMediaId
157
+ end
158
+ end
159
+
160
+ end
@@ -0,0 +1,183 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # ref: https://github.com/wolfg1969/rack-weixin/lib/weixin/model.rb
3
+ require 'roxml'
4
+
5
+ module WeixinRailsMiddleware
6
+
7
+ class ReplyMessage
8
+ include ROXML
9
+ xml_name :xml
10
+ #xml_convention :camelcase
11
+
12
+ xml_accessor :ToUserName, :cdata => true
13
+ xml_accessor :FromUserName, :cdata => true
14
+ xml_reader :CreateTime, :as => Integer
15
+ xml_reader :MsgType, :cdata => true
16
+
17
+ def initialize
18
+ @CreateTime = Time.now.to_i
19
+ end
20
+
21
+ def to_xml
22
+ super.to_xml(:encoding => 'UTF-8', :indent => 0, :save_with => 0)
23
+ end
24
+ end
25
+
26
+ # <xml>
27
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
28
+ # <FromUserName><![CDATA[fromUser]]></FromUserName>
29
+ # <CreateTime>12345678</CreateTime>
30
+ # <MsgType><![CDATA[text]]></MsgType>
31
+ # <Content><![CDATA[Hello]]></Content>
32
+ # </xml>
33
+
34
+ class TextReplyMessage < ReplyMessage
35
+ xml_accessor :Content, :cdata => true
36
+ def initialize
37
+ super
38
+ @MsgType = 'text'
39
+ end
40
+ end
41
+
42
+ class Music
43
+ include ROXML
44
+ xml_accessor :Title, :cdata => true
45
+ xml_accessor :Description, :cdata => true
46
+ xml_accessor :MusicUrl, :cdata => true
47
+ xml_accessor :HQMusicUrl, :cdata => true
48
+ end
49
+
50
+ # <xml>
51
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
52
+ # <FromUserName><![CDATA[fromUser]]></FromUserName>
53
+ # <CreateTime>12345678</CreateTime>
54
+ # <MsgType><![CDATA[music]]></MsgType>
55
+ # <Music>
56
+ # <Title><![CDATA[TITLE]]></Title>
57
+ # <Description><![CDATA[DESCRIPTION]]></Description>
58
+ # <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl>
59
+ # <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
60
+ # <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId>
61
+ # </Music>
62
+ # </xml>
63
+
64
+ class MusicReplyMessage < ReplyMessage
65
+ xml_accessor :Music, :as => Music
66
+ def initialize
67
+ super
68
+ @MsgType = 'music'
69
+ end
70
+ end
71
+
72
+ class Article
73
+ include ROXML
74
+ xml_accessor :Title, :cdata => true
75
+ xml_accessor :Description, :cdata => true
76
+ xml_accessor :PicUrl, :cdata => true
77
+ xml_accessor :Url, :cdata => true
78
+ end
79
+
80
+ # <xml>
81
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
82
+ # <FromUserName><![CDATA[fromUser]]></FromUserName>
83
+ # <CreateTime>12345678</CreateTime>
84
+ # <MsgType><![CDATA[news]]></MsgType>
85
+ # <ArticleCount>2</ArticleCount>
86
+ # <Articles>
87
+ # <item>
88
+ # <Title><![CDATA[title1]]></Title>
89
+ # <Description><![CDATA[description1]]></Description>
90
+ # <PicUrl><![CDATA[picurl]]></PicUrl>
91
+ # <Url><![CDATA[url]]></Url>
92
+ # </item>
93
+ # <item>
94
+ # <Title><![CDATA[title]]></Title>
95
+ # <Description><![CDATA[description]]></Description>
96
+ # <PicUrl><![CDATA[picurl]]></PicUrl>
97
+ # <Url><![CDATA[url]]></Url>
98
+ # </item>
99
+ # </Articles>
100
+ # </xml>
101
+
102
+ class NewsReplyMessage < ReplyMessage
103
+ xml_accessor :ArticleCount, :as => Integer
104
+ xml_accessor :Articles, :as => [Article], :in => 'Articles', :from => 'item'
105
+ def initialize
106
+ super
107
+ @MsgType = 'news'
108
+ end
109
+ end
110
+
111
+ # <xml>
112
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
113
+ # <FromUserName><![CDATA[fromUser]]></FromUserName>
114
+ # <CreateTime>12345678</CreateTime>
115
+ # <MsgType><![CDATA[video]]></MsgType>
116
+ # <Video>
117
+ # <MediaId><![CDATA[media_id]]></MediaId>
118
+ # <Title><![CDATA[title]]></Title>
119
+ # <Description><![CDATA[description]]></Description>
120
+ # </Video>
121
+ # </xml>
122
+
123
+ class Video
124
+ include ROXML
125
+ xml_accessor :MediaId, :cdata => true
126
+ xml_accessor :Description, :cdata => true
127
+ xml_accessor :Title, :cdata => true
128
+ end
129
+
130
+ class VideoReplyMessage < ReplyMessage
131
+ xml_accessor :Video, :as => Video
132
+ def initialize
133
+ super
134
+ @MsgType = 'video'
135
+ end
136
+ end
137
+
138
+ # <xml>
139
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
140
+ # <FromUserName><![CDATA[fromUser]]></FromUserName>
141
+ # <CreateTime>12345678</CreateTime>
142
+ # <MsgType><![CDATA[voice]]></MsgType>
143
+ # <Voice>
144
+ # <MediaId><![CDATA[media_id]]></MediaId>
145
+ # </Voice>
146
+ # </xml>
147
+ class Voice
148
+ include ROXML
149
+ xml_accessor :MediaId, :cdata => true
150
+ end
151
+
152
+ class VoiceReplyMessage < ReplyMessage
153
+ xml_accessor :Voice, :as => Voice
154
+ def initialize
155
+ super
156
+ @MsgType = 'voice'
157
+ end
158
+ end
159
+
160
+ # <xml>
161
+ # <ToUserName><![CDATA[toUser]]></ToUserName>
162
+ # <FromUserName><![CDATA[fromUser]]></FromUserName>
163
+ # <CreateTime>12345678</CreateTime>
164
+ # <MsgType><![CDATA[image]]></MsgType>
165
+ # <Image>
166
+ # <MediaId><![CDATA[media_id]]></MediaId>
167
+ # </Image>
168
+ # </xml>
169
+
170
+ class Image
171
+ include ROXML
172
+ xml_accessor :MediaId, :cdata => true
173
+ end
174
+
175
+ class ImageReplyMessage < ReplyMessage
176
+ xml_accessor :Image, :as => Image
177
+ def initialize
178
+ super
179
+ @MsgType = 'image'
180
+ end
181
+ end
182
+
183
+ end
@@ -0,0 +1,3 @@
1
+ module WeixinRailsMiddleware
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,97 @@
1
+ module WeixinRailsMiddleware
2
+ module WeixinMessageHelper
3
+
4
+ def reply_text_message(from, to, content)
5
+ message = TextReplyMessage.new
6
+ message.ToUserName = to
7
+ message.FromUserName = from
8
+ message.Content = content
9
+ message.to_xml
10
+ end
11
+
12
+ def generate_music(title, desc, music_url, hq_music_url)
13
+ music = Music.new
14
+ music.Title = title
15
+ music.Description = desc
16
+ music.MusicUrl = music_url
17
+ music.HQMusicUrl = hq_music_url
18
+ music
19
+ end
20
+
21
+ # music = generate_music
22
+ def reply_music_message(from, to, music)
23
+ message = MusicReplyMessage.new
24
+ message.ToUserName = to
25
+ message.FromUserName = from
26
+ message.Music = music
27
+ message.to_xml
28
+ end
29
+
30
+ def generate_article(title, desc, pic_url, link_url)
31
+ item = Article.new
32
+ item.Title = title
33
+ item.Description = desc
34
+ item.PicUrl = pic_url
35
+ item.Url = link_url
36
+ item
37
+ end
38
+
39
+ # articles = [generate_article]
40
+ def reply_news_message(from, to, articles)
41
+ message = NewsReplyMessage.new
42
+ message.ToUserName = to
43
+ message.FromUserName = from
44
+ message.Articles = articles
45
+ message.ArticleCount = articles.count
46
+ message.to_xml
47
+ end
48
+
49
+ def generate_video(media_id, desc, title)
50
+ video = Video.new
51
+ video.MediaId = media_id
52
+ video.Description = desc
53
+ video.Title = title
54
+ vodeo
55
+ end
56
+
57
+ def replay_video_message(video)
58
+ message = VideoReplyMessage.new
59
+ message.Video = video
60
+ message.to_xml
61
+ end
62
+
63
+ def generate_voice(media_id)
64
+ voice = Voice.new
65
+ voice.MediaId = media_id
66
+ voice
67
+ end
68
+
69
+ def reply_voice_message(voice)
70
+ message = VoiceReplyMessage.new
71
+ message.Voice = voice
72
+ message.to_xml
73
+ end
74
+
75
+ def generate_image(media_id)
76
+ image = Image.new
77
+ image.MediaId = media_id
78
+ image
79
+ end
80
+
81
+ def reply_imgage_message(image)
82
+ message = ImageReplyMessage.new
83
+ message.Image = image
84
+ end
85
+
86
+ # take the weixin params
87
+ def current_weixin_params
88
+ request.body.read
89
+ end
90
+
91
+ # return a message class with current_weixin_params
92
+ def current_weixin_message
93
+ Message.factory(current_weixin_params)
94
+ end
95
+
96
+ end
97
+ end
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: weixin_rails_middleware
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - DylanDeng
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.6.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.6.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '3.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '3.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: multi_json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.7.9
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: 1.7.9
69
+ - !ruby/object:Gem::Dependency
70
+ name: multi_xml
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: 0.5.2
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: 0.5.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: roxml
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: weixin_rails_middleware for integration weixin develop
98
+ email:
99
+ - dylan@beansmile.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - app/controllers/weixin_rails_middleware/application_controller.rb
105
+ - app/controllers/weixin_rails_middleware/weixin_controller.rb
106
+ - config/routes.rb
107
+ - lib/generators/templates/initializer.rb
108
+ - lib/generators/templates/weixin_controller.rb
109
+ - lib/generators/weixin_rails_middleware/install_generator.rb
110
+ - lib/tasks/weixin_rails_middleware_tasks.rake
111
+ - lib/weixin_rails_middleware/configuration.rb
112
+ - lib/weixin_rails_middleware/engine.rb
113
+ - lib/weixin_rails_middleware/message.rb
114
+ - lib/weixin_rails_middleware/reply_message.rb
115
+ - lib/weixin_rails_middleware/version.rb
116
+ - lib/weixin_rails_middleware/weixin_message_helper.rb
117
+ - lib/weixin_rails_middleware.rb
118
+ - MIT-LICENSE
119
+ - Rakefile
120
+ homepage: http://github.com/lanrion/weixin_rails_middleware
121
+ licenses: []
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.0.3
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: weixin_rails_middleware for integration weixin
143
+ test_files: []