Added list method and fixed some errors during parsing of czech post json response
This commit is contained in:
@@ -61,7 +61,8 @@ object CheckDeliveryDialog {
|
|||||||
sendMessage("Please enter parcel ID.", waitParcelId(parcelId => addParcel(parcelId)), initial)
|
sendMessage("Please enter parcel ID.", waitParcelId(parcelId => addParcel(parcelId)), initial)
|
||||||
case RemoveParcel =>
|
case RemoveParcel =>
|
||||||
sendMessage("Please enter parcel ID.", waitParcelId(parcelId => removeParcel(parcelId)), initial)
|
sendMessage("Please enter parcel ID.", waitParcelId(parcelId => removeParcel(parcelId)), initial)
|
||||||
case ListParcels => sendMessage("This command is not supported yet.", initial, initial)
|
case ListParcels =>
|
||||||
|
listParcels
|
||||||
case Help =>
|
case Help =>
|
||||||
sendMessage("Supported commands: /add, /remove, /list, /help", initial, initial)
|
sendMessage("Supported commands: /add, /remove, /list, /help", initial, initial)
|
||||||
case DeliveryStateChanged(state) =>
|
case DeliveryStateChanged(state) =>
|
||||||
@@ -98,6 +99,28 @@ object CheckDeliveryDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def listParcels: Behavior[Command] = Behaviors.setup { ctx =>
|
||||||
|
case class ListParcelsSuccess(parcelsList: String) extends Command
|
||||||
|
case class ListParcelsFailure(exception: Throwable) extends Command
|
||||||
|
implicit val timeout: Timeout = 5.seconds
|
||||||
|
|
||||||
|
ctx.ask[CzechPostDeliveryCheck.Command, CzechPostDeliveryCheck.ListParcelsResult](czechPostDeliveryCheck)(ref => CzechPostDeliveryCheck.ListParcels(ref)) {
|
||||||
|
case Success(CzechPostDeliveryCheck.ListParcelsResult(parcelsList)) => ListParcelsSuccess(parcelsList)
|
||||||
|
case Failure(exception) => ListParcelsFailure(exception)
|
||||||
|
}
|
||||||
|
|
||||||
|
Behaviors.receiveMessage {
|
||||||
|
case ListParcelsSuccess(parcelsList) =>
|
||||||
|
sendMessage(parcelsList, initial, initial)
|
||||||
|
case ListParcelsFailure(exception) =>
|
||||||
|
ctx.log.error(exception, "action=list_parcels result=failure chat_id={}", chatId)
|
||||||
|
sendMessage("Failed to get list of the your watched parcels. Please try again later.", initial, initial)
|
||||||
|
case otherMessage =>
|
||||||
|
stashBuffer.stash(otherMessage)
|
||||||
|
Behaviors.same
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def removeParcel(parcelId: String): Behavior[Command] = Behaviors.setup { ctx =>
|
def removeParcel(parcelId: String): Behavior[Command] = Behaviors.setup { ctx =>
|
||||||
case object RemoveParcelSuccess extends Command
|
case object RemoveParcelSuccess extends Command
|
||||||
case class RemoveParcelFailure(exception: Throwable) extends Command
|
case class RemoveParcelFailure(exception: Throwable) extends Command
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ object Entities {
|
|||||||
text: String,
|
text: String,
|
||||||
postcode: Option[String],
|
postcode: Option[String],
|
||||||
postoffice: Option[String],
|
postoffice: Option[String],
|
||||||
idIcon: Option[String],
|
idIcon: Option[Int],
|
||||||
publicAccess: Int,
|
publicAccess: Int,
|
||||||
latitude: Option[Double],
|
latitude: Option[Double],
|
||||||
longitude: Option[Double],
|
longitude: Option[Double],
|
||||||
@@ -58,12 +58,12 @@ object CzechPostDeliveryCheck {
|
|||||||
sealed trait CommandResult
|
sealed trait CommandResult
|
||||||
sealed trait Event
|
sealed trait Event
|
||||||
case class ParcelState(attributes: Option[Entities.Attributes] = None, states: Set[Entities.State] = Set.empty) {
|
case class ParcelState(attributes: Option[Entities.Attributes] = None, states: Set[Entities.State] = Set.empty) {
|
||||||
def prettyPrint: String = {
|
def prettyPrint(parcelId: String): String = {
|
||||||
val statesString = states
|
val statesString = states
|
||||||
.map(state => s"${state.prettyPrint}\n===========================\n")
|
.map(state => s"${state.prettyPrint}\n===========================\n")
|
||||||
.mkString
|
.mkString
|
||||||
|
|
||||||
s"""|*New state(s):*
|
s"""|*New state(s) of the parcel $parcelId:*
|
||||||
|===========================
|
|===========================
|
||||||
|$statesString""".stripMargin
|
|$statesString""".stripMargin
|
||||||
}
|
}
|
||||||
@@ -72,6 +72,8 @@ object CzechPostDeliveryCheck {
|
|||||||
|
|
||||||
case class AddParcel(parcelId: String, replyTo: ActorRef[CommandResult]) extends Command
|
case class AddParcel(parcelId: String, replyTo: ActorRef[CommandResult]) extends Command
|
||||||
case class RemoveParcel(parcelId: String, replyTo: ActorRef[CommandResult]) extends Command
|
case class RemoveParcel(parcelId: String, replyTo: ActorRef[CommandResult]) extends Command
|
||||||
|
case class ListParcels(replyTo: ActorRef[ListParcelsResult]) extends Command
|
||||||
|
case class ListParcelsResult(parcelsList: String)
|
||||||
|
|
||||||
case object CommandResultSuccess extends CommandResult
|
case object CommandResultSuccess extends CommandResult
|
||||||
case class CommandResultFailure(exception: Throwable) extends CommandResult
|
case class CommandResultFailure(exception: Throwable) extends CommandResult
|
||||||
@@ -154,13 +156,21 @@ object CzechPostDeliveryCheck {
|
|||||||
.thenRun(_ => replyTo ! CommandResultFailure(ParcelIdNotFound(parcelId)))
|
.thenRun(_ => replyTo ! CommandResultFailure(ParcelIdNotFound(parcelId)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ListParcels(replyTo) =>
|
||||||
|
val parcelsList = "*List of your watched parcels:*\n" + (if (state.parcelStates.keys.nonEmpty) state.parcelStates.keys.toSeq.sorted.map(id => id + "\n").mkString else "(empty)")
|
||||||
|
Effect.none
|
||||||
|
.thenRun(_ => replyTo ! ListParcelsResult(parcelsList))
|
||||||
|
|
||||||
case CheckParcels =>
|
case CheckParcels =>
|
||||||
|
ctx.log.info("action=check_parcel_state chat_id={}", chatId)
|
||||||
val parcelIds = state.parcelStates.keys.grouped(10).map(ids => ids.foldLeft("")((acc, id) => if (acc.isEmpty) id else s"$acc;$id"))
|
val parcelIds = state.parcelStates.keys.grouped(10).map(ids => ids.foldLeft("")((acc, id) => if (acc.isEmpty) id else s"$acc;$id"))
|
||||||
|
|
||||||
for (ids <- parcelIds) {
|
for (ids <- parcelIds) {
|
||||||
val checkUri = Uri(s"https://b2c.cpost.cz/services/ParcelHistory/getDataAsJson?idParcel=$ids&language=en")
|
val checkUri = Uri(s"https://b2c.cpost.cz/services/ParcelHistory/getDataAsJson?idParcel=$ids&language=en")
|
||||||
val request = HttpRequest(uri = checkUri, headers = immutable.Seq(Accept(MediaTypes.`application/json`)))
|
val request = HttpRequest(uri = checkUri, headers = immutable.Seq(Accept(MediaTypes.`application/json`)))
|
||||||
|
|
||||||
|
ctx.log.info("action=check_parcel_state chat_id={} check_uri={}", chatId, checkUri)
|
||||||
|
|
||||||
http
|
http
|
||||||
.singleRequest(request, connectionContext = sslContext, settings = connectionSettings)
|
.singleRequest(request, connectionContext = sslContext, settings = connectionSettings)
|
||||||
.transform {
|
.transform {
|
||||||
@@ -174,6 +184,10 @@ object CzechPostDeliveryCheck {
|
|||||||
case Failure(exception) =>
|
case Failure(exception) =>
|
||||||
ctx.log.error(exception, "Error checking parcel history.")
|
ctx.log.error(exception, "Error checking parcel history.")
|
||||||
}
|
}
|
||||||
|
.andThen {
|
||||||
|
case Success(_) => ctx.log.info("action=check_parcel_state result=success chat_id={} check_uri={}", chatId, checkUri)
|
||||||
|
case Failure(exception) => ctx.log.error(exception, "action=check_parcel_state result=failure chat_id={} check_uri={}", chatId, checkUri)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Effect.none
|
Effect.none
|
||||||
@@ -194,7 +208,7 @@ object CzechPostDeliveryCheck {
|
|||||||
.persist(attributesChangedEvent ++ stateEvents)
|
.persist(attributesChangedEvent ++ stateEvents)
|
||||||
.thenRun(_ => {
|
.thenRun(_ => {
|
||||||
if (newStates.nonEmpty) {
|
if (newStates.nonEmpty) {
|
||||||
stateReporter ! DeliveryStateChanged(ParcelState(None, newStates).prettyPrint)
|
stateReporter ! DeliveryStateChanged(ParcelState(None, newStates).prettyPrint(parcelId))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import akka.actor.typed.scaladsl.{Behaviors, StashBuffer}
|
|||||||
import akka.actor.typed.{ActorRef, Behavior, DispatcherSelector}
|
import akka.actor.typed.{ActorRef, Behavior, DispatcherSelector}
|
||||||
import akka.http.scaladsl.marshalling.Marshal
|
import akka.http.scaladsl.marshalling.Marshal
|
||||||
import akka.http.scaladsl.model._
|
import akka.http.scaladsl.model._
|
||||||
import akka.http.scaladsl.server.Directives.{as, entity, onComplete, path, post, complete}
|
import akka.http.scaladsl.server.Directives.{as, entity, onComplete, path, post, complete, extractLog}
|
||||||
import akka.http.scaladsl.server.Route
|
import akka.http.scaladsl.server.Route
|
||||||
import akka.http.scaladsl.{ConnectionContext, Http, HttpExt, HttpsConnectionContext}
|
import akka.http.scaladsl.{ConnectionContext, Http, HttpExt, HttpsConnectionContext}
|
||||||
import akka.stream.ActorMaterializer
|
import akka.stream.ActorMaterializer
|
||||||
@@ -202,13 +202,19 @@ object TelegramBot {
|
|||||||
|
|
||||||
path(hookId) {
|
path(hookId) {
|
||||||
post {
|
post {
|
||||||
|
extractLog { log =>
|
||||||
entity(as[Update]) { update =>
|
entity(as[Update]) { update =>
|
||||||
onComplete(updatesProcessor.?[DialogManager.CommandResult](ref => DialogManager.ProcessUpdate(update, ref))) {
|
onComplete(updatesProcessor.?[DialogManager.CommandResult](ref => DialogManager.ProcessUpdate(update, ref))) {
|
||||||
case Success(processResult) => processResult match {
|
case Success(processResult) => processResult match {
|
||||||
case DialogManager.ProcessUpdateSuccess => complete(HttpResponse(status = StatusCodes.OK))
|
case DialogManager.ProcessUpdateSuccess => complete(HttpResponse(status = StatusCodes.OK))
|
||||||
case DialogManager.ProcessUpdateFailure(exception) => complete(HttpResponse(status = StatusCodes.InternalServerError))
|
case DialogManager.ProcessUpdateFailure(exception) =>
|
||||||
|
log.error(exception, "action=process_update result=failure message={}", update)
|
||||||
|
complete(HttpResponse(status = StatusCodes.InternalServerError))
|
||||||
|
}
|
||||||
|
case Failure(exception) =>
|
||||||
|
log.error(exception, "action=process_update result=failure message={}", update)
|
||||||
|
complete(HttpResponse(status = StatusCodes.InternalServerError))
|
||||||
}
|
}
|
||||||
case Failure(exception) => complete(HttpResponse(status = StatusCodes.InternalServerError))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user