这里有本博客另一篇类似的文章:Firebase应用报错信息发送到企业微信
缘由
最近总会遇到各种需要做及时通知的需求,不管是我们自己的各种性能监测,或者是其他重要的消息推送,总需要提供webhook接口,当然,直接使用比如钉钉或者企业微信接收是可以的,可是总会遇到某些系统(比如是三方的)只支持某一种,甚至都不支持,这个时候就需要有一个做中转的webhook接口,它可以适配各种通知平台,下发消息给钉钉/企业微信等。
思考
很显然,这里的中转webhook
是需要可编程的,我们可以是在一台新的云主机(EC2)上跑一个服务,也可以是在Kubernetes集群中跑一个服务,但是这样总会要提供一个服务,而且这个服务一直存在,一直消耗着资源。这不是我想要的,毕竟通知
这种事情发生的概率并不大,不需要一直消耗资源提供服务。
所以可以选择一个serverless
平台做类似的事情,我们托管代码,按需启动即可,省钱省事,做serverless
的鼻祖是AWS
的Lambda
,我就直接用Lambda
就行。
一个使用aws lambda来实现的例子
这里举个例子,公司使用了一个比较小的SQL审计平台Yearning,里面的webhook只支持钉钉,那我们要支持企业微信的机器人通知,就需要额外代码处理。
前提准备
我们先创建Lambda Function
并在高级选项里面选择Enable function URL
,这表示可以提供外网直接访问的URL
到这个界面就没必要继续添加trigger
或者destination
了,因为AWS整个体系很庞大,这个Lambda Function
可以有上游的触发器(某个事件触发),也可以处理完成后,根据结果,再调用下游的某个系统/接口。
我的代码很简单,就是将转发给钉钉的消息中的text
改成content
,转发给企业微信机器人就行
import json
import requests
def send_wechat(md):
wechat_bot_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"
request_data = md
r = requests.post(wechat_bot_url, data=json.dumps(request_data))
def lambda_handler(event, context):
body = event['body']
body = body.replace('text','content')
c = eval(body)
send_wechat(c)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
这里面的lambda_hander
是我们创建的lambda
入口, 点击Deploy
发布即可
python依赖相关的问题
我们使用postman
调用上面的公网访问URLhttps://xxxx.lambda.url.us-west-2.on.aws
,进入 Monitor
-> Logs
查看最新的日志,会发现报错了!
这是因为requests
并不是python自带的库,需要额外安装,lambda运行时无法识别,需要我们额外处理,有几个办法:
在 AWS Lambda 中,默认情况下是没有安装第三方库的,包括 requests
。您可以采取以下两种方法之一来解决这个问题:
方法一:将 requests
包打包到 Lambda 函数中
-
在本地环境中创建一个目录,并在其中安装
requests
包:mkdir lambda-package cd lambda-package pip install requests -t .
-
将
requests
包及其依赖项打包成一个 ZIP 文件:zip -r9 ../lambda-package.zip .
注意,这里会生成很多依赖的文件库
- 在 AWS Lambda 控制台中创建或更新您的 Lambda 函数,并上传
lambda-package.zip
文件作为函数代码。
方法二:使用 Lambda Layer
-
在本地环境中创建一个目录,并在其中安装
requests
包:mkdir lambda-layer cd lambda-layer pip install requests -t .
-
将
requests
包及其依赖项打包成一个 ZIP 文件:zip -r9 ../lambda-layer.zip .
-
在 AWS Lambda 控制台中创建一个新的 Lambda Layer,上传
lambda-layer.zip
文件作为 Layer 的内容。 -
在 Lambda 函数中将该 Layer 添加到函数的层配置中。
方法三:换一个库,比如使用urllib3
只是简单做一个网络请求的话,urllib3也可以了,并没有麻烦多少
import urllib3
http = urllib3.PoolManager()
wechat_bot_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxx"
md={"key1":"value1","key2":"value2"}
r = http.request('POST', wechat_bot_url, body=json.dumps(md))
这里我选择方法三,因为更快 😃
结果展示
修复上面问题后,内容如下:
最终将yearning
审核平台的消息推送,转接到企业微信:
总结
不管是FAAS
还是Serverless
还是Lambda
,这些并不只是概念里面的词,当我们有一些不那么频繁使用,不太想占用资源的需求是,就可以考虑使用这个技术。比较常见的webhook
,图片处理
,文本处理
等等工具应用场景都可以考虑使用。
评论区