📜 ⬆️ ⬇️

Telegram conference bot (Continued)

Good day, Habrahabr!


Vote


Today we will figure out how to expand the functionality of our bot. Let's go straight to the point ...


What will we teach the bot this time?



In the last part, we taught the bot:



The first part of the article is here!


Eating an elephant in parts


Let's add a mass mailing list with the ability to get feedback from the user. In this example, we will make the implementation of two buttons (Yes / No).


The task will consist of several parts:



Data model


We will need a new data model for voting results.


What are we going to store:



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


Now you need to save the results of the voting in the database and make sure that the user has already voted


 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); } }); } 

Saving the voting results will look like this:


 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); } }) } 

Event handlers


Use VoteService in the new Handler for voting buttons.
(For more details on how Handlers work, see the previous section)


Implement the getLastMessageText helper method in BotUtils.
In it, we get the text of the message to which the user responded.


 getLastMessageText: function (message) { return message.message.text; } 

Let us turn to 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); } }); }); } }); } }; 

Message and buttons


After we have described the registration of the results of the voting, we will send it out of the admin panel.


Let's start with the formation of MessageOptions, which will contain two buttons.
To do this, add the following method to BotUtils:
(In the last part you can find a short story about what MessageOptions and callback_data are)


 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'}] ] }) }; } 

New controller


Add a form to the admin page:


 <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> 

In this example, only one basic voting template is implemented. In the future, you can
make a special vote constructor in the admin panel, adding the ability to create other response options. We will implement this opportunity in the next part, while we restrict ourselves to simple yes and 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('/'); } 

Voting results


Let's output the voting results to the admin area. For the time being we will do this in the form of a list, then we will implement the vote counters, for greater clarity.


In HomeController we will get all the results from the database:


 VoteService.getAll(function (getVotesErr, votes) { if (getVotesErr) { Logger.notify('Some error!' + getVotesErr.message); } response.render('main', {users: users, votes: votes}); }); 

Add a list of results to the view:


 <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> 

More information about the user


To add to your newsletter treatment by name, you can expand the received information about the user. (The first time the user accessed the bot)


Add this method to BotUtils. Do not forget to add the new fields firstName and lastName to the UserModel data model.


 getClientInfo: function (message) { return { firstName: message.from.first_name, lastName: message.from.last_name, telegramId: message.hasOwnProperty('chat') ? message.chat.id : message.from.id }; } 

Sources


The complete code of the entire project is here!


Let me remind you that the telegram token and mongo connection string must be entered in the file /src/config.json


Continuation


If there are interesting offers, I will try to implement something new with our Telegram bot.
Thank you for your attention, habrovchane!


')

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


All Articles