add translation using i18n
This commit is contained in:
parent
21ea2cd48f
commit
93f746a766
|
@ -9,6 +9,7 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"i18n-js": "^4.4.3",
|
||||||
"matrix-bot-sdk": "^0.7.1",
|
"matrix-bot-sdk": "^0.7.1",
|
||||||
"nodemon": "^3.1.4",
|
"nodemon": "^3.1.4",
|
||||||
"pg": "^8.12.0"
|
"pg": "^8.12.0"
|
||||||
|
@ -288,6 +289,14 @@
|
||||||
"tweetnacl": "^0.14.3"
|
"tweetnacl": "^0.14.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bignumber.js": {
|
||||||
|
"version": "9.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz",
|
||||||
|
"integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/binary-extensions": {
|
"node_modules/binary-extensions": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||||
|
@ -1070,6 +1079,16 @@
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
},
|
},
|
||||||
|
"node_modules/i18n-js": {
|
||||||
|
"version": "4.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18n-js/-/i18n-js-4.4.3.tgz",
|
||||||
|
"integrity": "sha512-QIIyvJ+wOKdigL4BlgwiFFrpoXeGdlC8EYgori64YSWm1mnhNYYjIfRu5wETFrmiNP2fyD6xIjVG8dlzaiQr/A==",
|
||||||
|
"dependencies": {
|
||||||
|
"bignumber.js": "*",
|
||||||
|
"lodash": "*",
|
||||||
|
"make-plural": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/iconv-lite": {
|
"node_modules/iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
|
@ -1227,6 +1246,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
|
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/make-plural": {
|
||||||
|
"version": "7.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.4.0.tgz",
|
||||||
|
"integrity": "sha512-4/gC9KVNTV6pvYg2gFeQYTW3mWaoJt7WZE5vrp1KnQDgW92JtYZnzmZT81oj/dUTqAIu0ufI2x3dkgu3bB1tYg=="
|
||||||
|
},
|
||||||
"node_modules/matrix-bot-sdk": {
|
"node_modules/matrix-bot-sdk": {
|
||||||
"version": "0.7.1",
|
"version": "0.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/matrix-bot-sdk/-/matrix-bot-sdk-0.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/matrix-bot-sdk/-/matrix-bot-sdk-0.7.1.tgz",
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
"author": "leca",
|
"author": "leca",
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"i18n-js": "^4.4.3",
|
||||||
"matrix-bot-sdk": "^0.7.1",
|
"matrix-bot-sdk": "^0.7.1",
|
||||||
"nodemon": "^3.1.4",
|
"nodemon": "^3.1.4",
|
||||||
"pg": "^8.12.0"
|
"pg": "^8.12.0"
|
||||||
|
|
|
@ -6,6 +6,7 @@ CREATE TABLE IF NOT EXISTS users (
|
||||||
sex CHAR, -- 'm' of 'f'
|
sex CHAR, -- 'm' of 'f'
|
||||||
interest CHAR, -- male, female or both ('m', 'f' and 'b')
|
interest CHAR, -- male, female or both ('m', 'f' and 'b')
|
||||||
description VARCHAR(512) DEFAULT NULL,
|
description VARCHAR(512) DEFAULT NULL,
|
||||||
|
language VARCHAR(8) DEFAULT 'en',
|
||||||
country VARCHAR(64) DEFAULT NULL,
|
country VARCHAR(64) DEFAULT NULL,
|
||||||
city VARCHAR(64) DEFAULT NULL,
|
city VARCHAR(64) DEFAULT NULL,
|
||||||
current_action VARCHAR(16) DEFAULT NULL,
|
current_action VARCHAR(16) DEFAULT NULL,
|
||||||
|
|
12
src/db.js
12
src/db.js
|
@ -156,6 +156,14 @@ const markMessageAsRead = async (roomId, recipient) => {
|
||||||
return (await db.query("UPDATE messages SET read = TRUE WHERE sender = $1 AND recipient = $2", [roomId, recipient]));
|
return (await db.query("UPDATE messages SET read = TRUE WHERE sender = $1 AND recipient = $2", [roomId, recipient]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setUserLanguage = async (roomId, language) => {
|
||||||
|
await db.query("UPDATE users SET language = $1 WHERE room_id = $2", [language, roomId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUserLanguage = async (roomId) => {
|
||||||
|
return (await db.query("SELECT language FROM users WHERE room_id = $1", [roomId])).rows[0].language;
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
eraseUser,
|
eraseUser,
|
||||||
appendUserPictures,
|
appendUserPictures,
|
||||||
|
@ -176,5 +184,7 @@ export {
|
||||||
uploadMediaAsMessage,
|
uploadMediaAsMessage,
|
||||||
insertMessageIntoDB,
|
insertMessageIntoDB,
|
||||||
getUnreadMessages,
|
getUnreadMessages,
|
||||||
markMessageAsRead
|
markMessageAsRead,
|
||||||
|
setUserLanguage,
|
||||||
|
getUserLanguage
|
||||||
};
|
};
|
102
src/index.js
102
src/index.js
|
@ -13,7 +13,6 @@ import {
|
||||||
logError,
|
logError,
|
||||||
logInfo,
|
logInfo,
|
||||||
readConfig,
|
readConfig,
|
||||||
readMessages,
|
|
||||||
uploadMediaFromEvent
|
uploadMediaFromEvent
|
||||||
} from './utils.js';
|
} from './utils.js';
|
||||||
|
|
||||||
|
@ -31,16 +30,25 @@ import {
|
||||||
insertMessageIntoDB,
|
insertMessageIntoDB,
|
||||||
markMessageAsRead,
|
markMessageAsRead,
|
||||||
setUserState,
|
setUserState,
|
||||||
uploadMediaAsMessage
|
uploadMediaAsMessage,
|
||||||
|
setUserLanguage,
|
||||||
|
getUserLanguage
|
||||||
} from './db.js';
|
} from './db.js';
|
||||||
|
|
||||||
import { processRequest, showRandomProfileToUser, showNewLikes } from "./interactions.js";
|
import { processRequest, showRandomProfileToUser, showNewLikes } from "./interactions.js";
|
||||||
|
|
||||||
import { db } from "./db.js";
|
import { db } from "./db.js";
|
||||||
|
|
||||||
|
import fs from "fs";
|
||||||
|
|
||||||
|
import { I18n } from "i18n-js";
|
||||||
|
const i18n = new I18n({
|
||||||
|
en: JSON.parse(fs.readFileSync("./translations/en.json")),
|
||||||
|
ru: JSON.parse(fs.readFileSync("./translations/ru.json"))
|
||||||
|
});
|
||||||
|
i18n.defaultLocale = "en";
|
||||||
|
|
||||||
const config = readConfig();
|
const config = readConfig();
|
||||||
const messages = readMessages();
|
|
||||||
|
|
||||||
const homeserverUrl = config.homeserverURL;
|
const homeserverUrl = config.homeserverURL;
|
||||||
const accessToken = config.token;
|
const accessToken = config.token;
|
||||||
|
@ -60,11 +68,19 @@ client.on("room.message", async (roomId, event) => {
|
||||||
let answer = event.content.body;
|
let answer = event.content.body;
|
||||||
let msgtype = event.content.msgtype
|
let msgtype = event.content.msgtype
|
||||||
|
|
||||||
|
let preferredLanguage = await getUserLanguage(roomId);
|
||||||
|
if (!preferredLanguage) preferredLanguage = i18n.defaultLocale;
|
||||||
|
i18n.locale = preferredLanguage;
|
||||||
|
|
||||||
switch (current_action) {
|
switch (current_action) {
|
||||||
case "wait_start":
|
case "wait_start":
|
||||||
if (answer !== "!start") return;
|
let a = answer.split(" ")
|
||||||
|
if (a[0] !== "!start") return;
|
||||||
|
if (a[1] !== "ru" && a[1] !== "en") return;
|
||||||
|
await setUserLanguage(roomId, a[1]);
|
||||||
await setUserState(roomId, "country");
|
await setUserState(roomId, "country");
|
||||||
await client.sendText(roomId, messages.setup.country);
|
await client.sendText(roomId, i18n.t(["setup", "country"]));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "country":
|
case "country":
|
||||||
await processRequest(client, roomId, current_action, answer, 'city');
|
await processRequest(client, roomId, current_action, answer, 'city');
|
||||||
|
@ -78,12 +94,13 @@ client.on("room.message", async (roomId, event) => {
|
||||||
case "age":
|
case "age":
|
||||||
answer = parseInt(answer)
|
answer = parseInt(answer)
|
||||||
if (!answer) {
|
if (!answer) {
|
||||||
await client.sendText(roomId, messages.errors.didntunderstand);
|
await client.sendText(roomId, i18n.t(["general", "age"]));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (answer < 14) {
|
if (answer < 14) {
|
||||||
await client.sendText(roomId, messages.errors.tooyoung);
|
await client.sendText(roomId, i18n.t(["errors", "tooyoung"]));
|
||||||
|
|
||||||
await client.leaveRoom(roomId);
|
await client.leaveRoom(roomId);
|
||||||
await eraseUser(roomId);
|
await eraseUser(roomId);
|
||||||
return;
|
return;
|
||||||
|
@ -93,7 +110,8 @@ client.on("room.message", async (roomId, event) => {
|
||||||
case "sex":
|
case "sex":
|
||||||
answer = answer.toLowerCase().trim();
|
answer = answer.toLowerCase().trim();
|
||||||
if (answer.toLowerCase() != "male" && answer.toLowerCase() != "female") {
|
if (answer.toLowerCase() != "male" && answer.toLowerCase() != "female") {
|
||||||
await client.sendText(roomId, messages.errors.twosexes);
|
await client.sendText(roomId, i18n.t(["errors", "twosexes"]));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await processRequest(client, roomId, current_action, answer[0], 'interest');
|
await processRequest(client, roomId, current_action, answer[0], 'interest');
|
||||||
|
@ -101,7 +119,8 @@ client.on("room.message", async (roomId, event) => {
|
||||||
case "interest":
|
case "interest":
|
||||||
answer = answer.toLowerCase().trim();
|
answer = answer.toLowerCase().trim();
|
||||||
if (answer != "male" && answer != "female" && answer != "both") {
|
if (answer != "male" && answer != "female" && answer != "both") {
|
||||||
await client.sendText(roomId, messages.errors.didntunderstand);
|
await client.sendText(roomId, i18n.t(["errors", "didntunderstand"]));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await processRequest(client, roomId, current_action, answer[0], 'description');
|
await processRequest(client, roomId, current_action, answer[0], 'description');
|
||||||
|
@ -111,13 +130,15 @@ client.on("room.message", async (roomId, event) => {
|
||||||
break;
|
break;
|
||||||
case "pictures":
|
case "pictures":
|
||||||
if (event.content?.msgtype !== 'm.image' && event.content?.msgtype !== 'm.video') {
|
if (event.content?.msgtype !== 'm.image' && event.content?.msgtype !== 'm.video') {
|
||||||
await client.sendText(roomId, messages.setup.done);
|
await client.sendText(roomId, i18n.t(["setup", "done"]));
|
||||||
|
|
||||||
await setUserState(roomId, 'view_profiles');
|
await setUserState(roomId, 'view_profiles');
|
||||||
await showRandomProfileToUser(client, roomId);
|
await showRandomProfileToUser(client, roomId);
|
||||||
} else {
|
} else {
|
||||||
let pictures_count = parseInt(await getAmountOfUserPictures(roomId));
|
let pictures_count = parseInt(await getAmountOfUserPictures(roomId));
|
||||||
if (pictures_count >= maxAmountOfPhotoesPerUser) {
|
if (pictures_count >= maxAmountOfPhotoesPerUser) {
|
||||||
await client.sendText(roomId, messages.errors.toomuch);
|
await client.sendText(roomId, i18n.t(["errors", "toomuch"]));
|
||||||
|
|
||||||
await setUserState(roomId, 'view_profiles');
|
await setUserState(roomId, 'view_profiles');
|
||||||
await showRandomProfileToUser(client, roomId);
|
await showRandomProfileToUser(client, roomId);
|
||||||
} else {
|
} else {
|
||||||
|
@ -126,10 +147,13 @@ client.on("room.message", async (roomId, event) => {
|
||||||
await appendUserPictures(roomId, mxc, type);
|
await appendUserPictures(roomId, mxc, type);
|
||||||
let pictures_count = await getAmountOfUserPictures(roomId);
|
let pictures_count = await getAmountOfUserPictures(roomId);
|
||||||
if (pictures_count < maxAmountOfPhotoesPerUser) {
|
if (pictures_count < maxAmountOfPhotoesPerUser) {
|
||||||
await client.sendText(roomId, messages.setup.more + String(maxAmountOfPhotoesPerUser - pictures_count));
|
await client.sendText(roomId, i18n.t(["setup", "more"], { amount: String(maxAmountOfPhotoesPerUser - pictures_count) }));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
await client.sendText(roomId, messages.setup.enough);
|
await client.sendText(roomId, i18n.t(["setup", "enough"]));
|
||||||
await client.sendText(roomId, messages.setup.done);
|
|
||||||
|
await client.sendText(roomId, i18n.t(["setup", "done"]));
|
||||||
|
|
||||||
await setUserState(roomId, 'view_profiles');
|
await setUserState(roomId, 'view_profiles');
|
||||||
await showRandomProfileToUser(client, roomId);
|
await showRandomProfileToUser(client, roomId);
|
||||||
}
|
}
|
||||||
|
@ -142,12 +166,15 @@ client.on("room.message", async (roomId, event) => {
|
||||||
await appendUserLikes(roomId, currently_viewing);
|
await appendUserLikes(roomId, currently_viewing);
|
||||||
let value = await checkForMutualLike(roomId, currently_viewing);
|
let value = await checkForMutualLike(roomId, currently_viewing);
|
||||||
if (value) {
|
if (value) {
|
||||||
await client.sendText(roomId, messages.general.newlikes);
|
await client.sendText(roomId, i18n.t(["general", "newlikes"]));
|
||||||
await client.sendText(currently_viewing, messages.general.newlikes);
|
|
||||||
|
await client.sendText(roomId, i18n.t(["general", "newlikes"]));
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if (answer == '💌' || answer == '3') {
|
} else if (answer == '💌' || answer == '3') {
|
||||||
await setUserState(roomId, 'send_message');
|
await setUserState(roomId, 'send_message');
|
||||||
await client.sendText(roomId, messages.general.message);
|
await client.sendText(roomId, i18n.t(["general", "message"]));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else if (answer == '🏠️' || answer == '4') {
|
} else if (answer == '🏠️' || answer == '4') {
|
||||||
await client.sendText(roomId, messages.general.menu);
|
await client.sendText(roomId, messages.general.menu);
|
||||||
|
@ -168,10 +195,13 @@ client.on("room.message", async (roomId, event) => {
|
||||||
content = answer;
|
content = answer;
|
||||||
}
|
}
|
||||||
if (await insertMessageIntoDB(roomId, recipient, msgtype, content)) {
|
if (await insertMessageIntoDB(roomId, recipient, msgtype, content)) {
|
||||||
await client.sendText(recipient, messages.general.newmessage);
|
await client.sendText(roomId, i18n.t(["general", "newmessage"]));
|
||||||
await client.sendText(roomId, messages.general.messagesent);
|
|
||||||
|
await client.sendText(roomId, i18n.t(["general", "messagesent"]));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
await client.sendText(roomId, messages.errors.alreadymessaged);
|
await client.sendText(roomId, i18n.t(["general", "alreadymessaged"]));
|
||||||
|
|
||||||
}
|
}
|
||||||
await setUserState(roomId, 'view_profiles');
|
await setUserState(roomId, 'view_profiles');
|
||||||
await showRandomProfileToUser(client, roomId);
|
await showRandomProfileToUser(client, roomId);
|
||||||
|
@ -184,17 +214,21 @@ client.on("room.message", async (roomId, event) => {
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
await showNewLikes(client, roomId);
|
await showNewLikes(client, roomId);
|
||||||
await client.sendText(roomId, messages.general.menu);
|
await client.sendText(roomId, i18n.t(["general", "menu"]));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case '3':
|
case '3':
|
||||||
let unreadMessages = await getUnreadMessages(roomId);
|
let unreadMessages = await getUnreadMessages(roomId);
|
||||||
if (!unreadMessages || unreadMessages.length == 0) {
|
if (!unreadMessages || unreadMessages.length == 0) {
|
||||||
await client.sendText(roomId, messages.general.nonewmessages);
|
await client.sendText(roomId, i18n.t(["general", "nonewmessages"]));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await client.sendText(roomId, "Messages:");
|
await client.sendText(roomId, i18n.t(["general", "msg"]));
|
||||||
|
|
||||||
for (let message of unreadMessages) {
|
for (let message of unreadMessages) {
|
||||||
await client.sendText(roomId, message.mx_id + messages.general.showmessage);
|
await client.sendText(roomId, i18n.t(["general", "showmessage"], { user: message.mx_id }));
|
||||||
|
|
||||||
if (message.type == "t") {
|
if (message.type == "t") {
|
||||||
await client.sendText(roomId, message.content)
|
await client.sendText(roomId, message.content)
|
||||||
} else if (message.type == "p" || message.type == "v") {
|
} else if (message.type == "p" || message.type == "v") {
|
||||||
|
@ -214,16 +248,19 @@ client.on("room.message", async (roomId, event) => {
|
||||||
}
|
}
|
||||||
await markMessageAsRead(message.sender, roomId);
|
await markMessageAsRead(message.sender, roomId);
|
||||||
}
|
}
|
||||||
await client.sendText(roomId, messages.general.menu);
|
await client.sendText(roomId, i18n.t(["general", "menu"]));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
await client.sendText(roomId, messages.errors.didntunderstand);
|
await client.sendText(roomId, i18n.t(["general", "didntunderstand"]));
|
||||||
await client.sendText(roomId, messages.general.menu);
|
|
||||||
|
await client.sendText(roomId, i18n.t(["general", "menu"]));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
await client.sendText(roomId, messages.errors.didntunderstand);
|
await client.sendText(roomId, i18n.t(["general", "didntunderstand"]));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -249,7 +286,8 @@ client.on("room.invite", async (roomId, event) => {
|
||||||
let isDM = members.length == 2 ? true : false;
|
let isDM = members.length == 2 ? true : false;
|
||||||
|
|
||||||
if (!isDM) {
|
if (!isDM) {
|
||||||
await client.sendText(roomId, messages.errors.notadm);
|
await client.sendText(roomId, i18n.t(["errors", "notadm"]));
|
||||||
|
|
||||||
await client.leaveRoom(roomId)
|
await client.leaveRoom(roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +300,11 @@ client.on("room.invite", async (roomId, event) => {
|
||||||
if (!is_profile_exists) {
|
if (!is_profile_exists) {
|
||||||
await db.query("INSERT INTO users(mx_id, room_id, current_action) VALUES ($1, $2, $3)", [mx_id, roomId, "wait_start"])
|
await db.query("INSERT INTO users(mx_id, room_id, current_action) VALUES ($1, $2, $3)", [mx_id, roomId, "wait_start"])
|
||||||
|
|
||||||
await client.sendText(roomId, messages.general.welcome);
|
i18n.locale = "en";
|
||||||
|
await client.sendText(roomId, i18n.t(["general", "welcome"]));
|
||||||
|
i18n.locale = "ru";
|
||||||
|
await client.sendText(roomId, i18n.t(["general", "welcome"]));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
setUserState(roomId, 'view_profiles')
|
setUserState(roomId, 'view_profiles')
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ import {
|
||||||
logError,
|
logError,
|
||||||
logInfo,
|
logInfo,
|
||||||
readConfig,
|
readConfig,
|
||||||
readMessages
|
|
||||||
} from './utils.js';
|
} from './utils.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -14,9 +13,19 @@ import {
|
||||||
getAllLikesForUser,
|
getAllLikesForUser,
|
||||||
checkForMutualLike,
|
checkForMutualLike,
|
||||||
markLikeAsRead,
|
markLikeAsRead,
|
||||||
|
getUserLanguage
|
||||||
} from "./db.js";
|
} from "./db.js";
|
||||||
|
|
||||||
const messages = readMessages();
|
import fs from 'fs';
|
||||||
|
|
||||||
|
|
||||||
|
import { I18n } from "i18n-js";
|
||||||
|
const i18n = new I18n({
|
||||||
|
en: JSON.parse(fs.readFileSync("./translations/en.json")),
|
||||||
|
ru: JSON.parse(fs.readFileSync("./translations/ru.json"))
|
||||||
|
});
|
||||||
|
|
||||||
|
i18n.defaultLocale = "en";
|
||||||
|
|
||||||
const requiresLengths = {
|
const requiresLengths = {
|
||||||
"country": 64,
|
"country": 64,
|
||||||
|
@ -26,20 +35,32 @@ const requiresLengths = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const processRequest = async (client, roomId, question, answer, nextQuestion) => {
|
const processRequest = async (client, roomId, question, answer, nextQuestion) => {
|
||||||
|
|
||||||
|
let preferredLanguage = await getUserLanguage(roomId);
|
||||||
|
if (!preferredLanguage) preferredLanguage = i18n.defaultLocale;
|
||||||
|
i18n.locale = preferredLanguage;
|
||||||
|
|
||||||
if (answer.length > requiresLengths[question]) {
|
if (answer.length > requiresLengths[question]) {
|
||||||
await client.sendText(roomId, messages.errors.toobig);
|
await client.sendText(roomId, i18n.t(["errors", "toobig"]));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await db.query(`UPDATE users SET ${question} = $1 WHERE room_id = $2`, [answer, roomId]);
|
await db.query(`UPDATE users SET ${question} = $1 WHERE room_id = $2`, [answer, roomId]);
|
||||||
await client.sendText(roomId, `Set your ${question} setting to "${answer}".`);
|
await client.sendText(roomId, i18n.t(["general", "setopt"], { opt: answer }));
|
||||||
await client.sendText(roomId, messages.setup[nextQuestion]); //next question
|
|
||||||
|
await client.sendText(roomId, i18n.t(["setup", nextQuestion]));
|
||||||
|
|
||||||
setUserState(roomId, nextQuestion);
|
setUserState(roomId, nextQuestion);
|
||||||
};
|
};
|
||||||
|
|
||||||
const showRandomProfileToUser = async (client, roomId) => {
|
const showRandomProfileToUser = async (client, roomId) => {
|
||||||
|
let preferredLanguage = await getUserLanguage(roomId);
|
||||||
|
if (!preferredLanguage) preferredLanguage = i18n.defaultLocale;
|
||||||
|
i18n.locale = preferredLanguage;
|
||||||
|
|
||||||
let chosenProfile = await selectProfilesForUser(roomId);
|
let chosenProfile = await selectProfilesForUser(roomId);
|
||||||
if (!chosenProfile) {
|
if (!chosenProfile) {
|
||||||
await client.sendText(roomId, messages.errors.noprofiles);
|
await client.sendText(roomId, i18n.t(["errors", "noprofiles"]));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let message =
|
let message =
|
||||||
|
@ -71,13 +92,18 @@ ${chosenProfile.description}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const showProfileToUser = async (client, roomId, profileId) => {
|
const showProfileToUser = async (client, roomId, profileId) => {
|
||||||
|
let preferredLanguage = await getUserLanguage(roomId);
|
||||||
|
if (!preferredLanguage) preferredLanguage = i18n.defaultLocale;
|
||||||
|
i18n.locale = preferredLanguage;
|
||||||
|
|
||||||
let profileInfo = await getProfileInfo(profileId);
|
let profileInfo = await getProfileInfo(profileId);
|
||||||
let message =
|
let message =
|
||||||
`${profileInfo.country}, ${profileInfo.city}.
|
`${profileInfo.country}, ${profileInfo.city}.
|
||||||
${profileInfo.name}, ${profileInfo.sex == 'm' ? 'male' : 'female'}, ${profileInfo.age}.
|
${profileInfo.name}, ${profileInfo.sex == 'm' ? 'male' : 'female'}, ${profileInfo.age}.
|
||||||
${profileInfo.description}`;
|
${profileInfo.description}`;
|
||||||
|
|
||||||
await client.sendText(roomId, messages.general.showalike);
|
await client.sendText(roomId, i18n.t(["general", "showalike"]));
|
||||||
|
|
||||||
await client.sendText(roomId, message);
|
await client.sendText(roomId, message);
|
||||||
|
|
||||||
if (profileInfo.media) {
|
if (profileInfo.media) {
|
||||||
|
@ -95,8 +121,8 @@ ${profileInfo.description}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await client.sendText(roomId, i18n.t(["general", "mxid"], { mxid: profileInfo.mx_id }));
|
||||||
|
|
||||||
await client.sendText(roomId, messages.general.mxid + profileInfo.mx_id);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const showNewLikes = async (client, roomId) => {
|
const showNewLikes = async (client, roomId) => {
|
||||||
|
|
11
src/utils.js
11
src/utils.js
|
@ -8,7 +8,6 @@ import {
|
||||||
} from "matrix-bot-sdk";
|
} from "matrix-bot-sdk";
|
||||||
|
|
||||||
const configPath = './config.json';
|
const configPath = './config.json';
|
||||||
const messagesPath = './messages.json';
|
|
||||||
|
|
||||||
const logError = (message) => {
|
const logError = (message) => {
|
||||||
let time = new Date;
|
let time = new Date;
|
||||||
|
@ -40,14 +39,6 @@ const readConfig = () => {
|
||||||
return JSON.parse(fs.readFileSync(configPath));
|
return JSON.parse(fs.readFileSync(configPath));
|
||||||
};
|
};
|
||||||
|
|
||||||
const readMessages = () => {
|
|
||||||
if (!fs.existsSync(messagesPath)) {
|
|
||||||
logError("No 'messages.json' file found. Please, ensure that you are up to date by syncing using 'git pull' command.");
|
|
||||||
process.exit(-1);
|
|
||||||
}
|
|
||||||
return JSON.parse(fs.readFileSync(messagesPath));
|
|
||||||
};
|
|
||||||
|
|
||||||
const uploadMediaFromEvent = async (client, event) => {
|
const uploadMediaFromEvent = async (client, event) => {
|
||||||
const message = new MessageEvent(event);
|
const message = new MessageEvent(event);
|
||||||
const fileEvent = new MessageEvent(message.raw);
|
const fileEvent = new MessageEvent(message.raw);
|
||||||
|
@ -69,4 +60,4 @@ const convertMsgType = (msgtype) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export { readMessages, readConfig, logError, logInfo, uploadMediaFromEvent, convertMsgType };
|
export { readConfig, logError, logInfo, uploadMediaFromEvent, convertMsgType };
|
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"general": {
|
||||||
|
"welcome": "Hello! I am a bot for new meetings in Matrix!\nTo start, please, type \"!start <language>\", where language are 'en' or 'ru'.\nI'll ask some questions to fill your profile. You can change that info later, if you will.\nThen, I'll start showing you another people's profiles.\nYou can like other profile, skip or send a message to the person.\nIf you mutually liked each other, you'll be given each other's MXID to start a DM.\nMy source code can be found on gitea: https://git.foxarmy.org/leca/heart2heart.\n\nGood luck!",
|
||||||
|
"rate": "Decide wether you like (👍️, ❤️ or 1), dislike (👎️, 💔 or 2) or wanna send a messsage (💌 or 3). Write '🏠️' or 4 to quit to menu. Any other response counts as dislike.",
|
||||||
|
"menu": "Pick an action:\n1) Start watching profiles\n2) Check for mutual likes\n3) Check for messages",
|
||||||
|
"newlikes": "You have new mutual like(s)! Go into menu (🏠️) to see!",
|
||||||
|
"showalike": "This person and you mutually liked each other!",
|
||||||
|
"mxid": "Go drop them a line! Their MXID is: %{mxid}",
|
||||||
|
"message": "Write one message to this person or upload one picture/video to send them!",
|
||||||
|
"newmessage": "You've got new message(s)! Go to a menu (🏠️) to see!",
|
||||||
|
"showmessage": " sent you this: ",
|
||||||
|
"nonewmessages": "You have no new messages!",
|
||||||
|
"messagesent": "You message was sent!",
|
||||||
|
"msg": "Messages:",
|
||||||
|
"setopt": "Got \"%{opt}\""
|
||||||
|
},
|
||||||
|
"setup": {
|
||||||
|
"country": "Write a name of country you are living in. Prefer local language. For example, 'Россия', 'United States' or 'Україна'.",
|
||||||
|
"city": "Write a name of city you are living in. Prefer local language. For example, 'Москва', 'Washington, D.C.', or 'Київ'.",
|
||||||
|
"name": "Write a name of your profile. Not longer than 32 symbols",
|
||||||
|
"description": "Write a description of your profile. Not longer than 512 symbols.",
|
||||||
|
"age": "Write your age. People yonger than 14 are disallowed to use the service.",
|
||||||
|
"sex": "Write your sex: Male or female.",
|
||||||
|
"interest": "Write who you are interested to talk to? Write 'both', 'male', or 'female'.",
|
||||||
|
"pictures": "Send up to five pictures that will be shown in your profile. Write any text message when you are done.",
|
||||||
|
"done": "Phew! You are done filling your profile! Now I'll start showing you others profiles!",
|
||||||
|
"more": "Got that cool picture! You still can upload up %{amount} picture(s)",
|
||||||
|
"enough": "That's enough of pictures! Let's go further!"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"notadm": "This room is not a DM (direct or private messages). You should invite me in a DM! By the way, I support encrypted rooms! Bye and see you in DM!",
|
||||||
|
"toobig": "Sorry! The length of what you have written here is bigger than I expected! If you beleive that it is an error, please, file an issue on my git: https://git.foxarmy.org/leca/heart2heart. Otherwise, write something a little bit smaller! Thank you!",
|
||||||
|
"tooyoung": "Sorry! You are too young for this! Please, come back when you'll turn at least 14! Thank you and good bye!",
|
||||||
|
"toomuch": "You have loaded more that 5 pictures. I'll not upload that. Going to the next step...",
|
||||||
|
"twosexes": "There are only two sexes! Please, choose your biological one.",
|
||||||
|
"didntunderstand": "I cannot understand your answer. Please, read my question again and answer!",
|
||||||
|
"notimplemented": "This feature is not yet implemented! Please, keep track of my updates at https://git.foxarmy.org/leca/heart2heart. Bother your admins to update, if released! ;)",
|
||||||
|
"noprofiles": "There are no profiles left for you! I'm sorry. Please, come back later!",
|
||||||
|
"alreadymessaged": "You have already messaged that person. Your message was not sent!"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"general": {
|
||||||
|
"welcome": "Привет! Я бот, который поможет вам найти новые знакомства в Матриксе!\nЧтобы начать, напишите \"!start <язык>\". Вместо <язык> вставьте ru или en.\nЯ спрошу несколько вопросов, чтобы заполнить ваш профиль. Вы сможете изменить информацию позже.\nПосле этого, я начну показывать вам профили других пользователей..\nВы можете лайкать, скипать чужие профили или отправлять им сообщения.\nЕсли вы взаимно лайкнули друг друг, вам будут показаны ваши MXID.\nМой исходный код можно найти на gitea: https://git.foxarmy.org/leca/heart2heart.\n\nУдачи!",
|
||||||
|
"rate": "Решите, нравится лм (👍️, ❤️ or 1), не нравится (👎️, 💔 or 2) или вы хотите отправить сообщение (💌 or 3). Напишите '🏠️' или 4 чтобы выйти в меню. Любой другой ответ считается как \"не нравится\".",
|
||||||
|
"menu": "Выберете действие:\n1) Начать просмотр профилей\n2) Проверить взаимные лайки\n3) Проверить сообщения",
|
||||||
|
"newlikes": "У вас новый(-ие) взаимные лайк(и)! Выйдите в меню (🏠️) чтобы посмотреть!",
|
||||||
|
"showalike": "Этот человек и вы друг друга взаимно лайкнули!",
|
||||||
|
"mxid": "Идите и напишите этому человеку! MXID: %{mxid}",
|
||||||
|
"message": "Напишите одно сообщение этому человеку или загрузите одно видиео или картинку, чтобы отправить вместо текстового сообщения!",
|
||||||
|
"newmessage": "У вас новое(-ие) сообщение(-ия)! Выйдите в меню (🏠️) чтобы посмотреть!",
|
||||||
|
"showmessage": "%{user} отправил(-а) вам: ",
|
||||||
|
"nonewmessages": "У вас нет новых сообщений!",
|
||||||
|
"messagesent": "Ваше сообщение было отправлено!",
|
||||||
|
"msg": "Сообщения:",
|
||||||
|
"setopt": "Записал \"%{opt}\""
|
||||||
|
},
|
||||||
|
"setup": {
|
||||||
|
"country": "Напишите имя страны, в которой вы находитесь. Предпочтительно на местном языке. Например, 'Россия', 'United States' или 'Україна'.",
|
||||||
|
"city": "Напишите имя города, в котором вы находитесь. Предпочтительно на местном языке. Например, 'Москва', 'Washington, D.C.', или 'Київ'.",
|
||||||
|
"name": "Напишите имя вашего профиля. Не больше 32 символов",
|
||||||
|
"description": "Напишите описание вашего профиля. Не больше 512 символов.",
|
||||||
|
"age": "Напишите ваш возраст. Людям, младше 14 не разрешено использовать этот сервис.",
|
||||||
|
"sex": "Напишите ваш пол: Male or female. (на английском)",
|
||||||
|
"interest": "Напишите, с кем вам интересно знакомиться? Напишите 'both', 'male', или 'female'. (тоже на английском)",
|
||||||
|
"pictures": "Отправьте до пяти картинок или видео, которые будут отображены в вашем профиле. Напишите любое текстовое сообщение, если решите загрузить меньше.",
|
||||||
|
"done": "Хух! Мы закончили заполнять профиль! Теперь я начинаю показывать вам чужие профили!",
|
||||||
|
"more": "Принял эту крутую картинку! Вы всё ещё можете загрузить %{amount} картинок(ку)",
|
||||||
|
"enough": "Хватит картинок, давайте дальше!"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"notadm": "Эта комната - не ЛС (личные сообщения). Вы должны пригласить меня в ЛС! Кстати, я поддержиавю зашифрованные комнаты! Пока и увидимся в ЛС!",
|
||||||
|
"toobig": "Извините! Длина того, что вы написали больше, чем я ожидал! Если вы думаете, что это ошибка, пожалуйста, создайте issue на моём гите(Предпочтительно на английском): https://git.foxarmy.org/leca/heart2heart. Или попытайтесь написать что-то меньше! Спасибо!",
|
||||||
|
"tooyoung": "Извините! Вы слишком молоды для этого! Пожалуйста, возвращайтесь, когда вам будет минимум 14! Спасибо и пока!",
|
||||||
|
"toomuch": "Вы загрузили больше 5 картинок. Я не буду это загружать. Переходим к следующему шагу...",
|
||||||
|
"twosexes": "Возможно, вы ошиблись в написании пола! Пожалуйста, напишите \"male\" или \"female\".",
|
||||||
|
"didntunderstand": "Я не понимаю ваш ответ. Пожалуйста, перечитайте моё прошлое сообщение и попробуйте снова!",
|
||||||
|
"notimplemented": "Эта возможность ещё не добавлена! Пожалуйста, следите за обновлениями на моём git'е: https://git.foxarmy.org/leca/heart2heart. Доставайте своих админов, чтобы обновлялись, когда новая версия выходит ;)",
|
||||||
|
"noprofiles": "Не могу найти профили, которые подходят вашим критериям! Извините. Попробуйте позже!",
|
||||||
|
"alreadymessaged": "Вы уже отправляли сообщение этому человеку. Ваше сообщение не было отправлено!"
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue