2
0
mirror of https://github.com/thedevs-network/the-guard-bot synced 2025-09-03 23:55:15 +00:00

added custom commands

This commit is contained in:
Pouria Ezzati
2017-10-04 20:55:50 +03:30
parent 5fe5bd4561
commit 88a08d0d88
7 changed files with 325 additions and 2 deletions

View File

@@ -0,0 +1,24 @@
'use strict';
// DB
const { isAdmin } = require('../../stores/user');
const { addCommand } = require('../../stores/command');
// Bot
const { replyOptions } = require('../../bot/options');
const addCommandHandler = async ({ chat, message, reply }) => {
const user = message.from;
if (chat.type !== 'private') {
return null;
}
if (!await isAdmin(user)) {
return reply(' <b>Sorry, only admins access this command.</b>',
replyOptions);
}
await addCommand({ id: user.id });
return reply('Enter a name for the command.\n\nFor example: <b>rules</b>',
replyOptions);
};
module.exports = addCommandHandler;

View File

@@ -1,5 +1,8 @@
'use strict'; 'use strict';
// DB
const { listCommands } = require('../../stores/command');
const commandReference = `\ const commandReference = `\
<b>Master commands</b>: <b>Master commands</b>:
<code>/admin</code> - Makes the user admin. <code>/admin</code> - Makes the user admin.
@@ -21,11 +24,25 @@ const commandReference = `\
<code>/report</code> - Reports the replied-to message to admins. <code>/report</code> - Reports the replied-to message to admins.
`; `;
const commandReferenceHandler = ({ chat, replyWithHTML }) => { const actions = `\n
/addcommand - to create custom commands.
/removecommand <code>&lt;name&gt;</code> - to remove a custom command.`;
const commandReferenceHandler = async ({ chat, replyWithHTML }) => {
if (chat.type !== 'private') { if (chat.type !== 'private') {
return null; return null;
} }
return replyWithHTML(commandReference); const customCommands = await listCommands();
const customCommandsText = customCommands.length
? '\n<b>Custom commands:</b>\n' +
customCommands
.filter(command => command.isActive)
.sort((a, b) => a.role < b.role)
.map(command => `[${command.role}] <code>/${command.name}</code>`)
.join('\n')
: '';
return replyWithHTML(commandReference + customCommandsText + actions);
}; };
module.exports = commandReferenceHandler; module.exports = commandReferenceHandler;

View File

@@ -0,0 +1,52 @@
'use strict';
// Utils
const { loadJSON } = require('../../utils/json');
// Config
const { masterID } = loadJSON('config.json');
// DB
const { isAdmin } = require('../../stores/user');
const { getCommand, removeCommand } = require('../../stores/command');
// Bot
const { replyOptions } = require('../../bot/options');
const removeCommandHandler = async ({ chat, message, reply }) => {
const user = message.from;
const { text } = message;
if (chat.type !== 'private') {
return null;
}
if (!await isAdmin(user)) {
return reply(' <b>Sorry, only admins access this command.</b>',
replyOptions);
}
const [ , commandName ] = text.split(' ');
if (!commandName) {
return reply(
'Enter a command name to remove.\n\n' +
'For example:\n/removecommand <b>rules</b>',
replyOptions);
}
const command = await getCommand({ name: commandName });
if (!command) {
return reply(' <b>Command couldn\'t be found.</b>',
replyOptions);
}
if (command.role === 'Master' && user.id !== masterID) {
return reply(' <b>Sorry, only master can remove this command.</b>',
replyOptions);
}
await removeCommand({ name: commandName });
return reply(
`✅ <code>/${commandName}</code> ` +
'<b>has been removed successfully.</b>',
replyOptions);
};
module.exports = removeCommandHandler;

View File

@@ -0,0 +1,120 @@
'use strict';
const { Markup } = require('telegraf');
// Bot
const { replyOptions } = require('../../bot/options');
// DB
const { isAdmin } = require('../../stores/user');
const {
getCommand,
removeCommand,
updateCommand
} = require('../../stores/command');
const addCustomCmdHandler = async ({ chat, message, reply }, next) => {
const { text, photo, document, video, audio } = message;
const { id } = message.from;
if (text && /^\/\w+/.test(text)) {
await removeCommand({ id, isActive: false });
return next();
}
const command = await getCommand({ id, isActive: false });
if (chat.type !== 'private' ||
!await isAdmin(message.from) ||
!command ||
!command.state) {
return next();
}
const { state } = command;
if (state === 'add') {
if (!/^(?=\D)\w+$/.test(text)) {
reply('Please send a valid command.');
return next();
}
if (await getCommand({ isActive: true, name: text })) {
reply(
' <b>This command already exists.</b>\n\n' +
'/commands - to see the list of commands.\n' +
'/addcommand - to add a command.\n' +
'/removecommand <code>&lt;name&gt;</code>' +
' - to remove a command.',
replyOptions);
return next();
}
await updateCommand({ id, name: text, state: 'role' });
reply('Who can use this command?', Markup.keyboard([
[ 'Master', 'Admins', 'Everyone' ]
])
.oneTime()
.resize()
.extra());
return next();
}
if (state === 'role') {
if (text !== 'Master' && text !== 'Admins' && text !== 'Everyone') {
reply('Please send a valid role.', Markup.keyboard([
[ 'Master', 'Admins', 'Everyone' ]
])
.oneTime()
.resize()
.extra());
return next();
}
await updateCommand({ id, role: text, state: 'content' });
reply(
'Send the content you wish to be shown when the command is used.' +
'.\n\nSupported contents:\n- <b>Text (HTML)</b>\n- <b>Photo</b>' +
'\n- <b>Video</b>\n- <b>Document</b>\n- <b>Audio</b>',
replyOptions);
return next();
}
if (state === 'content') {
let newCommand;
if (text) {
newCommand = { content: text, type: 'text' };
}
if (photo) {
newCommand = {
content: photo[photo.length - 1].file_id,
type: 'photo'
};
}
if (document) {
newCommand = { content: document.file_id, type: 'document' };
}
if (video) {
newCommand = { content: video.file_id, type: 'video' };
}
if (audio) {
newCommand = { content: audio.file_id, type: 'audio' };
}
if (message.caption) {
newCommand.caption = message.caption;
}
await Promise.all([
updateCommand(Object.assign(
{},
newCommand,
{ id, isActive: true, state: null })),
]);
reply(
'✅ <b>New command has been created successfully.</b>\n\n' +
'This command can be used in groups now. ' +
'Custom commands can reply other messages too.\n\n' +
'/commands - to see the list of commands.\n' +
'/addcommand - to add a new command.\n' +
'/removecomand <code>&lt;name&gt;</code> - to remove a command.',
replyOptions);
return next();
}
return next();
};
module.exports = addCustomCmdHandler;

View File

@@ -0,0 +1,66 @@
'use strict';
// Utils
const { loadJSON } = require('../../utils/json');
// Config
const { masterID } = loadJSON('config.json');
// DB
const { getCommand } = require('../../stores/command');
const { isAdmin } = require('../../stores/user');
const runCustomCmdHandler = async (ctx, next) => {
const { message } = ctx;
const user = message.from;
const isCommand = message.entities &&
message.entities.filter(entity => entity.type === 'bot_command');
if (!isCommand || !isCommand.length) {
return next();
}
const commandName = message.text.split(' ')[0].replace('/', '');
const command = await getCommand({ isActive: true, name: commandName });
if (!command) {
return next();
}
const { caption, content, role, type } = command;
const replyTo = message.reply_to_message
? { reply_to_message_id: message.reply_to_message.message_id }
: {};
const options = Object.assign(replyTo, caption ? { caption } : {});
if (
role === 'Master' &&
user.id !== masterID ||
role === 'Admins' &&
!await isAdmin(user)
) {
return next();
}
if (type === 'text') {
ctx.replyWithHTML(content, options);
return next();
}
if (type === 'photo') {
ctx.replyWithPhoto(content, options);
return next();
}
if (type === 'video') {
ctx.replyWithVideo(content, replyTo);
return next();
}
if (type === 'document') {
ctx.replyWithDocument(content, replyTo);
return next();
}
if (type === 'audio') {
ctx.replyWithAudio(content, replyTo);
return next();
}
return next();
};
module.exports = runCustomCmdHandler;

View File

@@ -18,6 +18,8 @@ const kickBannedHandler = require('./handlers/middlewares/kickBanned');
const addUserHandler = require('./handlers/middlewares/addUser'); const addUserHandler = require('./handlers/middlewares/addUser');
const removeLinksHandler = require('./handlers/middlewares/removeLinks'); const removeLinksHandler = require('./handlers/middlewares/removeLinks');
const checkUsernameHandler = require('./handlers/middlewares/checkUsername'); const checkUsernameHandler = require('./handlers/middlewares/checkUsername');
const addCustomCmdHandler = require('./handlers/middlewares/addCustomCmd');
const runCustomCmdHandler = require('./handlers/middlewares/runCustomCmd');
const antibotHandler = require('./handlers/middlewares/antibot'); const antibotHandler = require('./handlers/middlewares/antibot');
const addedToGroupHandler = require('./handlers/middlewares/addedToGroup'); const addedToGroupHandler = require('./handlers/middlewares/addedToGroup');
@@ -36,6 +38,8 @@ const staffHandler = require('./handlers/commands/staff');
const linkHandler = require('./handlers/commands/link'); const linkHandler = require('./handlers/commands/link');
const groupsHandler = require('./handlers/commands/groups'); const groupsHandler = require('./handlers/commands/groups');
const commandReferenceHandler = require('./handlers/commands/commands'); const commandReferenceHandler = require('./handlers/commands/commands');
const addCommandHandler = require('./handlers/commands/addCommand');
const removeCommandHandler = require('./handlers/commands/removeCommand');
const helpHandler = require('./handlers/commands/help'); const helpHandler = require('./handlers/commands/help');
bot.on('new_chat_members', addedToGroupHandler); bot.on('new_chat_members', addedToGroupHandler);
@@ -45,6 +49,8 @@ bot.use(kickBannedHandler);
bot.on('message', addUserHandler); bot.on('message', addUserHandler);
bot.on('message', removeLinksHandler); bot.on('message', removeLinksHandler);
bot.on('message', checkUsernameHandler); bot.on('message', checkUsernameHandler);
bot.on('message', addCustomCmdHandler);
bot.on('message', runCustomCmdHandler);
bot.on('new_chat_members', antibotHandler); bot.on('new_chat_members', antibotHandler);
bot.on([ 'new_chat_members', 'left_chat_member' ], deleteAfter(2 * 60 * 1000)); bot.on([ 'new_chat_members', 'left_chat_member' ], deleteAfter(2 * 60 * 1000));
bot.command('admin', adminHandler); bot.command('admin', adminHandler);
@@ -62,6 +68,8 @@ bot.command('staff', staffHandler);
bot.command('link', linkHandler); bot.command('link', linkHandler);
bot.command('groups', groupsHandler); bot.command('groups', groupsHandler);
bot.command('commands', commandReferenceHandler); bot.command('commands', commandReferenceHandler);
bot.command('addcommand', addCommandHandler);
bot.command('removecommand', removeCommandHandler);
bot.command([ 'start', 'help' ], helpHandler); bot.command([ 'start', 'help' ], helpHandler);
bot.catch(logError); bot.catch(logError);

36
stores/command.js Normal file
View File

@@ -0,0 +1,36 @@
'use strict';
const Datastore = require('nedb-promise');
const Command = new Datastore({
autoload: true,
filename: 'data/Command.db',
});
Command.ensureIndex({
fieldName: 'name',
unique: true,
});
const addCommand = command =>
Command.update(
{ id: command.id, isActive: false },
{ id: command.id, isActive: false, state: 'add', },
{ upsert: true });
const updateCommand = (data) =>
Command.update({ id: data.id, isActive: false }, { $set: data });
const removeCommand = command => Command.remove(command);
const getCommand = (data) => Command.findOne(data);
const listCommands = () => Command.find({ isActive: true });
module.exports = {
addCommand,
getCommand,
listCommands,
removeCommand,
updateCommand,
};