module Util::Wechat BASE_SITE = 'https://api.weixin.qq.com'.freeze Error = Class.new(StandardError) class << self attr_accessor :appid, :secret def js_sdk_signature(url, noncestr, timestamp) data = { jsapi_ticket: jsapi_ticket, noncestr: noncestr, timestamp: timestamp, url: url } str = data.map { |k, v| "#{k}=#{v}" }.join('&') Digest::SHA1.hexdigest(str) end def access_token # 7200s 有效时间 Rails.cache.fetch(access_token_cache_key, expires_in: 100.minutes) do result = request(:get, '/cgi-bin/token', appid: appid, secret: secret, grant_type: 'client_credential') result['access_token'] end end def refresh_access_token Rails.cache.delete(access_token_cache_key) access_token end def jsapi_ticket # 7200s 有效时间 Rails.cache.fetch(jsapi_ticket_cache_key, expires_in: 100.minutes) do result = request(:get, '/cgi-bin/ticket/getticket', access_token: access_token, type: 'jsapi') result['ticket'] end end def refresh_jsapi_ticket Rails.cache.delete(jsapi_ticket_cache_key) jsapi_ticket end def access_token_cache_key "#{base_cache_key}/access_token" end def jsapi_ticket_cache_key "#{base_cache_key}/jsapi_ticket" end def base_cache_key "wechat/#{appid}" end private def request(method, url, **params) Rails.logger.error("[wechat] request: #{method} #{url} #{params.inspect}") client = Faraday.new(url: BASE_SITE) response = client.public_send(method, url, params) result = JSON.parse(response.body) Rails.logger.error("[wechat] response:#{response.status} #{result.inspect}") if response.status != 200 raise Error, result.inspect end if result['errcode'].present? && result['errcode'].to_i.nonzero? raise Error, result.inspect end result end end end