simple_wx 0.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 +7 -0
- data/.gitignore +23 -0
- data/README.md +22 -0
- data/config/initializers/simple_wx.rb.example +5 -0
- data/lib/simple_wx/access_token.rb +79 -0
- data/lib/simple_wx/base.rb +37 -0
- data/lib/simple_wx/menu.rb +73 -0
- data/lib/simple_wx/message.rb +59 -0
- data/lib/simple_wx/messages/image_message.rb +23 -0
- data/lib/simple_wx/messages/text_message.rb +23 -0
- data/lib/simple_wx/o_auth.rb +82 -0
- data/lib/simple_wx/signaturer.rb +31 -0
- data/lib/simple_wx/user_info.rb +49 -0
- data/lib/simple_wx/version.rb +3 -0
- data/lib/simple_wx.rb +31 -0
- data/simple_wx.gemspec +25 -0
- metadata +101 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 3352241216ce336988e4fa27a330ba1d723e0558
         | 
| 4 | 
            +
              data.tar.gz: e07e3618c8533fdf0afae69d27b08ea7b554f6a5
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: ca678fc595eef2f1424dd3b6b34c21d1577ff80c03b6e6300e22ddc5cb1798b97276fb7fd28c14c01d1853cac726164082233f1b0bdd78df712242e56c4575d2
         | 
| 7 | 
            +
              data.tar.gz: cb8a81f1373d22ab77a7e5cbb38cfe9cb6a5d8a34218cccd6c3501486e653ac81c402d1beed8e8dd8cc04ca8c0a8c76461f07d17662f08c70dfae47dca026437
         | 
    
        data/.gitignore
    ADDED
    
    | @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            *.gem
         | 
| 2 | 
            +
            *.rbc
         | 
| 3 | 
            +
            .bundle
         | 
| 4 | 
            +
            .config
         | 
| 5 | 
            +
            .yardoc
         | 
| 6 | 
            +
            Gemfile.lock
         | 
| 7 | 
            +
            InstalledFiles
         | 
| 8 | 
            +
            _yardoc
         | 
| 9 | 
            +
            coverage
         | 
| 10 | 
            +
            doc/
         | 
| 11 | 
            +
            lib/bundler/man
         | 
| 12 | 
            +
            pkg
         | 
| 13 | 
            +
            rdoc
         | 
| 14 | 
            +
            spec/reports
         | 
| 15 | 
            +
            test/tmp
         | 
| 16 | 
            +
            test/version_tmp
         | 
| 17 | 
            +
            tmp
         | 
| 18 | 
            +
            *.bundle
         | 
| 19 | 
            +
            *.so
         | 
| 20 | 
            +
            *.o
         | 
| 21 | 
            +
            *.a
         | 
| 22 | 
            +
            mkmf.log
         | 
| 23 | 
            +
            /.idea
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            ## initializers/simple_wx.rb:
         | 
| 2 | 
            +
            ```
         | 
| 3 | 
            +
              WeixinSetting = YAML.load_file(File.join "#{Rails.root}", "config", "weixin.yml")[Rails.env || "development"]
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              module SimpleWx
         | 
| 6 | 
            +
                @@weixin_config = YAML.load_file(File.join "#{Rails.root}", "config", "weixin.yml")[Rails.env || "development"]
         | 
| 7 | 
            +
                @@logger = Rails.logger
         | 
| 8 | 
            +
                @@redis  = Redis::Objects.redis
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
            ```
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            ## config/weixin.yml:
         | 
| 13 | 
            +
            ```
         | 
| 14 | 
            +
              development:
         | 
| 15 | 
            +
                app_id: app_id
         | 
| 16 | 
            +
                app_secret: app_secret
         | 
| 17 | 
            +
                serial_no: 微信号 (gh...)
         | 
| 18 | 
            +
                token: token
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              production:
         | 
| 21 | 
            +
                # ...
         | 
| 22 | 
            +
            ```
         | 
| @@ -0,0 +1,79 @@ | |
| 1 | 
            +
            module SimpleWx
         | 
| 2 | 
            +
              class AccessToken < Base
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                ### Usage
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                # ---------- class-methods ----------
         | 
| 7 | 
            +
                #
         | 
| 8 | 
            +
                # SimpleWx::AccessToken.access_token
         | 
| 9 | 
            +
                # SimpleWx::AccessToken.server_ip
         | 
