Compare commits

...

1 Commits

Author SHA1 Message Date
Pavel Kachalouski
3a3de48c8f Set initial dialog status as waiting for command
All checks were successful
continuous-integration/drone/push Build is passing
2019-05-19 21:19:36 +02:00
2 changed files with 41 additions and 38 deletions

View File

@@ -36,7 +36,6 @@ object CheckDeliveryDialog {
case "/remove" => RemoveParcel case "/remove" => RemoveParcel
case "/list" => ListParcels case "/list" => ListParcels
case "/help" => Help case "/help" => Help
case "/start" => Help
case _ => Help case _ => Help
} }
} }
@@ -58,6 +57,8 @@ object CheckDeliveryDialog {
one_time_keyboard = Some(true) one_time_keyboard = Some(true)
)) ))
private val removeKeyboard = Some(ReplyKeyboardRemove())
def behavior(chatId: Long, botUri: BotUri): Behavior[Command] = Behaviors.setup[Command] { ctx => def behavior(chatId: Long, botUri: BotUri): Behavior[Command] = Behaviors.setup[Command] { ctx =>
implicit val materializer: ActorMaterializer = ActorMaterializer()(ctx.system.toUntyped) implicit val materializer: ActorMaterializer = ActorMaterializer()(ctx.system.toUntyped)
implicit val executionContext: ExecutionContext = ctx.system.dispatchers.lookup(DispatcherSelector.default()) implicit val executionContext: ExecutionContext = ctx.system.dispatchers.lookup(DispatcherSelector.default())
@@ -66,8 +67,6 @@ object CheckDeliveryDialog {
val deliveryStateAdapter: ActorRef[CzechPostDeliveryCheck.DeliveryStateChanged] = ctx.messageAdapter(stateChanged => DeliveryStateChanged(stateChanged.state)) val deliveryStateAdapter: ActorRef[CzechPostDeliveryCheck.DeliveryStateChanged] = ctx.messageAdapter(stateChanged => DeliveryStateChanged(stateChanged.state))
val czechPostDeliveryCheck = ctx.spawnAnonymous(Behaviors.supervise(CzechPostDeliveryCheck.behavior(chatId.toString, deliveryStateAdapter)).onFailure(SupervisorStrategy.restart)) val czechPostDeliveryCheck = ctx.spawnAnonymous(Behaviors.supervise(CzechPostDeliveryCheck.behavior(chatId.toString, deliveryStateAdapter)).onFailure(SupervisorStrategy.restart))
def initial: Behavior[Command] = sendMessage(SendMessage(chatId, "Waiting for a command...", reply_markup = commandsKeyboard), waitCommand, initial)
def waitCommand: Behavior[Command] = Behaviors.receiveMessage { def waitCommand: Behavior[Command] = Behaviors.receiveMessage {
case ProcessMessage(msg, replyTo) => case ProcessMessage(msg, replyTo) =>
val command = msg.text.map(text => DialogCommand.parse(text)) val command = msg.text.map(text => DialogCommand.parse(text))
@@ -78,21 +77,21 @@ object CheckDeliveryDialog {
Behaviors.same Behaviors.same
} else { } else {
val message = SendMessage(chatId, "This command is unsupported.") val message = SendMessage(chatId, "This command is unsupported.")
sendMessage(message, initial, initial) sendMessage(message, waitCommand, waitCommand)
} }
case AddParcel => case AddParcel =>
val message = SendMessage(chatId, "Please enter a parcel ID.") val message = SendMessage(chatId, "Please enter a parcel ID.", reply_markup = removeKeyboard)
sendMessage(message, waitParcelId(parcelId => addParcel(parcelId)), initial) sendMessage(message, waitParcelId(parcelId => addParcel(parcelId)), waitCommand)
case RemoveParcel => case RemoveParcel =>
removeParcel(initial, initial) removeParcel(waitCommand, waitCommand)
case ListParcels => case ListParcels =>
listParcels listParcels
case Help => case Help =>
val message = SendMessage(chatId, helpMessage) val message = SendMessage(chatId, helpMessage, reply_markup = commandsKeyboard)
sendMessage(message, initial, initial) sendMessage(message, waitCommand, waitCommand)
case DeliveryStateChanged(state) => case DeliveryStateChanged(state) =>
val message = SendMessage(chatId, state, Some("Markdown")) val message = SendMessage(chatId, state, Some("Markdown"))
sendMessage(message, initial, initial) sendMessage(message, waitCommand, waitCommand)
case _ => case _ =>
Behaviors.unhandled Behaviors.unhandled
} }
@@ -110,17 +109,17 @@ object CheckDeliveryDialog {
Behaviors.receiveMessage { Behaviors.receiveMessage {
case AddParcelSuccess => case AddParcelSuccess =>
val message = SendMessage(chatId, s"Parcel $parcelId was added to the watch list.") val message = SendMessage(chatId, s"Parcel $parcelId was added to the watch list.", reply_markup = commandsKeyboard)
sendMessage(message, initial, initial) sendMessage(message, waitCommand, waitCommand)
case AddParcelFailure(exception) => case AddParcelFailure(exception) =>
exception match { exception match {
case CzechPostDeliveryCheck.DuplicateParcelId(_) => case CzechPostDeliveryCheck.DuplicateParcelId(_) =>
val message = SendMessage(chatId, s"Parcel $parcelId is in the watch list already.") val message = SendMessage(chatId, s"Parcel $parcelId is in the watch list already.", reply_markup = commandsKeyboard)
sendMessage(message, initial, initial) sendMessage(message, waitCommand, waitCommand)
case _ => case _ =>
ctx.log.error(exception, "action=add_parcel result=failure") ctx.log.error(exception, "action=add_parcel result=failure")
val message = SendMessage(chatId, s"Adding parcel failed. Please try again.") val message = SendMessage(chatId, s"Adding parcel failed. Please try again.", reply_markup = commandsKeyboard)
sendMessage(message, initial, initial) sendMessage(message, waitCommand, waitCommand)
} }
case otherMessage => case otherMessage =>
stashBuffer.stash(otherMessage) stashBuffer.stash(otherMessage)
@@ -141,12 +140,12 @@ object CheckDeliveryDialog {
Behaviors.receiveMessage { Behaviors.receiveMessage {
case ListParcelsSuccess(parcelsList) => case ListParcelsSuccess(parcelsList) =>
val messageText = "*List of your watched parcels:*\n" + (if (parcelsList.nonEmpty) parcelsList.toSeq.sorted.mkString("\n") else "(empty)") val messageText = "*List of your watched parcels:*\n" + (if (parcelsList.nonEmpty) parcelsList.toSeq.sorted.mkString("\n") else "(empty)")
val message = SendMessage(chatId, messageText, Some("Markdown")) val message = SendMessage(chatId, messageText, Some("Markdown"), reply_markup = commandsKeyboard)
sendMessage(message, initial, initial) sendMessage(message, waitCommand, waitCommand)
case ListParcelsFailure(exception) => case ListParcelsFailure(exception) =>
ctx.log.error(exception, "action=list_parcels result=failure chat_id={}", chatId) ctx.log.error(exception, "action=list_parcels result=failure chat_id={}", chatId)
val message = SendMessage(chatId, "Failed to get a list of your watched parcels. Please try again later.") val message = SendMessage(chatId, "Failed to get a list of your watched parcels. Please try again later.", reply_markup = commandsKeyboard)
sendMessage(message, initial, initial) sendMessage(message, waitCommand, waitCommand)
case otherMessage => case otherMessage =>
stashBuffer.stash(otherMessage) stashBuffer.stash(otherMessage)
Behaviors.same Behaviors.same
@@ -172,13 +171,13 @@ object CheckDeliveryDialog {
val message = SendMessage(chatId, "Please enter a parcel id to remove.", reply_markup = Some(markup)) val message = SendMessage(chatId, "Please enter a parcel id to remove.", reply_markup = Some(markup))
sendMessage(message, waitParcelId(parcelId => removeParcelId(parcelId)), onFailure) sendMessage(message, waitParcelId(parcelId => removeParcelId(parcelId)), onFailure)
} else { } else {
val message = SendMessage(chatId, "You don't have watched parcels. There is nothing to remove.") val message = SendMessage(chatId, "You don't have watched parcels. There is nothing to remove.", reply_markup = commandsKeyboard)
sendMessage(message, onSuccess, onFailure) sendMessage(message, onSuccess, onFailure)
} }
case ListParcelsFailure(exception) => case ListParcelsFailure(exception) =>
ctx.log.error(exception, "action=list_parcels result=failure chat_id={}", chatId) ctx.log.error(exception, "action=list_parcels result=failure chat_id={}", chatId)
val message = SendMessage(chatId, "Failed to get a list of your watched parcels. Please try again later.") val message = SendMessage(chatId, "Failed to get a list of your watched parcels. Please try again later.", reply_markup = commandsKeyboard)
sendMessage(message, initial, initial) sendMessage(message, waitCommand, waitCommand)
case otherMessage => case otherMessage =>
stashBuffer.stash(otherMessage) stashBuffer.stash(otherMessage)
Behaviors.same Behaviors.same
@@ -198,17 +197,17 @@ object CheckDeliveryDialog {
Behaviors.receiveMessage { Behaviors.receiveMessage {
case RemoveParcelSuccess => case RemoveParcelSuccess =>
val message = SendMessage(chatId, s"Parcel $parcelId was removed from the watch list.") val message = SendMessage(chatId, s"Parcel $parcelId was removed from the watch list.", reply_markup = commandsKeyboard)
sendMessage(message, initial, initial) sendMessage(message, waitCommand, waitCommand)
case RemoveParcelFailure(exception) => case RemoveParcelFailure(exception) =>
exception match { exception match {
case CzechPostDeliveryCheck.ParcelIdNotFound(_) => case CzechPostDeliveryCheck.ParcelIdNotFound(_) =>
val message = SendMessage(chatId, s"Parcel $parcelId is not found in the list of the watched parcels.") val message = SendMessage(chatId, s"Parcel $parcelId is not found in the list of the watched parcels.", reply_markup = commandsKeyboard)
sendMessage(message, initial, initial) sendMessage(message, waitCommand, waitCommand)
case _ => case _ =>
ctx.log.error(exception, "action=add_parcel result=failure") ctx.log.error(exception, "action=add_parcel result=failure")
val message = SendMessage(chatId, s"Remove of the parcel failed. Please try again.") val message = SendMessage(chatId, s"Remove of the parcel failed. Please try again.", reply_markup = commandsKeyboard)
sendMessage(message, initial, initial) sendMessage(message, waitCommand, waitCommand)
} }
case otherMessage => case otherMessage =>
stashBuffer.stash(otherMessage) stashBuffer.stash(otherMessage)
@@ -223,7 +222,7 @@ object CheckDeliveryDialog {
// val button2 = KeyboardButton("button2") // val button2 = KeyboardButton("button2")
// val keyboard = ReplyKeyboardMarkup(Seq(Seq(button1, button2))) // val keyboard = ReplyKeyboardMarkup(Seq(Seq(button1, button2)))
// val message = SendMessage(chatId, "Please enter parcel ID.", reply_markup = Some(keyboard)) // val message = SendMessage(chatId, "Please enter parcel ID.", reply_markup = Some(keyboard))
// sendMessage(message, waitParcelId(parcelId => addParcel(parcelId)), initial) // sendMessage(message, waitParcelId(parcelId => addParcel(parcelId)), waitCommand)
// } // }
def waitParcelId(onFinish: String => Behavior[Command]): Behavior[Command] = Behaviors.receiveMessage { def waitParcelId(onFinish: String => Behavior[Command]): Behavior[Command] = Behaviors.receiveMessage {
@@ -241,7 +240,7 @@ object CheckDeliveryDialog {
Behaviors.same Behaviors.same
} }
def sendMessage(message: SendMessage, onSuccess: => Behavior[Command], onFailure: => Behavior[Command], attempt: Int = 0): Behavior[Command] = Behaviors.setup[Command] { ctx => def sendMessage(message: SendMessage, onSuccess: => Behavior[Command], onFailure: => Behavior[Command], attempt: Int = 1): Behavior[Command] = Behaviors.setup[Command] { ctx =>
import io.circe.generic.auto._ import io.circe.generic.auto._
import io.circe.syntax._ import io.circe.syntax._
@@ -255,7 +254,7 @@ object CheckDeliveryDialog {
Source Source
.single(request) .single(request)
.initialDelay(2.seconds * attempt) .initialDelay(2.seconds * (attempt - 1))
.mapAsync(1) { request => .mapAsync(1) { request =>
http http
.singleRequest(request) .singleRequest(request)
@@ -281,7 +280,7 @@ object CheckDeliveryDialog {
case SendMessageFailure(exception) => case SendMessageFailure(exception) =>
ctx.log.error(exception, "action=send_message status=finished result=failure chat_id={} attempt={}", chatId, attempt) ctx.log.error(exception, "action=send_message status=finished result=failure chat_id={} attempt={}", chatId, attempt)
if (attempt >= 5) { if (attempt > 5) {
ctx.log.error(exception, "action=send_message result=failure message=attempts threshold exceeded") ctx.log.error(exception, "action=send_message result=failure message=attempts threshold exceeded")
stashBuffer.unstashAll(ctx, onFailure) stashBuffer.unstashAll(ctx, onFailure)
} else { } else {
@@ -293,6 +292,6 @@ object CheckDeliveryDialog {
} }
} }
initial waitCommand
} }
} }

View File

@@ -104,7 +104,7 @@ object TelegramBot {
} }
} }
def settingWebhook(binding: Http.ServerBinding): Behavior[Command] = Behaviors.setup[Command] { ctx => def settingWebhook(binding: Http.ServerBinding, attempt: Int = 1): Behavior[Command] = Behaviors.setup[Command] { ctx =>
case object SetWebhookSuccess extends Command case object SetWebhookSuccess extends Command
case class SetWebhookFailure(exception: Throwable) extends Command case class SetWebhookFailure(exception: Throwable) extends Command
@@ -145,9 +145,13 @@ object TelegramBot {
ctx.log.info("action=set_webhook result=success") ctx.log.info("action=set_webhook result=success")
stashBuffer.unstashAll(ctx, started(binding)) stashBuffer.unstashAll(ctx, started(binding))
case SetWebhookFailure(exception) => case SetWebhookFailure(exception) =>
ctx.log.error("action=set_webhook result=failure", exception) if (attempt > 20) {
ctx.log.error("action=start_bot result=failure") ctx.log.error(exception, "action=set_webhook result=failure attempt={}", attempt)
unbindingServer(binding, None) ctx.log.error("action=start_bot result=failure")
unbindingServer(binding, None)
} else {
settingWebhook(binding, attempt = attempt + 1)
}
case otherCommand: Command => case otherCommand: Command =>
stashBuffer.stash(otherCommand) stashBuffer.stash(otherCommand)
Behaviors.same Behaviors.same