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

如何用Scala向Microsoft Graph API发送带JSON邮件数据的POST请求

使用Scala调用Microsoft Graph API发送邮件

1. 添加依赖

先在build.sbt中添加构造JSON和发送HTTP请求所需的依赖:

libraryDependencies ++= Seq(
  "com.typesafe.play" %% "play-json" % "2.9.2",
  "com.typesafe.akka" %% "akka-http" % "10.2.10",
  "com.typesafe.akka" %% "akka-stream" % "2.6.20"
)

2. 构造符合Graph API要求的JSON请求体

根据Graph API的规范,邮件请求体需要包含收件人、主题、内容等字段,我们用Play JSON库将Scala对象转换为标准JSON:

import play.api.libs.json._

// 定义与Graph API请求结构匹配的case class
case class EmailAddress(address: String, name: String)
case class Recipient(emailAddress: EmailAddress)
case class ItemBody(contentType: String, content: String)
case class SendMailMessage(
  subject: String,
  body: ItemBody,
  toRecipients: List[Recipient]
)
case class SendMailRequest(message: SendMailMessage, saveToSentItems: Boolean)

// 生成JSON序列化/反序列化规则
implicit val emailAddressFormat: OFormat[EmailAddress] = Json.format[EmailAddress]
implicit val recipientFormat: OFormat[Recipient] = Json.format[Recipient]
implicit val itemBodyFormat: OFormat[ItemBody] = Json.format[ItemBody]
implicit val sendMailMessageFormat: OFormat[SendMailMessage] = Json.format[SendMailMessage]
implicit val sendMailRequestFormat: OFormat[SendMailRequest] = Json.format[SendMailRequest]

// 构造具体邮件内容
val mailRequest = SendMailRequest(
  message = SendMailMessage(
    subject = "Scala测试邮件",
    body = ItemBody(
      contentType = "HTML", // 可选"Text"纯文本格式
      content = "<h2>测试邮件标题</h2><p>这是通过Scala调用Graph API发送的邮件内容</p>"
    ),
    toRecipients = List(
      Recipient(EmailAddress("target@example.com", "目标收件人"))
    )
  ),
  saveToSentItems = true
)

// 转换为JSON字符串
val jsonBody = Json.toJson(mailRequest).toString()

3. 发送POST请求到Graph API

用Akka HTTP发送带令牌的POST请求:

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.stream.ActorMaterializer
import scala.concurrent.Future

// 初始化Akka运行环境
implicit val system: ActorSystem = ActorSystem("GraphMailSender")
implicit val materializer: ActorMaterializer = ActorMaterializer()
implicit val executionContext = system.dispatcher

// 替换为你已获取的有效访问令牌
val accessToken = "your-valid-access-token"

// Graph API发邮件端点(当前用户发送用/me,应用权限发送需用/users/{user-id}/sendMail)
val endpoint = "https://graph.microsoft.com/v1.0/me/sendMail"

// 构造HTTP请求
val request = HttpRequest(
  method = HttpMethods.POST,
  uri = endpoint,
  headers = List(
    headers.Authorization(headers.OAuth2BearerToken(accessToken)),
    headers.`Content-Type`(ContentTypes.`application/json`)
  ),
  entity = HttpEntity(ContentTypes.`application/json`, jsonBody)
)

// 发送请求并处理响应
val responseFuture: Future[HttpResponse] = Http().singleRequest(request)

responseFuture.onComplete {
  case scala.util.Success(response) =>
    if (response.status.isSuccess) {
      println("邮件发送成功")
    } else {
      response.entity.dataBytes.runFold(ByteString.empty)(_ ++ _).map(_.utf8String).foreach { body =>
        println(s"发送失败,状态码:${response.status},响应详情:$body")
      }
    }
    system.terminate()
  case scala.util.Failure(ex) =>
    println(s"请求出错:${ex.getMessage}")
    system.terminate()
}

关键注意事项

  • 权限配置:确保Azure应用已添加Mail.Send权限(委托权限或应用权限,根据认证方式选择),应用权限需完成管理员同意。
  • 令牌范围:获取令牌时,请求的scope必须包含https://graph.microsoft.com/Mail.Send。
  • 端点适配:如果是服务端用应用权限发送,需替换端点为https://graph.microsoft.com/v1.0/users/{目标用户ID}/sendMail。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:54:24