こんにちは、ハブラハブル!
今日は、ボットの機能を拡張する方法を見つけます。 要点を理解しましょう...
今回はボットに何を教えますか?
最後の部分では、ボットを教えました。
- telegra.phリンクの形式でイベントスケジュールを送信します。
- Webサイトまたはチャットイベントへのリンクをシャッフルします。
- 管理パネルからユーザーに通知を送信します。
象を部分的に食べる
ユーザーからフィードバックを受け取る機能を備えたバルクメッセージングを追加しましょう。 この例では、2つのボタン(はい/いいえ)を実装します。
タスクはいくつかの部分で構成されます。
- データベースの結果データモデルを説明する
- それらを保存および受信するサービスを実装する
- 投票用の2つのボタンがあるメッセージを準備する
- ユーザーがボタンをクリックしてキャッチし、声をデータベースに保存する
- 管理パネルでアンケートを作成するフォームを追加します
- 管理パネルに投票結果を表示する
データモデル
投票結果に新しいデータモデルが必要になります
何を保存しますか:
- ユーザーID
- 質問自体のテキスト(質問のIDの保存を実装できます)
- 質問への回答(ボタンテキスト)
- 時間
var mongoose = require('mongoose'); var Schema = mongoose.Schema; var VoteSchema = new Schema({ telegramId: String, question: String, answer: String, time: String }); var Vote = mongoose.model('vote', VoteSchema);
VoteService
ここで、投票結果の保存をデータベースに実装し、ユーザーがすでに投票していることを確認する必要があります。
isNew: function (telegramId, question, callback) { // , // id VoteModel.findOne({telegramId: telegramId, question: question}, function (err, existingVote) { if (err) { callback(err, null); return; } if (existingVote) { callback(null, false); } else { callback(null, true); } }); }
投票結果を保存すると、次のようになります。
saveVote: function (voteInfo, callback) { this.isNew(voteInfo.telegramId, voteInfo.question, function (err, result) { if (err) { callback(err, null); return; } if (result) { var newVoteDto = new VoteModel({ telegramId: voteInfo.telegramId, question: voteInfo.question, answer: voteInfo.answer, time: voteInfo.time }); newVoteDto.save(function (err) { if (err) { callback(err, null); } else { callback(null, true); } }); }else{ callback(null, false); } }) }
イベントハンドラー
投票ボタンには、新しいハンドラーでVoteServiceを使用します。
(ハンドラーの配置方法の詳細については、前の部分を参照してください)
BotUtilsにヘルパーメソッドgetLastMessageTextを実装します。
その中で、ユーザーが返信したメッセージのテキストを取得します。
getLastMessageText: function (message) { return message.message.text; }
VoteHandlerに進みましょう。
var VoteHandler = { register: function (telegramBot, messageOptions) { telegramBot.on('callback_query', function (message) { // var clientInfo = BotUtils.getClientInfo(message); // var lastMessageText = BotUtils.getLastMessageText(message); // // , // " " if(message.data === 'yes' || message.data === 'no'){ // var voteInfo = { telegramId: clientInfo.telegramId, question: lastMessageText, answer: message.data, time: Date.now().toString() }; // . // , // ( ) VoteService.saveVote(voteInfo, function (saveErr, result) { if (saveErr) { telegramBot.sendMessage(clientInfo.telegramId, 'Some error! Sorry', messageOptions); return; } MessagesService.getByTitle('thanks', function (err, message) { if(err){ telegramBot.sendMessage(clientInfo.telegramId, 'Some error! Sorry', messageOptions); }else{ telegramBot.sendMessage(clientInfo.telegramId, message.text, messageOptions); } }); }); } }); } };
メッセージとボタン
投票結果の登録について説明した後、管理パネルから送信します。
2つのボタンを含むMessageOptionsの形成から始めましょう。
これを行うには、このメソッドをBotUtilsに追加します。
(最後の部分では、MessageOptionsとcallback_dataが何であるかについての短い話を見つけることができます)
buildMessageOptionsForVoting: function () { return { parse_mode: "HTML", disable_web_page_preview: false, reply_markup : JSON.stringify({ inline_keyboard: [ [{ text: '', callback_data: 'yes' }, { text: '', callback_data: 'no'}] ] }) }; }
新しいコントローラー
フォームを管理ページに追加します。
<h2> </h2> <form method="POST" action="/voting"> <h3>:</h3> <textarea class="form-control" rows="3" type="text" name="message">" -..."</textarea> <input align="right" class="btn btn-success" type="submit" value=""> </form>
この例では、1つの基本的な投票テンプレートのみが実装されています。 将来的には、できます
管理パネルで投票の特別なコンストラクタを作成し、他の回答オプションを作成する機能を追加します。 この機会を次のパートで実装しますが、単純なyesとnoに制限します。
votingController: function (request, response) { // var message = request.body.message; var telegramBot = this.telegramBot; // UserService.getAll(function (err, users) { if (err) { Logger.notify('Some error!' + err.message); return; } // , . var messageOptionsForOptions = BotUtils.buildMessageOptionsForVoting(); users.forEach(function (user) { telegramBot.sendMessage(user.telegramId, message, messageOptionsForOptions); }); }); response.redirect('/'); }
投票結果
管理パネルに投票結果を表示します。 これをリストの形式で行いますが、より明確にするために、投票カウンターをさらに実装します。
HomeControllerで、データベースからすべての結果を取得します。
VoteService.getAll(function (getVotesErr, votes) { if (getVotesErr) { Logger.notify('Some error!' + getVotesErr.message); } response.render('main', {users: users, votes: votes}); });
結果のリストをビューに追加します。
<h2> :</h2> <ul> <% for(var i=0; i<votes.length; i++) {%> <li class="list-group-item list-group-item-info"> <%= votes[i].telegramId %> <%= votes[i].question %> <%= votes[i].answer %> </li> <% } %> </ul>
より多くのユーザーデータ
ニュースレターに名前でアピールを追加するには、ユーザーについて受け取った情報を展開できます。 (ユーザーが最初にボットに連絡したとき)
そのようなメソッドをBotUtilsに追加します。 新しいfirstNameフィールドとlastNameフィールドをUserModelデータモデルに追加することを忘れないでください。
getClientInfo: function (message) { return { firstName: message.from.first_name, lastName: message.from.last_name, telegramId: message.hasOwnProperty('chat') ? message.chat.id : message.from.id }; }
ソースコード
テレグラムトークンとmongo接続文字列を/src/config.jsonファイルに書き込む必要があることを思い出させてください
継続
興味深い提案が表示された場合は、Telegramボットに新しいものを実装してみます。
カブロビテス、ご清聴ありがとうございました!