如何用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
相关产品推荐
相关产品推荐

