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)
|
||||
case RemoveParcel =>
|
||||
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 =>
|
||||
sendMessage("Supported commands: /add, /remove, /list, /help", initial, initial)
|
||||
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 =>
|
||||
case object RemoveParcelSuccess extends Command
|
||||
case class RemoveParcelFailure(exception: Throwable) extends Command
|
||||
|
||||
@@ -38,7 +38,7 @@ object Entities {
|
||||
text: String,
|
||||
postcode: Option[String],
|
||||
postoffice: Option[String],
|
||||
idIcon: Option[String],
|
||||
idIcon: Option[Int],
|
||||
publicAccess: Int,
|
||||
latitude: Option[Double],
|
||||
longitude: Option[Double],
|
||||
@@ -58,12 +58,12 @@ object CzechPostDeliveryCheck {
|
||||
sealed trait CommandResult
|
||||
sealed trait Event
|
||||
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
|
||||
.map(state => s"${state.prettyPrint}\n===========================\n")
|
||||
.mkString
|
||||
|
||||
s"""|*New state(s):*
|
||||
s"""|*New state(s) of the parcel $parcelId:*
|
||||
|===========================
|
||||
|$statesString""".stripMargin
|
||||
}
|
||||
@@ -72,6 +72,8 @@ object CzechPostDeliveryCheck {
|
||||
|
||||
case class AddParcel(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 class CommandResultFailure(exception: Throwable) extends CommandResult
|
||||
@@ -154,13 +156,21 @@ object CzechPostDeliveryCheck {
|
||||
.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 =>
|
||||
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"))
|
||||
|
||||
for (ids <- parcelIds) {
|
||||
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`)))
|
||||
|
||||
ctx.log.info("action=check_parcel_state chat_id={} check_uri={}", chatId, checkUri)
|
||||
|
||||
http
|
||||
.singleRequest(request, connectionContext = sslContext, settings = connectionSettings)
|
||||
.transform {
|
||||
@@ -174,6 +184,10 @@ object CzechPostDeliveryCheck {
|
||||
case Failure(exception) =>
|
||||
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
|
||||
@@ -194,7 +208,7 @@ object CzechPostDeliveryCheck {
|
||||
.persist(attributesChangedEvent ++ stateEvents)
|
||||
.thenRun(_ => {
|
||||
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.http.scaladsl.marshalling.Marshal
|
||||
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.{ConnectionContext, Http, HttpExt, HttpsConnectionContext}
|
||||
import akka.stream.ActorMaterializer
|
||||
@@ -202,13 +202,19 @@ object TelegramBot {
|
||||
|
||||
path(hookId) {
|
||||
post {
|
||||
extractLog { log =>
|
||||
entity(as[Update]) { update =>
|
||||
onComplete(updatesProcessor.?[DialogManager.CommandResult](ref => DialogManager.ProcessUpdate(update, ref))) {
|
||||
case Success(processResult) => processResult match {
|
||||
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