开发微信公众号时,用接口被动回复用户消息,遇到了“该公众号暂时无法提供服务,请稍后再试”这个问题,这里是开发中是用lua脚本写的,在这里踩了一个大的坑,回复消息的时候怎么也回复不出去,一直提示该公众号暂时无法提供服务,请稍后再试,浪费了一天时间呀,文档上说的问题是1、开发者在5秒内未回复任何内容2、开发者回复了异常数据,比如JSON数据等。于是,在这两个问题上拼命找原因,好像这两个点都没有问题。于是把组好的xml格式中FromUserName,ToUserName这两个字段的赋值颠倒一下,终于解决了。这里记录一下开发过程。
这是文档上的截图:
--这里是xml工具类
module(..., package.seeall)
local log = require("common.log").log
local cjson = require("cjson")
require("LuaXml")
function xml2table(xmlstr)
if xmlstr == nil or xml=="" then
return nil
end
if not ngx.re.match( xmlstr, "<(\\S*?)[^>]*>.*?</\\1>|<.*? />" ) then
log("xfile match fail ")
return nil
end
local xfile = xml.eval(xmlstr)
local keytable = {}
log("获取的xml解析成json:" .. cjson.encode(xfile))
log("全部节点的内容:" .. table.getn(xfile))
keytable = totable(xfile)
return keytable
end
local key
local keytable = {}
function totable(v)
if type(v) == "table" then
for k , v1 in pairs(v) do
if type(v1) ~= "table" then
if k ==0 then
key = v1
elseif k==1 then
keytable[key] = v1
end
else
totable(v1)
end
end
end
return keytable
end
function table2xml(contab)
local sorted_tbl ={}
for i in pairs(contab) do
table.insert(sorted_tbl,i)
end
table.sort(sorted_tbl)
local to_bank_msg = "<xml>"
for i, v in pairs(sorted_tbl) do
if v ~=nil and v ~="" then
if type(contab[v]) == "string" then
to_bank_msg = to_bank_msg .. "\n<" .. v .. "><![CDATA[" .. contab[v] .. "]]></" .. v ..">"
else
to_bank_msg = to_bank_msg .. "\n<" .. v .. ">" .. contab[v] .. "</" .. v ..">"
end
end
end
to_bank_msg = to_bank_msg .. "\n</xml>"
return to_bank_msg
end
--这里是微信service的主类,接收微信过来的事件。
local callback_str = ""
function main()
--获取微信服务器请求过来的内容,根据不同事件做出处理
ngx.req.read_body()
local data = ngx.req.get_body_data()
if not data then --微信服务器验证自己服务器的url,返回随机加密字符串
local args = tools.getArgs()
return args.echostr
else
log(m_uuid,"微信服务器推送过来的内容==" .. data)
local xml_tab=xml.xml2table(data)
log(m_uuid,"解析xml内容==" .. cjson.encode(xml_tab))
local openid = xml_tab.FromUserName
log(m_uuid,"事件中的 openid == " .. openid )
local wx_msgtype_total = xml_tab.MsgType
log(m_uuid,"获取到的推送事件总类型==" .. wx_msgtype_total)
if "event" == wx_msgtype_total then
--相应业务逻辑
elseif "text" == wx_msgtype_total then --这里是接收到文本消息的自动回复
log(m_uuid,"接收文本消息事件")
local content = xml_tab.Content
local msgid = xml_tab.MsgId --排重用
local tousername = xml_tab.ToUserName
local fromusername = xml_tab.FromUserName
local createtime = xml_tab.CreateTime
local replycontent_A = "aaaaaaaaaaaaaa" --tools.gbk_to_u8("内容aaa")
local replycontent_B = tools.gbk_to_u8("内容bbb")
local replytab = {}
replytab.ToUserName = fromusername --!!!这里是个巨大的坑,获取的ToUserName 不能赋值给你返回微信服务器的ToUserName ,要把微信给你的FromUserName值给它
replytab.FromUserName = tousername --!!!这里是个巨大的坑,获取的FromUserName不能赋值给你返回微信服务器的FromUserName,要把微信给你的ToUserName值给它
replytab.CreateTime = tonumber(createtime) --!!!这里要是number类型的
replytab.MsgType = wx_msgtype_total
replytab.Content = replycontent_A
if "A" == content then --如果输入的是A,做出相应的业务逻辑处理
local xmlstr = xml.table2xml(replytab)
log(m_uuid,"接收的文本是A,执行缴费业务介绍回复"..xmlstr)
callback_str=xmlstr
elseif "B" == content then --如果输入的是B,做出相应的业务逻辑处理
log(m_uuid,"接收的文本是B,执行下载APP回复")
end
elseif "image" == wx_msgtype_total then --如果输入的是图片,做出相应的业务逻辑处理
log(m_uuid,"接收图片消息事件")
end
end
return callback_str
end
local result = main()
log(m_uuid,tostring(result))
--给微信服务器响应结果
ngx.say(tostring(result))