Telegramボットフレームワーク

たまたま私のビジネスがTelegram用のボットの作成と密接に関係していることが起こりました。 Telegram Bot APIが登場してすぐにそれらを書き始めました 、そのためのツールはありませんでした。 前の記事で部分的に説明したように、APIを操作するためのライブラリを自分で作成する必要がありました。 時間が経つにつれて、ライブラリは何度か書き直され、最終的にはさまざまなチップで大きくなりすぎました。 記事では、それを使ってボットを作成する方法についてお話します。





APIを使用するには、まずトークンを取得してこのボットを作成し、その指示に従ってください。

簡単なボットの例からすぐに始めます。

'use strict' var tg = require('telegram-node-bot')('YOUR_TOKEN') tg.router. when(['ping'], 'PingController') tg.controller('PingController', ($) => { tg.for('ping', () => { $.sendMessage('pong') }) }) 


うまくいく!



それでは、そこに書かれていることを分析しましょう。

 var tg = require('telegram-node-bot')('YOUR_TOKEN') 

ここではすべてが明確で、モジュールを宣言してトークンを渡します。

 tg.router. when(['ping'], 'PingController') 

次に、これらのチームを担当するチームとルーターを発表します。

 tg.controller('PingController', ($) => { tg.for('ping', () => { $.sendMessage('pong') }) }) 

その後、「PingController」コントローラーを作成し、その中でpingコマンドハンドラーを宣言します。

ボットがユーザーからコマンドを受け取ると、PingControllerがpingコマンドを処理することを理解し、pingコマンドハンドラーを実行します。

これについては、記事を閉じて簡単なボットの作成を開始することができますが、引き続き説明します。

ルーター


上で書いたように、ルーターはこれらのコマンドを処理するコマンドとコントローラーの通信を担当します。
明らかに、1つのコントローラーで複数のコマンドを処理できます。
ルーターには、予期しないコマンドを処理するコントローラーを宣言できる機能もあります。

 tg.router. when(['test', 'test2'], 'TestController'). // "TestController"     test,    test2 when(['ping'], 'PingController'). otherwise('OtherController') //"OtherController"      . 



コントローラー


ボットがユーザーからコマンドを受信すると、コントローラーがゲームに入ります。 上記の例からわかるように、コントローラーはユーザーコマンドを処理します。 1つのコントローラー内で、いくつかのコマンドを処理できます。

 tg.controller('TestController', ($) => { tg.for('test', () => { $.sendMessage('test') }) tg.for('test2', () => { $.sendMessage('test2') }) }) 

コントローラーでは、任意の関数、変数を記述することもできます。

範囲


各コントローラーは、特別な$- スコープ変数を受け入れます。
リクエストについて知る必要があるすべてを保存します:




たとえば、 scopeで sendMessage関数を呼び出したことがわかります 。 実際には、上記のフィールドに加えて、 スコープには、特定のチャットに対してすでに規定されているchatIdを持つすべてのライブラリ関数も含まれています。 同じsendMessage関数を直接呼び出すことができます。

 tg.controller('TestController', ($) => { tg.for('test', () => { tg.sendMessage($.chatId, 'test') }) tg.for('test2', () => { tg.sendMessage($.chatId, 'test2') }) }) 

同意します。メッセージが来た場所と同じチャットで書くので、チャットIDを書くことはあまり便利ではありません。

コールチェーン


時々、ユーザーに何かを尋ね、ユーザーからの情報を期待します。 これを実装する方法は? もちろん、ユーザーの状態を保存し、それに応じて「OtherController」で処理できますが、完全に美しいわけではなく、構造と読みやすさを損ないます。
そのような場合、 スコープにはwaitForRequest関数があります。
 tg.controller('TestController', ($) => { tg.for('/reg', ($) => { $.sendMessage('Send me your name!') $.waitForRequest(($) => { $.sendMessage('Hi ' + $.message.text + '!') }) }) }) 

waitForRequest関数は1つの引数を取ります。コールバックは、ユーザーが次のメッセージを送信するときに呼び出します。 新しいスコープがこのコールバックに渡されます 。 上記の例からわかるように、ユーザーに名前を入力して、次のメッセージを待って歓迎するようにお願いします。

ナビゲーション



ボットが認証を持っていると仮定すると、メインコントローラーでユーザーが認証されているかどうかを何らかの方法で確認し、ログインにリダイレクトする必要がありますが、どうすればよいでしょうか? これを行うために、コマンドを受け取り、ユーザーが送信したかのように実行するrouteTo関数があります。
 tg.controller('StartController', ($) => { tg.for('/profile', ($) => { if(!logined){ //     $.routeTo("/login") //   } }) }) 


フォーム


ユーザーからいくつかの情報を見つける必要があることがよくあります。これにはフォームジェネレータがあります。
 var form = { name: { q: 'Send me your name', error: 'sorry, wrong input', validator: (input, callback) => { if(input['text']) { callback(true) return } callback(false) } }, age: { q: 'Send me your age', error: 'sorry, wrong input', validator: (input, callback) => { if(input['text'] && IsNumeric(input['text'])) { callback(true) return } callback(false) } }, sex: { q: 'Select your sex', keyboard: [['male'],['famale'], ['UFO']], error: 'sorry, wrong input', validator: (input, callback) => { if(input['text'] && ['male', 'famale', 'UFO'].indexOf(input['text']) > -1) { callback(true) return } callback(false) } }, } $.runForm(form, (result) => { console.log(result) }) 

コードからわかるように、各フィールドにはユーザーに送信されるメッセージ、ユーザーからのメッセージを受け取るバリデーター、および入力データが正しくない場合のエラーメッセージがあります。 キーボードを送信することもできます。
runForm関数は、フォーム自体に記述したフィールドと同じフィールドを持つオブジェクトを返します。この場合、名前と年齢です。

メニュー



メニュー用の同様のツールがあります:
 $.runMenu({ message: 'Select:', 'Exit': { message: 'Do you realy want to exit?', 'yes': () => { }, 'no': () => { } } }) 

メニューは、フィールド名を持つキーボードを自動的に作成し、 メッセージフィールドで指定したメッセージと共に送信します。
メニュー項目は、オブジェクトまたは関数のいずれかです。 オブジェクトの場合、ユーザーはサブメニューを受け取り、機能の場合は呼び出され、ユーザーのリクエストを処理できるようにします。

また、メニューキーボードのボタンの位置を指定することもできます。 レイアウトフィールドがこれを担当します。まったく渡さない場合は、各行にボタンが1つあります。 1行あたりのボタンの最大数、または各行のボタン数の配列を渡すことができます。
 $.runMenu({ message: 'Select:', layout: 2, 'test1': () => {}, //    'test2': () => {}, //    'test3': () => {}, //    'test4': () => {}, //    'test5': () => {}, //    }) 


 $.runMenu({ message: 'Select:', layout: [1, 2, 1, 1], 'test1': () => {}, //    'test2': () => {}, //    'test3': () => {}, //    'test4': () => {}, //    'test5': () => {}, ///    }) 


API関数


APIを操作するためのすべての関数には、必須パラメーターとオプションパラメーターの両方があります。 たとえば、 sendMessage関数は必要なパラメーター(chatId、photo)のドキュメントに従っていますが、追加のパラメーターを渡すことができます。
 var options = { reply_markup: JSON.stringify({ one_time_keyboard: true, keyboard: [['test']] }) } $.sendMessage('test', options) 


この場合、最後のパラメーターは常にコールバックです。

以下に、現在サポートされているAPI関数と必須パラメーターのリストを示します( scopeから呼び出す場合、 chatIdパラメーター不要です)。



いくつかの関数を呼び出す例:
 var doc = { value: fs.createReadStream('file.png'), //stream filename: 'photo.png', contentType: 'image/png' } $.sendDocument(doc) $.sendPhoto(fs.createReadStream('photo.jpeg')) $.sendAudio(fs.createReadStream('audio.mp3')) $.sendVoice(fs.createReadStream('voice.ogg')) $.sendVideo(fs.createReadStream('video.mp4')) $.sendSticker(fs.createReadStream('sticker.webp')) 



記事をマスターしたすべての人に感謝します。GitHubへのリンク-github.com/Naltox/telegram-node-botおよびNPM: npmjs.com/package/telegram-node-bot

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


All Articles