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

Azure Function App通过Graph API发邮件本地正常云端失效

问题排查思路与解决方案

首先从你贴出的函数执行日志就能定位到最高概率的根因:整个函数从打印发送邮件日志到标记执行成功仅间隔1ms,根本没有等待Graph API请求返回就结束了进程,先从代码层排查修复:

  • 你贴出的axios调用只展示了try块开头,既没有等待请求完成的后续逻辑,也没有异常捕获逻辑,大概率是Blob触发函数的主入口没有await这个异步发信方法。非HTTP触发的Azure Function只要主函数执行完毕就会直接回收工作进程,挂起的异步请求会被直接掐断,不会等待响应返回,所以你会看到函数显示执行成功,但实际Graph请求根本没完成发送流程。
    参考修正代码:
    // 函数入口必须标记为async,所有异步操作必须显式await
    module.exports = async function(context, myBlob) {
      context.log("BEGIN: Sending email for failed referral via Graph API.");
      context.log(`Blob Name: ${context.bindingData.blobTrigger}`);
      // 省略获取access_token、构造email参数的逻辑
      try {
        const response = await axios({
          url: `${GRAPH_ENDPOINT}/v1.0/users/${FROM_ADDRESS}/sendMail`,
          method: "POST",
          headers: {
            "Authorization": `Bearer ${access_token}`,
            "Content-Type": "application/json",
          },
          // 注意:axios会自动将JS对象序列化为JSON,无需手动调用JSON.stringify,重复序列化反而会导致请求格式错误
          data: email,
        });
        // 必须打印响应状态做校验:sendMail接口成功的返回状态码是202 Accepted,不是200
        context.log(`Graph API call success, status code: ${response.status}`);
      } catch (err) {
        // 必须添加catch块打印完整错误,禁止吞掉异常静默返回成功
        const errMsg = err.response ? JSON.stringify(err.response.data) : err.message;
        context.log.error(`Send mail failed: ${errMsg}`);
        // 抛出错误让函数标记为执行失败,触发平台重试逻辑
        throw err;
      }
    };
    
  • 你代码中data: JSON.stringify(email)属于冗余操作,axios传入对象类型的data参数时会自动做JSON序列化,手动重复序列化会导致请求体格式不符合Graph API要求,部分场景下会被服务端直接丢弃请求且不返回明确错误。

如果修复代码异步问题后仍然无法收到邮件,按以下优先级排查配置问题:

  1. 校验访问令牌有效性
    你提到Application Insights中能看到令牌请求和Graph调用记录,但需要确认令牌本身是合法的:
    • 解码拿到的access_token,确认aud声明值为https://graph.microsoft.com,不是其他服务的资源端点
    • 确认roles声明中包含Mail.Send应用权限,不要误拿到委派权限的令牌
    • 确认令牌中的appid和你授予Mail.Send权限、做过管理员同意的AAD应用ID完全一致
  2. 排查VNET路由拦截问题
    你开启了route-all将所有流量路由到内部网络,这里存在明显的配置误区:
    • 调用Microsoft Graph发信走的是443端口的HTTPS协议,根本不经过25、587的SMTP端口,你之前放通SMTP端口的操作对Graph调用完全无效
    • 检查内部代理、防火墙、NSG规则是否放通了Function到Graph API端点的443出站流量,确认你放通的M365网段包含Graph服务的地址段,不要只放通Exchange SMTP相关网段
    • 可以在函数中加一段测试逻辑,直接请求Graph的元数据端点,验证到Graph服务的网络连通性
  3. 校验Exchange Online侧配置
    • 确认FROM_ADDRESS对应的是真实存在、未被禁用的Exchange Online邮箱,没有配置传输规则静默删除应用身份发送的邮件
    • 应用权限调用Graph发信不需要将邮箱加入特殊邮件组,只要AAD应用完成管理员授权即可调用,你配置的邮件组权限属于冗余操作,检查是否是该邮件组关联的传输规则反而拦截了邮件
    • 到Exchange管理中心查询发件邮箱的完整邮件跟踪日志,不要只查收件侧日志,确认邮件是否被反垃圾邮件策略、传输规则拦截
  4. 快速验证方法
    临时关闭Function的VNET集成,让出站流量走Azure默认公网出口测试发信,如果关闭VNET后能正常发信,可100%确认问题出在VNET路由、防火墙或NSG的443端口拦截配置上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 08:48:25