TelegramBot di Cloud Wolfram

Pendahuluan


Periode telah berlalu ketika setiap artikel kedua tentang Habrahabr dikhususkan untuk menulis bot telegram-nya. Juga, periode waktu berlalu ketika bot tanpa kesulitan dapat ditempatkan di komputer Anda atau hosting di Rusia. Enam bulan lalu, bot saya baru saja dimulai pada laptop dan tidak mengalami masalah saat terhubung ke API. Tetapi sekarang, ketika saya berpikir untuk membuatnya kembali bekerja, saya menyadari bahwa itu tidak akan mudah. Saya tidak ingin mencari dan mengkonfigurasi server proxy, dan terlebih lagi di luar negeri. Juga, sebelum itu saya menulis bot dalam Bahasa Wolfram dan tidak tahu bagaimana bahasa itu bekerja dengan server proxy, karena saya belum menggunakannya. Dan kemudian sebuah ide bagus muncul! Gunakan Wolfram Cloud. Dalam artikel ini saya ingin menunjukkan betapa sangat sederhana dengan pendaftaran, tetapi tanpa SMS Anda dapat memulai bot telegram sederhana Anda yang ditulis dalam Bahasa Wolfram. Dari alat Anda hanya perlu browser.


Sedikit tentang cloud Wolfram


Untuk mengakses cloud, Anda perlu membuat akun Wolfram. Untuk melakukan ini, buka https://account.wolfram.com dan ikuti instruksi setelah mengklik tombol Buat Satu.



Setelah semua manipulasi dilakukan, pada halaman utama cloud di https://www.wolframcloud.com semua produk dan rencana penggunaannya akan ditampilkan. Anda harus memilih Platform Pengembangan dan membuat buku catatan baru.



Semua kode yang diberikan nanti akan dieksekusi di cloud notebook khusus ini.


Cukup banyak tentang bot telegram


Ada banyak artikel yang didedikasikan untuk mereka. Di sini hanya perlu dikatakan bahwa sebelum melakukan semua tindakan lebih lanjut, bot harus dibuat dengan cara standar. Yaitu, mulailah obrolan dengan bot @BotFather dan kirimkan perintah:


/newbot 

Maka Anda hanya perlu mengikuti instruksi dan memasukkan nama dan login. Biarkan namanya menjadi Wolfram Cloud Bot dan login @ WolframCloud5973827Bot.



Implementasi API


Kami mengambil keuntungan dari rekomendasi @BotFather dan secara singkat memeriksa API HTTP dari telegram bot. Tugas menerapkan seluruh API belum layak. Untuk menulis bot, hanya sebagian kecil saja sudah cukup. Periksa apakah API dapat diakses dan bot dengan token yang ditentukan di atas ada. Untuk melakukan ini, cukup lakukan satu baris:


 URLExecute["https://api.telegram.org/bot753681357:AAFqdRFN_QoODJxsBy3VN2sVwWTPKJEqteY/getMe"] 

Keluar [..]: = ...
 {"ok" -> True, "result" -> {"id" -> 753681357, "is_bot" -> True, "first_name" -> "Wolfram Cloud Bot", "username" -> "WolframCloud5973827Bot"}} 

Perintah di atas adalah cara termudah untuk membuat permintaan HTTP dari Bahasa Wolfram. Tetapi mari kita sedikit mempersulitnya sehingga mudah untuk menerapkan semua metode API lainnya. Mari kita buat metode umum untuk mengeksekusi permintaan API:


 TelegramBot::usage = "TelegramBot[token]"; $telegramAPI = "https://api.telegram.org"; telegramExecute[ TelegramBot[token_String], method_String, parameters: {(_String -> _)...}: {} ] := Module[{ request, requestURL, requestRules, requestBody, response, responseBody }, requestURL = URLBuild[{$telegramAPI, "bot" <> token, method}]; requestRules = DeleteCases[parameters, _[_String, Automatic | Null | None]]; requestBody = ImportString[ExportString[requestRules, "JSON"], "Text"]; request = HTTPRequest[requestURL, <| Method -> "POST", "ContentType" -> "application/json; charset=utf-8", "Body" -> requestBody |>]; response = URLRead[request]; responseBody = response["Body"]; Return[ImportString[responseBody, "RawJSON"]] ] 

Periksa apakah ini berfungsi pada metode yang sudah diuji di atas:


 token = "753681357:AAFqdRFN_QoODJxsBy3VN2sVwWTPKJEqteY"; bot = TelegramBot[token]; telegramExecute[bot, "getMe"] 

Keluar [..]: = ...
 <|"ok" -> True, "result" -> <|"id" -> 753681357, "is_bot" -> True, "first_name" -> "Wolfram Cloud Bot", "username" -> "WolframCloud5973827Bot"|>|> 

