package samples import canoe.api._ import canoe.syntax._ import canoe.models.messages.TextMessage import cats.effect.{ExitCode, IO, IOApp, Timer} import cats.syntax.functor._ import fs2.Stream import scala.util.Try import scala.concurrent.duration._ /** * Example of scheduling a job after user-defined delay. * Each user can schedule any number of jobs and all of them * will be executed concurrently without blocking each other. */ object TimerAlarm extends IOApp { val token: String = "<your telegram token>" def run(args: List[String]): IO[ExitCode] = Stream .resource(TelegramClient.global[IO](token)) .flatMap { implicit client => Bot.polling[IO].follow(alarm) } .compile.drain.as(ExitCode.Success) def alarm[F[_]: TelegramClient: Timer]: Scenario[F, Unit] = for { chat <- Scenario.expect(command("alarm").chat) _ <- Scenario.eval(chat.send("Tell me in how many seconds you want to be notified?")) in <- Scenario.expect(textMessage) sec = Try(in.text.toInt).toOption.filter(_ > 0) _ <- sec match { case Some(i) => setTimer(in, i) case None => Scenario.eval(in.reply("I'm sorry, but I couldn't get that (expecting positive number)")) } } yield () def setTimer[F[_]: TelegramClient: Timer](m: TextMessage, i: Int): Scenario[F, Unit] = for { _ <- Scenario.eval(m.chat.send(s"Timer is set. You will receive a reply after $i seconds")) _ <- Scenario.eval(Timer[F].sleep(i.seconds)) _ <- Scenario.eval(m.reply("Time's up.")) } yield () }