| 10 | 
            +
                # SimpleWx::AccessToken.jsapi_ticket
         | 
| 11 | 
            +
                #
         | 
| 12 | 
            +
                # ---------- instance-methods -----------
         | 
| 13 | 
            +
                #
         | 
| 14 | 
            +
                # at = SimpleWx::AccessToken.new
         | 
| 15 | 
            +
                # at.access_token
         | 
| 16 | 
            +
                # at.server_ip
         | 
| 17 | 
            +
                # if at.error.present?
         | 
| 18 | 
            +
                #   ...
         | 
| 19 | 
            +
                # end
         | 
| 20 | 
            +
                #
         | 
| 21 | 
            +
             | 
| 22 | 
            +
             | 
| 23 | 
            +
                def server_ip
         | 
| 24 | 
            +
                  url = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=#{access_token}"
         | 
| 25 | 
            +
                  response = RestClient.get url
         | 
| 26 | 
            +
                  response_json = errcode_check(JSON.parse(response))
         | 
| 27 | 
            +
                  @server_ip = response_json["ip_list"]
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def access_token
         | 
| 31 | 
            +
                  SimpleWx.redis.exists("__weixin_access_token__") ? \
         | 
| 32 | 
            +
                  SimpleWx.redis.get("__weixin_access_token__") : get_new_token
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def jsapi_ticket
         | 
| 36 | 
            +
                  SimpleWx.redis.exists("__jsapi_ticket__") ? \
         | 
| 37 | 
            +
                  SimpleWx.redis.get("__jsapi_ticket__") : get_new_jsapi_ticket
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                private
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def get_new_jsapi_ticket
         | 
| 43 | 
            +
                  url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=#{access_token}&type=jsapi"
         | 
| 44 | 
            +
                  response = RestClient.get url
         | 
| 45 | 
            +
                  response_json = errcode_check(JSON.parse(response))
         | 
| 46 | 
            +
                  jsapi_ticket = response_json["ticket"]
         | 
| 47 | 
            +
                  if @error.blank?
         | 
| 48 | 
            +
                    SimpleWx.redis.multi do
         | 
| 49 | 
            +
                      SimpleWx.redis.set "__jsapi_ticket__", jsapi_ticket
         | 
| 50 | 
            +
                      SimpleWx.redis.expire "__jsapi_ticket__", 30.minutes.to_i
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
                  jsapi_ticket
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def get_new_token
         | 
| 57 | 
            +
                  url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=#{SimpleWx.weixin_config["app_id"]}&secret=#{SimpleWx.weixin_config["app_secret"]}"
         | 
| 58 | 
            +
                  response = RestClient.get url
         | 
| 59 | 
            +
                  response_json = errcode_check(JSON.parse(response))
         | 
| 60 | 
            +
                  access_token = response_json["access_token"]
         | 
| 61 | 
            +
                  if @error.blank?
         | 
| 62 | 
            +
                    SimpleWx.redis.multi do
         | 
| 63 | 
            +
                      SimpleWx.redis.set "__weixin_access_token__", access_token
         | 
| 64 | 
            +
                      SimpleWx.redis.expire "__weixin_access_token__", 30.minutes.to_i
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                  access_token
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                def self.method_missing m
         | 
| 71 | 
            +
                  instance = self.new
         | 
| 72 | 
            +
                  if instance.public_methods(false).include? m.to_sym
         | 
| 73 | 
            +
                    return instance.send(m)
         | 
| 74 | 
            +
                  else
         | 
| 75 | 
            +
                    super
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
            end
         | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            module SimpleWx
         | 
| 2 | 
            +
              class Base
         | 
| 3 | 
            +
                attr_accessor :error, :raise_flag
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize options = {}
         | 
| 6 | 
            +
                  raise 'SimpleWx.weixin_config is blank.' if SimpleWx.weixin_config.blank?
         | 
| 7 | 
            +
                  @raise_flag = options[:raise_flag]
         | 
| 8 | 
            +
                  @log_flag = options[:log_flag]
         | 
| 9 | 
            +
                  @error = {}
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                protected
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def errcode_check json, log_flag = nil
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  # 每次执行刷新 @error
         | 
| 17 | 
            +
                  # 根据 log_flag 打印日志
         | 
| 18 | 
            +
                  # 检查是否直接抛错
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  @error = {}
         | 
