Echo bot for Telegram on Kotlin

Introduction

As part of this article, we will create our own bot capable of re-sending messages sent by the user, taking into account formatting and media.





The topic of bots has been pounded to holes by many blogs, posts, blog posts and other coders. However, for the most part these are conditional Python / JS / PHP bots, in which you can usually do how it goes and everything seems to even work. At one time, I (almost) left these languages ​​in the world of strong typing and object orientation in Java, and later in Kotlin. At the time when I was interested in writing my first bot, only the pengrad / java-telegram-bot-api library was present on the github market , but for me personally it had one fatal drawback: at that time it completely duplicated the Telegram Bot API . that is, in fact, it was a gasket, which, in addition to interaction through Java classes, did not give anything else.





So I came up with the idea to write my own library for the Telegram Bot API. The first version covering the main API took me a month, but updates came out, users suggested ideas for improvement, and I often didn't like doing things with my hands on an ongoing basis. As a result, the library is developing to this day, it has a convenient API, its own DSL, but most importantly, it has not lost its original idea of ​​strictly typing work with the Telegram Bot API.





How bots generally work in Telegram

Telegram bots have a lot of restrictions. You can often look at beautiful numbers here , but in short (link to BotFather , so as not to repeat yourself ) (most likely, it will be replenished to expand your horizons):





  • By default, the bot does not see messages from other users in groups until a direct call to the bot by the command (this can be changed through the group privacy setting in BotFather)





  • By default, bots are not inline. Inline bots are like a bot for gifs, that is, when you enter the nickname of the bot, add a space and it offers you options. After clicking on the option, a message is sent to the chat with the content suggested by the bot (also enabled through the setting in BotFather)





    • In addition, after enabling the inline mode for the bot, you will need to separately enable support for inline mode for locations, when the bot can return results based on the user's geolocation.





  • There is no way to get chat history in the API right now. None. At all. You can only cache messages





On average, the bot development pipeline looks like this:





  • Idea





  • BotFather /newbot







  • ,









,

  1. BotFather /newbot











Readme , App.kt



. , :





suspend fun main(args: Array<String>) {
    val bot = telegramBot(args.first()) // 1
    val scope = CoroutineScope(Dispatchers.Default) // 2

    bot.buildBehaviour(scope) { // 3
        val me = getMe()

        onCommand("start", requireOnlyCommandInMessage = true) {
            reply(it, "Hello, I am ${me.firstName}")
        }
    }.join() // 4
}
      
      



  1. . args.first()



    , BotFather





  2. CoroutineScope



    . , -





  3. . buildBehaviour











:





onContentMessage { // 1
    execute( // 2
      	it.content.createResend(it.chat.id) // 3
    )
}
      
      



? , :





  1. : , , ..





  2. execute



    - . . , ,





  3. createResend , . -





- -. :





onCommand("start") { // 1
  reply(it, ",       ,    !") // 2
}
onCommand("help") {
  reply(it, "   ,      ?")
}
      
      



  1. /start



    , ,





  2. . it







onContentMessage



, :





fun save(sources: List<TextSource>) {
  //     
  println(sources.makeString()) // 3
}

onContentMessage {
  it.content.asTextContent() ?.let { content -> // 1
    save(content.textSources) // 2
  }
  execute(it.content.createResend(it.chat.id))
}
      
      



  1. asTextContent()



    , let



    ,





  2. content.textSources



    TextSource



    , :





    1. ( TextSource



      kotlinx.serialization



      )





    2. , ,





    3. -





  3. makeString



    will create TextSource



    text from the list that will be visible to the user without regard to formatting





Conclusion

So, we have created a bot that:





  • Can respond to simple commands /start



    and/help







  • Knows how to re-send received messages to the sender





  • Selects text messages and performs operations with their content





Further, it remains only to develop the bot as far as imagination is enough. For example, you can separate modules into functions / plugins, as I did in my PlaguBot e.






For more detailed information about the project, you can see its main page , wiki , project with examples and take a look at our telegram channel .








All Articles