记录一次
公众号大量同一时间发送模板,微信回调公众号告诉后台是否发送成功,因为没有业务处理,直接返回的success,报错Event=Template Send Job Finish。
这时候,nginx写了个转发到lua脚本处理请求,期间也出现过各种问题来阻碍我,简直疯了。实测有效~
-- 将请求交给PHP处理
function return_declined()
ngx.req.set_uri('/' .. ngx.var.uri .. '?' .. ngx.var.args, true);
ngx.exit(ngx.DECLINED);
end
-- 读取请求体
ngx.req.read_body();
local content = ngx.req.get_body_data();
if (not content) then
-- 如果请求体是空的, 不处理
return_declined();
end
-- 如果含有TEMPLATESENDJOBFINISH字符串, 响应success
local event = content:match('<Event><!%[CDATA%[(.*)]]></Event>');
if (event == 'TEMPLATESENDJOBFINISH' or event == 'VIEW') then
ngx.say('success');
ngx.exit(ngx.HTTP_OK);
end
-- 读取加密字符串
local encrypted = content:match('<Encrypt><!%[CDATA%[(.*)]]></Encrypt>');
if (not encrypted) then
-- 如果加密字符串是空的, 不处理
return_declined();
else
-- base64解码
local _encrypted = ngx.decode_base64(encrypted);
if (not _encrypted) then
-- 解码失败?
ngx.log(ngx.ERR, 'ngx.decode_base64() failed: ' .. encrypted);
return_declined();
end
encrypted = _encrypted;
end
-- 此处key需要替换为上图中的消息加解密Key
local aes_key = ngx.decode_base64('d9172b8a31042d1d60c8af719acddd89DdWeilyi663=');
local aes = require 'resty.aes';
-- 解密
local decrypted = aes:new(aes_key, nil, aes.cipher(256, 'cbc'), {iv=aes_key:sub(0, 16)}, 5):decrypt(encrypted);
if (not decrypted) then
-- 解密失败?
ngx.log(ngx.ERR, 'openssl.cipher:decrypt() failed: ' .. content);
return_declined();
end
-- ngx.log(ngx.ERR, 'event: ' .. decrypted:match('<Event><!%[CDATA%[([%a]+)]'));
-- 如果含有TEMPLATESENDJOBFINISH字符串, 响应success
if (decrypted:find('TEMPLATESENDJOBFINISH') or decrypted:find('VIEW')) then
ngx.say('success');
ngx.exit(ngx.HTTP_OK);
end
return_declined();