Bagus Mari kita buat fungsi terpisah untuk melakukan pemeriksaan bot:



 getMe::usage="getMe[bot]"; TelegramBot /: getMe[bot_TelegramBot] := telegramExecute[bot, "getMe"] getMe[bot] 

Keluar [..]: = ...
 <|"ok" -> True, "result" -> <|"id" -> 753681357, "is_bot" -> True, "first_name" -> "Wolfram Cloud Bot", "username" -> "WolframCloud5973827Bot"|>|> 

Sekarang, dengan cara yang sama, tetap menambahkan metode dasar yang diperlukan untuk membuat bot di cloud:


  • getUpdates - mendapatkan semua pesan terbaru yang ditulis ke bot

 getUpdates::usage = "getUpdates[bot, opts]"; Options[getUpdates] = { "offset" -> Automatic, "limit" -> Automatic, "timeout" -> Automatic, "allowed_updates" -> Automatic }; TelegramBot /: getUpdates[bot_TelegramBot, opts: OptionsPattern[getUpdates]] := telegramExecute[bot, "getUpdates", Flatten[{opts}]] 

  • setWebhook - menetapkan alamat server untuk memproses pembaruan

 setWebhook::usage = "setWebhook[bot, url, opts]"; Options[setWebhook] = { "certificate" -> Automatic, "max_connections" -> Automatic, "allowed_updates" -> Automatic }; TelegramBot /: setWebhook[bot_TelegramBot, url_String, opts: OptionsPattern[setWebhook]] := telegramExecute[bot, "setWebhook", Join[{"url" -> url}, Flatten[{opts}]]] 


 deleteWebhook::usage = "deleteWebhook[bot]"; TelegramBot /: deleteWebhook[bot_TelegramBot] := telegramExecute[bot, "deleteWebhook"] 


 getWebhookInfo::usage = "getWebhookInfo[bot]"; TelegramBot /: getWebhookInfo[bot_TelegramBot] := telegramExecute[bot, "getWebhookInfo"] 


 sendMessage::usage = "sendMessage[bot, chat, text]"; Options[sendMessage] = { "parse_mode" -> Automatic, "disable_web_page_preview" -> Automatic, "disable_notification" -> Automatic, "reply_to_message_id" -> Automatic, "reply_markup" -> Automatic }; TelegramBot /: sendMessage[bot_TelegramBot, chat_Integer, text_String, opts: OptionsPattern[sendMessage]] := telegramExecute[ bot, "sendMessage", Join[{"chat_id" -> chat, "text" -> text}, Flatten[{opts}]] ] 

Versi minimum API siap. Mari kita periksa bagaimana mengirim pesan dan menerima pembaruan berfungsi. Untuk melakukan ini, buat obrolan dengan bot kami. Ketika bot dibuat, pesan pertama dengan teks / mulai akan dikirim. Mari kita lihat apakah masuk ke daftar pembaruan:


 updates = getUpdates[bot] 

Keluar [..]: = ...
 <|"ok" -> True, "result" -> {<|"update_id" -> 570790461, "message" -> <|"message_id" -> 1, "from" -> <|"id" -> 490138492, "is_bot" -> False, "first_name" -> "Kirill", "last_name" -> "Belov", "username" -> "KirillBelovTest"|>, "chat" -> <|"id" -> 490138492, "first_name" -> "Kirill", "last_name" -> "Belov", "username" -> "KirillBelovTest", "type" -> "private"|>, "date" -> 1542182547, "text" -> "/start", "entities" -> {<|"offset" -> 0, "length" -> 6, "type" -> "bot_command"|>}|>|>}|> 

Anda bisa mendapatkan data pembaruan terbaru dari daftar pembaruan sebagai berikut:


 lastUpdate = updates["result"][[-1]] 

Keluar [..]: = ...
 <|"update_id" -> 570790461, "message" -> <|"message_id" -> 1, "from" -> <|"id" -> 490138492, "is_bot" -> False, "first_name" -> "Kirill", "last_name" -> "Belov", "username" -> "KirillBelovTest"|>, "chat" -> <|"id" -> 490138492, "first_name" -> "Kirill", "last_name" -> "Belov", "username" -> "KirillBelovTest", "type" -> "private"|>, "date" -> 1542182547, "text" -> "/start", "entities" -> {<|"offset" -> 0, "length" -> 6, "type" -> "bot_command"|>}|>|> 

Dan ini adalah bagaimana Anda bisa mendapatkan obrolan dari mana pesan itu berasal dan teks pesan:


 chat = lastUpdate["message", "chat", "id"] text = lastUpdate["message", "text"] 

