class Wechat::Api::Client

Constants

API_BASE

Attributes

app_id[R]
logger[RW]
secret[R]
site[RW]
ticket[R]

Public Class Methods

new(app_id, secret) click to toggle source
# File lib/wechat/api/client.rb, line 26
def initialize(app_id, secret)
  @app_id, @secret = app_id, secret
  @logger = Logger.new(STDOUT)
  @ticket = JsTicket.new self
  @token_file = File.join('/tmp', "wechat-api-#{app_id}")
end

Public Instance Methods

access_token() click to toggle source
# File lib/wechat/api/client.rb, line 33
def access_token
  @access_token ||= begin
    token = MultiJson.load(File.read(@token_file))
    token['access_token']
  rescue
    refresh
  end
end
get(uri, params = {}) click to toggle source
# File lib/wechat/api/client.rb, line 53
def get(uri, params = {})
  with_access_token(uri, params) do |url, params_with_token|
    debug_request do
      connection.get do |req|
        req.url url, params_with_token
        req.headers[:accept] = 'application/json'
        req.headers[:content_type] = 'application/json'
      end
    end
  end
end
post(uri, data = {}) click to toggle source
# File lib/wechat/api/client.rb, line 65
def post(uri, data = {})
  with_access_token(uri, {}) do |url, params|
    debug_request do
      connection.post do |req|
        req.url url, params
        req.headers[:accept] = 'application/json'
        req.headers[:content_type] = 'application/json'
        req.body = MultiJson.dump(data)
      end
    end
  end
end
refresh() click to toggle source
# File lib/wechat/api/client.rb, line 42
def refresh
  url = format('%stoken', base_url)
  resp = connection.get(url, token_params)
  response = MultiJson.load(resp.body)
  return handle_error(response) if response['errcode']

  @access_token = response['access_token']
  File.open(@token_file, 'w') { |f| f.write(resp.body) } if @access_token
  @access_token
end
with_access_token(uri, params, tried = 2) { |url, merge(access_token: access_token)| ... } click to toggle source
# File lib/wechat/api/client.rb, line 78
def with_access_token(uri, params, tried = 2)
  url = format('%s%s', base_url, uri)
  begin
    resp = yield(url, params.merge(access_token: access_token))
    raise ResponseError, resp unless resp.success?

    response = MultiJson.load(resp.body)
    handle_error(response)
  rescue AccessTokenExpiredError => e
    refresh
    retry unless (tried -= 1).zero?
    raise e
  end
end

Private Instance Methods

base_url() click to toggle source
# File lib/wechat/api/client.rb, line 95
def base_url
  site || API_BASE
end
connection() click to toggle source
# File lib/wechat/api/client.rb, line 126
def connection
  @connection ||= begin
    Faraday.new do |faraday|
      faraday.adapter Faraday.default_adapter
    end
  end
end
debug_request() { || ... } click to toggle source
# File lib/wechat/api/client.rb, line 99
def debug_request
  response = yield
  logger.debug { response }
  response
end
handle_error(response) click to toggle source
# File lib/wechat/api/client.rb, line 105
def handle_error(response)
  case response['errcode']
  when 0, nil
    response
  when 40_001, 42_001, 40_014
    raise AccessTokenExpiredError, response
  when 43_004
    raise SubscribeError, response
  else
    raise ResponseError, response
  end
end
token_params() click to toggle source
# File lib/wechat/api/client.rb, line 118
def token_params
  {
    grant_type: 'client_credential',
    appid: app_id,
    secret: secret
  }
end