| 21 | 
            +
                  raise "Responsed nothing from Weixin" if json.nil? && @raise_flag
         | 
| 22 | 
            +
                  if json["errcode"].present? && json["errcode"].to_i != 0
         | 
| 23 | 
            +
                    SimpleWx.logger.error(json)
         | 
| 24 | 
            +
                    @error = json
         | 
| 25 | 
            +
                    raise "Weixin response json with errcode: #{json}" if @raise_flag
         | 
| 26 | 
            +
                  else
         | 
| 27 | 
            +
                    if log_flag
         | 
| 28 | 
            +
                      SimpleWx.logger.info("SimpleWxLog:#{self.class.name} -- #{log_flag} -- #{json}")
         | 
| 29 | 
            +
                    else
         | 
| 30 | 
            +
                      SimpleWx.logger.debug("SimpleWxLog:#{self.class.name} -- #{json}")
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                  json
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
| @@ -0,0 +1,73 @@ | |
| 1 | 
            +
            module SimpleWx
         | 
| 2 | 
            +
              class Menu < Base
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                ### Usage
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                # ---------- class-methods ----------
         | 
| 7 | 
            +
                #
         | 
| 8 | 
            +
                # SimpleWx::Menu.show
         | 
| 9 | 
            +
                # SimpleWx::Menu.create(buttons)
         | 
| 10 | 
            +
                # => true/false
         | 
| 11 | 
            +
                # SimpleWx::Menu.delete
         | 
| 12 | 
            +
                # => true/false
         | 
| 13 | 
            +
                #
         | 
| 14 | 
            +
                # ---------- instance-methods -----------
         | 
| 15 | 
            +
                #
         | 
| 16 | 
            +
                # menu = SimpleWx::Menu.new
         | 
| 17 | 
            +
                # menu.show
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                # if menu.create(buttons)
         | 
| 20 | 
            +
                #   ...
         | 
| 21 | 
            +
                # else
         | 
| 22 | 
            +
                #  p menu.error
         | 
| 23 | 
            +
                # end
         | 
| 24 | 
            +
                #
         | 
| 25 | 
            +
                # menu.delete!
         | 
| 26 | 
            +
                # when "errcode" existed in json of response, it will raise the error:
         | 
| 27 | 
            +
                # => "Weixin response json with errcode: #{json}"
         | 
| 28 | 
            +
                #
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def initialize options = {}
         | 
| 31 | 
            +
                  @access_token = options[:access_token] || AccessToken.access_token
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def show
         | 
| 35 | 
            +
                  url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=#{@access_token}"
         | 
| 36 | 
            +
                  response = RestClient.get url
         | 
| 37 | 
            +
                  response_json = errcode_check(JSON.parse(response))
         | 
| 38 | 
            +
                  @menus = response_json["menu"]
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def create menu_hash
         | 
| 42 | 
            +
                  url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=#{@access_token}"
         | 
| 43 | 
            +
                  response = RestClient.post(url, JSON.generate({button: menu_hash}))
         | 
| 44 | 
            +
                  errcode_check(JSON.parse(response))
         | 
| 45 | 
            +
                  @error.blank?
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def delete
         | 
| 49 | 
            +
                  url = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=#{@access_token}"
         | 
| 50 | 
            +
                  response = RestClient.get url
         | 
| 51 | 
            +
                  errcode_check(JSON.parse(response))
         | 
| 52 | 
            +
                  @error.blank?
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                def create! menu_hash
         | 
| 56 | 
            +
                  @raise_flag ||= true
         | 
| 57 | 
            +
                  create menu_hash
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def delete!
         | 
| 61 | 
            +
                  @raise_flag ||= true
         | 
| 62 | 
            +
                  delete
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                def self.method_missing m, *args
         | 
| 66 | 
            +
                  if instance_methods.include? m.to_sym
         | 
| 67 | 
            +
                    self.new.send(m, *args)
         | 
| 68 | 
            +
                  else
         | 
| 69 | 
            +
                    super
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
            end
         | 
| @@ -0,0 +1,59 @@ | |
| 1 | 
            +
            module SimpleWx
         | 
| 2 | 
            +
              class Message < Base
         | 
| 3 | 
            +
                attr_accessor :openid, :json, :xml
         | 
| 4 | 
            +
                def initialize options
         | 
| 5 | 
            +
                  @openid = options.delete(:openid)
         | 
