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

使用MS Graph API从VBA发送邮件时遇400错误请求问题

问题分析与解决方案

错误原因

你遇到的400 错误请求是因为**/me端点仅支持委派身份验证流**,而你在VBA中使用的是客户端凭据流(通过Client ID+Client Secret获取令牌),这种流属于应用权限模式——应用本身拥有独立权限,无法用/me指代当前用户,必须明确指定要操作的用户账户。

解决步骤

1. 确认应用权限配置

确保你的Azure Entra ID应用已配置应用权限类型的Mail.Send权限,且已获得管理员同意:

  • 进入Azure Entra ID应用的「API权限」页面
  • 添加权限 → Microsoft Graph → 应用权限 → 搜索Mail.Send并勾选
  • 点击「授予管理员同意」(需要全局管理员或Exchange管理员权限)

2. 修改Graph API请求路径

将原来的/me/sendMail替换为/users/{目标用户邮箱或用户ID}/sendMail,比如目标邮箱是sender@yourdomain.com,则路径为/users/sender@yourdomain.com/sendMail。

3. VBA代码示例

以下是完整的VBA实现逻辑,包含令牌获取与邮件发送:

Sub SendMailWithGraphAPI()
    Dim tenantId As String
    Dim clientId As String
    Dim clientSecret As String
    Dim senderEmail As String
    Dim token As String
    Dim httpObj As Object
    
    ' 替换为你的实际信息
    tenantId = "你的Tenant ID"
    clientId = "你的Client ID"
    clientSecret = "你的Client Secret"
    senderEmail = "发件人邮箱@你的域名.com"
    
    ' 1. 获取应用访问令牌
    Set httpObj = CreateObject("MSXML2.XMLHTTP")
    httpObj.Open "POST", "https://login.microsoftonline.com/" & tenantId & "/oauth2/v2.0/token", False
    httpObj.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    httpObj.Send "grant_type=client_credentials&client_id=" & clientId & "&client_secret=" & clientSecret & "&scope=https://graph.microsoft.com/.default"
    
    ' 解析令牌
    token = Split(Split(httpObj.responseText, """access_token"":""")(1), """")(0)
    
    ' 2. 构造邮件请求并发送
    Dim mailPayload As String
    mailPayload = "{""message"": {" & _
                """subject"": ""VBA测试邮件""," & _
                """body"": {" & _
                    """contentType"": ""Text""," & _
                    """content"": ""这是通过Graph API从Word VBA发送的邮件。""}" & _
                ",""toRecipients"": [{" & _
                    """emailAddress"": {" & _
                        """address"": ""收件人邮箱@example.com""" & _
                    "}" & _
                "}]}" & _
            "},""saveToSentItems"": true}"
    
    httpObj.Open "POST", "https://graph.microsoft.com/v1.0/users/" & senderEmail & "/sendMail", False
    httpObj.setRequestHeader "Authorization", "Bearer " & token
    httpObj.setRequestHeader "Content-Type", "application/json"
    httpObj.Send mailPayload
    
    ' 处理响应结果
    If httpObj.Status = 202 Then
        MsgBox "邮件发送成功!"
    Else
        MsgBox "发送失败:" & vbCrLf & "状态码:" & httpObj.Status & vbCrLf & "详情:" & httpObj.responseText
    End If
    
    Set httpObj = Nothing
End Sub

注意事项

  • 确保VBA项目已启用「Microsoft XML, v6.0」引用(VBA编辑器→工具→引用→勾选对应选项)
  • 发件人邮箱必须是当前租户内的有效用户,应用的Mail.Send权限允许代表该用户发送邮件
  • 若仍有权限报错,再次确认应用权限已添加并完成管理员同意操作

内容的提问来源于stack exchange,提问作者East Anglian Sailing Trust

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:28:15