当前位置: 首页 > news >正文

完整教程:爱发电nginx转发企业微信webhook

问题

由于爱发电的webhook格式,与企业微信的webhook格式不一致,因此我将介绍如何使用nginx来实现中间件修改内容。

使用条件

1、保证你有一台公网可以访问的服务器
2、保证你已经可以登录企业微信,并且可以创建webhook机器人

分析

爱发电的请求格式:

{
"ec": 200,
"em": "ok",
"data": {
"type": "order",
"order": {
"out_trade_no": "20210",
"user_id": "adf397fe",
"plan_id": "a4535",
"month": 1,
"total_amount": "5.00",
"show_amount": "5.00",
"status": 2,
"remark": "",
"redeem_id": "",
"product_type": 0,
"discount": "0.00",
"sku_detail": [],
"address_person": "",
"address_phone": "",
"address_address": ""
}
}
}

响应格式:

{"ec":200,"em":""}

因为爱发电的文档说了跟没说一样,这里就不贴文档链接了。

企业微信的请求格式:
企业微信webhook说明文档
请求格式:

{
"msgtype": "markdown",
"markdown": {
"content": "test<font color=\"warning\">132例</font>test2\n>类型:<font color=\"comment\">test3</font>\n>test4<font color=\"comment\">test5/font>\n>test6<font color=\"comment\">test7</font>"
}
}

响应格式:

{"errcode":0,"errmsg":"ok"}

因此要对请求和响应都要做修改,否则会出现格式不对,导致发送webhook失败。
大致思路是这样的:
在这里插入图片描述

开始配置

1、1panel 安装 openresty

OpenResty 是在 Nginx 基础上扩展了一整套 Lua 能力的增强版 Nginx。

安装完成后,点击网站,创建。
选择反向代理。
主域名填服务器的域名,代理地址随便填,因为等下用不上。
在这里插入图片描述

2、配置DNS

点击配置
在这里插入图片描述
点击配置文件
在这里插入图片描述
因为等下使用的lua_resty_http没有自己的DNS,必须要人工设置一个进去。
在这里插入图片描述
在server_name下面添加,这里我添加了两个常用的DNS服务器地址

resolver 223.5.5.5 119.29.29.29 valid=300s;

3、添加lua_resty_http

下载仓库:https://github.com/ledgetech/lua-resty-http
提取 lib/resty下的三个lua文件。
接着放到这个目录下,如果你是用docker也是一样的

/opt/1panel/apps/openresty/openresty/lualib/resty/http/http_headers.lua
/opt/1panel/apps/openresty/openresty/lualib/resty/http/http_connect.lua
/opt/1panel/apps/openresty/openresty/lualib/resty/http/http.lua

接着映射文件到这个路径,使得nginx可以搜索到lua脚本

/usr/local/openresty/lualib/resty/http_headers.lua
/usr/local/openresty/lualib/resty/http_connect.lua
/usr/local/openresty/lualib/resty/http.lua

4、修改location配置

你可以理解为匹配请求路径并定义响应规则
路径在你创建的代理配置中:
/opt/1panel/apps/openresty/openresty/www/sites/xxxxxxxx/proxy/xxxxxx.conf
如果你是用自己的openresty,就要把这个代理配置添加到你的server块中。

说明:
1、该代码块实现了两个功能,爱发电的key使用特殊的逻辑来转换,非爱发电的key就直接透传转发。
2、下面的key == “XXX”,对应着企业微信webhook的参数key的内容,只有这里需要你把对应的key填入。

location ^~ /cgi-bin/webhook/send {
content_by_lua_block {
local cjson = require "cjson"
local ngx = ngx
local http = require "resty.http"
-- 获取查询参数 'key'
local args = ngx.req.get_uri_args()
local key = args.key
-- 检查是否需要转换
if key == "XXX" then
-- 获取请求的 JSON 数据
ngx.req.read_body()
local req_body = ngx.req.get_body_data()
-- 如果请求体为空,直接返回 400 错误
if not req_body then
ngx.status = 400
ngx.say('{"error": "no request body"}')
return
end
-- 解析 JSON 数据
local data, err = cjson.decode(req_body)
if not data then
ngx.status = 400
ngx.say('{"error": "invalid json format"}')
return
end
-- 转换数据为企业微信 Webhook 接口需要的格式
local msg = {
msgtype = "markdown",
markdown = {
content = "### 新订单通知\n\n" ..
"**订单号**:<font color=\"warning\">" .. data.data.order.out_trade_no .. "</font>\n\n" ..
"**用户ID**:<font color=\"comment\">" .. data.data.order.user_id .. "</font>\n\n" ..
"**计划ID**:<font color=\"comment\">" .. data.data.order.plan_id .. "</font>\n\n" ..
"**订单状态**:<font color=\"comment\">" .. (data.data.order.status == 2 and "待支付" or "已支付") .. "</font>\n\n" ..
"**金额**:<font color=\"comment\">" .. data.data.order.total_amount .. "</font>\n\n" ..
"**折扣**:<font color=\"comment\">" .. data.data.order.discount .. "</font>\n\n" ..
"**产品类型**:<font color=\"comment\">" .. (data.data.order.product_type == 0 and "普通商品" or "VIP商品") .. "</font>\n\n" ..
"**用户备注**:<font color=\"comment\">" .. (data.data.order.remark == "" and "无" or data.data.order.remark) .. "</font>\n\n" ..
"### 地址信息\n\n" ..
"**收货人**:<font color=\"comment\">" .. (data.data.order.address_person == "" and "无" or data.data.order.address_person) .. "</font>\n\n" ..
"**电话**:<font color=\"comment\">" .. (data.data.order.address_phone == "" and "无" or data.data.order.address_phone) .. "</font>\n\n" ..
"**地址**:<font color=\"comment\">" .. (data.data.order.address_address == "" and "无" or data.data.order.address_address) .. "</font>\n\n"
}
}
-- 调用企业微信 Webhook
local httpc = http.new()
local full_url = "https://qyapi.weixin.qq.com" .. ngx.var.request_uri
local res, err = httpc:request_uri(full_url, {
method = "POST",
body = cjson.encode(msg),
headers = {
["Content-Type"] = "application/json"
},
ssl_verify = false
})
-- 如果请求失败,返回错误信息
if not res then
ngx.status = 500
ngx.say('{"error": "failed to forward request", "info": "' .. (err or "unknown error") ..'"}')
ngx.log(ngx.ERR, "Failed to forward request to WeChat: " .. (err or "unknown error"))
ngx.log(ngx.ERR, "body : " .. cjson.encode(msg))
return
end
-- 解析企业微信返回的响应
local response = cjson.decode(res.body)
-- 根据企业微信返回的响应构建新的响应格式
local response_msg = {
ec = 200,
em = "",  -- em 字段为空
}
-- 如果响应成功,更新 em 字段为 "",如果有错误,返回相应的 errmsg
if response.errcode ~= 0 then
response_msg.em = response.errmsg or "unknown error"
end
-- 发送修改后的响应
ngx.header.content_type = "application/json"
ngx.say(cjson.encode(response_msg))
else
-- 直接转发请求到企业微信
local httpc = http.new()
-- 读取原始请求体
ngx.req.read_body()
local req_body = ngx.req.get_body_data()
-- 构建完整的 URL
local full_url = "https://qyapi.weixin.qq.com" .. ngx.var.request_uri
-- 转发请求
local res, err = httpc:request_uri(full_url, {
method = ngx.var.request_method,
body = req_body,
headers = ngx.req.get_headers(),
ssl_verify = false
})
if not res then
ngx.status = 502
ngx.say('{"error": "Bad Gateway"}')
return
end
-- 返回原始响应
ngx.status = res.status
for k, v in pairs(res.headers) do
ngx.header[k] = v
end
ngx.say(res.body)
end
}
}

5、测试

在爱发电的网站上有测试按钮,可以直接使用它进行测试。
在这里插入图片描述

因为我的服务器已经支持了 https协议,所以我只需要把 企业微信的webhook URL中的域名,替换成我自己的域名,就可以直接拿来使用。
不建议直接使用 http协议,有安全隐患。

http://www.jsqmd.com/news/33339/

相关文章:

  • The 2025 ICPC Asia Wuhan Regional Contest
  • python 字符串压缩(字符串-中等)含源码(九) - 教程
  • 贪心(2)——按位异或
  • 2025年基因导入仪制造厂技术实力排名白皮书,基因导入仪厂家推荐
  • 学术会议合集 | 声学、流体力学、当代体育、信息技术等EI会议合集
  • 统一Git提交信息
  • 小鹏 IRON 机器人因 “太像人” 遭质疑?
  • Rockyos10 网卡配置固定IP
  • 2025 年安规测试仪源头厂家最新推荐排行榜:综合耐压电气等多类型设备品牌深度测评与靠谱厂家筛选三项/新能源/光伏安规测试仪公司推荐
  • 2025年广州电商交易平台权威推荐榜单:b2b系统/电商平台/企业数字化平台精选
  • 2025年海南消防设施维修培训权威推荐:海口消防设施检测/三亚中级证机构/海南消防设施操作员机构精选
  • 从上位机到边缘计算:Linux 正在统治整个工业世界
  • 2025年口碑好的特级酒精生产厂家排行榜,推荐一下特级酒精生产厂家
  • 2025 年最新推荐钢花管源头厂家排行榜:聚焦高强度耐腐蚀环保型产品,精选五大靠谱品牌实测推荐地质钢花管/桩基钢花管/R780 地质钢花管公司推荐
  • Ubuntu 如何在桌面添加应用快捷方式 - 阿源
  • 2025 年 11 月景观不锈钢护栏,灯光不锈钢护栏,河道不锈钢护栏厂家最新推荐,聚焦资质、案例、售后的十家机构深度解读!
  • 2025年厂房装修定制公司新推荐排行榜白皮书,厂房装修怎么选
  • 2025年温州新能源导电连接企业口碑排名:浙江中燕企业解析
  • 2025 最新推荐!降血糖咨询服务平台推荐权威发布,绿色干预理念引领,行业标杆品牌甄选降血糖推荐
  • 2025 年 11 月复合管不锈钢护栏,绳索不锈钢护栏,防撞立柱不锈钢护栏厂家最新推荐,实力品牌深度解析采购无忧之选!
  • 2025年初榨橄榄油优质厂家权威推荐榜单:橄榄果渣油/纯正橄榄油/精炼橄榄油源头厂家精选
  • 【IEEE出版 | 往届已EI检索,发表有保障!】第二届智能船舶与机电系统国际学术会议(ICISES 2025)
  • 【IEEE出版 | 往届快至会后4个月EI检索!】第五届智能电网与能源互联网国际会议(SGEI 2025)
  • 客户案例|思念食品x燕千云AI-ITR,构建智能协同的客户服务流体系
  • 详细介绍:企业级数据库实操手册:从架构部署到安全运维的落地指南
  • 2025 年 11 月热泵刮板蒸发器,多效蒸发器,蒸汽刮板蒸发器厂家最新推荐,聚焦资质、案例、售后的五家机构深度解读!
  • 2025 年 11 月低温蒸发器,低温热泵蒸发器,热泵刮板蒸发器厂家最新推荐,聚焦资质、案例、售后的五家机构深度解读!
  • 导致Resources文件夹的资源在Android打包后丢失的原因
  • 2025年江苏医疗器械CE认证服务商权威推荐:江苏电子产品CE认证/江苏电器CE认证/江苏灯具CE认证服务机构精选
  • 银行转账惊魂记:MySQL事务与隔离级别的奇幻冒险 - 详解