From 3a3de48c8f3435fe3d71503484c85d612619c6a1 Mon Sep 17 00:00:00 2001 From: Pavel Kachalouski Date: Sun, 19 May 2019 20:10:46 +0200 Subject: [PATCH] Set initial dialog status as waiting for command --- .../eu/xeppaka/bot/CheckDeliveryDialog.scala | 67 +++++++++---------- .../scala/eu/xeppaka/bot/TelegramBot.scala | 12 ++-- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/main/scala/eu/xeppaka/bot/CheckDeliveryDialog.scala b/src/main/scala/eu/xeppaka/bot/CheckDeliveryDialog.scala index e1a5713..ce56984 100644 --- a/src/main/scala/eu/xeppaka/bot/CheckDeliveryDialog.scala +++ b/src/main/scala/eu/xeppaka/bot/CheckDeliveryDialog.scala @@ -36,7 +36,6 @@ object CheckDeliveryDialog { case "/remove" => RemoveParcel case "/list" => ListParcels case "/help" => Help - case "/start" => Help case _ => Help } } @@ -58,6 +57,8 @@ object CheckDeliveryDialog { one_time_keyboard = Some(true) )) + private val removeKeyboard = Some(ReplyKeyboardRemove()) + def behavior(chatId: Long, botUri: BotUri): Behavior[Command] = Behaviors.setup[Command] { ctx => implicit val materializer: ActorMaterializer = ActorMaterializer()(ctx.system.toUntyped) 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 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 { case ProcessMessage(msg, replyTo) => val command = msg.text.map(text => DialogCommand.parse(text)) @@ -78,21 +77,21 @@ object CheckDeliveryDialog { Behaviors.same } else { val message = SendMessage(chatId, "This command is unsupported.") - sendMessage(message, initial, initial) + sendMessage(message, waitCommand, waitCommand) } case AddParcel => - val message = SendMessage(chatId, "Please enter a parcel ID.") - sendMessage(message, waitParcelId(parcelId => addParcel(parcelId)), initial) + val message = SendMessage(chatId, "Please enter a parcel ID.", reply_markup = removeKeyboard) + sendMessage(message, waitParcelId(parcelId => addParcel(parcelId)), waitCommand) case RemoveParcel => - removeParcel(initial, initial) + removeParcel(waitCommand, waitCommand) case ListParcels => listParcels case Help => - val message = SendMessage(chatId, helpMessage) - sendMessage(message, initial, initial) + val message = SendMessage(chatId, helpMessage, reply_markup = commandsKeyboard) + sendMessage(message, waitCommand, waitCommand) case DeliveryStateChanged(state) => val message = SendMessage(chatId, state, Some("Markdown")) - sendMessage(message, initial, initial) + sendMessage(message, waitCommand, waitCommand) case _ => Behaviors.unhandled } @@ -110,17 +109,17 @@ object CheckDeliveryDialog { Behaviors.receiveMessage { case AddParcelSuccess => - val message = SendMessage(chatId, s"Parcel $parcelId was added to the watch list.") - sendMessage(message, initial, initial) + val message = SendMessage(chatId, s"Parcel $parcelId was added to the watch list.", reply_markup = commandsKeyboard) + sendMessage(message, waitCommand, waitCommand) case AddParcelFailure(exception) => exception match { case CzechPostDeliveryCheck.DuplicateParcelId(_) => - val message = SendMessage(chatId, s"Parcel $parcelId is in the watch list already.") - sendMessage(message, initial, initial) + val message = SendMessage(chatId, s"Parcel $parcelId is in the watch list already.", reply_markup = commandsKeyboard) + sendMessage(message, waitCommand, waitCommand) case _ => ctx.log.error(exception, "action=add_parcel result=failure") - val message = SendMessage(chatId, s"Adding parcel failed. Please try again.") - sendMessage(message, initial, initial) + val message = SendMessage(chatId, s"Adding parcel failed. Please try again.", reply_markup = commandsKeyboard) + sendMessage(message, waitCommand, waitCommand) } case otherMessage => stashBuffer.stash(otherMessage) @@ -141,12 +140,12 @@ object CheckDeliveryDialog { Behaviors.receiveMessage { case ListParcelsSuccess(parcelsList) => 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")) - sendMessage(message, initial, initial) + val message = SendMessage(chatId, messageText, Some("Markdown"), reply_markup = commandsKeyboard) + sendMessage(message, waitCommand, waitCommand) case ListParcelsFailure(exception) => 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.") - sendMessage(message, initial, initial) + val message = SendMessage(chatId, "Failed to get a list of your watched parcels. Please try again later.", reply_markup = commandsKeyboard) + sendMessage(message, waitCommand, waitCommand) case otherMessage => stashBuffer.stash(otherMessage) Behaviors.same @@ -172,13 +171,13 @@ object CheckDeliveryDialog { val message = SendMessage(chatId, "Please enter a parcel id to remove.", reply_markup = Some(markup)) sendMessage(message, waitParcelId(parcelId => removeParcelId(parcelId)), onFailure) } 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) } case ListParcelsFailure(exception) => 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.") - sendMessage(message, initial, initial) + val message = SendMessage(chatId, "Failed to get a list of your watched parcels. Please try again later.", reply_markup = commandsKeyboard) + sendMessage(message, waitCommand, waitCommand) case otherMessage => stashBuffer.stash(otherMessage) Behaviors.same @@ -198,17 +197,17 @@ object CheckDeliveryDialog { Behaviors.receiveMessage { case RemoveParcelSuccess => - val message = SendMessage(chatId, s"Parcel $parcelId was removed from the watch list.") - sendMessage(message, initial, initial) + val message = SendMessage(chatId, s"Parcel $parcelId was removed from the watch list.", reply_markup = commandsKeyboard) + sendMessage(message, waitCommand, waitCommand) case RemoveParcelFailure(exception) => exception match { case CzechPostDeliveryCheck.ParcelIdNotFound(_) => - val message = SendMessage(chatId, s"Parcel $parcelId is not found in the list of the watched parcels.") - sendMessage(message, initial, initial) + val message = SendMessage(chatId, s"Parcel $parcelId is not found in the list of the watched parcels.", reply_markup = commandsKeyboard) + sendMessage(message, waitCommand, waitCommand) case _ => ctx.log.error(exception, "action=add_parcel result=failure") - val message = SendMessage(chatId, s"Remove of the parcel failed. Please try again.") - sendMessage(message, initial, initial) + val message = SendMessage(chatId, s"Remove of the parcel failed. Please try again.", reply_markup = commandsKeyboard) + sendMessage(message, waitCommand, waitCommand) } case otherMessage => stashBuffer.stash(otherMessage) @@ -223,7 +222,7 @@ object CheckDeliveryDialog { // val button2 = KeyboardButton("button2") // val keyboard = ReplyKeyboardMarkup(Seq(Seq(button1, button2))) // 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 { @@ -241,7 +240,7 @@ object CheckDeliveryDialog { 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.syntax._ @@ -255,7 +254,7 @@ object CheckDeliveryDialog { Source .single(request) - .initialDelay(2.seconds * attempt) + .initialDelay(2.seconds * (attempt - 1)) .mapAsync(1) { request => http .singleRequest(request) @@ -281,7 +280,7 @@ object CheckDeliveryDialog { case SendMessageFailure(exception) => 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") stashBuffer.unstashAll(ctx, onFailure) } else { @@ -293,6 +292,6 @@ object CheckDeliveryDialog { } } - initial + waitCommand } } diff --git a/src/main/scala/eu/xeppaka/bot/TelegramBot.scala b/src/main/scala/eu/xeppaka/bot/TelegramBot.scala index 7b37c5c..751af3c 100644 --- a/src/main/scala/eu/xeppaka/bot/TelegramBot.scala +++ b/src/main/scala/eu/xeppaka/bot/TelegramBot.scala @@ -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 class SetWebhookFailure(exception: Throwable) extends Command @@ -145,9 +145,13 @@ object TelegramBot { ctx.log.info("action=set_webhook result=success") stashBuffer.unstashAll(ctx, started(binding)) case SetWebhookFailure(exception) => - ctx.log.error("action=set_webhook result=failure", exception) - ctx.log.error("action=start_bot result=failure") - unbindingServer(binding, None) + if (attempt > 20) { + ctx.log.error(exception, "action=set_webhook result=failure attempt={}", attempt) + ctx.log.error("action=start_bot result=failure") + unbindingServer(binding, None) + } else { + settingWebhook(binding, attempt = attempt + 1) + } case otherCommand: Command => stashBuffer.stash(otherCommand) Behaviors.same