Play JSON
The play-json
sub module provides Reads
and Writes
instances for all API models.
Dependency
In your build.sbt
add the module to the library dependencies.
libraryDependencies += "net.gutefrage.mandrill" %% "play-json" % "<version>"
Usage
Convert a send-template
request to json requires the following steps.
First import all necessary classes and instances.
import net.gutefrage.mandrill._
import net.gutefrage.mandrill.core._
import net.gutefrage.mandrill.playjson.messages._
import play.api.libs.json.Json
Next, create a send-template
request:
val apiKey = MandrillApiKey("your-api-key")
val sendTemplateBody = Mandrill(apiKey).
messages.
sendTemplate("my-template-slug").
to("foo@bar.com")
This request can be serialized to json with
val json = Json.toJson(sendTemplateBody)
// json: play.api.libs.json.JsValue = {"key":"your-api-key","template_name":"my-template-slug","to":[{"email":"foo@bar.com"}],"template_content":[],"message":{"merge_vars":[],"global_merge_vars":[]}}
Json.prettyPrint(json)
// res0: String =
// {
// "key" : "your-api-key",
// "template_name" : "my-template-slug",
// "to" : [ {
// "email" : "foo@bar.com"
// } ],
// "template_content" : [ ],
// "message" : {
// "merge_vars" : [ ],
// "global_merge_vars" : [ ]
// }
// }
Email Service with WSClient
The playframework provides a http client that works well together with play-json. This example doesn’t require a play application.
Email Service interface
The service can be used to send templates and check the API connection.
import scala.concurrent.Future
import net.gutefrage.mandrill.messages._
trait EmailService {
def status(): Future[Either[MandrillApiError, Unit]]
def send(template: SendTemplate): Future[Either[MandrillApiError, Seq[SendTemplateResponse]]]
}
Prolog
First, you need to add play-ws
as a dependency with
libraryDependency += "com.typesafe.play" %% "play-ws" % "2.5.10"
Next we need to create a WSClient
. In a play application you can inject it. For a standalone version
you have to create an instance of AhcWSClient
:
import akka.actor.ActorSystem
import akka.stream.{ActorMaterializer, Materializer}
import play.api.libs.ws._
import play.api.libs.ws.ahc.AhcWSClient
import scala.concurrent.ExecutionContext.Implicits._
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
val wsClient = AhcWSClient()
Implementation
Now we can implement our EmailService
trait. The implementation is very basic and doesn’t contain all the
necessary error handling, but gives you an idea how to roll your own email service.
import net.gutefrage.mandrill.playjson.core._
import net.gutefrage.mandrill.playjson.messages._
import net.gutefrage.mandrill.playjson.users._
import play.api.libs.json._
class WsEmailService(ws: WSClient, apiKey: MandrillApiKey) extends EmailService {
val api = "https://mandrillapp.com/api/1.0"
def status(): Future[Either[MandrillApiError, Unit]] = {
ws.url(s"$api/users/ping2.json").post(
Json.toJson(Mandrill(apiKey).users.ping)
).map {
case resp if resp.status <= 200 && resp.status <= 300 => Right(Unit)
case resp => Left(parseApiError(resp))
}
}
def send(template: SendTemplate): Future[Either[MandrillApiError, Seq[SendTemplateResponse]]] = {
ws.url(s"$api/messages/send-template.json").post(
Json.toJson(template)
).map {
case resp if resp.status <= 200 && resp.status <= 300 =>
// No invalid json error handling
val responses = Json.fromJson[Seq[SendTemplateResponse]](resp.json).get
Right(responses)
case resp => Left(parseApiError(resp))
}
}
// No error handling for invalid json
private def parseApiError[T](resp: WSResponse): MandrillApiError = Json.fromJson[MandrillApiError](resp.json).get
}
Usage
A short demonstration.
import scala.concurrent.Await, scala.concurrent.duration._
// import scala.concurrent.Await
// import scala.concurrent.duration._
val service = new WsEmailService(wsClient, apiKey)
// service: WsEmailService = WsEmailService@139b15d2
Await.result(service.status(), 5.seconds)
// res6: Either[net.gutefrage.mandrill.core.MandrillApiError,Unit] = Left(MandrillApiError(Invalid API key,Invalid_Key))
val template = Mandrill(apiKey).messages.sendTemplate("my-template").to("test@example.com")
// template: net.gutefrage.mandrill.messages.SendTemplate = SendTemplate(MandrillApiKey(your-api-key),TemplateName(my-template),List(Recipient(Email(test@example.com),None,None)),List(),Message(List(),List(),None),None)
Await.result(service.send(template), 5.seconds)
// res7: Either[net.gutefrage.mandrill.core.MandrillApiError,Seq[net.gutefrage.mandrill.messages.SendTemplateResponse]] = Left(MandrillApiError(Invalid API key,Invalid_Key))
And don’t forget to shutdown the clients.
wsClient.close()
system.terminate()