kykint

Save/load user lang preference from DB

...@@ -91,4 +91,8 @@ typings/ ...@@ -91,4 +91,8 @@ typings/
91 # Config file 91 # Config file
92 config.js 92 config.js
93 93
94 +# Database
95 +db/**
96 +!db/.placeholder
97 +
94 # End of https://www.gitignore.io/api/node 98 # End of https://www.gitignore.io/api/node
......
...@@ -13,6 +13,10 @@ const translate_api_url = 'https://openapi.naver.com/v1/papago/n2mt'; ...@@ -13,6 +13,10 @@ const translate_api_url = 'https://openapi.naver.com/v1/papago/n2mt';
13 // Language detection api url 13 // Language detection api url
14 const languagedetect_api_url = 'https://openapi.naver.com/v1/papago/detectLangs' 14 const languagedetect_api_url = 'https://openapi.naver.com/v1/papago/detectLangs'
15 15
16 +// Initialize database
17 +const db = require('./db');
18 +db.init();
19 +
16 // /echo [whatever] 20 // /echo [whatever]
17 bot.onText(/\/echo (.+)/, (msg, match) => { 21 bot.onText(/\/echo (.+)/, (msg, match) => {
18 // 'msg' is the received Message from Telegram 22 // 'msg' is the received Message from Telegram
...@@ -29,10 +33,11 @@ bot.onText(/\/echo (.+)/, (msg, match) => { ...@@ -29,10 +33,11 @@ bot.onText(/\/echo (.+)/, (msg, match) => {
29 /** 33 /**
30 * Translate given message and send it to the specified chatroom. 34 * Translate given message and send it to the specified chatroom.
31 * 35 *
36 + * @param {*} userId Id of the user that wants to translate
32 * @param {*} message Message to translate 37 * @param {*} message Message to translate
33 * @param {*} chatId Id of the chatroom to send translated message to 38 * @param {*} chatId Id of the chatroom to send translated message to
34 */ 39 */
35 -function translate(message, chatId) { 40 +function translate(userId, message, chatId) {
36 // Language detection options 41 // Language detection options
37 var lang_detect_options = { 42 var lang_detect_options = {
38 url: languagedetect_api_url, 43 url: languagedetect_api_url,
...@@ -56,37 +61,51 @@ function translate(message, chatId) { ...@@ -56,37 +61,51 @@ function translate(message, chatId) {
56 console.log('Language detected: ' + detect_body.langCode); 61 console.log('Language detected: ' + detect_body.langCode);
57 62
58 // Translate using papago 63 // Translate using papago
59 - // Target defaults to English for Korean source, or Korean for all other langs 64 + // Try to grab source lang and target lang from user's preference first.
65 + // If preference is not found, source default to detected language, and
66 + // target defaults to English for Korean source, or Korean for all other langs.
60 if (detect_body.langCode != 'unk') { 67 if (detect_body.langCode != 'unk') {
61 - source = detect_body.langCode; 68 + db.findPref(userId, "pref", (dbResult) => {
62 - target = source == 'ko' ? 'en' : 'ko'; 69 + // Choosing source language not implemented as of now
63 - 70 + if (dbResult != undefined) {
64 - // Papago translation options 71 + source = dbResult.source != undefined ? dbResult.source : detect_body.langCode;
65 - var translate_options = { 72 + target = dbResult.target != undefined ? dbResult.target : (source == 'ko' ? 'en' : 'ko');
66 - url: translate_api_url, 73 + } else {
67 - form: { 74 + source = detect_body.langCode;
68 - 'source': source, // Before translation 75 + target = source == 'ko' ? 'en' : 'ko';
69 - 'target': target, // After translation
70 - 'text': message // Message to translate
71 - },
72 - headers: {
73 - 'X-Naver-Client-Id': config.papago.client_id,
74 - 'X-Naver-Client-Secret': config.papago.client_secret
75 } 76 }
76 - }; 77 + console.log(source + ' => ' + target);
77 - 78 +
78 - // Send translatation request 79 + // Papago translation options
79 - request.post(translate_options, function (error, response, body) { 80 + var translate_options = {
80 - // On success 81 + url: translate_api_url,
81 - if (!error && response.statusCode == 200) { 82 + form: {
83 + 'source': source, // Before translation
84 + 'target': target, // After translation
85 + 'text': message // Message to translate
86 + },
87 + headers: {
88 + 'X-Naver-Client-Id': config.papago.client_id,
89 + 'X-Naver-Client-Secret': config.papago.client_secret
90 + }
91 + };
92 +
93 + // Send translatation request
94 + request.post(translate_options, function (error, response, body) {
82 var objBody = JSON.parse(response.body); 95 var objBody = JSON.parse(response.body);
83 - result.text = objBody.message.result.translatedText; 96 + if (!error && response.statusCode == 200) {
84 - 97 + // On success
98 + result.text = objBody.message.result.translatedText;
99 +
100 + console.log('Before: ' + message);
101 + console.log('After: ' + result.text);
102 + } else {
103 + // On failure
104 + result.text = '[' + objBody.errorCode + '] ' + objBody.errorMessage;
105 + }
85 // Send translated message 106 // Send translated message
86 - console.log('Before: ' + message);
87 - console.log('After: ' + result.text);
88 bot.sendMessage(chatId, result.text); 107 bot.sendMessage(chatId, result.text);
89 - } 108 + });
90 }); 109 });
91 } 110 }
92 // Language not detected 111 // Language not detected
...@@ -100,6 +119,7 @@ function translate(message, chatId) { ...@@ -100,6 +119,7 @@ function translate(message, chatId) {
100 119
101 // [Any normal message which is not a command (not starting with '/')] 120 // [Any normal message which is not a command (not starting with '/')]
102 bot.onText(/^(?!\/)((.|\n)+)/, (msg, match) => { 121 bot.onText(/^(?!\/)((.|\n)+)/, (msg, match) => {
122 + const userId = msg.from.id;
103 const chatId = msg.chat.id; 123 const chatId = msg.chat.id;
104 const chatType = msg.chat.type; 124 const chatType = msg.chat.type;
105 const received_msg = match[1]; 125 const received_msg = match[1];
...@@ -110,7 +130,7 @@ bot.onText(/^(?!\/)((.|\n)+)/, (msg, match) => { ...@@ -110,7 +130,7 @@ bot.onText(/^(?!\/)((.|\n)+)/, (msg, match) => {
110 return; 130 return;
111 } 131 }
112 132
113 - translate(received_msg, chatId); 133 + translate(userId, received_msg, chatId);
114 }); 134 });
115 135
116 // /t(ranslate) [Whatever] 136 // /t(ranslate) [Whatever]
...@@ -118,6 +138,7 @@ bot.onText(/^(?!\/)((.|\n)+)/, (msg, match) => { ...@@ -118,6 +138,7 @@ bot.onText(/^(?!\/)((.|\n)+)/, (msg, match) => {
118 // Also, if the given '/t' message is a reply to another message, 138 // Also, if the given '/t' message is a reply to another message,
119 // translate the reply target message as well. 139 // translate the reply target message as well.
120 bot.onText(/^\/(t|translate)($| ((.|\n)+))/, (msg, match) => { 140 bot.onText(/^\/(t|translate)($| ((.|\n)+))/, (msg, match) => {
141 + const userId = msg.from.id;
121 const chatId = msg.chat.id; 142 const chatId = msg.chat.id;
122 const chatType = msg.chat.type; 143 const chatType = msg.chat.type;
123 const received_msg = match[3]; 144 const received_msg = match[3];
...@@ -129,12 +150,12 @@ bot.onText(/^\/(t|translate)($| ((.|\n)+))/, (msg, match) => { ...@@ -129,12 +150,12 @@ bot.onText(/^\/(t|translate)($| ((.|\n)+))/, (msg, match) => {
129 // Translate the reply's target message 150 // Translate the reply's target message
130 if (isReply) { 151 if (isReply) {
131 const replyMsg = msg.reply_to_message.text; 152 const replyMsg = msg.reply_to_message.text;
132 - translate(replyMsg, chatId); 153 + translate(userId, replyMsg, chatId);
133 } 154 }
134 155
135 // Translate the message after '/t' if exists 156 // Translate the message after '/t' if exists
136 if (msgExists) { 157 if (msgExists) {
137 - translate(received_msg, chatId); 158 + translate(userId, received_msg, chatId);
138 } 159 }
139 }); 160 });
140 161
...@@ -194,11 +215,15 @@ bot.onText(/^\/(l|anguage)/, (msg, match) => { ...@@ -194,11 +215,15 @@ bot.onText(/^\/(l|anguage)/, (msg, match) => {
194 }); 215 });
195 216
196 bot.on('callback_query', (query) => { 217 bot.on('callback_query', (query) => {
197 - const data = query.data; 218 + const queryId = query.id;
219 + const userId = query.from.id;
220 + const langCode = query.data;
198 221
199 - const options = { 222 + db.updatePref(userId, { "pref": { "target": langCode } }, (result) => {
200 - text: 'From now on, your messages will be translated into ' + data 223 + const options = {
201 - } 224 + text: 'From now on, your messages will be translated into ' + langCode
225 + }
202 226
203 - bot.answerCallbackQuery(query.id, options); 227 + bot.answerCallbackQuery(queryId, options);
228 + })
204 }); 229 });
......
1 +// MongoDB handling module
2 +// TODO: error handling, data removal
3 +
4 +const MongoClient = require('mongodb').MongoClient;
5 +
6 +// Connection URL
7 +const url = 'mongodb://localhost:27017';
8 +
9 +var db, collection;
10 +
11 +// Use connect method to connect to the server
12 +const init = function () {
13 + MongoClient.connect(url, function (err, client) {
14 + if (err) {
15 + return;
16 + }
17 +
18 + console.log("Connected successfully to MongoDB server");
19 +
20 + db = client.db('telegrambot');
21 + collection = db.collection('users');
22 + });
23 +}
24 +
25 +const findData = function (userId, key, callback) {
26 + collection.find({ "userId": userId }).toArray(function (err, docs) {
27 + var cur = docs[0];
28 + if (cur != undefined) {
29 + const keys = key.split('.');
30 + for (var i = 0, subKey, len = keys.length; i < len; ++i) {
31 + subKey = keys[i];
32 + if (subKey == '') {
33 + continue;
34 + }
35 + if (cur.hasOwnProperty(subKey)) {
36 + cur = cur[subKey];
37 + } else {
38 + cur = undefined;
39 + break;
40 + }
41 + }
42 + }
43 + callback(cur);
44 + });
45 +};
46 +
47 +const updateData = function (userId, data, callback) {
48 + collection.updateOne(
49 + { "userId": userId },
50 + { $set: data },
51 + { upsert: true },
52 + function (err, result) {
53 + callback(result);
54 + });
55 +};
56 +
57 +module.exports = {
58 + init: init,
59 + findPref: findData,
60 + updatePref: updateData
61 +};
File mode changed
...@@ -74,6 +74,11 @@ ...@@ -74,6 +74,11 @@
74 "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", 74 "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
75 "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==" 75 "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w=="
76 }, 76 },
77 + "bson": {
78 + "version": "1.1.1",
79 + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz",
80 + "integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg=="
81 + },
77 "caseless": { 82 "caseless": {
78 "version": "0.12.0", 83 "version": "0.12.0",
79 "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 84 "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
...@@ -338,6 +343,12 @@ ...@@ -338,6 +343,12 @@
338 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", 343 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
339 "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" 344 "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
340 }, 345 },
346 + "memory-pager": {
347 + "version": "1.5.0",
348 + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
349 + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
350 + "optional": true
351 + },
341 "mime": { 352 "mime": {
342 "version": "1.6.0", 353 "version": "1.6.0",
343 "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 354 "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
...@@ -356,6 +367,26 @@ ...@@ -356,6 +367,26 @@
356 "mime-db": "1.40.0" 367 "mime-db": "1.40.0"
357 } 368 }
358 }, 369 },
370 + "mongodb": {
371 + "version": "3.2.6",
372 + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.2.6.tgz",
373 + "integrity": "sha512-qnHc4tjEkHKemuzBq9R7ycYnhFE0Dlpt6+n6suoZp2DcDdqviQ+teloJU24fsOw/PLmr75yGk4mRx/YabjDQEQ==",
374 + "requires": {
375 + "mongodb-core": "3.2.6",
376 + "safe-buffer": "^5.1.2"
377 + }
378 + },
379 + "mongodb-core": {
380 + "version": "3.2.6",
381 + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.6.tgz",
382 + "integrity": "sha512-i+XRVjur9D0ywGF7cFebOUnALnbvMHajdNhhl3TQuopW6QDE655G8CpPeERbqSqfa3rOKEUo08lENDIiBIuAvQ==",
383 + "requires": {
384 + "bson": "^1.1.1",
385 + "require_optional": "^1.0.1",
386 + "safe-buffer": "^5.1.2",
387 + "saslprep": "^1.0.0"
388 + }
389 + },
359 "ms": { 390 "ms": {
360 "version": "2.1.1", 391 "version": "2.1.1",
361 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 392 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
...@@ -500,6 +531,20 @@ ...@@ -500,6 +531,20 @@
500 "lodash": "^4.17.11" 531 "lodash": "^4.17.11"
501 } 532 }
502 }, 533 },
534 + "require_optional": {
535 + "version": "1.0.1",
536 + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
537 + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
538 + "requires": {
539 + "resolve-from": "^2.0.0",
540 + "semver": "^5.1.0"
541 + }
542 + },
543 + "resolve-from": {
544 + "version": "2.0.0",
545 + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
546 + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
547 + },
503 "safe-buffer": { 548 "safe-buffer": {
504 "version": "5.1.2", 549 "version": "5.1.2",
505 "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 550 "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
...@@ -510,6 +555,29 @@ ...@@ -510,6 +555,29 @@
510 "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 555 "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
511 "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 556 "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
512 }, 557 },
558 + "saslprep": {
559 + "version": "1.0.3",
560 + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
561 + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
562 + "optional": true,
563 + "requires": {
564 + "sparse-bitfield": "^3.0.3"
565 + }
566 + },
567 + "semver": {
568 + "version": "5.7.0",
569 + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
570 + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA=="
571 + },
572 + "sparse-bitfield": {
573 + "version": "3.0.3",
574 + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
575 + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
576 + "optional": true,
577 + "requires": {
578 + "memory-pager": "^1.0.2"
579 + }
580 + },
513 "sshpk": { 581 "sshpk": {
514 "version": "1.16.1", 582 "version": "1.16.1",
515 "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 583 "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
10 "author": "강수인", 10 "author": "강수인",
11 "license": "MIT", 11 "license": "MIT",
12 "dependencies": { 12 "dependencies": {
13 + "mongodb": "^3.2.6",
13 "node-telegram-bot-api": "^0.30.0", 14 "node-telegram-bot-api": "^0.30.0",
14 "request": "^2.88.0" 15 "request": "^2.88.0"
15 } 16 }
......