module Wechat::Responder::ClassMethods

Attributes

account_from_request[RW]

Public Instance Methods

on(message_type, with: nil, respond: nil, &block) click to toggle source
# File lib/wechat/responder.rb, line 21
def on(message_type, with: nil, respond: nil, &block)
  config = respond.nil? ? {} : { respond: respond }
  config[:proc] = block if block_given?

  if with.present?
    raise 'Only text, event, click, view, scan and batch_job can having :with parameters' unless %i[text event click view scan batch_job].include?(message_type)

    config[:with] = with
    if message_type == :scan
      raise 'on :scan only support string in parameter with, detail see https://github.com/Eric-Guo/wechat/issues/84' unless with.is_a?(String)

      self.known_scan_key_lists = with
    end
  elsif %i[click view scan batch_job].include?(message_type)
    raise 'Message type click, view, scan and batch_job must specify :with parameters'
  end

  case message_type
  when :click
    user_defined_click_responders(with) << config
  when :view
    user_defined_view_responders(with) << config
  when :batch_job
    user_defined_batch_job_responders(with) << config
  when :scan
    user_defined_scan_responders << config
  when :location
    user_defined_location_responders << config
  when :label_location
    user_defined_label_location_responders << config
  when :change_external_contact
    user_defined_change_external_contact_responders << config
  when :msgaudit_notify
    user_defined_msgaudit_notify_responders << config
  else
    user_defined_responders(message_type) << config
  end

  config
end
responder_for(message) { |* match_responders(responders, message)| ... } click to toggle source
# File lib/wechat/responder.rb, line 102
def responder_for(message)
  message_type = message[:MsgType].to_sym
  responders = user_defined_responders(message_type)

  case message_type
  when :text
    yield(* match_responders(responders, message[:Content]))
  when :event
    if message[:Event] == 'click' && !user_defined_click_responders(message[:EventKey]).empty?
      yield(* user_defined_click_responders(message[:EventKey]), message[:EventKey])
    elsif message[:Event] == 'view' && !user_defined_view_responders(message[:EventKey]).empty?
      yield(* user_defined_view_responders(message[:EventKey]), message[:EventKey])
    elsif message[:Event] == 'click'
      yield(* match_responders(responders, message[:EventKey]))
    elsif known_scan_key_lists.include?(message[:EventKey]) && %w[scan subscribe scancode_push scancode_waitmsg].freeze.include?(message[:Event])
      yield(* known_scan_with_match_responders(user_defined_scan_responders, message))
    elsif message[:Event] == 'batch_job_result'
      yield(* user_defined_batch_job_responders(message[:BatchJob][:JobType]), message[:BatchJob])
    elsif message[:Event] == 'location'
      yield(* user_defined_location_responders, message)
    elsif message[:Event] == 'change_external_contact'
      yield(* user_defined_change_external_contact_responders, message)
    elsif message[:Event] == 'msgaudit_notify'
      yield(* user_defined_msgaudit_notify_responders, message)
    else
      yield(* match_responders(responders, message[:Event]))
    end
  when :location
    yield(* user_defined_label_location_responders, message)
  else
    yield(responders.first)
  end
end
user_defined_batch_job_responders(with) click to toggle source
# File lib/wechat/responder.rb, line 72
def user_defined_batch_job_responders(with)
  @batch_job_responders ||= {}
  @batch_job_responders[with] ||= []
end
user_defined_change_external_contact_responders() click to toggle source
# File lib/wechat/responder.rb, line 89
def user_defined_change_external_contact_responders
  @user_defined_change_external_contact_responders ||= []
end
user_defined_click_responders(with) click to toggle source
# File lib/wechat/responder.rb, line 62
def user_defined_click_responders(with)
  @click_responders ||= {}
  @click_responders[with] ||= []
end
user_defined_label_location_responders() click to toggle source
# File lib/wechat/responder.rb, line 85
def user_defined_label_location_responders
  @user_defined_label_location_responders ||= []
end
user_defined_location_responders() click to toggle source
# File lib/wechat/responder.rb, line 81
def user_defined_location_responders
  @user_defined_location_responders ||= []
end
user_defined_msgaudit_notify_responders() click to toggle source
# File lib/wechat/responder.rb, line 93
def user_defined_msgaudit_notify_responders
  @user_defined_msgaudit_notify_responders ||= []
end
user_defined_responders(type) click to toggle source
# File lib/wechat/responder.rb, line 97
def user_defined_responders(type)
  @responders ||= {}
  @responders[type] ||= []
end
user_defined_scan_responders() click to toggle source
# File lib/wechat/responder.rb, line 77
def user_defined_scan_responders
  @user_defined_scan_responders ||= []
end
user_defined_view_responders(with) click to toggle source
# File lib/wechat/responder.rb, line 67
def user_defined_view_responders(with)
  @view_responders ||= {}
  @view_responders[with] ||= []
end

Private Instance Methods

known_scan_key_lists() click to toggle source
# File lib/wechat/responder.rb, line 168
def known_scan_key_lists
  @known_scan_key_lists ||= []
end
known_scan_key_lists=(qrscene_value) click to toggle source
# File lib/wechat/responder.rb, line 172
def known_scan_key_lists=(qrscene_value)
  @known_scan_key_lists ||= []
  @known_scan_key_lists << qrscene_value
end
known_scan_with_match_responders(responders, message) click to toggle source
# File lib/wechat/responder.rb, line 157
def known_scan_with_match_responders(responders, message)
  matched = responders.each_with_object({}) do |responder, memo|
    if %w[scan subscribe].freeze.include?(message[:Event]) && message[:EventKey] == responder[:with]
      memo[:scaned] ||= [responder, message[:Ticket]]
    elsif %w[scancode_push scancode_waitmsg].freeze.include?(message[:Event]) && message[:EventKey] == responder[:with]
      memo[:scaned] ||= [responder, message[:ScanCodeInfo][:ScanResult], message[:ScanCodeInfo][:ScanType]]
    end
  end
  matched[:scaned]
end
match_responders(responders, value) click to toggle source
# File lib/wechat/responder.rb, line 138
def match_responders(responders, value)
  matched = responders.each_with_object({}) do |responder, memo|
    condition = responder[:with]

    if condition.nil?
      memo[:general] ||= [responder, value]
      next
    end

    case condition
    when Regexp
      memo[:scoped] ||= [responder] + $LAST_MATCH_INFO.captures if value =~ condition
    when value
      memo[:scoped] ||= [responder, value]
    end
  end
  matched[:scoped] || matched[:general]
end