Skip to content

djpg/telegrambot4s

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TelegramBot4s

Travis CI Build Status Codacy Badge Telegram API Maven Central JitPack License

Idiomatic Scala wrapper for the Telegram Bot API.

The full API is supported: Payments, inline queries, upload files, callbacks, custom markups, games, chat actions... while being strongly-typed, fully asynchronous, and transparently camelCased.

Quick-start

Add to your build.sbt file:

libraryDependencies += "info.mukel" %% "telegrambot4s" % "2.9.5"

Leaking bot tokens

Do not expose tokens unintentionally.

Here's an example that avoids unintentional token sharing:

object SafeBot extends TelegramBot with Polling with Commands {
  // Use 'def' or 'lazy val' for the token, using a plain 'val' may/will
  // lead to initialization order issues.
  // Fetch the token from an environment variable or file.
  lazy val token = scala.util.Properties
    .envOrNone("BOT_TOKEN")
    .getOrElse(Source.fromFile("bot.token").getLines().mkString)

  on("/hello") { implicit msg => _ => reply("My token is SAFE!") }
}

SafeBot.run()

Webhooks vs Polling

Both methods are fully supported. Polling is the easiest method; it can be used locally without any additional requirements. It has been radically improved, doesn't flood the server (like other libraries do) and it's pretty fast.

Using webhooks requires a server (it won't work on your laptop). For a comprehensive reference check Marvin's Patent Pending Guide to All Things Webhook.

Payments

Payments are supported; refer to official payments documetation for details. I'll support developers willing to integrate and/or improve the payments API; please report issues here.

Bonus (or how to turn a spare phone into a Telegram Bot)

Beside the usual ways, I've managed to use the library on a Raspberry Pi 2, and most notably on an old Android (4.1.2) phone with a broken screen. It's also possible to docker-ize a bot.

Contributors

Contributions are highly appreciated, documentation improvements/corrections, idiomatic Scala, bug reports, even feature requests.

Usage

Just import info.mukel.telegrambot4s._, api._, methods._, models._, Implicits._ and you are good to go.

Reducing boilerplate

Implicits are provided to reduce boilerplate when dealing with the API; think seamless Option[T] and Either[L,R] conversions. Be aware that most examples need the implicits to compile.

import info.mukel.telegrambot4s.Implicits._

Running the examples

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 here.

Examples

Let me Google that for you!

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()

Google TTS

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("voice.mp3", bytes)
      request(SendVoice(msg.source, voiceMp3))
    }
  }
}

TextToSpeechBot.run()

Using webhooks

object WebhookBot extends TelegramBot with Webhook with Commands {
  def token = "TOKEN"
  override val port = 8443
  override val webhookUrl = "https://ed88ff73.ngrok.io"
  
  import info.mukel.telegrambot4s.Implicits._
  val rng = new Random(System.currentTimeMillis())
  on("/coin", "head or tail") { implicit msg => _ =>
    reply(if (rng.nextBoolean()) "Head!" else "Tail!")
  }
  on("/real", "real number in [0, 1]") { implicit msg => _ =>
    reply(rng.nextDouble().toString)
  }
  on("/die", "classic die [1 .. 6]") { implicit msg => _ =>
    reply((rng.nextInt(6) + 1).toString)
  }
  on("/dice", "throw two classic dice [1 .. 6]") { implicit msg => _ =>
    reply((rng.nextInt(6) + 1) + " " + (rng.nextInt(6) + 1))
  }
  on("/random", "integer in [0, n)") { implicit msg => {
    case Seq(Extractor.Int(n)) if n > 0 =>
      reply(rng.nextInt(n).toString)
    case _ =>
      reply("Invalid argumentヽ(ಠ_ಠ)ノ")
    }
  }
  on("/choose", "randomly picks one of the arguments") {
    implicit msg => args =>
      reply(if (args.isEmpty) "Empty list." else args(rng.nextInt(args.size)))
  }
}

WebhookBot.run()

Custom extensions

It's rather easy to augment your bot with custom DSL-ish shortcuts; e.g. this authenticatedOrElse snippet is taken from the AuthenticationBot example.

  ...
  on("/secret") { implicit msg => _ =>
    authenticatedOrElse {
      admin =>
        reply(
          s"""${admin.firstName}:
             |The answer to life the universe and everything: 42.
             |You can /logout now.""".stripMargin)
    } /* or else */ {
      user =>
        reply(s"${user.firstName}, you must /login first.")
    }
  }

Check out the sample bots for more functionality.

About

Telegram Bot API Wrapper for Scala

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Scala 100.0%