457 lines
13 KiB
Lua
457 lines
13 KiB
Lua
|
|
local skynet = require "skynet"
|
|||
|
|
local oo = require "Class"
|
|||
|
|
local gameCmd = require "GameCmd"
|
|||
|
|
local json =require "json"
|
|||
|
|
local log = require "Log"
|
|||
|
|
local sqlUrl = require "SqlUrl"
|
|||
|
|
local errorInfo = require "ErrorInfo"
|
|||
|
|
local dataType = require "DataType"
|
|||
|
|
local serverId = tonumber(skynet.getenv "serverId")
|
|||
|
|
local redisKeyUrl = require "RedisKeyUrl"
|
|||
|
|
local httpc = require "http.httpc"
|
|||
|
|
|
|||
|
|
|
|||
|
|
local Subscription = oo.class()
|
|||
|
|
local protocol ="https"
|
|||
|
|
|
|||
|
|
--域名
|
|||
|
|
local domain = "api.weixin.qq.com"
|
|||
|
|
|
|||
|
|
--推送地址 暂时写在这里
|
|||
|
|
local pushUrl = "/cgi-bin/message/subscribe/send?access_token=%s"
|
|||
|
|
|
|||
|
|
--获取token地址
|
|||
|
|
--local getTokenUrl = "/cgi-bin/token?grant_type=client_credential&appid=wxa2951c2cf9636811&secret=bada9eefee3db35b9c9fa21ed40787d8"
|
|||
|
|
local getTokenStableUrl="/cgi-bin/stable_token"--稳定模式
|
|||
|
|
local tokenStablePostData={
|
|||
|
|
grant_type="client_credential",--固定值
|
|||
|
|
appid="wxa2951c2cf9636811",--appid
|
|||
|
|
secret="bada9eefee3db35b9c9fa21ed40787d8"--appsecret
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
--方便管理订阅一个管理列表
|
|||
|
|
local subscriptionMap={}
|
|||
|
|
|
|||
|
|
-- 版本更新提醒
|
|||
|
|
local data1={
|
|||
|
|
character_string1={
|
|||
|
|
value="1.0.0"--版本号
|
|||
|
|
},
|
|||
|
|
thing2={
|
|||
|
|
value="版本描述"
|
|||
|
|
},
|
|||
|
|
date3={
|
|||
|
|
value="2024/01/01"--完成时间
|
|||
|
|
},
|
|||
|
|
time4={
|
|||
|
|
value="10:00:00"--更新时间
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
subscriptionMap[8]=data1
|
|||
|
|
|
|||
|
|
-- 邮箱金币
|
|||
|
|
local data2={
|
|||
|
|
date2={
|
|||
|
|
value = os.date("%H:%M",os.time())
|
|||
|
|
},
|
|||
|
|
thing1={
|
|||
|
|
value="待领取"
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
subscriptionMap[1]=data2
|
|||
|
|
|
|||
|
|
-- 种花成熟提醒
|
|||
|
|
local data3={
|
|||
|
|
phrase1={
|
|||
|
|
value="任务名称"
|
|||
|
|
},
|
|||
|
|
date2={
|
|||
|
|
value="完成日期"
|
|||
|
|
},
|
|||
|
|
time3={
|
|||
|
|
value="完成时间"
|
|||
|
|
},
|
|||
|
|
thing4={
|
|||
|
|
value="温馨提醒"
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
subscriptionMap[2]=data3
|
|||
|
|
-- 食堂进货提醒
|
|||
|
|
local data4={
|
|||
|
|
phrase1={
|
|||
|
|
value="任务名称"
|
|||
|
|
},
|
|||
|
|
date2={
|
|||
|
|
value="完成日期"
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
subscriptionMap[3]=data4
|
|||
|
|
-- 萌宠乐园出游提醒
|
|||
|
|
local data5={
|
|||
|
|
phrase1={
|
|||
|
|
value="任务名称"
|
|||
|
|
},
|
|||
|
|
time3={
|
|||
|
|
value="完成时间"
|
|||
|
|
},
|
|||
|
|
thing4={
|
|||
|
|
value="温馨提醒"
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
subscriptionMap[4]=data5
|
|||
|
|
-- 渔店钓鱼提醒
|
|||
|
|
local data6={
|
|||
|
|
phrase1={
|
|||
|
|
value="任务名称"
|
|||
|
|
},
|
|||
|
|
date2={
|
|||
|
|
value="完成日期"
|
|||
|
|
},
|
|||
|
|
time3={
|
|||
|
|
value="完成时间"
|
|||
|
|
},
|
|||
|
|
thing4={
|
|||
|
|
value="温馨提醒"
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
subscriptionMap[5]=data6
|
|||
|
|
-- 恋家置业收租提醒
|
|||
|
|
local data7={
|
|||
|
|
phrase1={
|
|||
|
|
value="任务名称"
|
|||
|
|
},
|
|||
|
|
time3={
|
|||
|
|
value="完成时间"
|
|||
|
|
},
|
|||
|
|
thing4={
|
|||
|
|
value="温馨提醒"
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
subscriptionMap[6]=data7
|
|||
|
|
-- 造型材料提醒
|
|||
|
|
local data8={
|
|||
|
|
phrase1={
|
|||
|
|
value="任务名称"
|
|||
|
|
},
|
|||
|
|
date2={
|
|||
|
|
value="完成日期"
|
|||
|
|
},
|
|||
|
|
thing11={
|
|||
|
|
value="未领取"
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
subscriptionMap[7]=data8
|
|||
|
|
|
|||
|
|
--初始化
|
|||
|
|
function Subscription:Init()
|
|||
|
|
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--每5秒调一次(测试阶段)
|
|||
|
|
function Subscription:On5SecTimer()
|
|||
|
|
|
|||
|
|
-- log.debug("微信订阅 每5秒调一次")
|
|||
|
|
-- --目前只有微信订阅消息
|
|||
|
|
-- self:GetSubscription(1)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--获取订阅信息
|
|||
|
|
function Subscription:GetSubscription(subscribeType)
|
|||
|
|
|
|||
|
|
--获取已经订阅的玩家key
|
|||
|
|
local keys= skynet.server.redis:smembers(redisKeyUrl.ThirdSubscribeSetKeys)
|
|||
|
|
|
|||
|
|
if keys == nil or #keys == 0 then
|
|||
|
|
|
|||
|
|
log.debug("GetSubscription keys is nil or #keys == 0")
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--订阅类型配置
|
|||
|
|
local cfgSubscriptions = skynet.server.gameConfig:GetAllCfg("Subscription")
|
|||
|
|
|
|||
|
|
if not cfgSubscriptions then
|
|||
|
|
log.debug("cfgSubscriptions is nil")
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--循环数据
|
|||
|
|
for _, setKey in ipairs(keys) do
|
|||
|
|
|
|||
|
|
local key=string.format(redisKeyUrl.ThirdSubscribe, setKey)
|
|||
|
|
|
|||
|
|
--获取订阅信息
|
|||
|
|
local subscribeInfoListStr = skynet.server.redis:hget(key,tostring(subscribeType))
|
|||
|
|
|
|||
|
|
--不存在数据跳出当前循环
|
|||
|
|
if subscribeInfoListStr == nil or subscribeInfoListStr == "" then
|
|||
|
|
goto coroutine1
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--反序列化成对象
|
|||
|
|
local subscribeInfoList = json:decode(subscribeInfoListStr)
|
|||
|
|
|
|||
|
|
--判断反序列化是否成功
|
|||
|
|
if subscribeInfoList == nil or next(subscribeInfoList) == nil then
|
|||
|
|
|
|||
|
|
log.debug(string.format("消息发布订阅反序列化失败,key:%s,subscribeInfoListStr:%s",key,subscribeInfoListStr))
|
|||
|
|
goto coroutine1
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--倒序遍历,删除不影响table后续索引
|
|||
|
|
for i = #subscribeInfoList, 1, -1 do
|
|||
|
|
|
|||
|
|
local subscribeInfo = subscribeInfoList[i]
|
|||
|
|
|
|||
|
|
--不存在存在数据
|
|||
|
|
if subscribeInfo == nil or next(subscribeInfo) == nil then
|
|||
|
|
goto coroutine
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--判断是否过期
|
|||
|
|
if subscribeInfo.expireTime < skynet.GetTime() and subscribeInfo.expireTime ~= 0 then
|
|||
|
|
|
|||
|
|
--删除订阅信息
|
|||
|
|
table.remove(subscribeInfoList,i)
|
|||
|
|
goto coroutine
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--是否需要推送
|
|||
|
|
if subscribeInfo.triggerTimestamp > skynet.GetTime()
|
|||
|
|
or subscribeInfo.triggerTimestamp == 0 --当前在线,没有推送时间
|
|||
|
|
or subscribeInfo.subscribeStatus == 2 --已推送
|
|||
|
|
or subscribeInfo.subscribeStatus == 3 then
|
|||
|
|
|
|||
|
|
goto coroutine
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local cfgSubscription={}
|
|||
|
|
|
|||
|
|
--根据配置获取提醒标题
|
|||
|
|
for _, value in pairs(cfgSubscriptions) do
|
|||
|
|
if value.id == subscribeInfo.subscribeId then
|
|||
|
|
cfgSubscription=value
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--推送消息到微信
|
|||
|
|
local ret = Subscription:pushMessage(subscribeType,cfgSubscription,subscribeInfo)
|
|||
|
|
if ret and cfgSubscription.subscribeType == 1
|
|||
|
|
and skynet.GetTime() > subscribeInfo.expireTime then--触发订阅,并且未过期 才重置
|
|||
|
|
--更新状态为已推送
|
|||
|
|
subscribeInfo.subscribeStatus = 2
|
|||
|
|
else--手动订阅则删除
|
|||
|
|
table.remove(subscribeInfoList,i)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- 跳出当前循环
|
|||
|
|
::coroutine::
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
if next(subscribeInfoList) ~= nil then
|
|||
|
|
|
|||
|
|
--更新订阅信息
|
|||
|
|
skynet.server.redis:hset(key,tostring(subscribeType),json:encode(subscribeInfoList))
|
|||
|
|
else
|
|||
|
|
--删除
|
|||
|
|
skynet.server.redis:hdel(key,tostring(subscribeType))
|
|||
|
|
|
|||
|
|
--删除索引
|
|||
|
|
skynet.server.redis:srem(redisKeyUrl.ThirdSubscribeSetKeys,setKey)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- 跳出当前循环
|
|||
|
|
::coroutine1::
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--每5分钟调一次
|
|||
|
|
function Subscription:On5MinTimer()
|
|||
|
|
|
|||
|
|
log.debug("微信订阅 五分钟检查一次")
|
|||
|
|
|
|||
|
|
self:GetSubscription(1)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--推送消息
|
|||
|
|
function Subscription:pushMessage(subscribeType,cfgSubscription,subscribeInfo)
|
|||
|
|
|
|||
|
|
--失败次数
|
|||
|
|
local failCount=0
|
|||
|
|
|
|||
|
|
--处理微信订阅消息(目前只有微信)
|
|||
|
|
if subscribeType ==1 then
|
|||
|
|
|
|||
|
|
--订阅内容
|
|||
|
|
local postData={
|
|||
|
|
touser = subscribeInfo.uniqueId,
|
|||
|
|
template_id = "",
|
|||
|
|
miniprogram_state = "developer",
|
|||
|
|
lang = "zh_CN",
|
|||
|
|
data={}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
local template_id=""
|
|||
|
|
local data={}
|
|||
|
|
|
|||
|
|
--获取token地址
|
|||
|
|
local tokenInfo = self:GetWxToken(false)
|
|||
|
|
if tokenInfo == "" then
|
|||
|
|
log.debug("获取token失败")
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--模版id
|
|||
|
|
postData.template_id=cfgSubscription.subscribeModelId
|
|||
|
|
|
|||
|
|
--设置订阅内容
|
|||
|
|
if subscriptionMap[cfgSubscription.id] then
|
|||
|
|
postData.data=subscriptionMap[cfgSubscription.id]
|
|||
|
|
|
|||
|
|
--版本更新
|
|||
|
|
if postData.data.character_string1 then
|
|||
|
|
--修改推送数值值
|
|||
|
|
postData.data.character_string1.value="1.0.0" --版本号
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--邮件时间
|
|||
|
|
if cfgSubscription.id == 1 then
|
|||
|
|
postData.data.date2.value= os.date("%H:%M",skynet.GetTime())
|
|||
|
|
postData.data.thing1.value= cfgSubscription.subscribeDesc
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--基本通用模板
|
|||
|
|
if postData.data.phrase1 then
|
|||
|
|
postData.data.phrase1.value= cfgSubscription.subscribeTitle
|
|||
|
|
end
|
|||
|
|
if postData.data.thing4 then
|
|||
|
|
postData.data.thing4.value= cfgSubscription.subscribeDesc
|
|||
|
|
end
|
|||
|
|
if postData.data.date2 then
|
|||
|
|
postData.data.date2.value= os.date("%m月%d日",subscribeInfo.triggerTimestamp)
|
|||
|
|
end
|
|||
|
|
if postData.data.time3 then
|
|||
|
|
postData.data.time3.value= os.date("%H:%M:%S",subscribeInfo.triggerTimestamp)
|
|||
|
|
end
|
|||
|
|
else--模版id不存在
|
|||
|
|
log.debug(string.format("消息订阅 消息id不存在,subscribeId:%s",cfgSubscription.id))
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- --版本更新提醒
|
|||
|
|
-- if cfgSubscription.id==8 then
|
|||
|
|
-- postData.data=data1
|
|||
|
|
|
|||
|
|
-- --修改推送数值值
|
|||
|
|
-- postData.data.character_string1.value="1.0.0" --版本号
|
|||
|
|
|
|||
|
|
-- --邮箱金币
|
|||
|
|
-- elseif cfgSubscription.id==1 then
|
|||
|
|
-- postData.data=data2
|
|||
|
|
-- postData.data.date2.value= os.date("%H:%M",skynet.GetTime())
|
|||
|
|
-- postData.data.thing1.value= cfgSubscription.subscribeDesc
|
|||
|
|
|
|||
|
|
-- -- "种花成熟提醒
|
|||
|
|
-- -- 渔店钓鱼提醒
|
|||
|
|
-- -- 食堂进货提醒
|
|||
|
|
-- -- 萌宠乐园出游提醒
|
|||
|
|
-- -- 恋家置业收租提醒
|
|||
|
|
-- -- 食堂收菜提醒
|
|||
|
|
-- -- 造型材料提醒"
|
|||
|
|
-- elseif cfgSubscription.id>=2 and cfgSubscription.id<=7 then
|
|||
|
|
-- postData.data=data3
|
|||
|
|
-- postData.data.phrase1.value= cfgSubscription.subscribeTitle
|
|||
|
|
-- postData.data.thing4.value= cfgSubscription.subscribeDesc
|
|||
|
|
-- postData.data.date2.value= os.date("%m月%d日",subscribeInfo.triggerTimestamp)
|
|||
|
|
-- postData.data.time3.value= os.date("%H:%M:%S",subscribeInfo.triggerTimestamp)
|
|||
|
|
|
|||
|
|
-- else--模版id不存在
|
|||
|
|
-- log.debug(string.format("消息订阅 消息id不存在,subscribeId:%s",cfgSubscription.id))
|
|||
|
|
-- return false
|
|||
|
|
-- end
|
|||
|
|
|
|||
|
|
::top::
|
|||
|
|
|
|||
|
|
local url =string.format(pushUrl,tokenInfo)
|
|||
|
|
|
|||
|
|
--推送
|
|||
|
|
local status,body = skynet.server.httpClient:PostJson(domain,url,json:encode(postData),protocol)
|
|||
|
|
|
|||
|
|
if type(status)=="table" then
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
if status ~= 200 then
|
|||
|
|
log.warning(string.format("微信订阅推送 返回状态 ~= 200 url:%s,status:%d,body:%s",url,status,body))
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--反序列化结果
|
|||
|
|
local bodyObj = json:decode(body)
|
|||
|
|
local errcode = tonumber(bodyObj.errcode)
|
|||
|
|
|
|||
|
|
--推送失败,就意味着后面都会失败,没必要再次推送
|
|||
|
|
if errcode ~= 0 then
|
|||
|
|
|
|||
|
|
if (errcode == 40001 or errcode == 42001)and failCount < 5 then --token过期,重试5次
|
|||
|
|
|
|||
|
|
log.debug("重新获取token:",errcode,failCount)
|
|||
|
|
--获取token地址
|
|||
|
|
tokenInfo = self:GetWxToken(true)
|
|||
|
|
if tokenInfo == "" then
|
|||
|
|
log.debug("获取token失败")
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
failCount=failCount+1
|
|||
|
|
goto top
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--微信token信息
|
|||
|
|
local token=""
|
|||
|
|
local expires_in=0
|
|||
|
|
|
|||
|
|
--推送消息到微信等
|
|||
|
|
function Subscription:GetWxToken(isForce)
|
|||
|
|
|
|||
|
|
--判断token是否过期,未过期直接返回之前的token
|
|||
|
|
if expires_in > 0 and expires_in > skynet.GetTime() and token ~= "" and not isForce then
|
|||
|
|
return token
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--获取token-stable模式
|
|||
|
|
local status,body =skynet.server.httpClient:PostJson(domain,getTokenStableUrl,json:encode(tokenStablePostData),protocol) -- skynet.server.httpClient:Get(domain,getTokenUrl,protocol)
|
|||
|
|
|
|||
|
|
if status ~= 200 then
|
|||
|
|
log.warning(string.format("微信订阅推送 获取token失败,domain:%s,url:%s,status:%d,body:%s",domain,getTokenStableUrl,status,body))
|
|||
|
|
return 0
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--反序列号结果
|
|||
|
|
local bodyObj = json:decode(body)
|
|||
|
|
|
|||
|
|
--反序列化失败
|
|||
|
|
if bodyObj == nil or next(bodyObj) == nil then
|
|||
|
|
log.warning(string.format("微信订阅推送 bodyObj反序列化失败,domain:%s,url:%s,status:%d,body:%s",domain,getTokenStableUrl,status,body))
|
|||
|
|
return 0
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
token = bodyObj.access_token
|
|||
|
|
expires_in =skynet.GetTime() + tonumber(bodyObj.expires_in)
|
|||
|
|
if token == nil or expires_in == nil then
|
|||
|
|
log.warning(string.format("微信订阅推送 token反序列化失败,domain:%s,url:%s,status:%d,body:%s",domain,getTokenStableUrl,status,body))
|
|||
|
|
return 0
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
return token
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
skynet.server.subscription = Subscription
|
|||
|
|
return Subscription
|