├── .gitignore ├── Answers.pdf ├── Questions.pdf ├── mydb.sqlite3 ├── README.md ├── package.json ├── mailFile.js ├── createDoc.js ├── privacy_policy.md └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | #Project specific file 2 | .env 3 | node_modules/ 4 | -------------------------------------------------------------------------------- /Answers.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apoorva-mk/ReWise-Messenger-Bot/HEAD/Answers.pdf -------------------------------------------------------------------------------- /Questions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apoorva-mk/ReWise-Messenger-Bot/HEAD/Questions.pdf -------------------------------------------------------------------------------- /mydb.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apoorva-mk/ReWise-Messenger-Bot/HEAD/mydb.sqlite3 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # reWise-Messenger-Bot 2 | 3 | A facebook messenger bot that leverages AI in question generation and quizzing. 4 | --- 5 | 6 | Features: 7 | - Click pictures of notes/ text material and find a list of questions generated which can be of various formats. 8 | - Also, you can get a copy of the questions and answers in a easy to distribute format if you'd like to take a quiz. 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "messenger-webhook", 3 | "version": "1.0.0", 4 | "description": "Webhook to setup messenger bot", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node index.js" 9 | }, 10 | "author": "Apoorva", 11 | "license": "ISC", 12 | "dependencies": { 13 | "axios": "^0.19.2", 14 | "body-parser": "^1.19.0", 15 | "docx": "^5.0.2", 16 | "dotenv": "^8.2.0", 17 | "express": "^4.17.1", 18 | "googleapis": "^39.2.0", 19 | "image-to-base64": "^2.0.1", 20 | "jspdf": "^1.5.3", 21 | "nodemailer": "^6.4.5", 22 | "pdfkit": "^0.11.0", 23 | "request": "^2.88.2", 24 | "sqlite3": "^4.1.1" 25 | }, 26 | "engines": { 27 | "node": "11.x" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /mailFile.js: -------------------------------------------------------------------------------- 1 | nodemailer = require('nodemailer'); 2 | require('dotenv').config(); 3 | 4 | function sendAttachments(recipient_email) { 5 | myEmail = "rewise_bot.com"; 6 | let transport = nodemailer.createTransport({ 7 | host: 'smtp.mail.yahoo.com', 8 | port: 465, 9 | secure: false, 10 | service: 'yahoo', 11 | auth: { 12 | user: myEmail, 13 | pass: process.env.PASS 14 | }, 15 | debug: false, 16 | logger: true 17 | }); 18 | 19 | let message= { 20 | from: myEmail, 21 | to: recipient_email, 22 | subject: "Mail from ReWise", 23 | text: "Hey, please find attached your quiz generated with answer keys", 24 | attachements: [ 25 | { 26 | path: "./Questions.pdf" 27 | }, 28 | { 29 | path: "./Answers.pdf" 30 | } 31 | ] 32 | } 33 | 34 | transport.sendMail(message, function(err){ 35 | if(err){ 36 | console.log(err); 37 | console.log("Failed to send email.\n"); 38 | return; 39 | } 40 | else{ 41 | console.log("Attachments successfully sent!"); 42 | } 43 | }); 44 | } 45 | 46 | 47 | module.exports.sendAttachments = sendAttachments; 48 | -------------------------------------------------------------------------------- /createDoc.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | const PDFDocument=require('pdfkit'); 3 | const doc = new PDFDocument; 4 | module.exports.createDoc = createDoc; 5 | 6 | function createDoc(questions, answers){ 7 | console.log(questions, answers); 8 | var d = new Date(); 9 | console.log(d); 10 | //creating questions document 11 | var doc = new PDFDocument(); 12 | doc.pipe(fs.createWriteStream('Questions.pdf')); 13 | 14 | // draw some text 15 | doc.fontSize(25).text('Rewise Quiz - Questions', 100, 80); 16 | doc.moveDown(); 17 | doc 18 | .font("Times-Roman", 15) 19 | .text('Name: ') 20 | .moveDown(); 21 | 22 | doc 23 | .font("Times-Roman", 15) 24 | .text('Roll No: ') 25 | .moveDown(); 26 | 27 | date = d.getDate()+"/"+(d.getMonth()+1)+"/"+d.getFullYear(); 28 | console.log(date, typeof(date)); 29 | doc 30 | .font("Times-Roman", 15) 31 | .text('Date: '+d.getDate()+"/"+(d.getMonth()+1)+"/"+d.getFullYear()) 32 | .moveDown(); 33 | 34 | doc 35 | .font("Times-Roman",17) 36 | .text('Answer the following questions in the space given below') 37 | .moveDown() 38 | 39 | var i; 40 | for (i = 0; i < questions.length; i++) { 41 | doc 42 | .font('Times-Roman', 13) 43 | .text("Question "+(i+1)+": "+questions[i]) 44 | .moveDown() 45 | .moveDown() 46 | 47 | doc.lineWidth(1); 48 | doc.lineJoin('round') 49 | .rect(100, 330+i*74, 400, 1) 50 | .stroke(); 51 | doc.moveDown(); 52 | doc.moveDown(); 53 | } 54 | doc.lineWidth(0.5); 55 | doc.end(); 56 | 57 | //creating answer key document 58 | var doc = new PDFDocument(); 59 | doc.pipe(fs.createWriteStream('Answers.pdf')); 60 | 61 | // draw some text 62 | doc.fontSize(25).text('Rewise Quiz - Answer Key', 100, 80); 63 | doc.moveDown(); 64 | for (i = 0; i < answers.length; i++) { 65 | doc 66 | .font('Times-Roman', 13) 67 | .text("Answer "+(i+1)+": "+answers[i]) 68 | .moveDown() 69 | .moveDown() 70 | } 71 | doc.end(); 72 | } 73 | 74 | 75 | module.exports.createDoc = createDoc; -------------------------------------------------------------------------------- /privacy_policy.md: -------------------------------------------------------------------------------- 1 | ## Privacy Policy 2 | 3 | built the MessengerBot app as an Open Source app. This SERVICE is provided by at no cost and is intended for use as is. 4 | 5 | This page is used to inform visitors regarding my policies with the collection, use, and disclosure of Personal Information if anyone decided to use my Service. 6 | 7 | If you choose to use my Service, then you agree to the collection and use of information in relation to this policy. The Personal Information that I collect is used for providing and improving the Service. I will not use or share your information with anyone except as described in this Privacy Policy. 8 | 9 | The terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which is accessible at MessengerBot unless otherwise defined in this Privacy Policy. 10 | 11 | **Information Collection and Use** 12 | 13 | For a better experience, while using our Service, I may require you to provide us with certain personally identifiable information, including but not limited to Name, Gender, Location. The information that I request will be retained on your device and is not collected by me in any way. 14 | 15 | The app does use third party services that may collect information used to identify you. 16 | 17 | Link to privacy policy of third party service providers used by the app 18 | 19 | * [Google Play Services](https://www.google.com/policies/privacy/) 20 | 21 | **Log Data** 22 | 23 | I want to inform you that whenever you use my Service, in a case of an error in the app I collect data and information (through third party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address, device name, operating system version, the configuration of the app when utilizing my Service, the time and date of your use of the Service, and other statistics. 24 | 25 | **Cookies** 26 | 27 | Cookies are files with a small amount of data that are commonly used as anonymous unique identifiers. These are sent to your browser from the websites that you visit and are stored on your device's internal memory. 28 | 29 | This Service does not use these “cookies” explicitly. However, the app may use third party code and libraries that use “cookies” to collect information and improve their services. You have the option to either accept or refuse these cookies and know when a cookie is being sent to your device. If you choose to refuse our cookies, you may not be able to use some portions of this Service. 30 | 31 | **Service Providers** 32 | 33 | I may employ third-party companies and individuals due to the following reasons: 34 | 35 | * To facilitate our Service; 36 | * To provide the Service on our behalf; 37 | * To perform Service-related services; or 38 | * To assist us in analyzing how our Service is used. 39 | 40 | I want to inform users of this Service that these third parties have access to your Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose. 41 | 42 | **Security** 43 | 44 | I value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and I cannot guarantee its absolute security. 45 | 46 | **Links to Other Sites** 47 | 48 | This Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by me. Therefore, I strongly advise you to review the Privacy Policy of these websites. I have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services. 49 | 50 | **Children’s Privacy** 51 | 52 | These Services do not address anyone under the age of 13. I do not knowingly collect personally identifiable information from children under 13\. In the case I discover that a child under 13 has provided me with personal information, I immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact me so that I will be able to do necessary actions. 53 | 54 | **Changes to This Privacy Policy** 55 | 56 | I may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. I will notify you of any changes by posting the new Privacy Policy on this page. These changes are effective immediately after they are posted on this page. 57 | 58 | **Contact Us** 59 | 60 | If you have any questions or suggestions about my Privacy Policy, do not hesitate to contact me at apoorva.mk99@gmail.com. 61 | 62 | This privacy policy page was created at [privacypolicytemplate.net](https://privacypolicytemplate.net) and modified/generated by [App Privacy Policy Generator](https://app-privacy-policy-generator.firebaseapp.com/) -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | express = require('express'), 2 | bodyParser = require('body-parser'), 3 | app = express().use(bodyParser.json()); 4 | require('dotenv').config() 5 | const PAGE_ACCESS_TOKEN = process.env.PAGE_ACCESS_TOKEN; 6 | const request = require('request'); 7 | const sqlite3 = require('sqlite3').verbose(); 8 | const image2base64 = require('image-to-base64'); 9 | const axios = require('axios'); 10 | var createDoc = require("./createDoc"); 11 | var sendAttachments = require("./mailFile"); 12 | 13 | 14 | //Start process 15 | app.listen(process.env.PORT || 1337, () => console.log('webhook is listening')); 16 | file_path = process.env.DB_FILE_NAME 17 | 18 | //Creating a database and table 19 | let db = new sqlite3.Database(file_path, (err) => { 20 | if (err) { 21 | console.log('Error when creating the database', err) 22 | } else { 23 | console.log('Database created!, path: "./mydb.sqlite3"') 24 | createTable() 25 | } 26 | }); 27 | 28 | sendAttachments.sendAttachments("apoorva.mk99@gmail.com"); 29 | 30 | //creating a table to hold state 31 | const createTable = () => { 32 | console.log("Create table 'users' and 'content' in database"); 33 | db.run("CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY AUTOINCREMENT, psid TEXT, state TEXT, quiz_state TEXT)"); 34 | db.run("CREATE TABLE IF NOT EXISTS contents(id INTEGER PRIMARY KEY AUTOINCREMENT, psid TEXT, content TEXT)"); 35 | db.run("CREATE TABLE IF NOT EXISTS questions(id INTEGER PRIMARY KEY AUTOINCREMENT, psid TEXT, curr_question INTEGER, questions TEXT, correct_answers TEXT, user_answers TEXT, total_questions INTEGER, score INTEGER)") 36 | } 37 | 38 | app.post('/webhook', (req, res) => { 39 | 40 | let body = req.body; 41 | 42 | // Checks this is an event from a page subscription 43 | if (body.object === 'page') { 44 | 45 | // Iterates over each entry - there may be multiple if batched 46 | body.entry.forEach(function(entry) { 47 | 48 | // Gets the body of the webhook event 49 | let webhook_event = entry.messaging[0]; 50 | console.log(webhook_event); 51 | 52 | // Get the sender PSID 53 | let sender_psid = webhook_event.sender.id; 54 | console.log('Sender PSID: ' + sender_psid); 55 | 56 | // Check if the event is a message or postback and 57 | // pass the event to the appropriate handler function 58 | if (webhook_event.message) { 59 | if(webhook_event.message.text){ 60 | if(webhook_event.message.text=="QUIT"){ 61 | resp = createResponse(process.env.THANK_YOU) 62 | callSendAPI(sender_psid, resp); 63 | reset(sender_psid); 64 | } 65 | else{ 66 | getUserState(sender_psid, webhook_event.message); 67 | } 68 | } 69 | 70 | if(webhook_event.message.attachments){ 71 | console.log(webhook_event.message.attachments); 72 | console.log(webhook_event.message.attachments[0].payload.sticker_id); 73 | if(webhook_event.message.attachments[0].payload.sticker_id == 369239263222822){ 74 | console.log("Recieved thumbs up sticker") 75 | continue1(sender_psid, webhook_event.message); 76 | } 77 | else{ 78 | handleAttachments(sender_psid, webhook_event.message.attachments); 79 | } 80 | } 81 | 82 | //handleMessage(sender_psid, webhook_event.message); 83 | } else if (webhook_event.postback) { 84 | handlePostback(sender_psid, webhook_event.postback); 85 | } 86 | }); 87 | // Returns a '200 OK' response to all requests 88 | res.status(200).send('EVENT_RECEIVED'); 89 | } else { 90 | // Returns a '404 Not Found' if event is not from a page subscription 91 | res.sendStatus(404); 92 | } 93 | 94 | }); 95 | 96 | // Adds support for GET requests to our webhook 97 | app.get('/webhook', (req, res) => { 98 | 99 | // Your verify token. Should be a random string. 100 | let VERIFY_TOKEN = "HfdjiJkoInkj24ji903UHI89909inoj909" 101 | 102 | // Parse the query params 103 | let mode = req.query['hub.mode']; 104 | let token = req.query['hub.verify_token']; 105 | let challenge = req.query['hub.challenge']; 106 | 107 | // Checks if a token and mode is in the query string of the request 108 | if (mode && token) { 109 | 110 | // Checks the mode and token sent is correct 111 | if (mode === 'subscribe' && token === VERIFY_TOKEN) { 112 | 113 | // Responds with the challenge token from the request 114 | console.log('WEBHOOK_VERIFIED'); 115 | res.status(200).send(challenge); 116 | 117 | } else { 118 | // Responds with '403 Forbidden' if verify tokens do not match 119 | res.sendStatus(403); 120 | } 121 | } 122 | }); 123 | 124 | // Handles messages events 125 | function handleMessage(sender_psid, received_message) { 126 | let response; 127 | 128 | // Check if the message contains text 129 | if (received_message.text) { 130 | 131 | // Create the payload for a basic text message 132 | response = { 133 | "text": `You sent the message: "${received_message.text}". Now send me an image!` 134 | } 135 | } 136 | 137 | // Sends the response message 138 | callSendAPI(sender_psid, response); 139 | 140 | } 141 | 142 | // Handles messaging_postbacks events 143 | function handlePostback(sender_psid, received_postback) { 144 | if(received_postback.payload=="3"){ 145 | console.log("Moving to state 3, quiz starting"); 146 | updateState(sender_psid, "3"); 147 | resp = createResponse("Take a deep breath, the quiz is about to start.") 148 | callSendAPI(sender_psid, resp, 3); 149 | //displayQuestion(sender_psid); 150 | } 151 | else{ 152 | console.log("Moving to state 4"); 153 | updateState(sender_psid, "4"); 154 | generateQuizSheet(sender_psid); 155 | } 156 | } 157 | 158 | // Sends response messages via the Send API 159 | function callSendAPI(sender_psid, response, follow_up=0) { 160 | // Construct the message body 161 | let request_body = { 162 | "recipient": { 163 | "id": sender_psid 164 | }, 165 | "message": response 166 | } 167 | 168 | // Send the HTTP request to the Messenger Platform 169 | request({ 170 | "uri": "https://graph.facebook.com/v2.6/me/messages", 171 | "qs": { "access_token": process.env.PAGE_ACCESS_TOKEN }, 172 | "method": "POST", 173 | "json": request_body 174 | }, (err, res, body) => { 175 | if (!err) { 176 | console.log('message sent!') 177 | if(follow_up == 1){ 178 | continueInteraction0(sender_psid, "0"); 179 | } 180 | else if (follow_up ==2){ 181 | sendButtonMenu(sender_psid); 182 | } 183 | else if (follow_up == 3){ 184 | displayQuestion(sender_psid); 185 | } 186 | else if(follow_up == 4){ 187 | res = createResponse(process.env.THANK_YOU); 188 | callSendAPI(sender_psid, res); 189 | reset(sender_psid); 190 | } 191 | } else { 192 | console.error("Unable to send message:" + err); 193 | } 194 | }); 195 | 196 | } 197 | 198 | 199 | function getUserState(sender_psid, message){ 200 | db.all("SELECT * from users where psid='"+sender_psid+"'",function(err,rows){ 201 | console.log(rows); 202 | if(rows.length == 0){ 203 | console.log("User not saved, saving new user"); 204 | db.run("INSERT into users (psid,state,quiz_state) VALUES ('"+sender_psid+"','0','0')"); 205 | db.run("INSERT into contents (psid, content) VALUES ('"+sender_psid+"','')"); 206 | db.run("INSERT into questions (psid, curr_question, questions, correct_answers, user_answers, total_questions, score) VALUES ('"+sender_psid+"',0,'','','',0,0)"); 207 | console.log("Saved all the initial details of user"); 208 | greetUser(sender_psid); 209 | } 210 | else { 211 | console.log("Old user"); 212 | console.log(rows[0].psid+" "+rows[0].state+" "+rows[0].quiz_state); 213 | 214 | if(rows[0].state=="0") 215 | continueInteraction0(sender_psid, rows[0].state, 1); 216 | 217 | else if(rows[0].state=="1"){ 218 | continue1(sender_psid, message); 219 | } 220 | 221 | else if(rows[0].state=="3"){ 222 | console.log("Checking the answer sent"); 223 | checkAnswer(sender_psid, message.text); 224 | } 225 | 226 | else if(rows[0].state=="5"){ 227 | console.log("Sending email"); 228 | sendEmail(sender_psid, message.text); 229 | } 230 | } 231 | }); 232 | } 233 | 234 | //Create a response with a given text 235 | function createResponse(content){ 236 | let response; 237 | // Create the payload for a basic text message 238 | response = { 239 | "text": content 240 | } 241 | 242 | return response; 243 | } 244 | 245 | 246 | //Greeting new users 247 | function greetUser(sender_psid){ 248 | console.log("Greeting user"); 249 | response = createResponse(process.env.INTRO_TEXT); 250 | callSendAPI(sender_psid, response, 1); 251 | } 252 | 253 | //Continuing interaction with old users 254 | function continueInteraction0(sender_psid, state, welcome_flag=0){ 255 | if(state=='0'){ 256 | console.log("State 0"); 257 | welcome = ""; 258 | if (welcome_flag == 1){ 259 | welcome="Hey there, welcome back to Rewise! " 260 | } 261 | response = createResponse(welcome+process.env.WELCOME_BACK); 262 | callSendAPI(sender_psid, response); 263 | updateState(sender_psid, "1"); 264 | } 265 | 266 | } 267 | 268 | //update the users state 269 | function updateState(sender_psid, new_state){ 270 | db.run("UPDATE users SET state="+new_state+" where psid='"+sender_psid+"'"); 271 | } 272 | 273 | 274 | function reset(sender_psid){ 275 | //TO DO 276 | console.log("Reset the user state to 0"); 277 | updateState(sender_psid, "0"); 278 | 279 | } 280 | 281 | 282 | function handleAttachments(sender_psid, attachments){ 283 | db.all("SELECT * from users where psid='"+sender_psid+"'",function(err,rows){ 284 | console.log(rows); 285 | if (err){ 286 | console.log(err); 287 | } 288 | else{ 289 | if(rows.length == 0){ 290 | resp= createResponse(process.env.ERR_MSG); 291 | callSendAPI(sender_psid, resp); 292 | } 293 | else if (rows[0].state!='1'){ 294 | resp= createResponse(process.env.ERR_MSG); 295 | callSendAPI(sender_psid, resp); 296 | } 297 | else{ 298 | console.log(attachments); 299 | var attachment 300 | for (attachment of attachments){ 301 | convertImage(attachment.payload.url, sender_psid); 302 | } 303 | } 304 | } 305 | }); 306 | } 307 | 308 | function convertImage(path, sender_psid){ 309 | image2base64(path) 310 | .then( 311 | (response) => { 312 | //console.log(response); 313 | saveText(response, sender_psid); 314 | } 315 | ) 316 | .catch( 317 | (error) => { 318 | console.log(error); 319 | } 320 | ) 321 | } 322 | 323 | function saveText(base64encoding, sender_psid){ 324 | axios.post('https://apoorvamk.pythonanywhere.com/', { 325 | base64encodedimage: base64encoding 326 | }) 327 | .then((response) => { 328 | console.log(response.data); 329 | db.all("SELECT * from contents where psid='"+sender_psid+"'",function(err,rows){ 330 | console.log(rows); 331 | if(rows.length==0){ 332 | console.log("Some error occurred"); 333 | } 334 | else{ 335 | console.log("Appending more content"); 336 | new_content=rows[0].content+" "+response.data; 337 | new_content = new_content.replace(/['"]+/g, ''); 338 | console.log(new_content); 339 | db.run("UPDATE contents SET content='"+new_content+"' where psid='"+sender_psid+"'"); 340 | } 341 | }); 342 | 343 | }, (error) => { 344 | console.log(error); 345 | }); 346 | } 347 | 348 | function continue1(sender_psid, message){ 349 | 350 | //console.log("Moving to state 2"); 351 | db.all("SELECT * from contents where psid='"+sender_psid+"'",function(err,rows){ 352 | console.log(rows); 353 | if(rows.length==0){ 354 | console.log("Some error occurred while trying to fetch stored content"); 355 | } 356 | else{ 357 | new_content=rows[0].content; 358 | words = wordCount(new_content); 359 | if(words<300){ 360 | resp = createResponse(process.env.NOT_ENOUGH); 361 | callSendAPI(sender_psid, resp); 362 | } 363 | else{ 364 | console.log("Creating quiz"); 365 | updateState(sender_psid, "2"); 366 | //res = createResponse(process.env.WAIT); 367 | getQuestions(rows[0].content, sender_psid, 2, callSendAPI); 368 | //sendButtonMenu(sender_psid); 369 | } 370 | } 371 | }); 372 | 373 | } 374 | 375 | function wordCount(content){ 376 | str = content; 377 | str = str.replace(/(^\s*)|(\s*$)/gi,""); 378 | str = str.replace(/[ ]{2,}/gi," "); 379 | str = str.replace(/\n /,"\n"); 380 | return str.split(' ').length; 381 | } 382 | 383 | function sendButtonMenu(sender_psid){ 384 | response = { 385 | "recipient":{ 386 | "id":sender_psid 387 | }, 388 | "message":{ 389 | "attachment":{ 390 | "type":"template", 391 | "payload":{ 392 | "template_type":"button", 393 | "text":"What do you want to do next?", 394 | "buttons":[ 395 | { 396 | "type":"postback", 397 | "title":"Take quiz now.", 398 | "payload":"3" 399 | }, 400 | { 401 | "type":"postback", 402 | "title":"Send generated quiz.", 403 | "payload":"4" 404 | } 405 | ] 406 | } 407 | } 408 | } 409 | } 410 | 411 | request({ 412 | "uri": "https://graph.facebook.com/v2.6/me/messages", 413 | "qs": { "access_token": process.env.PAGE_ACCESS_TOKEN }, 414 | "method": "POST", 415 | "json": response 416 | }, (err, res, body) => { 417 | if (!err) { 418 | console.log('Buttons sent!') 419 | } else { 420 | console.error("Unable to send message:" + err); 421 | } 422 | }); 423 | } 424 | 425 | function getQuestions(content, sender_psid, follow_up, callback){ 426 | console.log("Generating questions"); 427 | const headers= { 428 | 'Content-Type': 'text/plain', 429 | 'Authorization': `Bearer ${process.env.AUTH_TOKEN}` 430 | } 431 | axios.post(process.env.QUIZ_URL, content, { 432 | headers: headers 433 | }) 434 | .then(function(response) { 435 | console.log("....................................................."); 436 | console.log(response.data.Data); 437 | console.log(".....................................................") 438 | var ques = []; 439 | var corr_ans = []; 440 | var user_ans = []; 441 | var obj; 442 | for ( obj of response.data.Data.recall){ 443 | ques.push(obj.Question); 444 | corr_ans.push(obj.Answer); 445 | 446 | if(ques.length==5){ 447 | break; 448 | } 449 | } 450 | console.log(JSON.stringify(ques)); 451 | db.run("UPDATE questions SET questions='"+JSON.stringify(ques)+"',correct_answers='"+JSON.stringify(corr_ans)+"',user_answers='"+JSON.stringify(user_ans)+"',total_questions="+ques.length+" where psid='"+sender_psid+"'"); 452 | res = createResponse(process.env.WAIT); 453 | callback(sender_psid, res, follow_up); 454 | 455 | }) 456 | .catch(function(error) { 457 | res = createResponse(process.env.ERR_Q); 458 | callback(sender_psid, res); 459 | console.log(error); 460 | }); 461 | } 462 | 463 | function displayQuestion(sender_psid){ 464 | console.log("In display question"); 465 | 466 | db.all("SELECT * from questions where psid='"+sender_psid+"'",function(err,rows){ 467 | console.log(rows); 468 | if(rows.length==0){ 469 | console.log("Some error occurred while fetching question number"); 470 | } 471 | else{ 472 | console.log("Ready to display question ", rows[0].curr_question); 473 | questions = JSON.parse(rows[0].questions); 474 | resp=createResponse("Question "+(rows[0].curr_question+1)+":\n"+questions[rows[0].curr_question]); 475 | callSendAPI(sender_psid, resp); 476 | db.run("UPDATE questions SET curr_question="+(rows[0].curr_question+1)+" where psid='"+sender_psid+"'"); 477 | } 478 | }); 479 | } 480 | 481 | function checkAnswer(sender_psid, answer){ 482 | console.log(answer); 483 | db.all("SELECT * from questions where psid='"+sender_psid+"'",function(err,rows){ 484 | console.log(rows); 485 | if(rows.length==0){ 486 | console.log("Some error occurred while fetching question number to check answer"); 487 | } 488 | else{ 489 | console.log("Inside checking answers"); 490 | console.log(rows[0]); 491 | answers = JSON.parse(rows[0].correct_answers); 492 | user_answers = JSON.parse(rows[0].user_answers); 493 | corr_answer = answers[rows[0].curr_question-1]; 494 | score = rows[0].score; 495 | console.log("Going to check answer"); 496 | if(corr_answer.toUpperCase() === answer.toUpperCase()){ 497 | user_answers.push("Correct"); 498 | score = score+1; 499 | console.log("Correct answer"); 500 | } 501 | else{ 502 | user_answers.push("Incorrect --> "+corr_answer); 503 | console.log("Incorrect answer"); 504 | } 505 | db.run("UPDATE questions SET score="+score+", user_answers='"+JSON.stringify(user_answers)+"' where psid='"+sender_psid+"'"); 506 | if(rows[0].curr_question==rows[0].total_questions){ 507 | displayReport(sender_psid, score, user_answers); 508 | } 509 | else{ 510 | displayQuestion(sender_psid); 511 | } 512 | 513 | } 514 | }); 515 | } 516 | 517 | function displayReport(sender_psid, score, user_answers){ 518 | console.log("Display the user quiz report"); 519 | var report = "Let's see how you did\n\n---QUIZ REPORT---\n"; 520 | var i; 521 | for (i = 0; i < user_answers.length; i++) { 522 | report+= "Q"+(i+1)+". "+user_answers[i] + "\n"; 523 | } 524 | 525 | report+="Overall Score: "+score+"/"+user_answers.length; 526 | 527 | res = createResponse(report); 528 | callSendAPI(sender_psid, res, 4); 529 | } 530 | 531 | function generateQuizSheet(sender_psid){ 532 | console.log("Generating quiz sheet"); 533 | db.all("SELECT * from questions where psid='"+sender_psid+"'",function(err,rows){ 534 | console.log(rows); 535 | if(rows.length ==0){ 536 | console.log("Some error in fetching questions and answers"); 537 | } 538 | else{ 539 | questions = JSON.parse(rows[0].questions); 540 | answers = JSON.parse(rows[0].correct_answers); 541 | createDoc.createDoc(questions, answers); 542 | getEmail(sender_psid); 543 | updateState(sender_psid, "5"); 544 | } 545 | }); 546 | } 547 | 548 | function getEmail(sender_psid){ 549 | resp=createResponse("Please provide your email address"); 550 | callSendAPI(resp); 551 | } 552 | 553 | function sendEmail(sender_id, email){ 554 | console.log("Sending files to email address"); 555 | sendAttachments.sendAttachments(email); 556 | resp=createResponse("The files have been sent to your email address"); 557 | callSendAPI(sender_id, resp, 4); 558 | } --------------------------------------------------------------------------------