Micronautで電報ボットを作成する


電報は、よく知られているインスタントメッセージングアプリケーションのユーザー数百万人のために世界中で使用されるので、プレゼンテーションはここに必要です.今日、Apiumhub teamに代わって、我々は特別な特徴に集中するつもりです:ボット、電報の中で動く第三者アプリケーション.ユーザーは、メッセージやコマンドを介してボットと対話することができます.これらのアプリケーションは、複数の使用をすることができます:いくつかの情報を取得、アイテムを購入、eコマースのサポートをチャット.そして今日の記事はMicronautと電報ボットを作成する方法です.

Micronautで電報ボットを作成する


彼らがどのように働くかを見るために、我々は楽しみのためにいくつかの基本的なコマンドで電報ロボットを作成するつもりです.プロジェクトは、要求された人口に関する情報を返すロボットです.私たちは開いたサードパーティAPIからこのデータを得ています.サービスは、それが我々のニーズに適しているかどうかを確認するためにMicronautフレームワークを使用して作成されます.
私たちのボットを起動し、2つの部分が必要です:
  • 私たちのボット
  • される電報アカウント
  • は、ボット
  • と対話するウェブサービスです
    プロジェクト全体を作成する手順を見てみましょう.

    ボットを作る


    電報は新しいアカウントを作成するボットを提供しています
    お使いの電報アカウントを介してbotfatherとの相互作用、いくつかのコマンドを入力する(/newbotを起動する)、それはあなたのボットを作成します.
    the botfather
    botfatherは電報APIと対話するのに必要であるアクセストークンを作成するでしょう.

    Webサービスの構成


    ボットからリクエストを受け取るには、2つのオプションがあります.
    1 . -長いポーリング-私たちのWebサービスは、要求を待っているすべての時間を電報サーバに接続されます
    2 - webhooks -私たちのサービスは、新しいメッセージがあるたびに電報が毎回呼び出すとAPIを提供する必要があります.
    それがより簡単で、より少ない資源を消費するので、我々はWebhooksを使用するつもりです(我々のWebServiceはちょうど完全な1つのオープン接続を持つ代わりに、新しい接続を待っています).
    URLを設定するには、Telegram APIへの簡単な呼び出しが必要です.
    
    curl -F "url=https://YOURDOMAIN.EXAMPLE/WEBHOOKLOCATION" https://api.telegram.org/bot/setWebhook 
    
    
    注意!

  • URLはHTTPS

  • ポートはこれらのうちの1つだけであることができます:443、80、88または8443

  • セキュリティ上の理由から、電報ネットワークからの要求のみを許可するのは良い考えかもしれません.
    我々のロボットはすでに構成されています、そして、我々がそれに送るどんなメッセージも我々のウェブサービスに受けられます.
    リクエストへの返信方法
    応答を我々のボットに返信するには、電報も2つのオプションを与えます.
    1 -同じリクエストで応答を返信する

    リクエストをHTTP 200で返信し、新しいリクエストをAPIに送る.

    私たちのWebサービスは、3番目のプロバイダと相互作用するので、どのようにそれが彼らの反応になるのか分からないので、我々は2番目のオプションを選択します:私たちはすぐにOKを送信しますし、我々はデータを一度の応答でAPIにポストを送信します.
    Webサービスを作成する
    Webサービスを作成するには、を使用します.それはJVMフレームワーク(Java、KotlinまたはGroovyで書かれることができます)は低メモリ消費を約束して、我々のユースケースのために非常に便利であるように見えない非ブロッキングHTTPサーバを提供します:我々が要求を処理する間、すぐにOKを返信する軽いフレームワークを必要とします.MicroNotがReactiveストリームをサポートしているため、この非同期呼び出しはRXJava経由で処理されます.
    彼らのツールMicronautで、我々のアプリケーションのために骨格を得ることは非常に簡単です.それは私たちの言語を選択し、ツール、テストフレームワークと必要に応じてエクストラを構築することができます.
    フレームワークのアップロードと実行により、リクエストを処理するコントローラを作成します.
    
    @Controller("/bot")
    class BotController {
    
        @Post("/")
        fun index(@Body request: String): HttpResponse {
            processRequest(request)
            return HttpResponse.ok()
        }
    }
    
    
    コントローラを定義しています
    *
    を定義してください.
    <研究ノート>二〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇円
    電報プロトコルを管理するために、我々はすでに電報APIのためにすべての要求と応答を実装した1 , micronaut launchを使用するつもりです.それらの多くは異なる言語で書かれている.
    ボットのロジックを実装する
    我々のテスト目的のために、我々はカタロニアの都市、町と村に関する若干の情報を得るためにopen source libraryによって提供される開いたデータを使用するつもりです.彼らのlisted by telegramStatistical Institute of Cataloniaを使用して、我々は特定の都市についてのデータを要求して、それをユーザーに示すことができます.
    ステップは、最初にユーザーが/タウンのXXXを持つ名前を検索し、ボットは、それの隣にリンクを使用可能な都市名のリストに対応します.ユーザーが場所の名前を確認して任意のリンクをクリックすると、人口の情報が表示されます.
    これまで、2つの可能なリクエストを処理する必要があります.
    1 -都市のリストを取得する
    
    {...}
    
        private fun processRequest(request: String) {
            val message: Message = BotUtils.parseUpdate(request).message()
            val chatId: Long = message.chat().id()
            val messageReceived = message.text()
            when (messageReceived.split(" ")[0]) {
                "/start" -> sendResponse(chatId, "This is the very beginning")
                "/town" -> getCityNamesList(messageReceived, chatId)
                else -> sendResponse(chatId, messageReceived.reversed())
            }
        }
    
    {...}
    
      private fun getCityNamesList(messageReceived: String, chatId: Long) {
            val search = messageReceived.split(" ").drop(1).joinToString("%20")
            val body: Flowable
            try {
                val client = RxHttpClient.create(URL("https://api.idescat.cat"))
                val towns: HttpRequest = HttpRequest.GET("/pob/v1/sug.txt?p=q/$search;tipus/mun")
                body = client.retrieve(towns).doOnError { sendResponse(chatId, "Error. Please try another name") }
            } catch (e: Exception) {
                sendResponse(chatId, "Nothing found. Please try another name")
                return
            }
    
            body.subscribe {
                val split = it.split("\n")
                val eq = "These are the cities found:\n" + split.map { "${cleanName(it)} /${it.base64encode()}" }
                    .joinToString("\n")
                sendResponse(chatId, eq)
            }
        }
    
      private fun sendResponse(chatId: Long, reply: String): SendResponse? {
            val bot = TelegramBot(TELEGRAM_TOKEN)
            return bot.execute(SendMessage(chatId, reply))
        }
    
    
    \/タウンXXコマンドは外部APIにリクエストを行い、都市のリストを取得します.RXHttpClientは、最終的に外部呼び出しから応答を返すflowableを作成します.我々がそれを購読したので、我々はその出来事を捕えます.そうすることで、プロセスはその応答を待ちませんし、リクエスト全体をブロックしません.
    非同期応答は、私たちのために作成されたアクセストークンの設定としてのみ必要な電報ライブラリを介して送信されます.
    2 -与えられた都市の情報を得る
    
    private fun getCityInfo(chatId: Long, messageReceived: String) {
            val cityDecoded: String
            try {
                cityDecoded = messageReceived.replace("/", "").base64decode()
            } catch (e: Exception) {
                sendResponse(chatId, "invalid text")
                return
            }
    
            val client = RxHttpClient.create(URL("https://api.idescat.cat"))
            val towns: HttpRequest = HttpRequest.GET("/emex/v1/dades.json?i=f171,f36,f42&lang=en&id=${cityDecoded}")
            client.retrieve(towns).subscribe {
                val data = Gson().fromJson(it, Fitxes::class.java)
                val texts = data.fitxes.indicadors.i.map { "${it.c}: ${it.v.split(",").first()}" }
                    .joinToString("\n")
                sendResponse(chatId, "Information about ${cleanName(cityDecoded)} \n${texts}")
            }
        }
    
    
    XXXXがBase 64符号化名である場合、外部APIへのリクエストが発生し、特定の都市の情報が取得されます.
    再び、フローチャートを作成し、結果を非同期で取得し、それらを電報に戻します.
    ボット作業中
    ここではバルセロナのスクリーンショットを見ることができます.ボーナス・トラックとして、どんな既存のコマンドも、ストリングを逆に返されます.
    Population search API
    結論
    それはどのようにMicronautと電報ボットとどのようにロボットのこの種の無限の可能性を発見する方法を知って楽しいプロジェクトだった.Micronaut Frameworkの使用法は、この特定のケースに非常によく適していますが、確かに、非同期プロセスが処理される必要があるときに特別にそれが他のケースのために心に留めておくツールでありえます.
    The municipality in figures API年には、が初めて登場した.