如何创建按需运行的Python通知服务(基于Webhooks)
实现方案:基于Webhooks的按需通知服务(Heroku部署)
1. 核心思路适配Heroku特性
Heroku的休眠机制刚好匹配你的"按需运行"需求——无请求时自动休眠,有HTTP请求触发时快速唤醒。所以核心逻辑很简单:把通知服务做成一个轻量HTTP服务,只暴露一个Webhook接收端点,完全由业务应用的请求触发通知操作,不需要后台常驻进程。
2. 定义Webhook请求规范
为了让多应用对接不混乱,统一请求格式(用JSON),示例如下:
{ "app_id": "order-service", "notification_type": "email", "recipient": "user@example.com", "content": "您的订单已发货,快递单号:123456", "metadata": {"order_id": "OD-7890"} }
app_id:标记发起请求的业务应用,方便后续排查和权限控制notification_type:指定通知渠道(邮件/短信/推送等),服务端根据这个调用对应发送逻辑recipient:接收目标(邮箱/手机号/设备ID)content:通知主体内容metadata:可选附加信息,用于个性化通知
3. 服务端核心代码实现(Python/Flask示例)
用Flask写一个极简的服务,适配Heroku的端口要求:
from flask import Flask, request, jsonify import os import smtplib from email.mime.text import MIMEText app = Flask(__name__) # 邮件发送逻辑(替换成你的实际配置) def send_email(recipient, content): msg = MIMEText(content) msg['Subject'] = '系统通知' msg['From'] = 'notifications@yourdomain.com' msg['To'] = recipient with smtplib.SMTP('smtp.yourdomain.com', 587) as server: server.starttls() server.login(os.environ.get('EMAIL_USER'), os.environ.get('EMAIL_PWD')) server.send_message(msg) # Webhook接收端点 @app.route('/webhook/notify', methods=['POST']) def handle_notify(): try: payload = request.get_json() # 可选:添加请求签名验证,防止恶意调用 # if not validate_signature(request.headers.get('X-Signature'), payload): # return jsonify({"status": "error", "msg": "无效签名"}), 403 # 根据通知类型分发任务 if payload['notification_type'] == 'email': send_email(payload['recipient'], payload['content']) elif payload['notification_type'] == 'sms': # 这里替换成短信API调用逻辑 pass # 可扩展更多通知渠道 return jsonify({"status": "success"}), 200 except Exception as e: return jsonify({"status": "error", "msg": str(e)}), 500 if __name__ == '__main__': # 读取Heroku自动分配的端口 port = int(os.environ.get('PORT', 5000)) app.run(host='0.0.0.0', port=port)
4. Heroku部署配置
- 新建
requirements.txt,列出依赖:
Flask==2.3.3
- 新建
Procfile,告诉Heroku启动命令:
web: python app.py
- 部署步骤:
- 本地用Git托管代码
- 关联Heroku远程仓库:
heroku git:remote -a 你的应用名称 - 推送代码:
git push heroku main
- 休眠无需额外配置:Heroku会自动在30分钟无请求后休眠,下一次请求触发唤醒(延迟约1-3秒,对通知场景完全可接受)
5. 业务应用对接方式
任何业务应用只需在需要发通知时,向你的Heroku应用URL发送POST请求即可。比如用curl测试:
curl -X POST https://你的应用名称.herokuapp.com/webhook/notify \ -H "Content-Type: application/json" \ -d '{ "app_id": "order-service", "notification_type": "email", "recipient": "user@example.com", "content": "您的订单已发货" }'
应用内可以用各自语言的HTTP客户端实现(比如Java的OkHttp、Node.js的axios)。
6. 优化建议
- 请求验证:给每个业务应用分配密钥,请求时用HMAC对payload签名,服务端验证签名,防止恶意请求
- 重试机制:如果通知发送失败(比如邮件服务器超时),可以把失败任务存入Heroku Redis插件,用Heroku Scheduler定时触发重试脚本
- 日志监控:用
heroku logs --tail实时查看日志,或者集成日志服务排查问题 - 限流:用Flask-Limiter之类的库限制请求频率,避免服务过载
内容的提问来源于stack exchange,提问作者vitxr
相关产品推荐
相关产品推荐

