diff --git a/handlers/commands/admin.js b/handlers/commands/admin.js index f2032d8..7477b30 100644 --- a/handlers/commands/admin.js +++ b/handlers/commands/admin.js @@ -12,9 +12,13 @@ const { masterID } = loadJSON('config.json'); const { replyOptions } = require('../../bot/options'); // DB -const { isAdmin, admin } = require('../../stores/user'); -const { isBanned } = require('../../stores/user'); -const { getWarns, nowarns } = require('../../stores/warn'); +const { + isAdmin, + admin, + isBanned, + getWarns, + nowarns +} = require('../../stores/user'); const adminHandler = async ({ message, reply }) => { if (message.from.id !== masterID) { diff --git a/handlers/commands/ban.js b/handlers/commands/ban.js index 29ce2c3..42d1b22 100644 --- a/handlers/commands/ban.js +++ b/handlers/commands/ban.js @@ -10,8 +10,7 @@ const { replyOptions } = require('../../bot/options'); // DB const { listGroups } = require('../../stores/group'); -const { isBanned, ban } = require('../../stores/user'); -const { isAdmin } = require('../../stores/user'); +const { isAdmin, isBanned, ban } = require('../../stores/user'); const banHandler = async ({ chat, message, reply, telegram }) => { if (!await isAdmin(message.from)) { diff --git a/handlers/commands/getwarns.js b/handlers/commands/getwarns.js index 9c2a544..d6c7a99 100644 --- a/handlers/commands/getwarns.js +++ b/handlers/commands/getwarns.js @@ -7,8 +7,7 @@ const { link } = require('../../utils/tg'); const { replyOptions } = require('../../bot/options'); // DB -const { getWarns } = require('../../stores/warn'); -const { isAdmin } = require('../../stores/user'); +const { isAdmin, getWarns } = require('../../stores/user'); const getWarnsHandler = async ({ message, reply }) => { if (!await isAdmin(message.from)) { @@ -25,13 +24,13 @@ const getWarnsHandler = async ({ message, reply }) => { } let i = 0; const warns = await getWarns(theUser); - if (warns.length < 1) { + if (!warns) { return reply(`✅ no warns for: ${link(theUser)}`, replyOptions); } return reply(`⚠️ Warns for ${link(theUser)}:\n\n` + warns .map(warn => ++i + '. ' + warn) - .join('\n\n'), replyOptions); + .join('\n'), replyOptions); }; module.exports = getWarnsHandler; diff --git a/handlers/commands/nowarns.js b/handlers/commands/nowarns.js index ccdb3cc..fd6ac77 100644 --- a/handlers/commands/nowarns.js +++ b/handlers/commands/nowarns.js @@ -8,8 +8,7 @@ const { logError } = require('../../utils/log'); const { replyOptions } = require('../../bot/options'); // DB -const { getWarns, nowarns } = require('../../stores/warn'); -const { isAdmin } = require('../../stores/user'); +const { isAdmin, getWarns, nowarns } = require('../../stores/user'); const nowarnsHandler = async ({ message, reply }) => { if (!await isAdmin(message.from)) { @@ -29,7 +28,7 @@ const nowarnsHandler = async ({ message, reply }) => { const warns = await getWarns(userToUnwarn); - if (warns.length < 1) { + if (!warns) { return reply(`ℹ️ ${link(userToUnwarn)} already has no warnings.`, replyOptions); } diff --git a/handlers/commands/unban.js b/handlers/commands/unban.js index ace409c..1eeb85f 100644 --- a/handlers/commands/unban.js +++ b/handlers/commands/unban.js @@ -9,8 +9,7 @@ const { replyOptions } = require('../../bot/options'); // DB const { listGroups } = require('../../stores/group'); -const { isBanned, unban } = require('../../stores/user'); -const { isAdmin } = require('../../stores/user'); +const { isAdmin, isBanned, unban } = require('../../stores/user'); const noop = Function.prototype; diff --git a/handlers/commands/unwarn.js b/handlers/commands/unwarn.js index cf12bed..dc5e3fc 100644 --- a/handlers/commands/unwarn.js +++ b/handlers/commands/unwarn.js @@ -7,8 +7,7 @@ const { link } = require('../../utils/tg'); const { replyOptions } = require('../../bot/options'); // DB -const Warn = require('../../stores/warn'); -const { isAdmin } = require('../../stores/user'); +const { isAdmin, getWarns, unwarn } = require('../../stores/user'); const unwarnHandler = async ({ message, reply }) => { if (!await isAdmin(message.from)) { @@ -26,12 +25,19 @@ const unwarnHandler = async ({ message, reply }) => { replyOptions); } - const allWarns = await Warn.getWarns(userToUnwarn); - const warn = await Warn.unwarn(userToUnwarn); + const allWarns = await getWarns(userToUnwarn); + + if (!allWarns) { + return reply(`ℹ️ ${link(userToUnwarn)} already has no warnings.`, + replyOptions); + } + + await unwarn(userToUnwarn); return reply( `❎ ${link(message.from)} pardoned ${link(userToUnwarn)} ` + - `for:\n\n${warn} (${allWarns.length}/3)`, + `for:\n\n${allWarns[allWarns.length - 1]}` + + `(${allWarns.length}/3)`, replyOptions); }; diff --git a/handlers/commands/warn.js b/handlers/commands/warn.js index ea6cf18..1cea32e 100644 --- a/handlers/commands/warn.js +++ b/handlers/commands/warn.js @@ -13,9 +13,7 @@ const bot = require('../../bot'); const { replyOptions } = require('../../bot/options'); // DB -const { warn } = require('../../stores/warn'); -const { ban } = require('../../stores/user'); -const { isAdmin } = require('../../stores/user'); +const { isAdmin, ban, getWarns, warn } = require('../../stores/user'); const warnHandler = async ({ message, chat, reply }) => { if (!await isAdmin(message.from)) { @@ -43,7 +41,8 @@ const warnHandler = async ({ message, chat, reply }) => { return reply('ℹ️ Can\'t warn other admins.', replyOptions); } - const warnCount = await warn(userToWarn, reason); + await warn(userToWarn, reason); + const warnCount = await getWarns(userToWarn); const promises = [ bot.telegram.deleteMessage(chat.id, message.message_id) ]; @@ -54,10 +53,10 @@ const warnHandler = async ({ message, chat, reply }) => { message.reply_to_message.message_id)); } - if (warnCount < numberOfWarnsToBan) { + if (warnCount.length < numberOfWarnsToBan) { promises.push(reply( `⚠️ ${link(message.from)} warned ${link(userToWarn)} ` + - `for:\n\n ${reason} (${warnCount}/3)`, + `for:\n\n ${reason} (${warnCount.length}/3)`, replyOptions)); } else { promises.push(bot.telegram.kickChatMember(chat.id, userToWarn.id)); @@ -65,7 +64,7 @@ const warnHandler = async ({ message, chat, reply }) => { promises.push(reply( `🚫 ${link(message.from)} banned ${link(userToWarn)} ` + 'for:\n\nReached max number of warnings ' + - `(${warnCount}/3)\n\n`, + `(${warnCount.length}/3)\n\n`, replyOptions)); } diff --git a/handlers/middlewares/addUser.js b/handlers/middlewares/addUser.js new file mode 100644 index 0000000..11704da --- /dev/null +++ b/handlers/middlewares/addUser.js @@ -0,0 +1,33 @@ +'use strict'; + +// Utils +const { logError } = require('../../utils/log'); + +// DB +const { addUser, isUser } = require('../../stores/user'); + +const addUserHandler = async ({ message }, next) => { + const usersToAdd = []; + if (message.from && !await isUser(message.from)) { + usersToAdd.push(message.from); + } + if ( + message.reply_to_message && + message.reply_to_message.from && + !await isUser(message.reply_to_message.from) + ) { + usersToAdd.push(message.reply_to_message.from); + } + + usersToAdd.forEach(async user => { + try { + await addUser(user); + } catch (err) { + logError(process.env.DEBUG)(err); + } + }); + + return next(); +}; + +module.exports = addUserHandler; diff --git a/handlers/middlewares/middleware.js b/handlers/middlewares/middleware.js index 776de06..abde9da 100644 --- a/handlers/middlewares/middleware.js +++ b/handlers/middlewares/middleware.js @@ -9,18 +9,10 @@ const bot = require('../../bot'); const { replyOptions } = require('../../bot/options'); // DB -const { addUser, isUser } = require('../../stores/user'); const { isBanned } = require('../../stores/user'); const middlewareHandler = async ({ chat, from, message, reply }, next) => { process.env.DEBUG === 'true' && message && print(message); - if (message && message.from && !await isUser(message.from)) { - try { - await addUser(message.from); - } catch (err) { - logError(process.env.DEBUG)(err); - } - } if ( message && message.text && diff --git a/handlers/middlewares/removeLinks.js b/handlers/middlewares/removeLinks.js index 118ef61..1552d21 100644 --- a/handlers/middlewares/removeLinks.js +++ b/handlers/middlewares/removeLinks.js @@ -17,9 +17,7 @@ const bot = require('../../bot'); const { replyOptions } = require('../../bot/options'); // DB -const { warn } = require('../../stores/warn'); -const { ban } = require('../../stores/user'); -const { isAdmin } = require('../../stores/user'); +const { isAdmin, ban, warn } = require('../../stores/user'); const { listGroups } = require('../../stores/group'); const removeLinks = async ({ message, chat, reply }, next) => { diff --git a/index.js b/index.js index 5bf20a7..e95a1f6 100644 --- a/index.js +++ b/index.js @@ -15,6 +15,7 @@ bot.telegram.getMe().then((botInfo) => { // Middleware Handlers const leaveUnmanagedHandler = require('./handlers/middlewares/leaveUnmanaged'); const middlewareHandler = require('./handlers/middlewares/middleware'); +const addUserHandler = require('./handlers/middlewares/addUser'); const removeLinksHandler = require('./handlers/middlewares/removeLinks'); const checkUsernameHandler = require('./handlers/middlewares/checkUsername'); const antibotHandler = require('./handlers/middlewares/antibot'); @@ -36,6 +37,7 @@ const groupsHandler = require('./handlers/commands/groups'); bot.on('new_chat_members', addedToGroupHandler); bot.use(leaveUnmanagedHandler); bot.use(middlewareHandler); +bot.on('message', addUserHandler); bot.on('message', removeLinksHandler); bot.on('message', checkUsernameHandler); bot.on('new_chat_members', antibotHandler); diff --git a/stores/user.js b/stores/user.js index 3d2798b..c7f63c9 100644 --- a/stores/user.js +++ b/stores/user.js @@ -32,11 +32,10 @@ const isUser = ({ id }) => const getUser = user => User.findOne(user); -const admin = ({ id, first_name = '', last_name = '', username = '' }) => +const admin = ({ id }) => User.update( { id }, - { first_name, id, last_name, status: 'admin', username, warns: [] }) - .catch(logError(process.env.DEBUG)); + { $set: { status: 'admin' } }); const getAdmins = () => User.find({ status: 'admin' }); @@ -47,24 +46,30 @@ const unadmin = ({ id }) => const isAdmin = ({ id }) => User.findOne({ id, status: 'admin' }); -const ban = (userToBan, banReason) => { - const { id, first_name = '', last_name = '', username = '' } = userToBan; - const userObj = { first_name, id, last_name, username, warns: [] }; - return User.findOne({ id }) - .then(user => user - ? User.update({ id }, { $set: { banReason, status: 'banned' } }) - : User.update( - { id }, - Object.assign({}, userObj, { banReason, status: 'banned' }), - { upsert: true })); -}; +const ban = ({ id }, ban_reason) => + User.update({ id }, { $set: { ban_reason, status: 'banned', warns: [] } }); const unban = ({ id }) => User.update({ id }, { $set: { banReason: '', status: 'member' } }); const isBanned = ({ id }) => User.findOne({ id, status: 'banned' }) - .then(user => user ? user.banReason : null); + .then(user => user ? user.ban_reason : null); + +const warn = ({ id }, reason) => + User.update({ id }, { $push: { warns: reason } }); + +const unwarn = ({ id }) => + User.update({ id }, { $pop: { warns: 1 } }); + +const nowarns = ({ id }) => + User.update({ id }, { $set: { warns: [] } }); + +const getWarns = ({ id }) => + User.findOne({ id }) + .then(user => user && user.warns.length > 0 + ? user.warns + : null); module.exports = { addUser, @@ -72,9 +77,13 @@ module.exports = { ban, getAdmins, getUser, + getWarns, isAdmin, isBanned, isUser, + nowarns, unadmin, - unban + unban, + unwarn, + warn };