class MiniProgram::Client
Attributes
app_secret[R]
appid[R]
Public Class Methods
new(appid: config.appid, app_secret: config.app_secret)
click to toggle source
# File lib/mini_program/client.rb, line 5 def initialize(appid: config.appid, app_secret: config.app_secret) @appid = appid @app_secret = app_secret if appid == 'your appid' warn "\e[33m" + "*" * 80 + "\e[0m" warn "\e[33m警告: 请将 config/initializer/mini_program.rb 中的 appid 修改成你实际的appid\e[0m" warn "\e[33m" + "*" * 80 + "\e[0m" end if app_secret == 'your app_secret' warn "\e[33m" + "*" * 80 + "\e[0m" warn "\e[33m警告: 请将 config/initializer/mini_program.rb 中的 app_secret 修改成你实际的app_secret\e[0m" warn "\e[33m" + "*" * 80 + "\e[0m" end end
Public Instance Methods
config()
click to toggle source
# File lib/mini_program/client.rb, line 136 def config appid, app_secret = if MiniProgram.appid && MiniProgram.app_secret [MiniProgram.appid, MiniProgram.app_secret] # 如果有挂载 WechatPayment 的 engine 时,使用里边的小程序配置 elsif Object.const_defined? "WechatPayment" [WechatPayment.sub_appid || WechatPayment.appid, WechatPayment.sub_app_secret || WechatPayment.app_secret] else [nil, nil] end Struct.new(:appid, :app_secret).new(appid, app_secret) end
get_access_token(fresh: false) { |result| ... }
click to toggle source
# File lib/mini_program/client.rb, line 22 def get_access_token(fresh: false) access_token = redis.get(access_token_store_key) if access_token.present? && !fresh return MiniProgram::ServiceResult.new(success: true, data: {access_token: access_token}) end result = request_access_token if result.success? redis.setex access_token_store_key, 1.5.hours.to_i, result.data["access_token"] end yield result if block_given? result end
get_phone_num(code:, encrypted_data:, iv:)
click to toggle source
获取用户手机号
# File lib/mini_program/client.rb, line 117 def get_phone_num(code:, encrypted_data:, iv:) login_result = login(code) return login_result if login_result.failure? open_id = login_result.data[:openid] session_key = login_result.data[:session_key] data = decrypt_phone_data(encrypted_data, iv, session_key) phone_num = JSON.parse(data)["phoneNumber"] MiniProgram::ServiceResult.new( success: true, data: { open_id: open_id, phone_num: phone_num }) end
login(code)
click to toggle source
调用微信授权登录 api
# File lib/mini_program/client.rb, line 70 def login(code) api = "https://api.weixin.qq.com/sns/jscode2session" params = { appid: appid, secret: app_secret, js_code: code, grant_type: :authorization_code } response = get(api, params) result = JSON.parse(response) if result["errcode"] logger.error <<~ERROR Get session key failed. api: #{api} result: #{result} ERROR return MiniProgram::ServiceResult.new(errors: result, message: result["errmsg"]) end MiniProgram::ServiceResult.new(success: true, data: result) end
request_access_token()
click to toggle source
调用微信 api 获取 access_token
@return MiniProgram::ServiceResult
# File lib/mini_program/client.rb, line 43 def request_access_token api = "https://api.weixin.qq.com/cgi-bin/token" params = { appid: appid, secret: app_secret, grant_type: :client_credential } response = get(api, params) result = JSON.parse(response) if result["errcode"].present? logger.error <<~ERROR Get access token failed. api: #{api} error: #{result} ERROR return MiniProgram::ServiceResult.new(success: false, data: result, message: result["errmsg"]) end MiniProgram::ServiceResult.new(success: true, data: result) end
send_msg(msg, to: )
click to toggle source
发送订阅消息 @param [MiniProgram::Msg] msg @param [String] to 用户的open id
# File lib/mini_program/client.rb, line 98 def send_msg(msg, to: ) open_id = to.try(:open_id) || to payload = msg.as_json.merge!(touser: open_id) # 获取 access_token get_token_result = get_access_token if get_token_result.failure? return get_token_result end api = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=#{get_token_result["access_token"]}" result = post(api, payload) msg_logger.info {"{params: #{payload}, response: #{result}}"} MiniProgram::ServiceResult.new(success: true, data: result) end
Private Instance Methods
access_token_store_key()
click to toggle source
# File lib/mini_program/client.rb, line 194 def access_token_store_key @access_token_store_key ||= "mp-#{appid}-access-token" end
decrypt_phone_data(encrypted_data, iv, session_key)
click to toggle source
# File lib/mini_program/client.rb, line 178 def decrypt_phone_data(encrypted_data, iv, session_key) aes = OpenSSL::Cipher::AES.new "128-CBC" aes.decrypt aes.key = Base64::decode64(session_key) aes.iv = Base64.decode64(iv) aes.update(Base64::decode64(encrypted_data)) + aes.final end
get(api, payload = {})
click to toggle source
# File lib/mini_program/client.rb, line 152 def get(api, payload = {}) uri = URI(api) if payload.present? uri.query = URI.encode_www_form(payload) end Net::HTTP.get(uri) end
logger()
click to toggle source
# File lib/mini_program/client.rb, line 186 def logger @logger ||= MiniProgram::RLogger.make("mini_program") end
msg_logger()
click to toggle source
# File lib/mini_program/client.rb, line 198 def msg_logger @msg_logger ||= MiniProgram::RLogger.make("wx_msg") end
post(api, payload = {}, options = {})
click to toggle source
# File lib/mini_program/client.rb, line 162 def post(api, payload = {}, options = {}) uri = URI(api) req = Net::HTTP::Post.new(uri) req["Content-Type"] = "application/json" options = { use_ssl: true }.merge(options) res = Net::HTTP.start(uri.host, uri.port, **options) do |http| http.request(req, payload.to_json) end JSON.parse(res.body) end
redis()
click to toggle source
# File lib/mini_program/client.rb, line 190 def redis @redis ||= Redis.current end