| 6 | 
            +
                  @access_token = options.delete(:access_token) || AccessToken.access_token
         | 
| 7 | 
            +
                  @custom_msg_url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=#{@access_token}"
         | 
| 8 | 
            +
                  @json = {}
         | 
| 9 | 
            +
                  @xml = {}
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                protected
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def set_json
         | 
| 15 | 
            +
                  @json[:touser]  = @openid
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def set_xml
         | 
| 19 | 
            +
                  @xml["ToUserName"]   = @openid
         | 
| 20 | 
            +
                  @xml["FromUserName"] = SimpleWx.weixin_config["serial_no"]
         | 
| 21 | 
            +
                  @xml["CreateTime"]   = Time.now.to_i.to_s
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def send_json
         | 
| 25 | 
            +
                  set_json
         | 
| 26 | 
            +
                  response = RestClient.post(@custom_msg_url, JSON.generate(@json))
         | 
| 27 | 
            +
                  errcode_check(JSON.parse(response))
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def send_json!
         | 
| 31 | 
            +
                  @raise_flag ||= true
         | 
| 32 | 
            +
                  send_json
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def to_xml
         | 
| 36 | 
            +
                  set_xml
         | 
| 37 | 
            +
                  builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
         | 
| 38 | 
            +
                    xml.xml do
         | 
| 39 | 
            +
                      recursively_xml xml, @xml
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
                  builder.to_xml
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                private
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def recursively_xml builder, hsh
         | 
| 48 | 
            +
                  hsh.each do |k, v|
         | 
| 49 | 
            +
                    if v.is_a? Hash
         | 
| 50 | 
            +
                      builder.send(k) do
         | 
| 51 | 
            +
                        recursively_xml(builder, v)
         | 
| 52 | 
            +
                      end
         | 
| 53 | 
            +
                    else
         | 
| 54 | 
            +
                      builder.send(k, v)
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            module SimpleWx
         | 
| 2 | 
            +
              module Messages
         | 
| 3 | 
            +
                class ImageMessage < Message
         | 
| 4 | 
            +
                  def initialize options
         | 
| 5 | 
            +
                    super
         | 
| 6 | 
            +
                    @media_id = options[:media_id]
         | 
| 7 | 
            +
                  end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def send_json
         | 
| 10 | 
            +
                    @json[:msgtype] = "image"
         | 
| 11 | 
            +
                    @json[:image] = {media_id: @media_id}
         | 
| 12 | 
            +
                    SimpleWx.logger.info("SimpleWxLog:#{self.class.name} -- #{@openid} -- #{json}")
         | 
| 13 | 
            +
                    super
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  def to_xml
         | 
| 17 | 
            +
                    @xml["MsgType"] = "image"
         | 
| 18 | 
            +
                    @xml["Image"] = { "MediaId" => @media_id }
         | 
| 19 | 
            +
                    super
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            module SimpleWx
         | 
| 2 | 
            +
              module Messages
         | 
| 3 | 
            +
                class TextMessage < Message
         | 
| 4 | 
            +
                  def initialize options
         | 
| 5 | 
            +
                    super
         | 
| 6 | 
            +
                    @content = options[:content]
         | 
| 7 | 
            +
                  end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def send_json
         | 
| 10 | 
            +
                    @json[:msgtype] = "text"
         | 
| 11 | 
            +
                    @json[:text] = {content: @content}
         | 
| 12 | 
            +
                    SimpleWx.logger.info("SimpleWxLog:#{self.class.name} -- #{@openid} -- #{json}")
         | 
| 13 | 
            +
                    super
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  def to_xml
         | 
| 17 | 
            +
                    @xml["MsgType"] = "text"
         | 
| 18 | 
            +
                    @xml["Content"] = @content
         | 
| 19 | 
            +
                    super
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,82 @@ | |
| 1 | 
            +
            module SimpleWx
         | 
| 2 | 
            +
              class OAuth < Base
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                ### Usage
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                # auth = SimpleWx::OAuth.new(code: "code")
         | 
| 7 | 
            +
                #
         | 
| 8 | 
            +
                # 调用 OAth2 的 access_token 接口, 返回结果信息
         | 
| 9 | 
            +
                # result_json = auth.get_access_token
         | 
| 10 | 
            +
                #
         | 
| 11 | 
            +
                # auth 返回的基本参数会赋值给对象属性
         | 
