lib/wechat.rb
# frozen_string_literal: true
require 'zeitwerk'
loader = Zeitwerk::Loader.for_gem
loader.ignore("#{__dir__}/action_controller")
loader.ignore("#{__dir__}/generators/**/*.rb")
loader.setup
require 'base64'
require 'openssl/cipher'
require 'ostruct'
module Wechat
class AccessTokenExpiredError < StandardError; end
class InvalidCredentialError < StandardError; end
class ResponseError < StandardError
attr_reader :error_code
def initialize(errcode, errmsg)
@error_code = errcode
super("#{errmsg}(#{error_code})")
end
end
def self.config(account = :default)
ApiLoader.config(account)
end
def self.api(account = :default)
@wechat_apis ||= {}
@wechat_apis[account.to_sym] ||= ApiLoader.with(account: account)
end
def self.reload_config!
ApiLoader.reload_config!
end
def self.decrypt(encrypted_data, session_key, ivector)
cipher = OpenSSL::Cipher.new('AES-128-CBC')
cipher.decrypt
cipher.key = Base64.decode64(session_key)
cipher.iv = Base64.decode64(ivector)
decrypted_data = Base64.decode64(encrypted_data)
JSON.parse(cipher.update(decrypted_data) + cipher.final)
rescue StandardError => e
{ errcode: 41003, errmsg: e.message }
end
end
ActionView::Base.include Wechat::Helpers if defined? ActionView::Base
require 'action_controller/wechat_responder' # To make wechat_api and wechat_responder available
module ActionController
if defined? Base
ActiveSupport.on_load(:action_controller_base) do
class << Base
include WechatResponder
end
end
end
if defined? API
ActiveSupport.on_load(:action_controller_api) do
class << API
include WechatResponder
end
end
end
end