I copied code from telegram/bot4s repository, put part of code to "object Main extends App", create sbt file, install libraries.
import cats.instances.future._
import cats.syntax.functor._
import com.bot4s.telegram.api.RequestHandler
import com.bot4s.telegram.api.declarative.Commands
import com.bot4s.telegram.clients.{FutureSttpClient, ScalajHttpClient}
import com.bot4s.telegram.future.{Polling, TelegramBot}
import com.bot4s.telegram.methods.SendDice
import scala.util.Try
import scala.concurrent.Future
/** Generates random values.
*/
class RandomBot(val token: String) extends TelegramBot
with Polling
with Commands[Future] {
//LoggerConfig.factory = PrintLoggerFactory()
// set log level, e.g. to TRACE
//LoggerConfig.level = LogLevel.TRACE
// Use sttp-based backend
implicit val backend = SttpBackends.default
override val client: RequestHandler[Future] = new FutureSttpClient(token)
// Or just the scalaj-http backend
// override val client: RequestHandler[Future] = new ScalajHttpClient(token)
val rng = new scala.util.Random(System.currentTimeMillis())
onCommand("coin" or "flip") { implicit msg =>
reply(if (rng.nextBoolean()) "Head!" else "Tail!").void
}
onCommand("real" | "double" | "float") { implicit msg =>
reply(rng.nextDouble().toString).void
}
onCommand("/die" | "roll") { implicit msg =>
reply("⚀⚁⚂⚃⚄⚅" (rng.nextInt(6)).toString).void
}
onCommand("random" or "rnd") { implicit msg =>
withArgs {
case Seq(Int(n)) if n > 0 =>
reply(rng.nextInt(n).toString).void
case _ => reply("Invalid argumentヽ(ಠ_ಠ)ノ").void
}
}
onCommand("choose" | "pick" | "select") { implicit msg =>
withArgs { args =>
replyMd(if (args.isEmpty) "No arguments provided." else args(rng.nextInt(args.size))).void
}
}
onCommand("auto") { implicit msg =>
request(SendDice(msg.chat.id)).void
}
// Extractor
object Int {
def unapply(s: String): Option[Int] = Try(s.toInt).toOption
}
}
object Main extends App {
val bot = new RandomBot("tokenhere")
val eol = bot.run()
println("Press [ENTER] to shutdown the bot, it may take a few seconds...")
scala.io.StdIn.readLine()
bot.shutdown() // initiate shutdown
// Wait for the bot end-of-life
Await.result(eol, Duration.Inf)
}
ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / scalaVersion := "2.13.16"
lazy val root = (project in file("."))
.settings(
name := "Meower"
)
// Core with minimal dependencies, enough to spawn your first bot.
libraryDependencies += "com.bot4s" %% "telegram-core" % "5.8.4"
// Extra goodies: Webhooks, support for games, bindings for actors.
libraryDependencies += "com.bot4s" %% "telegram-akka" % "5.8.4"
but after that I have failed build with:
C:\Users\днс\Music\play-samples-3.0.x\Meower\src\main\scala\Main.scala:25:26 not found: value SttpBackends implicit val backend = SttpBackends.default
C:\Users\днс\Music\play-samples-3.0.x\Meower\src\main\scala\Main.scala:26:49 could not find implicit value for parameter backend: sttp.client3.SttpBackend[scala.concurrent.Future,Any] Error occurred in an application involving default arguments. override val client: RequestHandler[Future] = new FutureSttpClient(token)
C:\Users\днс\Music\play-samples-3.0.x\Meower\src\main\scala\Main.scala:71:3 not found: value Await Await.result(eol, Duration.Inf)
C:\Users\днс\Music\play-samples-3.0.x\Meower\src\main\scala\Main.scala:71:21 not found: value Duration Await.result(eol, Duration.Inf)
What I need to do to fix these problems?
I've researced Can't find SttpBackends + "Error occurred in an application involving default arguments." and tried to fix my code, but i didn't have any success...
First you need to add two import
s to solve Await
and Duration
not found. So, just adding the following will solve that problem
import scala.concurrent.{Await, Future}
Then you have to decide which backend from sttp supported backends you want to use
Supported backends
sttp supports a number of synchronous and asynchronous backends. It’s the backends that take care of managing connections, sending requests and receiving responses: sttp defines only the API to describe the requests to be sent and handle the response data. Backends do all the heavy-lifting. Typically, a single backend instance is created for the lifetime of the application
Let's say we choose OkHttpFutureBackend.
Using OkHttp
To use, add the following dependency to your project:
"com.softwaremill.sttp.client3" %% "okhttp-backend" % "3.10.3"
Create the backend using:
import sttp.client3.okhttp.OkHttpFutureBackend import scala.concurrent.ExecutionContext.Implicits.global val backend = OkHttpFutureBackend()
So, all you have to do is add the following dependency in your build.sbt
libraryDependencies += "com.softwaremill.sttp.client3" %% "okhttp-backend" % "3.10.3"
And then in your RandomBot
class you have to replace the line
implicit val backend = SttpBackends.default
for this other one
//remember to add the import
import sttp.client3.okhttp.OkHttpFutureBackend
// the sttp backend for ok http, but you should be able to choose any of the supported ones
implicit val backend: SttpBackend[Future, capabilities.WebSockets] = OkHttpFutureBackend()
If you want to have your own class SttpBackends
to not replace the line mentioned before, you can create it as it is showed in the bot4s/telegram - examples - jvm - SttpBackends - v5.8.4
import sttp.client3.okhttp.OkHttpFutureBackend
import sttp.client3.SttpBackend
import scala.concurrent.Future
// the SttpBackends class definition
object SttpBackends {
// the val `default` invoked from `RandomBot`
val default: SttpBackend[Future, Any] = OkHttpFutureBackend()
}