Keluar [..]: = ...
 490138492 /start 

Seperti yang Anda lihat dari hasilnya, semuanya ada di tempatnya. Sekarang kami akan mengirim pesan atas nama bot menggunakan sendMessage.


 sendMessage[bot, chat, "hello"] 

Keluar [..]: = ...
 <|"ok" -> True, "result" -> <|"message_id" -> 2, "from" -> <|"id" -> 753681357, "is_bot" -> True, "first_name" -> "Wolfram Cloud Bot", "username" -> "WolframCloud5973827Bot"|>, "chat" -> <|"id" -> 490138492, "first_name" -> "Kirill", "last_name" -> "Belov", "username" -> "KirillBelovTest", "type" -> "private"|>, "date" -> 1542182601, "text" -> "hello"|>| > 


Secara umum, rangkaian fungsi ini sudah cukup. Namun, menggunakan metode getUpdates sangat tidak nyaman. Anda perlu menemukan cara untuk menangani pesan menggunakan webhook.


Membuat webhook


Wolram Langauge memiliki jenis fungsi khusus yang dibuat menggunakan APIFunction. Ini adalah contoh dari salah satunya:


 apiFunc = APIFunction[{"n" -> "Integer"}, Plot[Sin[#n * x], {x, -2Pi, 2Pi}]&, "PNG"]; apiFunc[{"n"->3}] 

Keluar [..]: = ...


Fitur-fitur ini dirancang khusus untuk ditempatkan di cloud. Fungsi ini akan menerima satu parameter permintaan sebagai input. Untuk menyebarkannya di cloud, cukup transfer fungsi itu sendiri ke CloudDeploy.


 apiObject = CloudDeploy[apiFunc, "Deploy/apiObject"] 

Keluar [..]: = ...
 CloudObject[https://www.wolframcloud.com/objects/kirillbelovtest/apiObject] 

Kemudian Anda dapat mengikuti tautan di browser dan menambahkan parameter kueri:



Fungsi di atas menangani parameter permintaan. Jadi, Anda perlu membuat fungsi yang sama untuk memproses isi permintaan HTTP yang berasal dari bot telegram dalam bentuk objek Pembaruan. Untuk menghasilkan alamat, kami menggunakan token untuk mendapatkan akses ke objek cloud lebih sulit. Anda juga harus menunjukkan bahwa objek memiliki akses publik, jika tidak telegram tidak akan bisa masuk ke webhook.


 deployWebhook[bot_TelegramBot, handler_] := CloudDeploy[APIFunction[{}, handler[HTTPRequestData["Body"]] &], "Deploy/Webhooks/" <> Hash[bot, "SHA", "HexString"], Permissions -> "Public" ] 

handler adalah penangan fungsi lain. Biarkan pawang mengubah string badan permintaan menjadi asosiasi, dapatkan pengenal obrolan dari sana dan kirim kembali kata "halo".


 handlerHello[bot_TelegramBot][body_String] := Block[{json = ImportString[body, "RawJSON"], chat}, chat = json["message", "chat", "id"]; sendMessage[bot, chat, "hello"]; ] 

Sekarang gunakan funky di cloud.


 webhookObject = deployWebhook[bot, handlerHello[bot]] 

Keluar [..]: = ...
 CloudObject[https://www.wolframcloud.com/objects/kirillbelovtest/Deploy/Webhooks/b9bd74f89348faecd6b683ba02637dd4d4028a28] 

Dan langkah terakhir adalah mentransfer alamat objek ini ke bot telegram.


 setWebhook[bot, webhookObject[[1]]] 

Keluar [..]: = ...
 <|"ok" -> True, "result" -> True, "description" -> "Webhook was set"|> 

Sekarang kita akan menulis sesuatu untuk bot dan melihat apa yang dikatakannya:



Dialog dapat dianggap sah. Untuk mengubah logika dari penangan yang ada, cukup gunakan kembali objek cloud. Pada saat yang sama, Anda tidak perlu lagi memasang webhook untuk bot.


Logika jawaban


Ini akan menjadi bagian terakhir dalam proses membuat bot di cloud Wolfram. Lebih lanjut, dengan cara yang sama, Anda dapat menyulitkan logika dan menambahkan metode API baru. Sekarang tentang dialog itu sendiri. Misalkan setelah mengirim perintah / mulai, bot mengembalikan respons "Halo" dan mengubah keyboard pengguna. Hanya dua tombol yang tersisa di keyboard: "Halo" dan "Siapa kamu?" Kami menyadari dialog dalam bentuk asosiasi. Kunci akan menjadi perintah yang dikirim pengguna ke bot. Nilai kuncinya adalah respons bot itu sendiri dan keyboard baru. Dalam hal ini, banyak tombol dan tombol harus sama persis. Jika tidak, suatu situasi dapat muncul ketika bot tidak tahu harus menjawab apa. Dalam kasus seperti itu, tentu saja, Anda dapat menambahkan jawaban default.


 keyboard[buttons : {__String}] := {"keyboard" -> {Table[{"text" -> button}, {button, buttons}]}, "resize_keyboard" -> True} $answers = <| (*user_text-><|"answer"->bot_text,"keyboard"->next_text|>*) "/start"-><|"answer"->"","keyboard"-> keyboard[{""," ?"}]|>, ""-><|"answer"->" ?", "keyboard" -> keyboard[{" ?"}]|> , " ?"-><|"answer"->"", "keyboard" -> keyboard[{""}]|> , " ?"-><|"answer"->"   Wolfram Language   ", "keyboard"->keyboard[{" ?"," ?"}]|> , " ?"-><|"answer"->"   :\nhttps://habr.com/post/422517/", "keyboard"->keyboard[{""," ?"}]|> , " ?"-><|"answer"->"  :\n@KirillBelovTest", "keyboard"->keyboard[{" ?",""}]|> , ""-><|"answer"->"", "keyboard"->keyboard[{""," ?"}]|> |>; answer[text_String] /; KeyExistsQ[$answers, text] := $answers[text] 

Sekarang buat penangan:


 handlerAbout[bot_TelegramBot][body_String] := Block[{json = ImportString[body, "RawJSON"], chat, text}, chat = json["message", "chat", "id"]; text = json["message", "text"]; sendMessage[bot, chat, answer[text]["answer"], "reply_markup" -> answer[text]["keyboard"]]; ] 

Dan gunakan kembali objek cloud:


 deployWebhook[bot, handlerAbout[bot]]; 

Mari kita verifikasi apa yang terjadi dalam obrolan dengan bot. Tapi pertama-tama, mari kita hapus riwayat pesan:



Perpanjangan fungsi


Sejauh ini, tidak ada perbedaan mendasar dari sejumlah besar bot yang ada. Mungkin tidak ada gunanya meminumnya juga? Arti dari semua pekerjaan yang dilakukan di atas adalah, jika Anda mengerti apa keuntungan dari bot seperti itu! Bagaimanapun, ia dapat menggunakan semua fitur Bahasa Wolfram dan Wolrfam Cloud. Apakah perlu bagi robot untuk menyelesaikan persamaan? Sangat mudah! Anda hanya perlu mendefinisikan ulang jawabannya!


 answer[text_String]["keyboard"] /; StringContainsQ[text, "  "] := Automatic answer[text_String]["answer"] /; StringContainsQ[text, "  "] := ToString[Flatten[Block[{args = StringSplit[text, "  "]}, Solve[ToExpression[args[[1]]], ToExpression[args[[2]]]] ]]] deployWebhook[bot, handlerAbout[bot]]; 


Jika seseorang tambahan memiliki minat pada kemampuan cloud, maka deskripsi yang baik tentang fungsinya ada di sini .


Keterbatasan


Wolfram Cloud adalah platform yang memungkinkan Anda menggunakan bahasa Wolfram secara gratis, sedangkan produk utama Wolfram Research, Mathematica, membutuhkan biaya. Oleh karena itu, ada batasan penggunaan dan menurut pendapat saya mereka sangat kuat. Saat menggunakan versi gratis Platform Pengembangan, pengguna diberikan 1.000 kredit cloud per bulan. Setiap pinjaman cloud memberikan waktu untuk menghitung jenis yang berbeda. Karena artikel tersebut berbicara tentang CloudDeploy + APIFunction, objek yang disimpan di cloud menghabiskan 1 kredit dalam 0,1 detik waktu komputasi. Sangat mudah untuk menghitung bahwa pengguna diberikan gratis hanya 1 menit dan 40 detik waktu server untuk pengoperasian aplikasinya (dalam hal ini, bot). Saya tidak perlu menambahkan apa pun di sini - ini sangat, sangat kecil. Penekanan utama adalah pada pengguna yang bekerja secara mandiri di Platform Pengembangan menggunakan browser. Memang, dalam mode ini tidak ada batas waktu, tetapi hanya sesuai dengan durasi sesi dan sumber daya yang dialokasikan. Dengan penggunaan ini, Platform Pengembangan hampir menjadi Mathematica penuh, tetapi tidak memerlukan instalasi dan lisensi.


Artikel dan kode di Wolfram Cloud

Source: https://habr.com/ru/post/id422517/


All Articles