Skip to content

Commit

Permalink
Merge branch 'master' of github.com:mleandrojr/mslovelace_bot
Browse files Browse the repository at this point in the history
  • Loading branch information
mleandrojr committed Apr 19, 2024
2 parents d422edf + 410cdd6 commit 75ff890
Show file tree
Hide file tree
Showing 11 changed files with 314 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ package-lock.json
!log/.gitkeep
log/*
node_modules
bun.lockb
9 changes: 9 additions & 0 deletions sql/update_2023-11-18_01.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS `macros` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`chat_id` int(10) unsigned NOT NULL,
`macro` varchar(50) NOT NULL,
`content` text NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_macro_id_chat_id` (`chat_id`),
CONSTRAINT `fk_macro_id_chat_id` FOREIGN KEY (`chat_id`) REFERENCES `chats` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
2 changes: 1 addition & 1 deletion src/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default class App {
*
* @var {number}
*/
private port: number;
private readonly port: number;

/**
* The constructor.
Expand Down
2 changes: 1 addition & 1 deletion src/command/Ban.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export default class Ban extends Command {

await ban.execute();
const message = Lang.get("bannedMessage")
.replace("{userId}", contextUser.getId())
.replace("{userid}", contextUser.getId())
.replace("{username}", contextUser.getFirstName() || contextUser.getUsername())
.replace("{reason}", reason.length ? reason : "Unknown");

Expand Down
248 changes: 248 additions & 0 deletions src/command/Macro.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
/**
* Ada Lovelace Telegram Bot
*
* This file is part of Ada Lovelace Telegram Bot.
* You are free to modify and share this project or its files.
*
* @package mslovelace_bot
* @author Marcos Leandro <mleandrojr@yggdrasill.com.br>
* @license GPLv3 <http://www.gnu.org/licenses/gpl-3.0.en.html>
*/

import Command from "./Command.js";
import Context from "../library/telegram/context/Context.js";
import CommandContext from "../library/telegram/context/Command.js";
import ChatHelper from "../helper/Chat.js";
import Chats from "../model/Chats.js";
import Macros from "../model/Macros.js";
import Lang from "../helper/Lang.js";

