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

如何使用Scala通过Graph API生成令牌并发送邮件通知

Scala实现Microsoft Graph API令牌生成(客户端凭证模式)

以下是对应你提供的Python代码的Scala版本,实现相同的客户端凭证模式获取Graph API访问令牌功能,提供两种常用实现方式:

方式一:使用Java HttpClient(依赖少,Scala兼容)

这种方式无需额外的Scala HTTP库,直接使用Java标准库的HttpClient,搭配轻量JSON解析库ujson:

import java.net.URI
import java.net.http.{HttpClient, HttpRequest, HttpResponse}
import java.nio.charset.StandardCharsets
import scala.jdk.CollectionConverters._

object GraphTokenGenerator {
  private val TOKEN_URL = "https://login.microsoftonline.com/bgd57sd-dsd-4b9d-b9c5-0f64b6755421/oauth2/token"

  def getAccessToken(url: String): String = {
    // 从环境变量读取客户端ID和密钥
    val clientId = sys.env("AD_APP_ID")
    val clientSecret = sys.env("AD_APP_SECRET")

    // 构造URL编码的表单参数
    val formData = Map(
      "client_id" -> clientId,
      "client_secret" -> clientSecret,
      "grant_type" -> "client_credentials",
      "resource" -> "https://graph.microsoft.com"
    ).map { case (key, value) =>
      s"$key=${java.net.URLEncoder.encode(value, StandardCharsets.UTF_8.name())}"
    }.mkString("&")

    // 创建并发送POST请求
    val client = HttpClient.newHttpClient()
    val request = HttpRequest.newBuilder()
      .uri(URI.create(url))
      .header("Content-Type", "application/x-www-form-urlencoded")
      .POST(HttpRequest.BodyPublishers.ofString(formData))
      .build()

    // 解析响应JSON,提取access_token
    val response = client.send(request, HttpResponse.BodyHandlers.ofString())
    val json = ujson.read(response.body())
    json("access_token").str
  }

  def main(args: Array[String]): Unit = {
    val accessToken = getAccessToken(TOKEN_URL)
    println(accessToken)
  }
}

依赖配置(build.sbt)

libraryDependencies += "com.lihaoyi" %% "ujson" % "3.1.2"

方式二:使用Akka HTTP(Scala异步HTTP库)

如果你的项目已经使用Akka生态,推荐用这种异步实现:

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.ActorMaterializer
import scala.concurrent.{ExecutionContextExecutor, Future}
import scala.util.{Failure, Success}

object GraphTokenAkka {
  private val TOKEN_URL = "https://login.microsoftonline.com/bgd57sd-dsd-4b9d-b9c5-0f64b6755421/oauth2/token"

  def main(args: Array[String]): Unit = {
    implicit val system: ActorSystem = ActorSystem("GraphTokenSystem")
    implicit val materializer: ActorMaterializer = ActorMaterializer()
    implicit val executionContext: ExecutionContextExecutor = system.dispatcher

    val clientId = sys.env("AD_APP_ID")
    val clientSecret = sys.env("AD_APP_SECRET")

    // 构造表单数据
    val formData = FormData(
      "client_id" -> clientId,
      "client_secret" -> clientSecret,
      "grant_type" -> "client_credentials",
      "resource" -> "https://graph.microsoft.com"
    )

    // 构建HTTP请求
    val request = HttpRequest(
      method = HttpMethods.POST,
      uri = TOKEN_URL,
      entity = formData.toEntity(HttpCharsets.`UTF-8`)
    )

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

    responseFuture.onComplete {
      case Success(response) =>
        Unmarshal(response.entity).to[String].map { body =>
          val json = ujson.read(body)
          val accessToken = json("access_token").str
          println(accessToken)
          system.terminate()
        }
      case Failure(ex) =>
        println(s"请求失败: ${ex.getMessage}")
        system.terminate()
    }
  }
}

依赖配置(build.sbt)

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-http" % "10.2.10",
  "com.typesafe.akka" %% "akka-stream" % "2.6.20",
  "com.lihaoyi" %% "ujson" % "3.1.2"
)

注意事项

  • 确保环境变量AD_APP_ID和AD_APP_SECRET已正确设置
  • 两种实现均遵循原Python代码的逻辑,使用客户端凭证授权模式
  • 若偏好其他JSON解析库,可将ujson替换为Play JSON、Circe等

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 11:03:19