module Wechat::Responder
Public Instance Methods
create()
click to toggle source
# File lib/wechat/responder.rb, line 187 def create request_msg = Wechat::Message.from_hash(post_body) response_msg = run_responder(request_msg) if response_msg.respond_to? :to_xml render plain: process_response(response_msg) else head :ok, content_type: 'text/html' end response_msg.save_session if response_msg.is_a?(Wechat::Message) && Wechat.config.have_session_class ActiveSupport::Notifications.instrument 'wechat.responder.after_create', request: request_msg, response: response_msg end
show()
click to toggle source
# File lib/wechat/responder.rb, line 178 def show if @we_corpid.present? echostr, _corp_id = unpack(decrypt(Base64.decode64(params[:echostr]), @we_encoding_aes_key)) render plain: echostr else render plain: params[:echostr] end end
Private Instance Methods
config_account()
click to toggle source
# File lib/wechat/responder.rb, line 204 def config_account account = self.class.account_from_request&.call(request) config = account ? Wechat.config(account) : nil @we_encrypt_mode = config&.encrypt_mode || self.class.encrypt_mode @we_encoding_aes_key = config&.encoding_aes_key || self.class.encoding_aes_key @we_token = config&.token || self.class.token @we_corpid = config&.corpid || self.class.corpid end
gen_msg(encrypt, timestamp, nonce)
click to toggle source
# File lib/wechat/responder.rb, line 292 def gen_msg(encrypt, timestamp, nonce) msg_sign = Signature.hexdigest(@we_token, timestamp, nonce, encrypt) { Encrypt: encrypt, MsgSignature: msg_sign, TimeStamp: timestamp, Nonce: nonce }.to_xml(root: 'xml', children: 'item', skip_instruct: true, skip_types: true) end
post_body()
click to toggle source
# File lib/wechat/responder.rb, line 230 def post_body if request.media_type == 'application/json' data_hash = params if @we_encrypt_mode && data['Encrypt'].present? content, @we_app_id = unpack(decrypt(Base64.decode64(data['Encrypt']), @we_encoding_aes_key)) data_hash = content end data_hash = data_hash.to_unsafe_hash if data_hash.instance_of?(ActionController::Parameters) HashWithIndifferentAccess.new(data_hash).tap do |msg| msg[:Event]&.downcase! end else post_xml end end
post_xml()
click to toggle source
# File lib/wechat/responder.rb, line 248 def post_xml data = request_content if @we_encrypt_mode && request_encrypt_content.present? content, @we_app_id = unpack(decrypt(Base64.decode64(request_encrypt_content), @we_encoding_aes_key)) data = Hash.from_xml(content) end data_hash = data.fetch('xml', {}) data_hash = data_hash.to_unsafe_hash if data_hash.instance_of?(ActionController::Parameters) HashWithIndifferentAccess.new(data_hash).tap do |msg| msg[:Event]&.downcase! end end
process_response(response)
click to toggle source
# File lib/wechat/responder.rb, line 281 def process_response(response) msg = response[:MsgType] == 'success' ? 'success' : response.to_xml if @we_encrypt_mode encrypt = Base64.strict_encode64(encrypt(pack(msg, @we_app_id), @we_encoding_aes_key)) msg = gen_msg(encrypt, params[:timestamp], params[:nonce]) end msg end
request_content()
click to toggle source
# File lib/wechat/responder.rb, line 305 def request_content params[:xml].nil? ? Hash.from_xml(request.raw_post) : { 'xml' => params[:xml] } end
request_encrypt_content()
click to toggle source
# File lib/wechat/responder.rb, line 301 def request_encrypt_content request_content&.dig('xml', 'Encrypt') end
run_responder(request)
click to toggle source
# File lib/wechat/responder.rb, line 263 def run_responder(request) self.class.responder_for(request) do |responder, *args| responder ||= self.class.user_defined_responders(:fallback).first next if responder.nil? if responder[:respond] request.reply.text responder[:respond] elsif responder[:proc] define_singleton_method :process, responder[:proc] number_of_block_parameter = responder[:proc].arity send(:process, *args.unshift(request).take(number_of_block_parameter)) else next end end end
verify_signature()
click to toggle source
# File lib/wechat/responder.rb, line 214 def verify_signature if @we_encrypt_mode signature = params[:signature] || params[:msg_signature] msg_encrypt = params[:echostr] || request_encrypt_content else signature = params[:signature] end msg_encrypt = nil unless @we_corpid.present? render plain: 'Forbidden', status: 403 if signature != Signature.hexdigest(@we_token, params[:timestamp], params[:nonce], msg_encrypt) end