diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks
new file mode 100644
index 0000000..107cb3a
--- /dev/null
+++ b/.idea/.rakeTasks
@@ -0,0 +1,7 @@
+
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..a26dc45
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..a9151ce
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/weixin_authorize.iml b/.idea/weixin_authorize.iml
new file mode 100644
index 0000000..b938183
--- /dev/null
+++ b/.idea/weixin_authorize.iml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..cbdadd3
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,1196 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+ 1439821400232
+
+ 1439821400232
+
+
+ 1440091917475
+
+
+ 1440091917475
+
+
+ 1440092094009
+
+
+ 1440092094010
+
+
+ 1440092763011
+
+
+ 1440092763011
+
+
+ 1440093870370
+
+
+ 1440093870370
+
+
+ 1440093973508
+
+
+ 1440093973508
+
+
+ 1440094310821
+
+
+ 1440094310821
+
+
+ 1440095106887
+
+
+ 1440095106887
+
+
+ 1440095208908
+
+
+ 1440095208908
+
+
+ 1440096038566
+
+
+ 1440096038566
+
+
+ 1440096214636
+
+
+ 1440096214636
+
+
+ 1440096608977
+
+
+ 1440096608977
+
+
+ 1440096714769
+
+
+ 1440096714769
+
+
+ 1440096840561
+
+
+ 1440096840561
+
+
+ 1440097548108
+
+
+ 1440097548109
+
+
+ 1440097734472
+
+
+ 1440097734472
+
+
+ 1440097838964
+
+
+ 1440097838964
+
+
+ 1440098579202
+
+
+ 1440098579202
+
+
+ 1440098642876
+
+
+ 1440098642876
+
+
+ 1440099051051
+
+
+ 1440099051051
+
+
+ 1440099255490
+
+
+ 1440099255490
+
+
+ 1440099550113
+
+
+ 1440099550113
+
+
+ 1440100495920
+
+
+ 1440100495920
+
+
+ 1440100517009
+
+
+ 1440100517009
+
+
+ 1440100657703
+
+
+ 1440100657703
+
+
+ 1440100770873
+
+
+ 1440100770873
+
+
+ 1440101193646
+
+
+ 1440101193646
+
+
+ 1440102232406
+
+
+ 1440102232406
+
+
+ 1440105077689
+
+
+ 1440105077690
+
+
+ 1440106916059
+
+
+ 1440106916059
+
+
+ 1440171035338
+
+
+ 1440171035338
+
+
+ 1440268632880
+
+
+ 1440268632881
+
+
+ 1440269511969
+
+
+ 1440269511969
+
+
+ 1440269633036
+
+
+ 1440269633037
+
+
+ 1440270532103
+
+
+ 1440270532103
+
+
+ 1440271009484
+
+
+ 1440271009484
+
+
+ 1440271049335
+
+
+ 1440271049335
+
+
+ 1440316621413
+
+
+ 1440316621413
+
+
+ 1440317287288
+
+
+ 1440317287288
+
+
+ 1440317620647
+
+
+ 1440317620647
+
+
+ 1440317665614
+
+
+ 1440317665614
+
+
+ 1440317829018
+
+
+ 1440317829018
+
+
+ 1440317991694
+
+
+ 1440317991694
+
+
+ 1440318080300
+
+
+ 1440318080300
+
+
+ 1440318135553
+
+
+ 1440318135553
+
+
+ 1440318141276
+
+
+ 1440318141276
+
+
+ 1440318277498
+
+
+ 1440318277499
+
+
+ 1440318348063
+
+
+ 1440318348063
+
+
+ 1440318821585
+
+
+ 1440318821585
+
+
+ 1440437585987
+
+
+ 1440437585988
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/weixin_authorize.rb b/lib/weixin_authorize.rb
index 2800ebe..c996a53 100644
--- a/lib/weixin_authorize.rb
+++ b/lib/weixin_authorize.rb
@@ -28,6 +28,12 @@ module JsTicket
autoload(:RedisStore, "weixin_authorize/js_ticket/redis_store")
end
+ module ApiTicket
+ autoload(:Store, "weixin_authorize/api_ticket/store")
+ autoload(:ObjectStore, "weixin_authorize/api_ticket/object_store")
+ autoload(:RedisStore, "weixin_authorize/api_ticket/redis_store")
+ end
+
OK_MSG = "ok".freeze
OK_CODE = 0.freeze
GRANT_TYPE = "client_credential".freeze
@@ -44,7 +50,7 @@ def http_get_without_token(url, url_params={}, endpoint="plain")
def http_post_without_token(url, post_body={}, url_params={}, endpoint="plain")
post_api_url = endpoint_url(endpoint, url)
# to json if invoke "plain"
- if endpoint == "plain" || endpoint == CUSTOM_ENDPOINT
+ if endpoint == "plain" || endpoint == "api" || endpoint == CUSTOM_ENDPOINT
post_body = JSON.dump(post_body)
end
load_json(resource(post_api_url).post(post_body, params: url_params))
@@ -88,6 +94,17 @@ def open_endpoint(url)
"https://open.weixin.qq.com#{url}"
end
+ def check_required_options(options, names, module_name='Weixin Authorize')
+ missinglsit = []
+ names.each do |name|
+ missinglsit << name if options.nil? ||
+ !options.has_key?(name) ||
+ options[name].nil? ||
+ (!options[name].is_a?(Integer) && options[name].empty?)
+ end
+ raise "#{module_name}: missing required param(缺少参数): #{missinglsit.join(', ')}"
+ end
+
end
-end
+end
\ No newline at end of file
diff --git a/lib/weixin_authorize/api/card.rb b/lib/weixin_authorize/api/card.rb
new file mode 100644
index 0000000..e893d85
--- /dev/null
+++ b/lib/weixin_authorize/api/card.rb
@@ -0,0 +1,799 @@
+# encoding: utf-8
+# ===================
+# 传入参数必须为 Symbol
+# ===================
+module WeixinAuthorize
+ # 考虑了一下由于 Client 本身会引入所有的API
+ # 而 JsonHelper 不属于 API 部分
+ # 所以还是把 JsonHelper 放在外层
+ module CardJsonHelper
+ MODULE_JSON_HELPER_NAME = 'CardJsonHelper(微信卡券接口助手)'
+ class << self
+ INVOKE_SKU_REQUIRED_FIELDS = %i(quantity)
+ def sku(params)
+ params = {
+ quantity: nil
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_SKU_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ params
+ end
+
+ INVOKE_DATEIINFO_REQUIRED_FIELDS = %i(type)
+ def date_info(params)
+ params = {
+ type: '',
+ begin_timestamp: nil,
+ end_timestamp: nil,
+ fixed_term: nil,
+ fixed_begin_term: nil
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_DATEIINFO_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ params
+ end
+
+ INVOKE_BASEINFO_REQUIRED_FIELDS = %i(logo_url code_type brand_name title sub_title color notice description sku date_info)
+ # 创建卡券base_info json
+ def base_info(params)
+ params = {
+ # 必填参数
+ logo_url: '',
+ code_type: '',
+ brand_name: '',
+ title: '',
+ sub_title: '',
+ color: '',
+ notice: '',
+ description: '',
+ sku: { quantity: nil },
+ date_info: {
+ type: '',
+ begin_timestamp: nil,
+ end_timestamp: nil,
+ fixed_term: nil,
+ fixed_begin_term: nil
+ },
+ # 可选参数
+ use_custom_code: nil,
+ bind_openid: nil,
+ service_phone: nil,
+ location_id_list: nil,
+ source: nil,
+ custom_url_name: nil,
+ custom_url: nil,
+ custom_url_sub_title: nil,
+ promotion_url_name: nil,
+ promotion_url: nil,
+ promotion_url_sub_title: nil,
+ get_limit: nil,
+ can_share: nil,
+ can_give_friend: nil
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_BASEINFO_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ params
+ end
+ end
+
+ class MemberCard
+ # 创建自定义会员信息类目json
+ # 会员卡激活后显示。
+ INVOKE_CUSTOMCELL_REQUIRED_FIELDS = %i(name_type tips url)
+ def self.custom_cell(params)
+ params = {
+ name_type: '',
+ tips: '',
+ url: ''
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_CUSTOMCELL_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ params
+ end
+
+ # 创建自定义会员信息类目json
+ # 会员信息类目名称,取以下任一值:
+ # name_type =
+ # 等级 FIELD_NAME_TYPE_LEVEL
+ # 印花 FIELD_NAME_TYPE_STAMP
+ # 折扣 FIELD_NAME_TYPE_DISCOUNT
+ # 成就 FIELD_NAME_TYPE_ACHIEVEMEN
+ # 里程 FIELD_NAME_TYPE_MILEAGE
+ # 优惠券 FIELD_NAME_TYPE_COUPON"
+ INVOKE_CUSTONFIELD_REQUIRED_FIELDS = %i(name_type url)
+ def self.custom_field(params)
+ params = {
+ name_type: '',
+ url: ''
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_CUSTONFIELD_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ params
+ end
+
+ INVOKE_BONUS_REQUIRED_FIELDS = %i(supply_bonus)
+ def self.bonus(params)
+ params = {
+ supply_bonus: nil,
+ bonus_url: nil,
+ bonus_cleared: nil,
+ bonus_rules: nil
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_BONUS_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ params
+ end
+
+ INVOKE_BALANCE_REQUIRED_FIELDS = %i(supply_balance)
+ def self.balance(params)
+ {
+ supply_balance: nil,
+ balance_url: nil,
+ balance_rules: nil
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_BALANCE_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ params
+ end
+
+ INVOKE_MEMBERCARD_REQUIRED_FIELDS = %i(activate_url prerogative bonus balance)
+ # 创建会员卡json
+ def self.create(bash_info, params)
+ params = {
+ activate_url: '',
+ prerogative: '',
+ bonus: {
+ supply_bonus: nil,
+ bonus_url: nil,
+ bonus_cleared: nil,
+ bonus_rules: nil
+ },
+ balance: {
+ supply_balance: nil,
+ balance_url: nil,
+ balance_rules: nil
+ },
+ custom_field: [],
+ custom_cell: []
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_MEMBERCARD_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ {
+ card: {
+ card_type: 'MEMBER_CARD',
+ base_info: bash_info,
+ activate_url: params[:activate_url],
+ prerogative: params[:prerogative],
+ supply_bonus: params[:bonus][:supply_bonus],
+ bonus_url: params[:bonus][:bonus_url],
+ bonus_cleared: params[:bonus][:bonus_cleared],
+ bonus_rules: params[:bonus][:bonus_rules],
+ supply_balance: params[:balance][:supply_balance],
+ balance_url: params[:balance][:balance_url],
+ balance_rules: params[:balance][:balance_rules],
+ custom_field1: params[:custom_field[0]],
+ custom_field2: params[:custom_field[1]],
+ custom_field3: params[:custom_field[2]],
+ custom_cell1: params[:custom_cell[0]]
+ }
+ }
+ end
+ end
+
+ INVOKE_GROUPON_REQUIRED_FIELDS = %i(deal_detail)
+ class Groupon
+ # 创建团购券json
+ def self.create(bash_info, params)
+ params = {
+ deal_detail: ''
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_GROUPON_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ {
+ card: {
+ card_type: 'GROUPON',
+ base_info: bash_info,
+ deal_detail: params[:deal_detail]
+ }
+ }
+ end
+ end
+
+ INVOKE_CASH_REQUIRED_FIELDS = %i(least_cost reduce_cost)
+ class Cash
+ # 创建代金券json
+ def self.create(bash_info, params)
+ params = {
+ least_cost: nil,
+ reduce_cost: nil
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_CASH_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ {
+ card: {
+ card_type: 'CASH',
+ base_info: bash_info,
+ least_cost: params[:least_cost],
+ reduce_cost: params[:reduce_cost],
+ }
+ }
+ end
+ end
+
+ INVOKE_DISCOUNT_REQUIRED_FIELDS = %i(discount)
+ class Discount
+ # 创建折扣券json
+ def self.create(bash_info, params)
+ params = {
+ discount: nil
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_DISCOUNT_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ {
+ card: {
+ card_type: 'DISCOUNT',
+ base_info: bash_info,
+ discount: params[:discount]
+ }
+ }
+ end
+ end
+
+ INVOKE_GIFT_REQUIRED_FIELDS = %i(gift)
+ class Gift
+ # 创建礼品券json
+ def self.create(bash_info, params)
+ params = {
+ gift: ''
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_GIFT_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ {
+ card: {
+ card_type: 'DISCOUNT',
+ base_info: bash_info,
+ gift: params[:gift]
+ }
+ }
+ end
+ end
+
+ INVOKE_GENERALCOUPON_REQUIRED_FIELDS = %i(default_detail)
+ class GeneralCoupon
+ # 创建通用券json
+ def self.create(bash_info, params)
+ params = {
+ default_detail: ''
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_GENERALCOUPON_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ {
+ card: {
+ card_type: 'GENERAL_COUPON',
+ base_info: bash_info,
+ default_detail: params[:default_detail]
+ }
+ }
+ end
+ end
+
+ INVOKE_MEETINGTICKET_REQUIRED_FIELDS = %i(meeting_detail)
+ class MeetingTicket
+ # 创建会议门票json
+ def self.create(bash_info, params)
+ params = {
+ meeting_detail: '',
+ map_url: nil
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_MEETINGTICKET_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ {
+ card: {
+ card_type: 'MEETING_TICKET',
+ base_info: bash_info,
+ meeting_detail: params[:meeting_detail],
+ map_url: params[:map_url]
+ }
+ }
+ end
+ end
+
+ INVOKE_SCENICTICKET_REQUIRED_FIELDS = %i(ticket_class guide_url)
+ class ScenicTicket
+ # 创建景区门票json
+ def self.create(bash_info, params)
+ params = {
+ ticket_class: '',
+ guide_url: ''
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_SCENICTICKET_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ {
+ card: {
+ card_type: 'SCENIC_TICKET',
+ base_info: bash_info,
+ ticket_class: params[:ticket_class],
+ guide_url: params[:guide_url]
+ }
+ }
+ end
+ end
+
+ INVOKE_BOARDPASS_REQUIRED_FIELDS = %i(from to flight air_model departure_time landing_time)
+ class BoardingPass
+ # 创建飞机票json
+ def self.create(bash_info, params)
+ params = {
+ from: '',
+ to: '',
+ flight: '',
+ gate: nil,
+ check_in_url: nil,
+ air_model: '',
+ departure_time: '',
+ landing_time: ''
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_BOARDPASS_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ {
+ card: {
+ card_type: 'BOARDING_PASS',
+ base_info: bash_info,
+ detail: params[:detail]
+ }
+ }
+ end
+ end
+
+ INVOKE_MOVIETICKET_REQUIRED_FIELDS = %i(tickedetailt_class)
+ class MovieTicket
+ # 创建电影票json
+ def self.create(bash_info, params)
+ params = {
+ tickedetailt_class: ''
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_MOVIETICKET_REQUIRED_FIELDS, MODULE_JSON_HELPER_NAME)
+ {
+ card: {
+ card_type: 'MOVIE_TICKET',
+ base_info: bash_info,
+ detail: params[:detail]
+ }
+ }
+ end
+ end
+ end
+
+ module Api
+ MODULE_API_CARD_NAME = 'Card API(微信卡券接口)'
+ module Card
+ def card_ext(card_id='', code=nil, openid=nil)
+ timestamp = Time.now.to_i
+ nonce_str = SecureRandom.hex(16)
+ apiticket = get_apiticket
+ sort_params = [ apiticket, timestamp.to_s, card_id.to_s, code.to_s, openid.to_s, nonce_str ].sort.join
+ signature = Digest::SHA1.hexdigest(sort_params)
+ {
+ code: code,
+ openid: openid,
+ timestamp: timestamp,
+ nonce_str: nonce_str,
+ signature: signature
+ }
+ end
+
+ # 预览接口
+ # https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=ACCESS_TOKEN
+ # touser = option { openid: openid, wxname: wxname }
+ def card_send_preview(card_id='', towxname='', toopenid='')
+ url = "/message/mass/preview"
+ wxcard_body = {
+ card_id: card_id,
+ card_ext: card_ext
+ }
+ post_body = {
+ msgtype: 'wxcard',
+ touser: toopenid,
+ towxname: towxname
+ }.merge(wxcard_body)
+ http_post(url, post_body)
+ end
+
+ # 获取卡券配色方案列表
+ # https://api.weixin.qq.com/card/getcolors?access_token=TOKEN
+ def card_colors
+ url = "#{card_base_url}/getcolors"
+ http_get(url, {} ,'api')
+ end
+
+
+ # 统计卡券数据 - 拉取会员卡数据接口
+ # https://api.weixin.qq.com/datacube/getcardmembercardinfo?access_token=ACCESS_TOKEN
+ def card_datacube_info_member_card(begin_date=0, end_date=0, cond_source=1)
+ begin_date = datacube_datetime_format begin_date
+ end_date = datacube_datetime_format end_date
+ url = "#{datacube_base_url}/getcardmembercardinfo"
+ post_body = {
+ begin_date: begin_date,
+ end_date: end_date,
+ cond_source: cond_source
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 获取免费券数据接口
+ # https://api.weixin.qq.com/datacube/getcardcardinfo?access_token=ACCESS_TOKEN
+ def card_datacube_info(begin_date=0, end_date=0, cond_source=1, card_id=nil)
+ begin_date = datacube_datetime_format begin_date
+ end_date = datacube_datetime_format end_date
+ url = "#{datacube_base_url}/getcardcardinfo"
+ post_body = {
+ begin_date: begin_date,
+ end_date: end_date,
+ cond_source: cond_source,
+ card_id: card_id
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 拉取卡券概况数据接口
+ # https://api.weixin.qq.com/datacube/getcardbizuininfo?access_token=ACCESS_TOKEN
+ def card_datacube(begin_date=0, end_date=0, cond_source=1)
+ begin_date = datacube_datetime_format begin_date
+ end_date = datacube_datetime_format end_date
+ url = "#{datacube_base_url}/getcardbizuininfo"
+ post_body = {
+ begin_date: begin_date,
+ end_date: end_date,
+ cond_source: cond_source
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 设置测试白名单
+ # https://api.weixin.qq.com/card/testwhitelist/set?access_token=TOKEN
+ def card_testwhitelist(wxusername=[], openid=[])
+ url = "#{card_base_url}/testwhitelist/set"
+ post_body = {
+ openid: openid[0, 9], # 微信接口限制10个白名单用户,多余的抛弃
+ username: wxusername[0,9] # 微信接口限制10个白名单用户,多余的抛弃
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 获取图文消息卡券HTML代码接口
+ # https://api.weixin.qq.com/card/mpnews/gethtml?access_token=TOKEN
+ def card_mpnews_html(card_id=nil)
+ url = "#{card_base_url}/mpnews/gethtml"
+ post_body = {
+ card_id: card_id
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 核查code接口
+ # http://api.weixin.qq.com/card/code/checkcode?access_token=ACCESS_TOKEN
+ def card_code_check(card_id='', codelist=[])
+ url = "#{card_base_url}/code/checkcode"
+ post_body = {
+ card_id: card_id,
+ code: codelist
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 导入code接口
+ # http://api.weixin.qq.com/card/code/deposit?access_token=ACCESS_TOKEN
+ # codelist = ['11111', '22222', '33333']
+ def card_code_deposit(card_id='', codelist=[])
+ url = "#{card_base_url}/code/deposit"
+ post_body = {
+ card_id: card_id,
+ code: codelist
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 创建货架接口
+ # https://api.weixin.qq.com/card/landingpage/create?access_token=$TOKEN
+ #
+ # 场景值 scene
+ # SCENE_NEAR_BY 附近
+ # SCENE_SCAN 扫一扫
+ # SCENE_SHAKE_TV 摇电视
+ # SCENE_WIFI 微信wifi
+ # SCENE_IBEACON iBeacon
+ # SCENE_PAY 微信支付
+ # SCENE_MENU 自定义菜单
+ # SCENE_MONENTS_AD 朋友圈广告
+ # SCENE_QRCODE 二维码
+ # SCENE_ARTICLE 公众号文章
+ # SCENE_H5 h5页面
+ # SCENE_SHAKE_CARD 摇礼券
+ # SCENE_BIZ_AD 公众号广告
+ # SCENE_IVR 自动回复
+ # SCENE_SMS 短信
+ # SCENE_MEMBER_CARD_ANNOUNCEMENT 会员卡公告
+ # SCENE_CARD_CUSTOM_CELL 卡券自定义cell
+ # SCENE_CARD_MSG_URL 卡券消息运营位
+ #
+ def card_landingpage_create(banner='', title='', can_share=false, scene='', cardlist=[{cardid: '', thumb_url: ''}])
+ url = "#{card_base_url}/landingpage/create"
+ post_body = {
+ banner: banner,
+ title: title,
+ can_share: can_share,
+ scene: scene,
+ cardlist: cardlist
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 创建二维码接口
+ # https://api.weixin.qq.com/card/qrcode/create?access_token=TOKEN
+ def card_qrcode_create(card_id='', code=nil, openid=nil,
+ expire_seconds=nil, is_unique_code=nil, outer_id=nil)
+ url = "#{card_base_url}/qrcode/create"
+ card_body = {
+ card_id: card_id,
+ code: code,
+ openid: openid,
+ is_unique_code: is_unique_code,
+ outer_id: outer_id
+ }
+ post_body = {
+ action_name: 'QR_CARD',
+ expire_seconds: expire_seconds,
+ action_info: {card: card_body}
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # Code解码接口
+ # https://api.weixin.qq.com/card/code/decrypt?access_token=TOKEN
+ def card_code_decrypt(encrypt_code='')
+ url = "#{card_base_url}/code/decrypt"
+ post_body = {
+ encrypt_code: encrypt_code
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 核销Code接口
+ # https://api.weixin.qq.com/card/code/consume?access_token=TOKEN
+ def card_code_consume(card_id=nil, code='')
+ url = "#{card_base_url}/code/consume"
+ post_body = {
+ card_id: card_id,
+ code: code
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+
+ # 设置卡券失效接口
+ # https://api.weixin.qq.com/card/code/unavailable?access_token=TOKEN
+ def card_code_unavailable(card_id=nil, code='')
+ url = "#{card_base_url}/code/unavailable"
+ post_body = {
+ card_id: card_id,
+ code: code
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 删除卡券接口
+ # https://api.weixin.qq.com/card/delete?access_token=TOKEN
+ def card_delete(card_id='')
+ url = "#{card_base_url}/delete"
+ post_body = {
+ card_id: card_id
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+
+ # 更改Code接口
+ # https://api.weixin.qq.com/card/code/update?access_token=TOKEN
+ def card_code_update(card_id=nil, code='', new_code='')
+ url = "#{card_base_url}/code/update"
+ post_body = {
+ card_id: card_id,
+ code: code,
+ new_code: new_code
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 修改库存接口
+ # https://api.weixin.qq.com/card/modifystock?access_token=TOKEN
+ def card_modify_stock(card_id='', increase_stock_value=nil, reduce_stock_value=nil)
+ url = "#{card_base_url}/modifystock"
+ post_body = {
+ card_id: card_id,
+ increase_stock_value: increase_stock_value,
+ reduce_stock_value: reduce_stock_value
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 更改卡券信息接口
+ # https://api.weixin.qq.com/card/update?access_token=TOKEN
+ def card_update(card_id='', card_type='', card)
+ card = card[:card] if card.has_key?(:card)
+ post_body = {
+ card_id: card_id,
+ "#{card_type}": card
+ }
+ endpoint = 'api'
+ endpoint = 'plain' if card.is_a?(String) # 第三方开发者自定义json
+ url = "#{card_base_url}/update"
+ http_post(url, post_body, {}, endpoint)
+ end
+
+ # 批量查询卡列表
+ # https://api.weixin.qq.com/card/batchget?access_token=TOKEN
+ # offset => 查询卡列表的起始偏移量,从0开始,即offset: 5是指从从列表里的第六个开始读取。
+ # count => 需要查询的卡片的数量(数量最大50)。
+ # status_list => 支持开发者拉出指定状态的卡券列表,例:仅拉出通过审核的卡券。
+ #
+ # 卡券状态
+ # CARD_STATUS_NOT_VERIFY 待审核
+ # CARD_STATUS_VERIFY_FALL 审核失败
+ # CARD_STATUS_VERIFY_OK 通过审核
+ # CARD_STATUS_USER_DELETE 卡券被用户删除
+ # CARD_STATUS_USER_DISPATCH 在公众平台投放过的卡券
+ def cards(offset=0, count=50, status_list=['CARD_STATUS_USER_DISPATCH'])
+ url = "#{card_base_url}/batchget"
+ post_body = {
+ offset: offset,
+ count: count,
+ status_list: status_list
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 查看卡券详情
+ # https://api.weixin.qq.com/card/get?access_token=TOKEN
+ def card(card_id='')
+ url = "#{card_base_url}/get"
+ post_body = {
+ card_id: card_id
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ # 获取用户已领取卡券接口
+ # https://api.weixin.qq.com/card/user/getcardlist?access_token=TOKEN
+ def user_cards(openid='', card_id=nil)
+ url = "#{card_base_url}/user/getcardlist"
+ post_body = {
+ openid: openid,
+ card_id: card_id
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+
+ # 查询Code
+ # https://api.weixin.qq.com/card/code/get?access_token=TOKEN
+ def card_code(card_id=nil, code='')
+ url = "#{card_base_url}/code/get"
+ post_body = {
+ code: code,
+ card_id: card_id
+ }
+ http_post(url, post_body, {}, 'api')
+ end
+
+ INVOKE_MEMBERCARD_ACTIVATE_REQUIRED_FIELDS = %i(membership_number code)
+ # 激活/绑定会员卡
+ # https://api.weixin.qq.com/card/membercard/activate?access_token=TOKEN
+ def card_member_card_activate(params)
+ params = {
+ membership_number: '',
+ code: '',
+ activate_begin_time: nil,
+ activate_end_time: nil,
+ init_bonus: nil,
+ init_balance: nil,
+ init_custom_field_value1: nil,
+ init_custom_field_value2: nil,
+ init_custom_field_value3: nil,
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_MEMBERCARD_ACTIVATE_REQUIRED_FIELDS, MODULE_API_CARD_NAME)
+ url = "#{card_base_url}/membercard/activate"
+ http_post(url, params, {}, 'api')
+ end
+
+ INVOKE_MEMBERCARD_UPDATE_REQUIRED_FIELDS = %i(code card_id)
+ # 更新会员信息
+ # https://api.weixin.qq.com/card/membercard/updateuser?access_token=TOKEN
+ def card_member_card_update_user(params)
+ invoke_required_fields = INVOKE_MEMBERCARD_UPDATE_REQUIRED_FIELDS
+ invoke_required_fields << :bonus if params[:add_bonus].nil?
+ invoke_required_fields << :balance if params[:add_balance].nil?
+ params = {
+ code: '',
+ card_id: '',
+ add_bonus: nil,
+ bonus: nil,
+ record_bonus: '',
+ add_balance: nil,
+ balance: nil,
+ record_balance: '',
+ custom_field_value1: '',
+ custom_field_value2: '',
+ custom_field_value3: ''
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, invoke_required_fields, MODULE_API_CARD_NAME)
+ url = "#{card_base_url}/membercard/updateuser"
+ http_post(url, params, {}, 'api')
+ end
+
+ INVOKE_MEETINGTICKET_UPDATE_REQUIRED_FIELDS = %i(code zone entrance seat_number)
+ # 更新会议门票
+ # https://api.weixin.qq.com/card/meetingticket/updateuser?access_token=TOKEN
+ def card_meeting_ticket_update_user(params)
+ params = {
+ code: '',
+ card_id: nil,
+ begin_time: nil,
+ end_time: nil,
+ zone: '',
+ entrance: '',
+ seat_number: ''
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_MEETINGTICKET_UPDATE_REQUIRED_FIELDS, MODULE_API_CARD_NAME)
+ url = "#{card_base_url}/meetingticket/updateuser"
+ http_post(url, params, {}, 'api')
+ end
+
+ INVOKE_MOVIETICKET_UPDATE_REQUIRED_FIELDS = %i(show_time duration code card_id ticket_class)
+ # 更新电影票
+ # https://api.weixin.qq.com/card/movieticket/updateuser?access_token=TOKEN
+ def card_moive_ticket_update_user(params)
+ params = {
+ code: '',
+ card_id: '',
+ ticket_class: '',
+ screening_room: nil,
+ seat_number: nil,
+ show_time: nil,
+ duration: nil
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_MOVIETICKET_UPDATE_REQUIRED_FIELDS, MODULE_API_CARD_NAME)
+ url = "#{card_base_url}/movieticket/updateuser"
+ http_post(url, params, {}, 'api')
+ end
+
+ INVOKE_BOARDPASS_UPDATE_REQUIRED_FIELDS = %i(code passenger_name etkt_bnr)
+ # 更新飞机票信息
+ # https://api.weixin.qq.com/card/boardingpass/checkin?access_token=TOKEN
+ def card_boarding_pass_checkin(params)
+ params = {
+ code: '',
+ card_id: nil,
+ passenger_name: '',
+ class: '',
+ seat: nil,
+ etkt_bnr: nil,
+ qrcode_data: nil,
+ is_cancel: nil
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_BOARDPASS_UPDATE_REQUIRED_FIELDS, MODULE_API_CARD_NAME)
+ url = "#{card_base_url}/boardingpass/checkin"
+ http_post(url, params, {}, 'api')
+ end
+
+ # 微信卡券创建接口
+ # https://api.weixin.qq.com/card/create?access_token=ACCESS_TOKEN
+ def card_create(card)
+ endpoint = 'api'
+ endpoint = 'plain' if card.is_a?(String) # 第三方开发者自定义json
+ url = "#{card_base_url}/create"
+ http_post(url, card, {}, endpoint)
+ end
+
+ private
+ def datacube_base_url
+ "/datacube"
+ end
+
+ def card_base_url
+ "/card"
+ end
+
+ def datacube_datetime_format(param)
+ param = Time.at(param) if param.is_a?(Integer)
+ param = param.strftime("%Y-%m-%d") if param.is_a?(Time)
+ param
+ end
+
+ end
+ end
+end
diff --git a/lib/weixin_authorize/api/custom.rb b/lib/weixin_authorize/api/custom.rb
index 9440c06..6ed91e4 100644
--- a/lib/weixin_authorize/api/custom.rb
+++ b/lib/weixin_authorize/api/custom.rb
@@ -145,6 +145,22 @@ def create_kf_session(account, open_id, text)
http_post(KF_SESSION_URL, post_body, {}, CUSTOM_ENDPOINT)
end
+ # 发送卡券
+ # {
+ # "touser":"OPENID",
+ # "msgtype":"wxcard",
+ # "wxcard":
+ # {
+ # "card_id":"123dsdajkasd231jhksad",
+ # "card_ext": {code: code, openid: openid, timestamp: 1402057159, signature: '017bb17407c8e0058a66d72dcc61632b70f511ad'}
+ # }
+ # }
+ def send_card_custom(to_user='', card_id='')
+ wxcard = default_options(to_user, 'wxcard').merge(
+ {wxcard:{card_id: card_id, card_ext: card_ext(card_id)}})
+ http_post(custom_base_url, wxcard)
+ end
+
private
# https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN
diff --git a/lib/weixin_authorize/api/mass.rb b/lib/weixin_authorize/api/mass.rb
index 76d68ef..1d164fe 100644
--- a/lib/weixin_authorize/api/mass.rb
+++ b/lib/weixin_authorize/api/mass.rb
@@ -3,6 +3,12 @@ module WeixinAuthorize
module Api
module Mass
+ # 获取自动回复规则
+ # https://api.weixin.qq.com/cgi-bin/get_current_autoreply_info?access_token=ACCESS_TOKEN
+ def mass_autoreply_rules
+ http_get('/get_current_autoreply_info')
+ end
+
MSG_TYPE = ["mpnews", "image", "text", "voice", "mpvideo"].freeze
# media_info= {"media_id" media_id}
diff --git a/lib/weixin_authorize/api/poi.rb b/lib/weixin_authorize/api/poi.rb
new file mode 100644
index 0000000..54d55bc
--- /dev/null
+++ b/lib/weixin_authorize/api/poi.rb
@@ -0,0 +1,105 @@
+# encoding: utf-8
+module WeixinAuthorize
+ module Api
+ module Poi
+ MODULE_NAME = 'POI API(微信门店接口)'
+
+ INVOKE_POI_REQUIRED_FIELDS = %i(business_name branch_name
+ province city district address
+ telephone categories
+ offset_type longitude latitude
+ photo_list special open_time avg_price)
+ # 创建门店
+ # http://api.weixin.qq.com/cgi-bin/poi/addpoi?access_token=TOKEN
+ def poi_add(params)
+ params = {
+ business_name: '',
+ branch_name: '',
+ province: '',
+ city: '',
+ district: '',
+ address: '',
+ telephone: '',
+ categories: '',
+ offset_type: 1, #火星坐标
+ longitude: '',
+ latitude: '',
+ photo_list: [],
+ special: '',
+ open_time: '',
+ avg_price: nil,
+ sid: '',
+ introduction: nil,
+ recommend: nil,
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_POI_REQUIRED_FIELDS, MODULE_NAME)
+ post_body = {
+ business: { base_info: params }
+ }
+ url = "#{poi_base_url}/addpoi"
+ http_post(url, post_body)
+ end
+
+ INVOKE_POI_UPDATE_REQUIRED_FIELDS = %i(poi_id)
+ # 修改门店
+ # https://api.weixin.qq.com/cgi-bin/poi/updatepoi?access_token=TOKEN
+ def poi_update(params)
+ params = {
+ poi_id: ''
+ }.merge(params)
+ WeixinAuthorize.check_required_options(params, INVOKE_POI_UPDATE_REQUIRED_FIELDS, MODULE_NAME)
+ post_body = {
+ business: { base_info: params }
+ }
+ url = "#{poi_base_url}/updatepoi"
+ http_post(url, post_body)
+ end
+
+ # 拉取门店类目表
+ # http://api.weixin.qq.com/cgi-bin/api_getwxcategory?access_token=TOKEN
+ def poi_category()
+ http_get("/api_getwxcategory")
+ end
+
+
+ # 删除门店
+ # https://api.weixin.qq.com/cgi-bin/poi/delpoi?access_token=TOKEN
+ def poi_delete(poi_id='')
+ url = "#{poi_base_url}/delpoi"
+ post_body = {
+ poi_id: poi_id
+ }
+ http_post(url, post_body)
+ end
+
+ # 查询门店信息
+ # http://api.weixin.qq.com/cgi-bin/poi/getpoi?access_token=TOKEN
+ def poi(poi_id='')
+ url = "#{poi_base_url}/getpoi"
+ post_body = {
+ poi_id: poi_id
+ }
+ http_post(url, post_body)
+ end
+
+
+ # 查询门店列表
+ # https://api.weixin.qq.com/cgi-bin/poi/getpoilist?access_token=TOKEN
+ def pois(offset=0, limit=50)
+ url = "#{poi_base_url}/getpoilist"
+ post_body = {
+ begin: offset,
+ limit: limit
+ }
+ http_post(url, post_body)
+ end
+
+ private
+
+ def poi_base_url
+ "/poi"
+ end
+
+ end
+ end
+end
diff --git a/lib/weixin_authorize/api_ticket/object_store.rb b/lib/weixin_authorize/api_ticket/object_store.rb
new file mode 100644
index 0000000..78273d6
--- /dev/null
+++ b/lib/weixin_authorize/api_ticket/object_store.rb
@@ -0,0 +1,21 @@
+module WeixinAuthorize
+ module ApiTicket
+ class ObjectStore < Store
+
+ def apiticket_expired?
+ # 如果当前token过期时间小于现在的时间,则重新获取一次
+ client.apiticket_expired_at <= Time.now.to_i
+ end
+
+ def apiticket
+ super
+ client.apiticket
+ end
+
+ def refresh_apiticket
+ super
+ end
+
+ end
+ end
+end
diff --git a/lib/weixin_authorize/api_ticket/redis_store.rb b/lib/weixin_authorize/api_ticket/redis_store.rb
new file mode 100644
index 0000000..a972e63
--- /dev/null
+++ b/lib/weixin_authorize/api_ticket/redis_store.rb
@@ -0,0 +1,41 @@
+module WeixinAuthorize
+ module ApiTicket
+ class RedisStore < Store
+ APITICKET = "apiticket"
+ EXPIRED_AT = "expired_at"
+
+ def apiticket_expired?
+ weixin_redis.hvals(client.apiticket_redis_key).empty?
+ end
+
+ def refresh_apiticket
+ super
+ weixin_redis.hmset(
+ client.apiticket_redis_key,
+ APITICKET,
+ client.apiticket,
+ EXPIRED_AT,
+ client.apiticket_expired_at
+ )
+ weixin_redis.expireat(
+ client.apiticket_redis_key,
+ client.apiticket_expired_at.to_i
+ )
+ end
+
+ def apiticket
+ super
+ client.apiticket = weixin_redis.hget(client.apiticket_redis_key, APITICKET)
+ client.apiticket_expired_at = weixin_redis.hget(
+ client.apiticket_redis_key,
+ EXPIRED_AT
+ )
+ client.apiticket
+ end
+
+ def weixin_redis
+ WeixinAuthorize.weixin_redis
+ end
+ end
+ end
+end
diff --git a/lib/weixin_authorize/api_ticket/store.rb b/lib/weixin_authorize/api_ticket/store.rb
new file mode 100644
index 0000000..77aa16d
--- /dev/null
+++ b/lib/weixin_authorize/api_ticket/store.rb
@@ -0,0 +1,40 @@
+# encoding: utf-8
+module WeixinAuthorize
+ module ApiTicket
+ class Store
+
+ attr_accessor :client
+
+ def initialize(client)
+ @client = client
+ end
+
+ def self.init_with(client)
+ if WeixinAuthorize.weixin_redis.nil?
+ ObjectStore.new(client)
+ else
+ RedisStore.new(client)
+ end
+ end
+
+ def apiticket_expired?
+ raise NotImplementedError, "Subclasses must implement a apiticket_expired? method"
+ end
+
+ def refresh_apiticket
+ set_apiticket
+ end
+
+ def apiticket
+ refresh_apiticket if apiticket_expired?
+ end
+
+ def set_apiticket
+ result = client.http_get("/ticket/getticket", {type: 'wx_card'}).result
+ client.apiticket = result["ticket"]
+ client.apiticket_expired_at = result["expires_in"] + Time.now.to_i
+ end
+
+ end
+ end
+end
diff --git a/lib/weixin_authorize/client.rb b/lib/weixin_authorize/client.rb
index cfd9362..246c424 100644
--- a/lib/weixin_authorize/client.rb
+++ b/lib/weixin_authorize/client.rb
@@ -5,10 +5,15 @@
module WeixinAuthorize
class Client
+<<<<<<< HEAD
+ include Api::Poi
+=======
include MonitorMixin
+>>>>>>> lanrion/master
include Api::User
+ include Api::Card
include Api::Menu
include Api::Custom
include Api::Groups
@@ -21,14 +26,21 @@ class Client
attr_accessor :app_id, :app_secret, :expired_at # Time.now + expires_in
attr_accessor :access_token, :redis_key, :custom_access_token
attr_accessor :jsticket, :jsticket_expired_at, :jsticket_redis_key
+ attr_accessor :apiticket, :apiticket_expired_at, :apiticket_redis_key
# options: redis_key, custom_access_token
def initialize(app_id, app_secret, options={})
@app_id = app_id
@app_secret = app_secret
@jsticket_expired_at = @expired_at = Time.now.to_i
+<<<<<<< HEAD
+ @apiticket_expired_at = @expired_at = Time.now.to_i
+ @redis_key = security_redis_key(options[:redis_key] || "weixin_#{app_id}")
+=======
@redis_key = security_redis_key(options[:redis_key] || "weixin_#{app_id}")
+>>>>>>> lanrion/master
@jsticket_redis_key = security_redis_key("js_sdk_#{app_id}")
+ @apiticket_redis_key = security_redis_key("api_ticket_#{app_id}")
@custom_access_token = options[:custom_access_token]
super() # Monitor#initialize
end
@@ -57,6 +69,14 @@ def get_jsticket
jsticket_store.jsticket
end
+ def apiticket_store
+ ApiTicket::Store.init_with(self)
+ end
+
+ def get_apiticket
+ apiticket_store.apiticket
+ end
+
# 获取js sdk 签名包
def get_jssign_package(url)
timestamp = Time.now.to_i