| 12 | 
            +
                # auth.access_token == result_json["access_token"]
         | 
| 13 | 
            +
                # => true
         | 
| 14 | 
            +
                #
         | 
| 15 | 
            +
                # 检查 access_token 是否过期
         | 
| 16 | 
            +
                # auth.access_token_valid?
         | 
| 17 | 
            +
                # => true
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                # auth.expires_in
         | 
| 20 | 
            +
                # => 7200
         | 
| 21 | 
            +
                # sleep 7201
         | 
| 22 | 
            +
                # auth.access_token_valid?
         | 
| 23 | 
            +
                # => false
         | 
| 24 | 
            +
                #
         | 
| 25 | 
            +
                # 刷新access_token接口
         | 
| 26 | 
            +
                # result_json = auth.refresh_token
         | 
| 27 | 
            +
                # auth.access_token == result_json["access_token"]
         | 
| 28 | 
            +
                # auth.access_token_valid?
         | 
| 29 | 
            +
                # => true
         | 
| 30 | 
            +
                #
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                attr_reader :code, :scope, :expires_in, :unionid, :result
         | 
| 33 | 
            +
                attr_accessor :access_token, :refresh_token, :openid
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def initialize options
         | 
| 36 | 
            +
                  @code = options[:code]
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                def get_access_token
         | 
| 40 | 
            +
                  url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=#{SimpleWx.weixin_config["app_id"]}&secret=#{SimpleWx.weixin_config["app_secret"]}&code=#{@code}&grant_type=authorization_code"
         | 
| 41 | 
            +
                  response = RestClient.get url
         | 
| 42 | 
            +
                  set_result(errcode_check(JSON.parse(response)))
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def get_user_info
         | 
| 46 | 
            +
                  UserInfo.get_auth_info(o_auth: self)
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def access_token_valid?
         | 
| 50 | 
            +
                  url = "https://api.weixin.qq.com/sns/auth?access_token=#{@access_token}&openid=#{@openid}"
         | 
| 51 | 
            +
                  response = RestClient.get url
         | 
| 52 | 
            +
                  errcode_check(JSON.parse(response))
         | 
| 53 | 
            +
                  @error.blank?
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def refresh_token
         | 
| 57 | 
            +
                  url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=#{SimpleWx.weixin_config["app_id"]}&grant_type=refresh_token&refresh_token=#{@refresh_token}"
         | 
| 58 | 
            +
                  response = RestClient.get url
         | 
| 59 | 
            +
                  set_result(errcode_check(JSON.parse(response)))
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def self.generate_auth_link url, state = "", scope = "snsapi_userinfo"
         | 
| 63 | 
            +
                  params = {
         | 
| 64 | 
            +
                    appid: SimpleWx.weixin_config["app_id"],
         | 
| 65 | 
            +
                    redirect_uri: url,
         | 
| 66 | 
            +
                    response_type: "code",
         | 
| 67 | 
            +
                    scope: scope,
         | 
| 68 | 
            +
                    state: state
         | 
| 69 | 
            +
                  }
         | 
| 70 | 
            +
                  "https://open.weixin.qq.com/connect/oauth2/authorize?#{params.to_query}#wechat_redirect"
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                private
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                def set_result result
         | 
| 76 | 
            +
                  result.each do |k, v|
         | 
| 77 | 
            +
                    instance_variable_set "@#{k}", v
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                  @result = result
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
            end
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            module SimpleWx
         | 
| 2 | 
            +
              class Signaturer < Base
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                ### Usage
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                # signer = SimpleWx::Signaturer.new timestamp: params[:timestamp], nonce: params[:nonce]
         | 
| 7 | 
            +
                # if signer.sign params[:signature]
         | 
| 8 | 
            +
                #   render text: params[:echostr]
         | 
| 9 | 
            +
                # else
         | 
| 10 | 
            +
                #   ...
         | 
| 11 | 
            +
                # end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def initialize options = {}
         | 
| 14 | 
            +
                  @timestamp = options.fetch :timestamp
         | 
| 15 | 
            +
                  @nonce     = options.fetch :nonce
         | 
| 16 | 
            +
                  @token     = SimpleWx.weixin_config["token"] #TODO 没有就raise错误,用method_missing
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def sign signture
         | 
| 20 | 
            +
                  @sort_array = [@timestamp, @nonce, @token].sort
         | 