export default class Macro extends Command {

/**
* Current loaded chat.
*
* @author Marcos Leandro
* @since 2023-11-18
*/
private chat: Record<string, any> = {};

/**
* The constructor.
*
* @author Marcos Leandro
* @since 2023-11-18
*
* @param context
*/
public constructor(context: Context) {
super(context);
this.setCommands(["macro", "madd", "mlist", "mremove"]);
}

/**
* Executes the command.
*
* @author Marcos Leandro
* @since 2023-11-18
*
* @param command
*/
public async run(command: CommandContext): Promise<void> {

this.context.message.delete();

const chat = await ChatHelper.getByTelegramId(this.context.chat.getId());
if (!chat) {
return;
}

Lang.set(chat.language || "us");

this.chat = chat;

let action = "index";
if (Macro.prototype.hasOwnProperty(command.getCommand())) {
action = command.getCommand();
}

const method = action as keyof typeof Macro.prototype;
await this[method](command as never);
}

/**
* Shows a macro.
*
* @author Marcos Leandro
* @since 2023-11-18
*
* @param command
*/
private index(command: CommandContext): void {

const params = command.getParams();
if (!Array.isArray(params) || params.length < 1) {
return;
}

const macro = params.shift()?.trim();
if (!macro || !macro.length) {
return;
}

const macros = new Macros();
macros
.select()
.where("chat_id").equal(this.chat.id)
.and("macro").equal(macro);

macros.execute().then((result: Record<string, any>) => {

if (!result.length) {
return;
}

const content = result[0].content;
const replyToMessage = this.context.message.getReplyToMessage();
console.log(replyToMessage);

if (replyToMessage) {
replyToMessage.reply(content, { parseMode : "HTML" });
return;
}

this.context.chat.sendMessage(content, { parseMode : "HTML" });
});
}

/**
* Adds a macro.
*
* @author Marcos Leandro
* @since 2023-11-18
*
* @param command
*/
private async madd(command: CommandContext): Promise<void> {

if (!await this.context.user.isAdmin()) {
return;
}

let params = command.getParams();
if (!Array.isArray(params) || params.length < 2) {
this.context.chat.sendMessage(Lang.get("macroMalformedCommandError"), { parseMode : "HTML" });
return;
}

const macro = params.shift()?.trim();
const content = params.join(" ").trim();

if (!macro || !macro.length || !content.length) {
this.context.chat.sendMessage(Lang.get("macroMalformedCommandError"), { parseMode : "HTML" });
return;
}

const macros = new Macros();
macros
.select()
.where("chat_id").equal(this.chat.id)
.and("macro").equal(macro.toLowerCase());

const result = await macros.execute();

if (result.length) {
const alreadyExistLang = Lang.get("macroAlreadyExists").replace("{macro}", macro);
this.context.chat.sendMessage(alreadyExistLang, { parseMode : "HTML" });
return;
}

macros
.insert()
.set("chat_id", this.chat.id)
.set("macro", macro.toLowerCase())
.set("content", content);

if (await macros.execute()) {
this.mlist(command);
return;
}

this.context.chat.sendMessage(Lang.get("macroAddError"), { parseMode : "HTML" });
}

/**
* Lists the macros.
*
* @author Marcos Leandro
* @since 2023-11-18
*
* @param command
*/
private async mlist(command: CommandContext): Promise<void> {

const macros = new Macros();
macros
.select()
.where("chat_id").equal(this.chat.id)
.orderBy("macro", "asc");

const result = await macros.execute();
if (!result.length) {
this.context.chat.sendMessage(Lang.get("macroNoMacroFound"), { parseMode : "HTML" });
return;
}

let message = Lang.get("macroList");
for (const row of result) {
message += ` • ${row.macro}\n`;
}

this.context.chat.sendMessage(message, { parseMode : "HTML" });
}

/**
* Removes a macro.
*
* @author Marcos Leandro
* @since 2023-11-18
*
* @param command
*/
private async mremove(command: CommandContext): Promise<void> {

if (!await this.context.user.isAdmin()) {
return;
}

const params = command.getParams();
if (!Array.isArray(params) || params.length < 1) {
return;
}

const macro = params.shift()?.trim();
if (!macro || !macro.length) {
return;
}

const macros = new Macros();
macros
.select()
.where("chat_id").equal(this.chat.id)
.and("macro").equal(macro);

const result = await macros.execute();

if (result.length) {

macros
.delete()
.where("chat_id").equal(this.chat.id)
.and("macro").equal(macro.toLowerCase());

macros.execute();
}

this.mlist(command);
}
}
2 changes: 2 additions & 0 deletions src/config/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import FederationManage from "../command/federation/Manage.js";
import FederationUser from "../command/federation/User.js";
import Greetings from "../command/Greetings.js";
import Kick from "../command/Kick.js";
import Macro from "../command/Macro.js";
import Npm from "../command/Npm.js";
import Report from "../command/Report.js";
import Restrict from "../command/Restrict.js";
Expand All @@ -37,6 +38,7 @@ export const commands = [
FederationUser,
Greetings,
Kick,
Macro,
Npm,
Report,
Restrict,
Expand Down
15 changes: 11 additions & 4 deletions src/controller/Controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,17 @@ export default class Controller {
* @param {Record<string, any>} payload
*/
protected async handle(payload: Record<string, any>): Promise<void> {
const context = new Context(payload);
this.handleActions(context);
this.handleCommands(context);
this.handleCallbacks(context);

try {

const context = new Context(payload);
this.handleActions(context);
this.handleCommands(context);
this.handleCallbacks(context);

} catch (error: any) {
Log.save(error.toString(), true, "error");
}
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/lang/br.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,10 @@ export default {
fedBannedMessage: "<a href=\"tg://user?id={userid}\">{username}</a> banido na federação.\nMotivo: {reason}",
fedBanOnlyAdminError: "Somente administradores podem banir usuários da federação.",
fedBanAdminError: "Você não pode banir administradores da federação.",
macroNoMacroFound: "A lista de macros está vazia.\nPara adicionar uma macro, use o comando <code>/madd</code> .",
macroMalformedCommandError: "Para adicionar uma nova macro, utilize o seguinte comando:\n<code>/madd {macro} {conteúdo}</code>",
macroList: "As seguintes macros estão disponíveis:\n\n",
macroAlreadyExists: "A macro {macro} já existe.",
macroAddError: "Ocorreu um erro ao adicionar a macro. Por favor, tente novamente mais tarde.",
macroRemoveError: "Ocorreu um erro ao remover a macro. Por favor, tente novamente mais tarde.",
};
6 changes: 6 additions & 0 deletions src/lang/us.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,10 @@ export default {
fedBannedMessage: "<a href=\"tg://user?id={userid}\">{username}</a> banned in federation.\nReason: {reason}",
fedBanOnlyAdminError: "Only admins can ban users in a federation.",
fedBanAdminError: "You can't ban admins in a federation.",
macroNoMacroFound: "The list of macros is empty.\nTo add a macro, use the command <code>/madd</code> .",
macroMalformedCommandError: "Malformed command. Please use the following syntax:\n<code>/madd {name} {content}</code>",
macroList: "The following macros are available:\n\n",
macroAlreadyExists: "The macro {macro} already exists.",
macroAddError: "An error occurred while adding the macro. Please try again later.",
macroRemoveError: "An error occurred while removing the macro. Please try again later.",
};
7 changes: 4 additions & 3 deletions src/library/telegram/context/Chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ChatLocation } from "../type/ChatLocation.js";
import { ChatPermissions } from "../type/ChatPermissions.js";
import { ChatPhoto } from "../type/ChatPhoto.js";
import { Message as MessageType } from "../type/Message.js";
import Log from "../../../helper/Log.js";

export default class Chat {

Expand Down Expand Up @@ -425,9 +426,9 @@ export default class Chat {
sendMessage.setOptions(options);
}

return sendMessage
.post()
return sendMessage.post()
.then((response) => response.json())
.then((json) => new Message(json.result));
.then((json) => new Message(json.result))
.catch((error) => console.error(error));
}
}
25 changes: 25 additions & 0 deletions src/model/Macros.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Ada Lovelace Telegram Bot
*
* This file is part of Ada Lovelace Telegram Bot.
* You are free to modify and share this project or its files.
*
* @package mslovelace_bot
* @author Marcos Leandro <mleandrojr@yggdrasill.com.br>
* @license GPLv3 <http://www.gnu.org/licenses/gpl-3.0.en.html>
*/

import DefaultModel from "./Model.js";

export default class Macros extends DefaultModel {

/**
* The constructor.
*
* @author Marcos Leandro
* @since 2023-11-18
*/
public constructor() {
super("macros");
}
}

0 comments on commit 75ff890

Please sign in to comment.