diff --git a/.gitignore b/.gitignore index ead6274..9d05631 100644 --- a/.gitignore +++ b/.gitignore @@ -138,5 +138,5 @@ reg.js #Bot data encryption_bot_sled bot.json - +bot_data postgres diff --git a/src/db.js b/src/db.js index e136a7d..856e77f 100644 --- a/src/db.js +++ b/src/db.js @@ -1,7 +1,7 @@ -import pg from 'pg' -import fs from 'fs' +import pg from 'pg'; +import fs from 'fs'; -const { Client } = pg +const { Client } = pg; const getClient = async () => { const client = new Client({ @@ -11,50 +11,50 @@ const getClient = async () => { port: 5432, database: process.env.POSTGRES_DB }); - await client.connect() + await client.connect(); - await client.query(fs.readFileSync('./scheme.psql').toString()) + await client.query(fs.readFileSync('./scheme.psql').toString()); - return client -} + return client; +}; -export const db = await getClient() +export const db = await getClient(); const getAmountOfUserPictures = async (roomId) => { - return (await db.query("SELECT COUNT(*) FROM media WHERE owner = $1 AND purpose = 'p'", [roomId])).rows[0].count -} + return (await db.query("SELECT COUNT(*) FROM media WHERE owner = $1 AND purpose = 'p'", [roomId])).rows[0].count; +}; const getCurrentUserAction = async (roomId) => { return (await db.query('SELECT current_action FROM users WHERE room_id = $1', [roomId])).rows[0].current_action; -} +}; const setUserState = async (roomId, state) => { await db.query("UPDATE users SET current_action = $1 WHERE room_id = $2", [state, roomId]); -} +}; const appendUserPictures = async (roomId, mxc, type) => { - await db.query("INSERT INTO media (owner, type, purpose, url) VALUES ($1, $2, 'p', $3)", [roomId, type, mxc]) -} + await db.query("INSERT INTO media (owner, type, purpose, url) VALUES ($1, $2, 'p', $3)", [roomId, type, mxc]); +}; const eraseUser = async (roomId) => { await db.query("DELETE FROM users WHERE room_id = $1", [roomId]); -} +}; const eraseUserLikes = async (roomId) => { await db.query("DELETE FROM likes WHERE sender = $1 OR recipient = $1", [roomId]); -} +}; const eraseUserMedia = async (roomId) => { await db.query("DELETE FROM media WHERE owner = $1", [roomId]); -} +}; const selectProfilesForUser = async (roomId) => { - let myInterest = (await db.query("SELECT interest FROM users WHERE room_id = $1", [roomId])).rows[0].interest - let mySex = (await db.query("SELECT sex FROM users WHERE room_id = $1", [roomId])).rows[0].sex - let userAge = (await db.query("SELECT age FROM users WHERE room_id = $1", [roomId])).rows[0].age + let myInterest = (await db.query("SELECT interest FROM users WHERE room_id = $1", [roomId])).rows[0].interest; + let mySex = (await db.query("SELECT sex FROM users WHERE room_id = $1", [roomId])).rows[0].sex; + let userAge = (await db.query("SELECT age FROM users WHERE room_id = $1", [roomId])).rows[0].age; //Selecting profiles other than user's and with difference in age +-2. - let user + let user; if (myInterest === 'b') // both, no matter what sex user = (await db.query(`SELECT room_id, name, age, sex, description, country, city FROM users @@ -64,7 +64,7 @@ const selectProfilesForUser = async (roomId) => { AND (interest = $3 OR interest = 'b') ORDER BY RANDOM() LIMIT 1`, [userAge, roomId, mySex]) - ).rows[0] + ).rows[0]; else { user = (await db.query(`SELECT room_id, name, age, sex, description, country, city FROM users @@ -75,22 +75,22 @@ const selectProfilesForUser = async (roomId) => { AND (interest = $4 OR interest = 'b') ORDER BY RANDOM() LIMIT 1`, [userAge, roomId, myInterest, mySex]) - ).rows[0] + ).rows[0]; } - if (!user) return null + if (!user) return null; let media = await getUserProfilePictures(user.room_id); - user.media = media - return user -} + user.media = media; + return user; +}; const setUserCurrentlyViewingProfile = async (roomId, anotherRoomId) => { await db.query("UPDATE users SET currently_viewing = $1 WHERE room_id = $2", [anotherRoomId, roomId]); -} +}; const getUserCurrentlyViewingProfile = async (roomId) => { - return (await db.query("SELECT currently_viewing FROM users WHERE room_id = $1", [roomId])).rows[0].currently_viewing -} + return (await db.query("SELECT currently_viewing FROM users WHERE room_id = $1", [roomId])).rows[0].currently_viewing; +}; //Newlike is a room id of a user who was liked_profiles const appendUserLikes = async (roomId, newLike) => { @@ -103,11 +103,11 @@ const appendUserLikes = async (roomId, newLike) => { AND l2.read = TRUE`); await db.query("INSERT INTO likes (sender, recipient) VALUES ($1, $2) ON CONFLICT DO NOTHING", [roomId, newLike]); -} +}; const getUserLikes = async (roomId) => { - return (await db.query("SELECT recipient FROM likes WHERE sender = $1", [roomId])).rows[0].recipient -} + return (await db.query("SELECT recipient FROM likes WHERE sender = $1", [roomId])).rows[0].recipient; +}; const checkForMutualLike = async (roomId1, roomId2) => { return (await db.query(`SELECT COUNT(*) > 0 AS value @@ -115,28 +115,28 @@ const checkForMutualLike = async (roomId1, roomId2) => { JOIN likes l2 ON l1.sender = l2.recipient AND l1.recipient = l2.sender WHERE (l1.read = FALSE OR l2.read = FALSE) AND l1.sender = $1 - AND l1.recipient = $2`, [roomId1, roomId2])).rows[0].value -} + AND l1.recipient = $2`, [roomId1, roomId2])).rows[0].value; +}; const getProfileInfo = async (roomId) => { let user = (await db.query("SELECT mx_id, room_id, name, age, sex, description, country, city FROM users WHERE room_id = $1", [roomId])).rows[0]; - if (!user) return null + if (!user) return null; let media = await getUserProfilePictures(user.room_id); - user.media = media - return user -} + user.media = media; + return user; +}; const getUserProfilePictures = async (roomId) => { - return (await db.query("SELECT url, type FROM media WHERE owner = $1 AND purpose = 'p'", [roomId])).rows -} + return (await db.query("SELECT url, type FROM media WHERE owner = $1 AND purpose = 'p'", [roomId])).rows; +}; const getAllLikesForUser = async (roomId) => { - return (await db.query("SELECT sender FROM likes WHERE recipient = $1 AND read = FALSE", [roomId])).rows -} + return (await db.query("SELECT sender FROM likes WHERE recipient = $1 AND read = FALSE", [roomId])).rows; +}; const markLikeAsRead = async (roomId, recipient,) => { await db.query("UPDATE likes SET read = TRUE WHERE sender = $1 AND recipient = $2", [roomId, recipient]); -} +}; export { eraseUser, appendUserPictures, @@ -154,4 +154,4 @@ export { markLikeAsRead, eraseUserLikes, eraseUserMedia -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/index.js b/src/index.js index dd0a3c5..0f585d5 100644 --- a/src/index.js +++ b/src/index.js @@ -8,8 +8,6 @@ import { import { StoreType } from "@matrix-org/matrix-sdk-crypto-nodejs"; -import fs from 'fs'; - import { logError, logInfo, @@ -28,19 +26,19 @@ import { getCurrentUserAction, getUserCurrentlyViewingProfile, setUserState -} from './db.js' +} from './db.js'; import { processRequest, showRandomProfileToUser, showNewLikes } from "./interactions.js"; -import { db } from "./db.js" +import { db } from "./db.js"; -const config = readConfig() -const messages = readMessages() +const config = readConfig(); +const messages = readMessages(); const homeserverUrl = config.homeserverURL; const accessToken = config.token; -const maxAmountOfPhotoesPerUser = config.maxAmountOfPhotoesPerUser +const maxAmountOfPhotoesPerUser = config.maxAmountOfPhotoesPerUser; const crypto = new RustSdkCryptoStorageProvider("./bot_data/encryption_bot_sled", StoreType.Sled); const storage = new SimpleFsStorageProvider("./bot_data/bot.json"); @@ -87,7 +85,7 @@ client.on("room.message", async (roomId, event) => { await processRequest(client, roomId, current_action, answer, 'sex'); break; case "sex": - answer = answer.toLowerCase().trim() + answer = answer.toLowerCase().trim(); if (answer.toLowerCase() != "male" && answer.toLowerCase() != "female") { await client.sendText(roomId, messages.errors.twosexes); return; @@ -95,7 +93,7 @@ client.on("room.message", async (roomId, event) => { await processRequest(client, roomId, current_action, answer[0], 'interest'); break; case "interest": - answer = answer.toLowerCase().trim() + answer = answer.toLowerCase().trim(); if (answer != "male" && answer != "female" && answer != "both") { await client.sendText(roomId, messages.errors.didntunderstand); return; @@ -108,13 +106,13 @@ client.on("room.message", async (roomId, event) => { case "pictures": if (event.content?.msgtype !== 'm.image' && event.content?.msgtype !== 'm.video') { await client.sendText(roomId, messages.setup.done); - await setUserState(roomId, 'view_profiles') + await setUserState(roomId, 'view_profiles'); await showRandomProfileToUser(client, roomId); } else { let pictures_count = parseInt(await getAmountOfUserPictures(roomId)); if (pictures_count >= maxAmountOfPhotoesPerUser) { await client.sendText(roomId, messages.errors.toomuch); - await setUserState(roomId, 'view_profiles') + await setUserState(roomId, 'view_profiles'); await showRandomProfileToUser(client, roomId); } else { const message = new MessageEvent(event); @@ -123,9 +121,9 @@ client.on("room.message", async (roomId, event) => { const mxc = await client.uploadContent(decrypted); let type; if (event.content.msgtype === "m.image") { - type = 'p' + type = 'p'; } else if (event.content.msgtype === "m.video") { - type = 'v' + type = 'v'; } await appendUserPictures(roomId, mxc, type); let pictures_count = await getAmountOfUserPictures(roomId); @@ -142,7 +140,7 @@ client.on("room.message", async (roomId, event) => { break; case "view_profiles": if (answer == '👍️' || answer == '❤️' || answer == '1') { - let currently_viewing = await getUserCurrentlyViewingProfile(roomId) + let currently_viewing = await getUserCurrentlyViewingProfile(roomId); await appendUserLikes(roomId, currently_viewing); let value = await checkForMutualLike(roomId, currently_viewing); if (value) { @@ -158,11 +156,14 @@ client.on("room.message", async (roomId, event) => { } await showRandomProfileToUser(client, roomId); + break; + case 'send_message': + break; case 'menu': switch (answer) { case '1': - await setUserState(roomId, 'view_profiles') + await setUserState(roomId, 'view_profiles'); await showRandomProfileToUser(client, roomId); break; case '2': @@ -170,6 +171,7 @@ client.on("room.message", async (roomId, event) => { await client.sendText(roomId, messages.general.menu); break; case '3': + await setUserState(roomId, 'send_message'); await client.sendText(roomId, messages.errors.notimplemented); break; default: @@ -193,7 +195,7 @@ client.on("room.event", async (roomId, event) => { await eraseUserMedia(roomId); logInfo(`Bot has left a room with ID ${roomId}`) client.leaveRoom(roomId); - } + } }) client.on("room.invite", async (roomId, event) => { diff --git a/src/interactions.js b/src/interactions.js index 97784b6..05acad4 100644 --- a/src/interactions.js +++ b/src/interactions.js @@ -14,16 +14,16 @@ import { getAllLikesForUser, checkForMutualLike, markLikeAsRead, -} from "./db.js" +} from "./db.js"; -const messages = readMessages() +const messages = readMessages(); const requiresLengths = { "country": 64, "city": 64, "description": 512, "name": 32, -} +}; const processRequest = async (client, roomId, question, answer, nextQuestion) => { if (answer.length > requiresLengths[question]) { @@ -34,7 +34,7 @@ const processRequest = async (client, roomId, question, answer, nextQuestion) => await client.sendText(roomId, `Set your ${question} setting to "${answer}".`); await client.sendText(roomId, messages.setup[nextQuestion]); //next question setUserState(roomId, nextQuestion); -} +}; const showRandomProfileToUser = async (client, roomId) => { let chosenProfile = await selectProfilesForUser(roomId); @@ -45,18 +45,18 @@ const showRandomProfileToUser = async (client, roomId) => { let message = `${chosenProfile.country}, ${chosenProfile.city}. ${chosenProfile.name}, ${chosenProfile.sex == 'm' ? 'male' : 'female'}, ${chosenProfile.age}. -${chosenProfile.description}` +${chosenProfile.description}`; - await setUserCurrentlyViewingProfile(roomId, chosenProfile.room_id) + await setUserCurrentlyViewingProfile(roomId, chosenProfile.room_id); await client.sendText(roomId, message); if (chosenProfile.media) { for (let media of chosenProfile.media) { - let msgtype + let msgtype; if (media.type == 'p') { - msgtype = "m.image" + msgtype = "m.image"; } else if (media.type == 'v') { - msgtype = "m.video" + msgtype = "m.video"; } await client.sendMessage(roomId, { msgtype: msgtype, @@ -67,26 +67,26 @@ ${chosenProfile.description}` } - await client.sendText(roomId, messages.general.rate) -} + await client.sendText(roomId, messages.general.rate); +}; const showProfileToUser = async (client, roomId, profileId) => { let profileInfo = await getProfileInfo(profileId); let message = `${profileInfo.country}, ${profileInfo.city}. ${profileInfo.name}, ${profileInfo.sex == 'm' ? 'male' : 'female'}, ${profileInfo.age}. -${profileInfo.description}` +${profileInfo.description}`; await client.sendText(roomId, messages.general.showalike); await client.sendText(roomId, message); if (profileInfo.media) { for (let media of profileInfo.media) { - let msgtype + let msgtype; if (media.type == 'p') { - msgtype = "m.image" + msgtype = "m.image"; } else if (media.type == 'v') { - msgtype = "m.video" + msgtype = "m.video"; } await client.sendMessage(roomId, { msgtype: msgtype, @@ -96,8 +96,8 @@ ${profileInfo.description}` } } - await client.sendText(roomId, messages.general.mxid + profileInfo.mx_id) -} + await client.sendText(roomId, messages.general.mxid + profileInfo.mx_id); +}; const showNewLikes = async (client, roomId) => { let likes = (await getAllLikesForUser(roomId)); @@ -107,6 +107,6 @@ const showNewLikes = async (client, roomId) => { await markLikeAsRead(liked.sender, roomId); } } -} +}; export { processRequest, showRandomProfileToUser, showNewLikes, showProfileToUser }; \ No newline at end of file diff --git a/src/utils.js b/src/utils.js index 81fcb93..d0980ff 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,17 +1,17 @@ -import fs from 'fs' +import fs from 'fs'; -const configPath = './config.json' -const messagesPath = './messages.json' +const configPath = './config.json'; +const messagesPath = './messages.json'; const logError = (message) => { - let time = new Date - console.error(`[${time.toLocaleString()}] [LOG] [E] ${message}`) -} + let time = new Date; + console.error(`[${time.toLocaleString()}] [LOG] [E] ${message}`); +}; const logInfo = (message) => { - let time = new Date - console.log(`[${time.toLocaleString()}] [LOG] [I] ${message}`) -} + let time = new Date; + console.log(`[${time.toLocaleString()}] [LOG] [I] ${message}`); +}; const readConfig = () => { @@ -20,25 +20,25 @@ const readConfig = () => { fs.writeFileSync(configPath, `{ "homeserverURL": "https://matrix.org/", - "token": "Super secret token! Do not show to anyone! Even your mum! ;)" + "token": "Super secret token! Do not show to anyone! Even your mum! ;)", + "maxAmountOfPhotoesPerUser": 5 }` ); - logError('[LOG] [E] Config file was not found. I have created a template, please, edit it and restart a bot.') + logError('[LOG] [E] Config file was not found. I have created a template, please, edit it and restart a bot.'); - process.exit(-1) + process.exit(-1); } - 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) + 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)) -} + return JSON.parse(fs.readFileSync(messagesPath)); +}; export {readMessages, readConfig, logError, logInfo}; \ No newline at end of file