当前位置: 首页 > 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 = ngxlocal 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 thenngx.status = 400ngx.say('{"error": "no request body"}')returnend-- 解析 JSON 数据local data, err = cjson.decode(req_body)if not data thenngx.status = 400ngx.say('{"error": "invalid json format"}')returnend-- 转换数据为企业微信 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"}
}-- 调用企业微信 Webhooklocal httpc = http.new()local full_url = "https://qyapi.weixin.qq.com" .. ngx.var.request_urilocal res, err = httpc:request_uri(full_url, {method = "POST",body = cjson.encode(msg),headers = {["Content-Type"] = "application/json"},ssl_verify = false })-- 如果请求失败,返回错误信息if not res thenngx.status = 500ngx.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))returnend-- 解析企业微信返回的响应local response = cjson.decode(res.body)-- 根据企业微信返回的响应构建新的响应格式local response_msg = {ec = 200,em = "",  -- em 字段为空}-- 如果响应成功,更新 em 字段为 "",如果有错误,返回相应的 errmsgif response.errcode ~= 0 thenresponse_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()-- 构建完整的 URLlocal 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 thenngx.status = 502ngx.say('{"error": "Bad Gateway"}')returnend-- 返回原始响应ngx.status = res.statusfor k, v in pairs(res.headers) dongx.header[k] = vendngx.say(res.body)end}
}

5、测试

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

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

http://www.dtcms.com/a/449307.html

相关文章:

  • 四川红叶建设有限公司网站长沙专业做网站
  • 光通信|模分复用技术-综述
  • Powercat内网端口转发实战:穿透边界服务器获取Shell
  • 千万级用户电商平台,Flink实时推荐系统如何实现毫秒级延迟?
  • 安装好vscode后,缺少vscode打开文件或文件夹选项
  • 装修网站开发思路用ps怎么做网站背景
  • 郑州网站zhi zuo网站开发+接活
  • NPM packages not found
  • user-interface 概念及题目
  • Asp.net core用Swashbuckle.AspNetCore库出现错误信息:No operations defined in spec!
  • 苏州做网站企业行业前10的网站建设
  • 鸿蒙NEXT网络通信进阶:全方位优化HTTP传输性能
  • 2025年--Lc166--H103.二叉树的锯齿形层序遍历(二叉树的层序遍历)--Java版
  • 做服装的网站淮北市建网站
  • 襄阳网站推广优化技巧宿州市建设工程质量监督站网站
  • 《从踩坑到精通:边缘网关在物联网场景下的实践与优化指南》
  • 光通信|神经网络助力OAM模式快速解调
  • CodeBuddy CLI全攻略:从安装到实战及文档化编程深度思考
  • 两个无重叠子数组的最大和
  • linux网络服务+linux数据库3
  • 206-基于深度学习的胸部CT肺癌诊断项目的设计与实现
  • 二叉树进阶面试题:最小栈 栈的压入·弹出序列 二叉树层序遍历
  • 【大模型LLMs】LangGraph实战:引入网络搜索tool和Memory机制的对话Agent案例
  • 企业网站开发毕业报告网络营销的推广工具
  • 手机网站开发需要哪些人百度广告联盟怎么加入
  • 书生浦语实战营第六期 L1-G3000
  • 前端IM应用开发中的难点解析与总结
  • Web 服务器 UserDir(~username)功能解析:从原理到安全实践
  • 25新三年级上册数学混合运算应用题八大专项+三年级上数学混合运算练习/八大考点(复合问题/倍数问题)+完整电子版可下载打印
  • Linux基础IO(下):文件重定向和缓冲区