使用 Scala 和 Play WS 将内联图像添加到 Mailgun 电子邮件

Adding inline images to Mailgun emails using Scala and Play WS

我可以成功地向 Mailgun 发出 POST 请求并按预期收到电子邮件。我正在尝试将图像内嵌到电子邮件中,但不知道该怎么做。

查看 https://documentation.mailgun.com/user_manual.html#sending-via-api 并选择 Java,我可以看到给出的示例使用 "inline"File 引用和媒体类型。查看 curl 示例,这似乎是不必要的,因为它只是引用了一个文件。

这是我发送电子邮件的方法:

  def send(message:EmailMessage) = {
    val postMessage = Map("from" -> Seq(message.from), "to" -> Seq(message.to), "subject" -> Seq(message.subject), "text" -> Seq(message.text), "html" -> Seq(message.html.toString()))
    val logo = FileBody(Play.getExistingFile("/public/images/logo.png").get)
    WS.url(apiUrl).withAuth("api", myKey, WSAuthScheme.BASIC).withBody(logo).post(postMessage)
  }

message.html.toString 如下所示:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body style="background-color:#9B59B6; padding:10px">
    <img src="cid:logo.png">
    <h1 style="color:#FFF">Activate!</h1>
</body>
</html>

发送邮件时发现logo.png文件,邮件顺利通过,但没有图像。这是电子邮件源到达 gmail 后的样子:

Mime-Version: 1.0
Content-Type: text/html; charset="ascii"
Content-Transfer-Encoding: 7bit

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    </head>
    <body style="background-color:#9B59B6; padding:10px">
        <img src="cid:logo.png">
        <h1 style="color:#FFF">Activate!</h1>
    </body>
</html>

我在电子邮件中看不到图像的任何 base64 编码。由于 curl 示例似乎只是将文件作为 POST 的一部分传递,我虽然会尝试这样做。这是我所做的:

  def send(message:EmailMessage) = {

    val logoFile = Play.getExistingFile("/public/images/logo.png").get
    val source = Files.readAllBytes(Paths.get(logoFile.getAbsolutePath))
    val logoBase64 = Base64.encodeBase64String(source)

    val postMessage = Map("from" -> Seq(message.from), "to" -> Seq(message.to), "subject" -> Seq(message.subject), "text" -> Seq(message.text), "html" -> Seq(message.html.toString()), "inline" -> Seq(logoBase64))
    WS.url("https://api.mailgun.net/v2/sandboxaa9afcea1f2e4d5db5e2c080f7784b74.mailgun.org/messages").withAuth("api", "key-f165695d4c72e929ff8215115e648c95", WSAuthScheme.BASIC).post(postMessage)
  }

我将徽标转换为 base64 并像其他参数一样 POSTed。还是不开心。

我在这里错过了什么?我是否需要在正文中传递它,但以某种方式指定这是一个 "inline" 文件?

我使用 Jersey 解决了这个问题,正如库部分所建议的:https://documentation.mailgun.com/libraries.html#java

我使用以下方法在 sbt 中导入了 Jersey:

libraryDependencies += "com.sun.jersey" % "jersey-core" % "1.18.3"

libraryDependencies += "com.sun.jersey" % "jersey-client" % "1.18.3"

libraryDependencies += "com.sun.jersey.contribs" % "jersey-multipart" % "1.18.3"

然后像这样创建我的电子邮件发送对象:

object Email {

  val client = Client.create()
  client.addFilter(new HTTPBasicAuthFilter("api", current.configuration.getString("mailgun.api.key").get))
  val webResource = client.resource(current.configuration.getString("mailgun.api.url").get)

  def send(message:EmailMessage) = {
    val form = new FormDataMultiPart
    form.field("from", message.from)
    form.field("to", message.to)
    form.field("subject", message.subject)
    form.field("text", message.text)
    form.field("html", message.html.toString())
    val logo = Play.getExistingFile("/public/images/logo.png").get
    form.bodyPart(new FileDataBodyPart("inline", logo, MediaType.APPLICATION_OCTET_STREAM_TYPE))

    webResource.`type`(MediaType.MULTIPART_FORM_DATA_TYPE).post(form)
  }
}

我希望这对某人有所帮助。