scala - 如何从方法中获取消息
问题描述
我想将控制台 IO 应用程序(总和计数)重写为 messenger-bot。让我在递归中StdIn.readLine()
得到下一个输入数字。
object HelloCountBot extends TelegramBot with Polling with Commands {
def go(number: Long, chatId: Long): IO[Long] =
for {
input <- ??? /*here I need get the next number*/
acc <- input.toLong match {
case 0L => sendMessageMethodIO(chatId, "The sum is:") *> IO(0L)
case _ => go(number + 1, chatId)
}
acc <- IO(acc + input.toLong)
} yield acc
/*input point for every new message*/
override def onMessage(message: Message) = message.text match {
case Some(text) if text == "start" => go(1, message.chat.id)
.unsafeRunSync
}
def main(args: Array[String]): Unit = HelloCountBot.run()
}
如何组织代码以从方法 onMessage 的递归中获取下一条消息,并返回 Unit。
解决方案
我在https://github.com/bot4s/telegram中没有找到任何以您想要的方式接收消息的方法。所以我认为最好的选择是创建有状态的机器人,如下例所示:https ://github.com/bot4s/telegram/blob/master/examples/src/StatefulBot.scala 。
因此,如果我正确理解了您的代码,则可以按以下方式对其进行重组(特征PerChatState
取自上面的链接):
object HelloCountBot
extends TelegramBot
with Polling
with Commands
with PerChatState[Long] {
override def onMessage(message: Message): Future[Unit] = {
implicit val msg = message
message.text match {
case Some(text) if text == "start" =>
Future {
setChatState(0L)
}
case Some(value) if value == "0" =>
withChatState {
sum =>
reply(s"The sum is ${sum.getOrElse(0L)}")
.map(_ => clearChatState)
}
case Some(value) =>
withChatState {
mayBeSum =>
Future {
mayBeSum.foreach(
sum => setChatState(sum + value.toLong)
)
}
}
}
}
def main(args: Array[String]): Unit = HelloCountBot.run()
}
它使用 Futures,但如果您愿意,可以将其重写为 IO。
推荐阅读
- ios - Cordova - 在标签中显示本地图像文件
- outlook-web-addins - Outlook 加载项:在 Outlook 客户端中保存相同内容后,未在 OWA 上获取 Outlook 加载项 RoamingSettings
- r - R - 如何在应用中使用 sum 和 group_by?
- xslt - 如何在单循环中读取 2 个逗号分隔的字符串 - XSLT
- mysql - 在 JOIN 查询中生成匿名 ID
- java - 使用@Autowired 时我什么时候必须创建新实例
- c# - 将路径中的“\\”替换为“\”
- c# - 无法在控制器上禁用验证
- haskell - Applicative 函子的`(<*>)` 定义?
- php - WHILE 循环 + mysqli_fetch_object