| 21 | 
            +
                  signture == sha1_encrypt
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                private
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def sha1_encrypt
         | 
| 27 | 
            +
                  encrypt_str = @sort_array.join
         | 
| 28 | 
            +
                  Digest::SHA1.hexdigest(encrypt_str)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
| @@ -0,0 +1,49 @@ | |
| 1 | 
            +
            module SimpleWx
         | 
| 2 | 
            +
              class UserInfo < Base
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                ### Usage
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                # ---------- class-methods ----------
         | 
| 7 | 
            +
                #
         | 
| 8 | 
            +
                # instance_of_oauth = SimpleWx::OAuth.new("code")
         | 
| 9 | 
            +
                # instance_of_oauth.get_access_token
         | 
| 10 | 
            +
                # user_info_hsh = SimpleWx::UserInfo.get_auth_info(o_auth: instance_of_oauth)
         | 
| 11 | 
            +
                #
         | 
| 12 | 
            +
                # user_info_hsh = SimpleWx::UserInfo.get_basic_info(access_token: "token", openid: "openid")
         | 
| 13 | 
            +
                #
         | 
| 14 | 
            +
                # ---------- instance-methods -----------
         | 
| 15 | 
            +
                #
         | 
| 16 | 
            +
                # @user_info = SimpleWx::UserInfo.new(access_token: "token", openid: "openid")
         | 
| 17 | 
            +
                # user_info_hsh = @user_info.get_basic_info
         | 
| 18 | 
            +
                # if @user_info.error.present?
         | 
| 19 | 
            +
                #   ...
         | 
| 20 | 
            +
                # end
         | 
| 21 | 
            +
                #
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def initialize options
         | 
| 24 | 
            +
                  @openid = options[:openid]
         | 
| 25 | 
            +
                  @o_auth = options[:o_auth]
         | 
| 26 | 
            +
                  @access_token = options[:access_token] || AccessToken.access_token
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def get_basic_info
         | 
| 30 | 
            +
                  url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=#{@access_token}&openid=#{@openid}&lang=zh_CN"
         | 
| 31 | 
            +
                  response = RestClient.get url
         | 
| 32 | 
            +
                  errcode_check(JSON.parse(response))
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def get_auth_info
         | 
| 36 | 
            +
                  url = "https://api.weixin.qq.com/sns/userinfo?access_token=#{@o_auth.access_token}&openid=#{@o_auth.openid}&lang=zh_CN"
         | 
| 37 | 
            +
                  response = RestClient.get url
         | 
| 38 | 
            +
                  errcode_check(JSON.parse(response))
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def self.method_missing m, hsh
         | 
| 42 | 
            +
                  if instance_methods.include? m.to_sym
         | 
| 43 | 
            +
                    self.new(hsh).send m
         | 
| 44 | 
            +
                  else
         | 
| 45 | 
            +
                    super
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
            end
         | 
    
        data/lib/simple_wx.rb
    ADDED
    
    | @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
            require 'redis'
         | 
| 3 | 
            +
            require 'yell'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module SimpleWx
         | 
| 6 | 
            +
              @@weixin_config = {}
         | 
| 7 | 
            +
              @@logger = Yell.new :datefile, 'simple_wx.log'
         | 
| 8 | 
            +
              @@redis  = Redis.new(host: '127.0.0.1', port: '6379', db: '0')
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              def self.weixin_config
         | 
| 11 | 
            +
                @@weixin_config
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              def self.logger
         | 
| 15 | 
            +
                @@logger
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              def self.redis
         | 
| 19 | 
            +
                @@redis
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            require 'simple_wx/base'
         | 
| 24 | 
            +
            require 'simple_wx/signaturer'
         | 
| 25 | 
            +
            require 'simple_wx/access_token'
         | 
| 26 | 
            +
            require 'simple_wx/menu'
         | 
| 27 | 
            +
            require 'simple_wx/user_info'
         | 
| 28 | 
            +
            require 'simple_wx/message'
         | 
| 29 | 
            +
            require 'simple_wx/messages/text_message'
         | 
| 30 | 
            +
            require 'simple_wx/messages/image_message'
         | 
| 31 | 
            +
             | 
    
        data/simple_wx.gemspec
    ADDED
    
    | @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            lib = File.expand_path('../lib', __FILE__)
         | 
