https://github.com/bot4s/telegram
Telegram Bot API Wrapper for Scala
https://github.com/bot4s/telegram
polling scala telegram telegram-api telegram-bot telegram-bot-api telegram-bots webhook
Last synced: 15 days ago
JSON representation
Telegram Bot API Wrapper for Scala
- Host: GitHub
- URL: https://github.com/bot4s/telegram
- Owner: bot4s
- License: apache-2.0
- Created: 2015-08-01T08:31:47.000Z (over 9 years ago)
- Default Branch: main
- Last Pushed: 2024-04-13T06:05:58.000Z (about 1 year ago)
- Last Synced: 2024-04-14T02:42:17.373Z (about 1 year ago)
- Topics: polling, scala, telegram, telegram-api, telegram-bot, telegram-bot-api, telegram-bots, webhook
- Language: Scala
- Homepage:
- Size: 2.17 MB
- Stars: 401
- Watchers: 19
- Forks: 96
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-telegram - bot4s.telegram - typed wrapper for the Telegram Bot API._ (Telegram Libraries / Scala)
- awesome-telegram - bot4s.telegram - typed wrapper for the Telegram Bot API._ (Telegram Libraries / Scala)
README
![]()
Idiomatic Scala wrapper for the
Telegram Bot API
# bot4s.telegram
Simple, extensible, strongly-typed wrapper for the [Telegram Bot API](https://core.telegram.org/bots/api).
# Table of contents
- [Quick start](#quick-start)
- [Leaking bot tokens](#leaking-bot-tokens)
- [Webhooks vs Polling](#webhooks-vs-polling)
- [Payments](#payments)
- [Games](#games)
- [Deployment](#deployment)
- [Running the examples](#running-the-examples)
- [A note on implicits](#a-note-on-implicits)
- [Examples](#examples)
- [Let me Google that for you!](#let-me-google-that-for-you)
- [Google Text To Speech](#google-tts)
- [Random Bot (Webhooks)](#using-webhooks)
- [Versioning](#versioning)
- [Authors](#authors)
- [License](#license)## As SBT/mill dependency
Add to your `build.sbt` file:
```scala
// 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"
```For [mill](https://com-lihaoyi.github.io/mill) add to your `build.sc` project deps:
```scala
ivy"com.bot4s::telegram-core:5.8.4", // core
ivy"com.bot4s::telegram-akka:5.8.4" // extra goodies
```## Leaking bot tokens
**Don't ever expose your bot's token.**
Hopefully [GitGuardian](https://www.gitguardian.com/) got you covered and will warn you about exposed API keys.
## Webhooks vs. Polling
Both methods are supported.
(Long) Polling is bundled in the `core` artifact and it's by far the easiest method.Webhook support comes in the `extra` artifact based on [akka-http](https://github.com/akka/akka-http); requires a server, it won't work on your laptop.
For a comprehensive reference check [Marvin's Patent Pending Guide to All Things Webhook](https://core.telegram.org/bots/webhooks).Some webhook examples are available [here](https://github.com/bot4s/telegram/blob/main/examples/src-jvm/WebhookBot.scala) and [here](https://github.com/bot4s/telegram/blob/main/examples/src-jvm/WebhookSSLBot.scala) (with self signed SSL certificate setup).
## Payments
Payments are supported since version 3.0; refer to [official payments documentation](https://core.telegram.org/bots/payments) for details.
I'll support developers willing to integrate and/or improve the payments API; please report issues [here](https://github.com/bot4s/telegram/issues/new).## Games
The Akka extensions include support for games in two flavors; self-hosted (served by the bot itself),
and external, hosted on e.g. GitHub Pages.
Check both the [self-hosted](https://github.com/bot4s/telegram/blob/main/examples/src-jvm/SelfHosted2048Bot.scala) and
[GitHub-hosted](https://github.com/bot4s/telegram/blob/main/examples/src-jvm/GitHubHosted2048Bot.scala) versions of the
popular [2048](https://gabrielecirulli.github.io/2048/) game.## Deployment
`bot4s.telegram` runs on Raspberry Pi, Heroku, Google App Engine and most notably on an old Android (4.1.2) phone with a broken screen via the JDK for ARM.
Bots also runs flawlessly on top of my master thesis: "A meta-circular Java bytecode interpreter for the GraalVM".Distribution/deployment is outside the scope of the library, but all platforms where Java is
supported should be compatible. You may find [sbt-assembly](https://github.com/sbt/sbt-assembly) and [sbt-docker](https://github.com/marcuslonnberg/sbt-docker)
very handy.Scala.js is also supported, bots can run on the browser via the SttpClient. NodeJs is not supported yet.
## Running the examples
`bot4s.telegram` uses [mill](https://com-lihaoyi.github.io/mill).
```
$ mill examples.jvm[2.13.10].console
[79/79] examples.jvm[2.13.10].console
Welcome to Scala 2.13.10 (OpenJDK 64-Bit Server VM, Java 11.0.10).
Type in expressions for evaluation. Or try :help.scala> new RandomBot("BOT_TOKEN").run()
```Change `RandomBot` to whatever bot you find interesting [here](https://github.com/bot4s/telegram/tree/main/examples).
## A note on implicits
A few implicits are provided to reduce boilerplate, but are discouraged because unexpected side-effects.
Think seamless `T => Option[T]` conversion, Markdown string extensions (these are fine)...
Be aware that, for conciseness, most examples need the implicits to compile, be sure to include them.`import com.bot4s.telegram.Implicits._`
## Examples
#### RandomBot! [(full example)](https://github.com/bot4s/telegram/blob/main/examples/src/RandomBot.scala)
```scala
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 slogging.{LogLevel, LoggerConfig, PrintLoggerFactory}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("/dice" | "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
}
}// Int(n) extractor
object Int {
def unapply(s: String): Option[Int] = Try(s.toInt).toOption
}
}// To run spawn the bot
val bot = new RandomBot("BOT_TOKEN")
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)
```#### Google TTS [(full example)](https://github.com/bot4s/telegram/blob/main/examples/src-jvm/TextToSpeechBot.scala)
```scala
import java.net.URLEncoderimport cats.instances.future._
import cats.syntax.functor._
import com.bot4s.telegram.Implicits._
import com.bot4s.telegram.api.declarative._
import com.bot4s.telegram.api.ChatActions
import com.bot4s.telegram.future.Polling
import com.bot4s.telegram.methods._
import com.bot4s.telegram.models._import scala.concurrent.Future
/** Text-to-speech bot (using Google TTS API)
*
* Google will rightfully block your IP in case of abuse.
* Usage: /speak Hello World
*/
object TextToSpeechBot extends TelegramBot
with Polling
with Commands[Future]
with InlineQueries[Future]
with ChatActions[Future] {override val client: RequestHandler[Future] = new ScalajHttpClient("BOT_TOKEN")
def ttsUrl(text: String): String =
s"http://translate.google.com/translate_tts?client=tw-ob&tl=en-us&q=${URLEncoder.encode(text, "UTF-8")}"onCommand("speak" | "say" | "talk") { implicit msg =>
withArgs { args =>
val text = args.mkString(" ")
for {
r <- Future { scalaj.http.Http(ttsUrl(text)).asBytes }
if r.isSuccess
bytes = r.body
_ <- uploadingAudio // hint the user
voiceMp3 = InputFile("voice.mp3", bytes)
_ <- request(SendVoice(msg.source, voiceMp3))
} yield ()
}
}
}val bot = TextToSpeechBot
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) // ScalaJs wont't let you do this
```#### Using webhooks
```scala
object LmgtfyBot extends AkkaTelegramBot
with Webhook
with Commands[Future] {val client = new AkkaHttpClient("BOT_TOKEN")
override val port = 8443
override val webhookUrl = "https://1d1ceb07.ngrok.io"onCommand("lmgtfy") { implicit msg =>
withArgs { args =>
reply(
"http://lmgtfy.com/?q=" + URLEncoder.encode(args.mkString(" "), "UTF-8"),
disableWebPagePreview = Some(true)
)
}
}
}
```Check out the [sample bots](https://github.com/bot4s/telegram/tree/main/examples) for more functionality.
## Versioning
This library uses [Semantic Versioning](http://semver.org/). For the versions available, see the [tags on this repository](https://github.com/bot4s/telegram/tags).
## Authors
- **Alfonso² Peterssen** - _Owner/maintainer_ - :octocat: [mukel](https://github.com/mukel)
_Looking for maintainers!_
See also the list of [awesome contributors](https://github.com/bot4s/telegram/contributors) who participated in this project.
Contributions are very welcome, documentation improvements/corrections, bug reports, even feature requests.## License
This project is licensed under the Apache 2.0 License - see the [LICENSE](/LICENSE) file for details.
## Buy Me A Coffee
If you like this library, please consider buying me a coffee. :relaxed: