You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask物联网监控应用阈值触发时无法向登录用户发邮件

问题解决:Flask-Mail发送Gmail邮件连接断开+阈值触发邮件失败

核心问题分析

你遇到的smtplib.SMTPServerDisconnected: 连接意外关闭错误,核心原因是SMTP配置参数不匹配,同时current_user在API路由中存在未验证登录状态的潜在问题,可能导致邮件无法正常发送。

分步修复方案

1. 修正Gmail SMTP配置(解决连接断开问题)

Gmail的SMTP端口与加密方式是严格对应的:

  • 端口465:必须使用SSL加密
  • 端口587:必须使用TLS加密

你当前的配置将465与TLS绑定,完全不符合Gmail的要求,导致服务器主动断开连接。修改__init__.py中的配置:

from flask_mail import Mail
mail = Mail()
def create_app():
    app = Flask(__name__)
    app.config.update(dict(
        MAIL_DEBUG = True,
        MAIL_SERVER = 'smtp.gmail.com',
        MAIL_PORT = 465,
        MAIL_USE_TLS = False,  # 改为False,465端口用SSL
        MAIL_USE_SSL = True,   # 改为True
        MAIL_USERNAME = 'sample@gmail.com',
        MAIL_PASSWORD = '你的应用密码',  # 确保是开启两步验证后生成的应用密码
        MAIL_DEFAULT_SENDER = 'sample@gmail.com'  # 统一发件人,避免权限校验失败
    ))
    mail.init_app(app)
    # 记得补充注册蓝图、初始化数据库等其他逻辑
    return app

2. 确保current_user在API路由中有效(解决无收件人/报错问题)

你的/gas_value和/current_value是API接口,若前端通过AJAX请求,必须确保请求携带用户会话Cookie,同时添加登录验证避免未登录时触发邮件逻辑报错。修改views.py:

from flask_login import login_required, current_user
# ...其他导入代码

@views.route('/gas_value')
@login_required  # 强制登录验证,确保只有已登录用户能触发警报
def gas_value():
    gas_value = mq6_modules[0].mq.MQPercentage()["GAS_LPG"]
    if gas_value >= 0.2:
        gas_reading = GasReading(value=gas_value)
        db.session.add(gas_reading)
        db.session.commit()
        # 先检查用户邮箱是否存在,避免空值报错
        if current_user.email:
            send_email(
                '燃气浓度过高警报',
                f'检测到燃气浓度值为{gas_value},已超过阈值0.2',
                current_user.email
            )
    return jsonify({'gas_value': gas_value})

@views.route('/current_value')
@login_required  # 添加登录验证
def current_value():
    current_value = powers[0].get_electricalsensor_readings()
    if current_value is not None:
        current_value_float = float(current_value)
        response = {'current_value': current_value}
        if current_value_float >= 0.2:
            current_reading = CurrentReading(value=current_value_float)
            db.session.add(current_reading)
            db.session.commit()
            if current_user.email:
                send_email(
                    '电流负载过高警报',
                    f'检测到电流值为{current_value_float},已超过阈值0.2',
                    current_user.email
                )
        return jsonify(response)
    else:
        return jsonify({'current_value': 'Unavailable'})

3. 验证Gmail账户配置

  • 确保账户已开启两步验证,应用密码是在两步验证开启后生成的(Gmail已废弃低安全应用访问,必须用应用密码)
  • 应用密码是16位无空格字符串,确认输入无错误

4. 测试邮件发送

添加测试路由验证配置是否正常:

@views.route('/test_email')
@login_required
def test_email():
    try:
        send_email('测试邮件', '这是一封测试邮件', current_user.email)
        return '邮件发送成功'
    except Exception as e:
        return f'发送失败:{str(e)}'

额外优化建议

  • 避免邮件轰炸:在数据库中记录最后一次发送警报的时间,设置冷却周期(如5分钟),防止阈值反复触发导致频繁发信
  • 添加异常捕获:修改send_email函数捕获异常,避免邮件发送失败导致整个请求崩溃:
from flask_mail import Message
from . import mail
import traceback

def send_email(subject, body, recipient_email):
    try:
        msg = Message(subject, recipients=[recipient_email], sender='noreply@demo.com')
        msg.body = body
        mail.send(msg)
        return True
    except Exception as e:
        print(f"邮件发送失败: {str(e)}")
        traceback.print_exc()
        return False

内容的提问来源于stack exchange,提问作者Ae gis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 08:15:03