| 3 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 | 
            +
            require 'simple_wx/version'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Gem::Specification.new do |spec|
         | 
| 7 | 
            +
              spec.name          = "simple_wx"
         | 
| 8 | 
            +
              spec.version       = SimpleWx::VERSION
         | 
| 9 | 
            +
              spec.authors       = ["Scott1743"]
         | 
| 10 | 
            +
              spec.email         = ["512981271@qq.com"]
         | 
| 11 | 
            +
              spec.summary       = ""
         | 
| 12 | 
            +
              spec.description   = %q{Ruby Api for WeiXin}
         | 
| 13 | 
            +
              spec.license       = "MIT"
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              spec.files         = `git ls-files -z`.split("\x0")
         | 
| 16 | 
            +
              spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
         | 
| 17 | 
            +
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         | 
| 18 | 
            +
              spec.require_paths = ["lib"]
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              spec.add_dependency 'redis', '~> 3.2.1'
         | 
| 21 | 
            +
              spec.add_dependency 'yell', '~> 2.0.0'
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              spec.add_development_dependency "bundler", "~> 1.6"
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,101 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: simple_wx
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.0.0
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Scott1743
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2015-11-12 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: redis
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - "~>"
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: 3.2.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.2.1
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: yell
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - "~>"
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: 2.0.0
         | 
| 34 | 
            +
              type: :runtime
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - "~>"
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: 2.0.0
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: bundler
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - "~>"
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '1.6'
         | 
| 48 | 
            +
              type: :development
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - "~>"
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '1.6'
         | 
| 55 | 
            +
            description: Ruby Api for WeiXin
         | 
| 56 | 
            +
            email:
         | 
| 57 | 
            +
            - 512981271@qq.com
         | 
| 58 | 
            +
            executables: []
         | 
| 59 | 
            +
            extensions: []
         | 
| 60 | 
            +
            extra_rdoc_files: []
         | 
| 61 | 
            +
            files:
         | 
| 62 | 
            +
            - ".gitignore"
         | 
| 63 | 
            +
            - README.md
         | 
| 64 | 
            +
            - config/initializers/simple_wx.rb.example
         | 
| 65 | 
            +
            - lib/simple_wx.rb
         | 
| 66 | 
            +
            - lib/simple_wx/access_token.rb
         | 
| 67 | 
            +
            - lib/simple_wx/base.rb
         | 
| 68 | 
            +
            - lib/simple_wx/menu.rb
         | 
| 69 | 
            +
            - lib/simple_wx/message.rb
         | 
| 70 | 
            +
            - lib/simple_wx/messages/image_message.rb
         | 
| 71 | 
            +
            - lib/simple_wx/messages/text_message.rb
         | 
| 72 | 
            +
            - lib/simple_wx/o_auth.rb
         | 
| 73 | 
            +
            - lib/simple_wx/signaturer.rb
         | 
| 74 | 
            +
            - lib/simple_wx/user_info.rb
         | 
| 75 | 
            +
            - lib/simple_wx/version.rb
         | 
| 76 | 
            +
            - simple_wx.gemspec
         | 
| 77 | 
            +
            homepage: 
         | 
| 78 | 
            +
            licenses:
         | 
| 79 | 
            +
            - MIT
         | 
| 80 | 
            +
            metadata: {}
         | 
| 81 | 
            +
            post_install_message: 
         | 
| 82 | 
            +
            rdoc_options: []
         | 
| 83 | 
            +
            require_paths:
         | 
| 84 | 
            +
            - lib
         | 
| 85 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 86 | 
            +
              requirements:
         | 
| 87 | 
            +
              - - ">="
         | 
| 88 | 
            +
                - !ruby/object:Gem::Version
         | 
| 89 | 
            +
                  version: '0'
         | 
| 90 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 91 | 
            +
              requirements:
         | 
| 92 | 
            +
              - - ">="
         | 
| 93 | 
            +
                - !ruby/object:Gem::Version
         | 
| 94 | 
            +
                  version: '0'
         | 
| 95 | 
            +
            requirements: []
         | 
| 96 | 
            +
            rubyforge_project: 
         | 
| 97 | 
            +
            rubygems_version: 2.2.2
         | 
| 98 | 
            +
            signing_key: 
         | 
| 99 | 
            +
            specification_version: 4
         | 
| 100 | 
            +
            summary: ''
         | 
| 101 | 
            +
            test_files: []
         |