Telegram Bot API Wrapper for Scala
Idiomatic Scala wrapper for the Telegram Bot API. The full API is supported, inline queries, callbacks, editing messages, games, custom markups, uploading files, chat actions... while being strongly-typed (no JSON strings), fully asynchronous (on top of Akka), and transparently camelCased.
Cross-compiled to Scala 2.11 and 2.12.
I encourage users to report any bug or broken functionality, I'll do my best to give proper support in a reasonable time frame.
- Per-user synchronous requests
- Request feature here
Add to your build.sbt
file:
libraryDependencies += "info.mukel" %% "telegrambot4s" % "2.0.2"
Add to your build.sbt
file:
scalaVersion := "2.11.8"
resolvers += "jitpack" at "https://jitpack.io"
libraryDependencies += "com.github.mukel" %% "telegrambot4s" % "v2.0.2"
Make sure to specify Scala version in your build file, inserting a line like the first one, or you'll get by default a 2.10 Scala version for which this repository does not work.
You can also pull any branch or release from Jitpack, check it out.
Do not expose tokens unintentionally.
In order to avoid unintentional token sharing, store tokens in an un-tracked file e.g. "bot.token" as follows:
object SafeBot extends TelegramBot with Polling with Commands {
def token = Source.fromFile("bot.token").getLines().next
on("/hello") { implicit msg => _ =>
reply("My token is SAFE!")
}
}
SafeBot.run()
Both methods are fully supported. Polling is the easiest method; it can be used locally without any additional requirements. Polling has been radically improved, it doesn't flood the server and it's very fast. Using webhooks requires a server (it won't work on your laptop). Self-signed certificates are also supported, but you must issue the certificates yourself. For a comprehensive reference check Marvin's Patent Pending Guide to All Things Webhook.
Beside the usual ways, I've managed to run some bots successfully on a Raspberry Pi 2, and most notably on an old Android (4.1.2) phone with a broken screen.
Contributions are highly appreciated, documentation improvements/corrections, idiomatic Scala, bug reports, even feature requests. Creating a bot is also a contribution, I'll add a link to your bot here anytime.
- Andrey Romanov
- Dmitry Kurinskiy
- ex0ns
- hamidr
- Juan Julián Merelo Guervós
- Kirill Lastovirya
- Maxim Cherkasov
- Onilton Maciel
- Pedro Larroy
- reimai
Just add scala import info.mukel.telegrambot4s._, api._, methods._, models._, Implicits._
and you are good to go.
Get into the test console in sbt
sbt
[info] Loading project definition from ./telegrambot4s/project
[info] Set current project to telegrambot4s (in build file:./telegrambot4s/)
> test:console
[info] Compiling 10 Scala sources to ./telegrambot4s/target/scala-2.11/test-classes...
[info] Starting scala interpreter...
[info]
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_101).
Type in expressions for evaluation. Or try :help.
scala> import info.mukel.telegrambot4s.examples._
import info.mukel.telegrambot4s.examples._
scala> new RandomBot("TOKEN_HERE").run()
Change RandomBot
to whatever bot you find interesting.
object LmgtfyBot extends TelegramBot with Polling with Commands {
def token = "TOKEN"
on("/lmgtfy") { implicit msg => args =>
reply(
"http://lmgtfy.com/?q=" + URLEncoder.encode(args mkString " ", "UTF-8"),
disableWebPagePreview = true
)
}
}
LmgtfyBot.run()
object TextToSpeechBot extends TelegramBot with Polling with Commands with ChatActions {
def token = "TOKEN"
val ttsApiBase = "http://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=en-us&q="
on("/speak") { implicit msg => args =>
val text = args mkString " "
val url = ttsApiBase + URLEncoder.encode(text, "UTF-8")
for {
response <- Http().singleRequest(HttpRequest(uri = Uri(url)))
if response.status.isSuccess()
bytes <- Unmarshal(response).to[ByteString]
} /* do */ {
uploadingAudio // Hint the user
val voiceMp3 = InputFile.FromByteString("voice.mp3", bytes)
api.request(SendVoice(msg.sender, voiceMp3))
}
}
}
TextToSpeechBot.run()
object WebhookBot extends TelegramBot with Webhook with Commands {
def token = "TOKEN"
override val port = 8443
override val webhookUrl = "https://ed88ff73.ngrok.io"
val rng = new Random(System.currentTimeMillis())
on("/coin") { implicit msg => _ => reply(if (rng.nextBoolean()) "Head!" else "Tail!") }
on("/real") { implicit msg => _ => reply(rng.nextDouble().toString) }
on("/dice") { implicit msg => _ => reply((rng.nextInt(6) + 1).toString) }
// /random n
on("/random") { implicit msg => {
case Seq(s) =>
reply(Try(s.toInt).map { case n if (n > 0) => rng.nextInt(n).toString }.getOrElse("Invalid argument"))
}
}
// /choose Ana Bob Charles
on("/choose") { implicit msg => args =>
reply(if (args.isEmpty) "Empty list." else args(rng.nextInt(args.size)))
}
}
WebhookBot.run()
Check out the sample bots for more functionality.