Moved everything to /src
This commit is contained in:
parent
dec0390280
commit
1072b641c8
29 changed files with 10 additions and 2 deletions
64
src/commands/admin.js
Normal file
64
src/commands/admin.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
const Config = require('../props/config.json');
|
||||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
|
||||
async function collectInfo(ctx) {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const chatId = ctx.chat.id || Strings.unKnown;
|
||||
const adminId = ctx.from.id || Strings.unKnown;
|
||||
const userId = parseInt(ctx.message.text.split(' ')[1], 10);
|
||||
const admins = await ctx.telegram.getChatAdministrators(chatId);
|
||||
const isAdmin = admins.some(admin => admin.user.id === adminId);
|
||||
const onCrew = Config.admins.includes(adminId);
|
||||
|
||||
return { Strings, chatId, userId, isAdmin, onCrew };
|
||||
}
|
||||
|
||||
async function handleMember(ctx, action, successMessage, errorMessage) {
|
||||
const { Strings, chatId, userId, isAdmin, onCrew } = await collectInfo(ctx);
|
||||
|
||||
if (onCrew || isAdmin) {
|
||||
if (isNaN(userId)) {
|
||||
return ctx.reply(Strings.invalidId, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
try {
|
||||
await action(chatId, userId);
|
||||
const report = successMessage.replace('{userId}', userId);
|
||||
ctx.reply(report, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} catch (err) {
|
||||
const error = errorMessage.replace('{tgErr}', err.message);
|
||||
ctx.reply(error, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
} else {
|
||||
ctx.reply(Strings.noPermission, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command('ban', spamwatchMiddleware, (ctx) => {
|
||||
handleMember(ctx, (chatId, userId) => ctx.telegram.kickChatMember(chatId, userId),
|
||||
getStrings(ctx.from.language_code).banSuccess,
|
||||
getStrings(ctx.from.language_code).banErr
|
||||
);
|
||||
});
|
||||
|
||||
bot.command('unban', spamwatchMiddleware, (ctx) => {
|
||||
handleMember(ctx, (chatId, userId) => ctx.telegram.unbanChatMember(chatId, userId),
|
||||
getStrings(ctx.from.language_code).unBanSuccess,
|
||||
getStrings(ctx.from.language_code).unBanErr
|
||||
);
|
||||
});
|
||||
};
|
67
src/commands/cat.js
Normal file
67
src/commands/cat.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
const axios = require('axios');
|
||||
|
||||
module.exports = (bot) => {
|
||||
// bot.command("cat", spamwatchMiddleware, async (ctx) => {
|
||||
// const Strings = getStrings(ctx.from.language_code);
|
||||
// const userInput = ctx.message.text.split(' ').slice(1).join(' ').replace(/\s+/g, '');
|
||||
// let request = "";
|
||||
|
||||
// if (userInput && userInput.includes("gif")) {
|
||||
// request = `/gif${userInput.replace("gif", "")}`;
|
||||
// const apiUrl = `https://cataas.com/cat${request}`;
|
||||
|
||||
// try {
|
||||
// await ctx.replyWithAnimation(apiUrl, {
|
||||
// caption: `🐱`,
|
||||
// parse_mode: 'Markdown',
|
||||
// reply_to_message_id: ctx.message.message_id
|
||||
// });
|
||||
// } catch (error) {
|
||||
// ctx.reply(Strings.catGifErr, {
|
||||
// parse_mode: 'Markdown',
|
||||
// reply_to_message_id: ctx.message.message_id
|
||||
// });
|
||||
// };
|
||||
// } else {
|
||||
// request = userInput ? `/${userInput}` : '';
|
||||
// const apiUrl = `https://cataas.com/cat${request}`;
|
||||
|
||||
// try {
|
||||
// await ctx.replyWithPhoto(apiUrl, {
|
||||
// caption: `🐱`,
|
||||
// parse_mode: 'Markdown',
|
||||
// reply_to_message_id: ctx.message.message_id
|
||||
// });
|
||||
// } catch (error) {
|
||||
// ctx.reply(Strings.catImgErr, {
|
||||
// parse_mode: 'Markdown',
|
||||
// reply_to_message_id: ctx.message.message_id
|
||||
// });
|
||||
// };
|
||||
// };
|
||||
// });
|
||||
|
||||
bot.command("cat", spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const apiUrl = "https://cataas.com/cat?json=true";
|
||||
const response = await axios.get(apiUrl);
|
||||
const data = response.data;
|
||||
const imageUrl = `https://cataas.com/cat/${data._id}`;
|
||||
|
||||
try {
|
||||
await ctx.replyWithPhoto(imageUrl, {
|
||||
caption: `🐱`,
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} catch (error) {
|
||||
ctx.reply(Strings.catImgErr, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
223
src/commands/crew.js
Normal file
223
src/commands/crew.js
Normal file
|
@ -0,0 +1,223 @@
|
|||
const Config = require('../props/config.json');
|
||||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
const os = require('os');
|
||||
const { exec } = require('child_process');
|
||||
const { error } = require('console');
|
||||
|
||||
function getGitCommitHash() {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec('git rev-parse --short HEAD', (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(`Error: ${stderr}`);
|
||||
} else {
|
||||
resolve(stdout.trim());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function updateBot() {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec('git pull && echo "A" >> restart.txt', (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(`Error: ${stderr}`);
|
||||
} else {
|
||||
resolve(stdout.trim());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function formatUptime(uptime) {
|
||||
const hours = Math.floor(uptime / 3600);
|
||||
const minutes = Math.floor((uptime % 3600) / 60);
|
||||
const seconds = Math.floor(uptime % 60);
|
||||
return `${hours}h ${minutes}m ${seconds}s`;
|
||||
}
|
||||
|
||||
function getSystemInfo() {
|
||||
const { platform, release, arch, cpus, totalmem, freemem, loadavg, uptime } = os;
|
||||
const [cpu] = cpus();
|
||||
return `*Server Stats*\n\n` +
|
||||
`*OS:* \`${platform()} ${release()}\`\n` +
|
||||
`*Arch:* \`${arch()}\`\n` +
|
||||
`*Node.js Version:* \`${process.version}\`\n` +
|
||||
`*CPU:* \`${cpu.model}\`\n` +
|
||||
`*CPU Cores:* \`${cpus().length} cores\`\n` +
|
||||
`*RAM:* \`${(freemem() / (1024 ** 3)).toFixed(2)} GB / ${(totalmem() / (1024 ** 3)).toFixed(2)} GB\`\n` +
|
||||
`*Load Average:* \`${loadavg().map(avg => avg.toFixed(2)).join(', ')}\`\n` +
|
||||
`*Uptime:* \`${formatUptime(uptime())}\`\n\n`;
|
||||
}
|
||||
|
||||
async function handleAdminCommand(ctx, action, successMessage, errorMessage) {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const userId = ctx.from.id;
|
||||
if (Config.admins.includes(userId)) {
|
||||
try {
|
||||
await action();
|
||||
ctx.reply(successMessage, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} catch (error) {
|
||||
ctx.reply(errorMessage.replace('{error}', error.message), {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
} else {
|
||||
ctx.reply(Strings.botAdminOnly, {
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command('getbotstats', spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
handleAdminCommand(ctx, async () => {
|
||||
const stats = getSystemInfo();
|
||||
await ctx.reply(stats, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}, '', Strings.errorRetrievingStats);
|
||||
});
|
||||
|
||||
bot.command('getbotcommit', spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
handleAdminCommand(ctx, async () => {
|
||||
try {
|
||||
const commitHash = await getGitCommitHash();
|
||||
await ctx.reply(Strings.currentCommit.replace('{commitHash}', commitHash), {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} catch (error) {
|
||||
ctx.reply(Strings.errorRetrievingCommit.replace('{error}', error), {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
}, '', Strings.errorRetrievingCommit);
|
||||
});
|
||||
|
||||
bot.command('updatebot', spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
handleAdminCommand(ctx, async () => {
|
||||
try {
|
||||
const result = await updateBot();
|
||||
await ctx.reply(Strings.botUpdated.replace('{result}', result), {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} catch (error) {
|
||||
ctx.reply(Strings.errorUpdatingBot.replace('{error}', error), {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
}, '', Strings.errorUpdatingBot);
|
||||
});
|
||||
|
||||
bot.command('setbotname', spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const botName = ctx.message.text.split(' ').slice(1).join(' ');
|
||||
handleAdminCommand(ctx, async () => {
|
||||
await ctx.telegram.setMyName(botName);
|
||||
}, Strings.botNameChanged.replace('{botName}', botName), Strings.botNameErr.replace('{error}', error));
|
||||
});
|
||||
|
||||
bot.command('setbotdesc', spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const botDesc = ctx.message.text.split(' ').slice(1).join(' ');
|
||||
handleAdminCommand(ctx, async () => {
|
||||
await ctx.telegram.setMyDescription(botDesc);
|
||||
}, Strings.botDescChanged.replace('{botDesc}', botDesc), Strings.botDescErr.replace('{error}', error));
|
||||
});
|
||||
|
||||
bot.command('botkickme', spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
handleAdminCommand(ctx, async () => {
|
||||
ctx.reply(Strings.kickingMyself, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
await ctx.telegram.leaveChat(ctx.chat.id);
|
||||
}, '', Strings.kickingMyselfErr);
|
||||
});
|
||||
|
||||
bot.command('getfile', spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const botFile = ctx.message.text.split(' ').slice(1).join(' ');
|
||||
handleAdminCommand(ctx, async () => {
|
||||
try {
|
||||
await ctx.replyWithDocument({
|
||||
source: botFile,
|
||||
caption: botFile
|
||||
});
|
||||
} catch (error) {
|
||||
ctx.reply(Strings.fileError.replace('{error}', error.message), {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
}, '', Strings.fileError);
|
||||
});
|
||||
|
||||
bot.command('run', spamwatchMiddleware, async (ctx) => {
|
||||
const command = ctx.message.text.split(' ').slice(1).join(' ');
|
||||
handleAdminCommand(ctx, async () => {
|
||||
if (!command) {
|
||||
return ctx.reply('Por favor, forneça um comando para executar.');
|
||||
}
|
||||
|
||||
exec(command, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
return ctx.reply(`\`${error.message}\``, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
if (stderr) {
|
||||
return ctx.reply(`\`${stderr}\``, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
ctx.reply(`\`${stdout}\``, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
});
|
||||
}, '', "Nope!");
|
||||
});
|
||||
|
||||
bot.command('eval', spamwatchMiddleware, async (ctx) => {
|
||||
const code = ctx.message.text.split(' ').slice(1).join(' ');
|
||||
if (!code) {
|
||||
return ctx.reply('Por favor, forneça um código para avaliar.');
|
||||
}
|
||||
|
||||
try {
|
||||
const result = eval(code);
|
||||
ctx.reply(`Result: ${result}`, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} catch (error) {
|
||||
ctx.reply(`Error: ${error.message}`, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
bot.command('crash', spamwatchMiddleware, async (ctx) => {
|
||||
handleAdminCommand(ctx, async () => {
|
||||
ctx.reply(null);
|
||||
}, '', "Nope!");
|
||||
});
|
||||
};
|
26
src/commands/dog.js
Normal file
26
src/commands/dog.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
const axios = require('axios');
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command("dog", spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const apiUrl = "https://dog.ceo/api/breeds/image/random";
|
||||
const response = await axios.get(apiUrl);
|
||||
const data = response.data;
|
||||
|
||||
try {
|
||||
await ctx.replyWithPhoto(data.message, {
|
||||
caption: `🐶`,
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} catch (error) {
|
||||
ctx.reply(Strings.dogImgErr, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
139
src/commands/fun.js
Normal file
139
src/commands/fun.js
Normal file
|
@ -0,0 +1,139 @@
|
|||
const resources = require('../props/resources.json');
|
||||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
|
||||
function sendRandomReply(ctx, gifUrl, textKey, notTextKey) {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const shouldSendGif = Math.random() < 0.5;
|
||||
|
||||
if (shouldSendGif) {
|
||||
ctx.replyWithAnimation(gifUrl, {
|
||||
caption: Strings[textKey],
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
}).catch(err => {
|
||||
gifErr = gifErr.replace('{err}', err);
|
||||
|
||||
ctx.reply(Strings.gifErr, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
});
|
||||
} else {
|
||||
ctx.reply(Strings[notTextKey], {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function handleDiceCommand(ctx, emoji, delay) {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
|
||||
const result = await ctx.sendDice({ emoji, reply_to_message_id: ctx.message.message_id });
|
||||
const botResponse = Strings.funEmojiResult
|
||||
.replace('{emoji}', result.dice.emoji)
|
||||
.replace('{value}', result.dice.value);
|
||||
|
||||
setTimeout(() => {
|
||||
ctx.reply(botResponse, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}, delay);
|
||||
}
|
||||
|
||||
function getRandomInt(max) {
|
||||
return Math.floor(Math.random() * max);
|
||||
}
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command('random', spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const randomValue = getRandomInt(11);
|
||||
const randomVStr = Strings.randomNum.replace('{number}', randomValue);
|
||||
|
||||
ctx.reply(
|
||||
randomVStr, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
});
|
||||
|
||||
bot.command('dice', spamwatchMiddleware, async (ctx) => {
|
||||
await handleDiceCommand(ctx, undefined, 4000);
|
||||
});
|
||||
|
||||
bot.command('slot', spamwatchMiddleware, async (ctx) => {
|
||||
await handleDiceCommand(ctx, '🎰', 3000);
|
||||
});
|
||||
|
||||
bot.command('ball', spamwatchMiddleware, async (ctx) => {
|
||||
await handleDiceCommand(ctx, '⚽', 3000);
|
||||
});
|
||||
|
||||
bot.command('dart', spamwatchMiddleware, async (ctx) => {
|
||||
await handleDiceCommand(ctx, '🎯', 3000);
|
||||
});
|
||||
|
||||
bot.command('bowling', spamwatchMiddleware, async (ctx) => {
|
||||
await handleDiceCommand(ctx, '🎳', 3000);
|
||||
});
|
||||
|
||||
bot.command('idice', spamwatchMiddleware, async (ctx) => {
|
||||
ctx.replyWithSticker(
|
||||
resources.infiniteDice, {
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
});
|
||||
|
||||
bot.command('furry', spamwatchMiddleware, async (ctx) => {
|
||||
sendRandomReply(ctx, resources.furryGif, 'isFurry', 'isNtFurry');
|
||||
});
|
||||
|
||||
bot.command('gay', spamwatchMiddleware, async (ctx) => {
|
||||
sendRandomReply(ctx, resources.gayFlag, 'isGay', 'isNtGay');
|
||||
});
|
||||
|
||||
bot.command('soggy', spamwatchMiddleware, async (ctx) => {
|
||||
const userInput = ctx.message.text.split(' ')[1];
|
||||
|
||||
switch (true) {
|
||||
case (userInput === "2" || userInput === "thumb"):
|
||||
ctx.replyWithPhoto(
|
||||
resources.soggyCat2, {
|
||||
caption: resources.soggyCat2,
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
break;
|
||||
|
||||
case (userInput === "3" || userInput === "sticker"):
|
||||
ctx.replyWithSticker(
|
||||
resources.soggyCatSticker, {
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
break;
|
||||
|
||||
case (userInput === "4" || userInput === "alt"):
|
||||
ctx.replyWithPhoto(
|
||||
resources.soggyCatAlt, {
|
||||
caption: resources.soggyCatAlt,
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
ctx.replyWithPhoto(
|
||||
resources.soggyCat, {
|
||||
caption: resources.soggyCat,
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
break;
|
||||
};
|
||||
});
|
||||
};
|
245
src/commands/gsmarena.js
Normal file
245
src/commands/gsmarena.js
Normal file
|
@ -0,0 +1,245 @@
|
|||
// Ported and improved from Hitalo's PyKorone bot
|
||||
// Copyright (c) 2024 Hitalo M. (https://github.com/HitaloM)
|
||||
// Original code license: BSD-3-Clause
|
||||
// With some help from GPT (I don't really like AI but whatever)
|
||||
// If this were a kang, I would not be giving credits to him!
|
||||
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
|
||||
const axios = require('axios');
|
||||
const { parse } = require('node-html-parser');
|
||||
|
||||
class PhoneSearchResult {
|
||||
constructor(name, url) {
|
||||
this.name = name;
|
||||
this.url = url;
|
||||
Object.freeze(this);
|
||||
}
|
||||
}
|
||||
|
||||
const HEADERS = {
|
||||
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
||||
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
|
||||
};
|
||||
|
||||
function getDataFromSpecs(specsData, category, attributes) {
|
||||
const details = specsData?.specs?.[category] || {};
|
||||
|
||||
return attributes
|
||||
.map(attr => details[attr] || null)
|
||||
.filter(Boolean)
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
function parseSpecs(specsData) {
|
||||
const categories = {
|
||||
"status": ["Launch", ["Status"]],
|
||||
"network": ["Network", ["Technology"]],
|
||||
"system": ["Platform", ["OS"]],
|
||||
"models": ["Misc", ["Models"]],
|
||||
"weight": ["Body", ["Weight"]],
|
||||
"jack": ["Sound", ["3.5mm jack"]],
|
||||
"usb": ["Comms", ["USB"]],
|
||||
"sensors": ["Features", ["Sensors"]],
|
||||
"battery": ["Battery", ["Type"]],
|
||||
"charging": ["Battery", ["Charging"]],
|
||||
"display_type": ["Display", ["Type"]],
|
||||
"display_size": ["Display", ["Size"]],
|
||||
"display_resolution": ["Display", ["Resolution"]],
|
||||
"platform_chipset": ["Platform", ["Chipset"]],
|
||||
"platform_cpu": ["Platform", ["CPU"]],
|
||||
"platform_gpu": ["Platform", ["GPU"]],
|
||||
"memory": ["Memory", ["Internal"]],
|
||||
"main_camera_single": ["Main Camera", ["Single"]],
|
||||
"main_camera_dual": ["Main Camera", ["Dual"]],
|
||||
"main_camera_triple": ["Main Camera", ["Triple"]],
|
||||
"main_camera_quad": ["Main Camera", ["Quad"]],
|
||||
"main_camera_features": ["Main Camera", ["Features"]],
|
||||
"main_camera_video": ["Main Camera", ["Video"]],
|
||||
"selfie_camera_single": ["Selfie Camera", ["Single"]],
|
||||
"selfie_camera_dual": ["Selfie Camera", ["Dual"]],
|
||||
"selfie_camera_triple": ["Selfie Camera", ["Triple"]],
|
||||
"selfie_camera_quad": ["Selfie Camera", ["Quad"]],
|
||||
"selfie_camera_features": ["Selfie Camera", ["Features"]],
|
||||
"selfie_camera_video": ["Selfie Camera", ["Video"]]
|
||||
};
|
||||
|
||||
const parsedData = Object.keys(categories).reduce((acc, key) => {
|
||||
const [cat, attrs] = categories[key];
|
||||
acc[key] = getDataFromSpecs(specsData, cat, attrs) || "";
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
parsedData["name"] = specsData.name || "";
|
||||
parsedData["url"] = specsData.url || "";
|
||||
|
||||
return parsedData;
|
||||
}
|
||||
|
||||
function formatPhone(phone) {
|
||||
const formattedPhone = parseSpecs(phone);
|
||||
const attributesDict = {
|
||||
"Status": "status",
|
||||
"Network": "network",
|
||||
"OS": "system",
|
||||
"Models": "models",
|
||||
"Weight": "weight",
|
||||
"3.5mm jack": "jack",
|
||||
"USB": "usb",
|
||||
"Sensors": "sensors",
|
||||
"Battery": "battery",
|
||||
"Charging": "charging",
|
||||
"Display Type": "display_type",
|
||||
"Display Size": "display_size",
|
||||
"Display Resolution": "display_resolution",
|
||||
"Chipset": "platform_chipset",
|
||||
"CPU": "platform_cpu",
|
||||
"GPU": "platform_gpu",
|
||||
"Memory": "memory",
|
||||
"Rear Camera (Single)": "main_camera_single",
|
||||
"Rear Camera (Dual)": "main_camera_dual",
|
||||
"Rear Camera (Triple)": "main_camera_triple",
|
||||
"Rear Camera (Quad)": "main_camera_quad",
|
||||
"Rear Camera (Features)": "main_camera_features",
|
||||
"Rear Camera (Video)": "main_camera_video",
|
||||
"Front Camera (Single)": "selfie_camera_single",
|
||||
"Front Camera (Dual)": "selfie_camera_dual",
|
||||
"Front Camera (Triple)": "selfie_camera_triple",
|
||||
"Front Camera (Quad)": "selfie_camera_quad",
|
||||
"Front Camera (Features)": "selfie_camera_features",
|
||||
"Front Camera (Video)": "selfie_camera_video"
|
||||
};
|
||||
|
||||
const attributes = Object.entries(attributesDict)
|
||||
.filter(([_, key]) => formattedPhone[key])
|
||||
.map(([label, key]) => `<b>${label}:</b> <code>${formattedPhone[key]}</code>`)
|
||||
.join("\n\n");
|
||||
|
||||
const deviceUrl = `<b>GSMArena page:</b> ${formattedPhone.url}`;
|
||||
const deviceImage = phone.picture ? `<b>Device Image</b>: ${phone.picture}` : '';
|
||||
|
||||
return `<b>\n\nName: </b><code>${formattedPhone.name}</code>\n\n${attributes}\n\n${deviceImage}\n\n${deviceUrl}`;
|
||||
}
|
||||
|
||||
async function fetchHtml(url) {
|
||||
try {
|
||||
const response = await axios.get(url, { headers: HEADERS });
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error("Error fetching HTML:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function searchPhone(phone) {
|
||||
try {
|
||||
const searchUrl = `https://m.gsmarena.com/results.php3?sQuickSearch=yes&sName=${encodeURIComponent(phone)}`;
|
||||
const htmlContent = await fetchHtml(searchUrl);
|
||||
const root = parse(htmlContent);
|
||||
const foundPhones = root.querySelectorAll('.general-menu.material-card ul li');
|
||||
|
||||
return foundPhones.map((phoneTag) => {
|
||||
const name = phoneTag.querySelector('img')?.getAttribute('title') || "";
|
||||
const url = phoneTag.querySelector('a')?.getAttribute('href') || "";
|
||||
return new PhoneSearchResult(name, url);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error searching for phone:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function checkPhoneDetails(url) {
|
||||
try {
|
||||
const htmlContent = await fetchHtml(`https://www.gsmarena.com/${url}`);
|
||||
const root = parse(htmlContent);
|
||||
const specsTables = root.querySelectorAll('table[cellspacing="0"]');
|
||||
const specsData = extractSpecs(specsTables);
|
||||
const metaScripts = root.querySelectorAll('script[language="javascript"]');
|
||||
const meta = metaScripts.length ? metaScripts[0].text.split("\n") : [];
|
||||
const name = extractMetaData(meta, "ITEM_NAME");
|
||||
const picture = extractMetaData(meta, "ITEM_IMAGE");
|
||||
|
||||
return { ...specsData, name, picture, url: `https://www.gsmarena.com/${url}` };
|
||||
} catch (error) {
|
||||
console.error("Error fetching phone details:", error);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function extractSpecs(specsTables) {
|
||||
return {
|
||||
specs: specsTables.reduce((acc, table) => {
|
||||
const feature = table.querySelector('th')?.text.trim() || "";
|
||||
table.querySelectorAll('tr').forEach((tr) => {
|
||||
const header = tr.querySelector('.ttl')?.text.trim() || "info";
|
||||
let detail = tr.querySelector('.nfo')?.text.trim() || "";
|
||||
detail = detail.replace(/\s*\n\s*/g, " / ").trim();
|
||||
if (!acc[feature]) {
|
||||
acc[feature] = {};
|
||||
}
|
||||
acc[feature][header] = acc[feature][header]
|
||||
? `${acc[feature][header]} / ${detail}`
|
||||
: detail;
|
||||
});
|
||||
return acc;
|
||||
}, {})
|
||||
};
|
||||
}
|
||||
|
||||
function extractMetaData(meta, key) {
|
||||
const line = meta.find((line) => line.includes(key));
|
||||
return line ? line.split('"')[1] : "";
|
||||
}
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command(['d', 'device'], spamwatchMiddleware, async (ctx) => {
|
||||
const userId = ctx.from.id;
|
||||
const userName = ctx.from.first_name;
|
||||
|
||||
const phone = ctx.message.text.split(" ").slice(1).join(" ");
|
||||
if (!phone) {
|
||||
return ctx.reply("Please provide the phone name.", { reply_to_message_id: ctx.message.message_id });
|
||||
}
|
||||
|
||||
const results = await searchPhone(phone);
|
||||
if (results.length === 0) {
|
||||
return ctx.reply("No phones found.", { reply_to_message_id: ctx.message.message_id });
|
||||
}
|
||||
|
||||
const testUser = `<a href="tg://user?id=${userId}">${userName}</a>, Select a device:`;
|
||||
const options = {
|
||||
parse_mode: 'HTML',
|
||||
disable_web_page_preview: true,
|
||||
reply_markup: {
|
||||
inline_keyboard: results.map(result => [{ text: result.name, callback_data: `details:${result.url}:${ctx.from.id}` }])
|
||||
}
|
||||
};
|
||||
ctx.reply(testUser, options);
|
||||
|
||||
});
|
||||
|
||||
bot.action(/details:(.+):(.+)/, async (ctx) => {
|
||||
const url = ctx.match[1];
|
||||
const userId = parseInt(ctx.match[2]);
|
||||
const userName = ctx.from.first_name;
|
||||
|
||||
const callbackQueryUserId = ctx.update.callback_query.from.id;
|
||||
|
||||
if (userId !== callbackQueryUserId) {
|
||||
return ctx.answerCbQuery(`${userName}, you are not allowed to interact with this.`);
|
||||
}
|
||||
|
||||
ctx.answerCbQuery();
|
||||
|
||||
const phoneDetails = await checkPhoneDetails(url);
|
||||
|
||||
if (phoneDetails.name) {
|
||||
const message = formatPhone(phoneDetails);
|
||||
ctx.editMessageText(`<b><a href="tg://user?id=${userId}">${userName}</a>, there are the details of your device:</b>` + message, { parse_mode: 'HTML', disable_web_page_preview: false });
|
||||
} else {
|
||||
ctx.reply("Error fetching phone details.", { reply_to_message_id: ctx.message.message_id });
|
||||
}
|
||||
});
|
||||
};
|
86
src/commands/help.js
Normal file
86
src/commands/help.js
Normal file
|
@ -0,0 +1,86 @@
|
|||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
|
||||
async function sendHelpMessage(ctx, isEditing) {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const options = {
|
||||
parse_mode: 'Markdown',
|
||||
reply_markup: {
|
||||
inline_keyboard: [
|
||||
[{ text: Strings.mainCommands, callback_data: 'helpMain' }, { text: Strings.usefulCommands, callback_data: 'helpUseful' }],
|
||||
[{ text: Strings.interactiveEmojis, callback_data: 'helpInteractive' }, { text: Strings.funnyCommands, callback_data: 'helpFunny' }],
|
||||
[{ text: Strings.lastFm, callback_data: 'helpLast' }, { text: Strings.animalCommands, callback_data: 'helpAnimals' }],
|
||||
[{ text: Strings.ytDlp, callback_data: 'helpYouTube' }, { text: Strings.myLittlePony, callback_data: 'helpMLP' }]
|
||||
]
|
||||
}
|
||||
};
|
||||
const helpText = Strings.lynxHelp;
|
||||
if (isEditing) {
|
||||
await ctx.editMessageText(helpText, options);
|
||||
} else {
|
||||
await ctx.reply(helpText, options);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.help(spamwatchMiddleware, async (ctx) => {
|
||||
await sendHelpMessage(ctx);
|
||||
});
|
||||
|
||||
bot.on('callback_query', async (ctx) => {
|
||||
const callbackData = ctx.callbackQuery.data;
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const options = {
|
||||
parse_mode: 'Markdown',
|
||||
disable_web_page_preview: true,
|
||||
reply_markup: JSON.stringify({
|
||||
inline_keyboard: [
|
||||
[{ text: Strings.goBack, callback_data: 'helpBack' }],
|
||||
]
|
||||
})
|
||||
};
|
||||
|
||||
switch (callbackData) {
|
||||
case 'helpMain':
|
||||
await ctx.answerCbQuery();
|
||||
await ctx.editMessageText(Strings.mainCommandsDesc, options);
|
||||
break;
|
||||
case 'helpUseful':
|
||||
await ctx.answerCbQuery();
|
||||
await ctx.editMessageText(Strings.usefulCommandsDesc, options);
|
||||
break;
|
||||
case 'helpInteractive':
|
||||
await ctx.answerCbQuery();
|
||||
await ctx.editMessageText(Strings.interactiveEmojisDesc, options);
|
||||
break;
|
||||
case 'helpFunny':
|
||||
await ctx.answerCbQuery();
|
||||
await ctx.editMessageText(Strings.funnyCommandsDesc, options);
|
||||
break;
|
||||
case 'helpLast':
|
||||
await ctx.answerCbQuery();
|
||||
await ctx.editMessageText(Strings.lastFmDesc, options);
|
||||
break;
|
||||
case 'helpYouTube':
|
||||
await ctx.answerCbQuery();
|
||||
await ctx.editMessageText(Strings.ytDlpDesc, options);
|
||||
break;
|
||||
case 'helpAnimals':
|
||||
await ctx.answerCbQuery();
|
||||
await ctx.editMessageText(Strings.animalCommandsDesc, options);
|
||||
break;
|
||||
case 'helpMLP':
|
||||
await ctx.answerCbQuery();
|
||||
await ctx.editMessageText(Strings.myLittlePonyDesc, options);
|
||||
break;
|
||||
case 'helpBack':
|
||||
await ctx.answerCbQuery();
|
||||
await sendHelpMessage(ctx, true);
|
||||
break;
|
||||
default:
|
||||
await ctx.answerCbQuery(Strings.invalidOption);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
75
src/commands/http.js
Normal file
75
src/commands/http.js
Normal file
|
@ -0,0 +1,75 @@
|
|||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
const axios = require('axios');
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command("http", spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const userInput = ctx.message.text.split(' ')[1];
|
||||
const apiUrl = "https://status.js.org/codes.json";
|
||||
|
||||
if (!userInput || isNaN(userInput)) {
|
||||
return ctx.reply(Strings.httpCodeInvalid, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await axios.get(apiUrl);
|
||||
const data = response.data;
|
||||
const codesArray = Array.isArray(data) ? data : Object.values(data);
|
||||
const codeInfo = codesArray.find(item => item.code === parseInt(userInput));
|
||||
|
||||
if (codeInfo) {
|
||||
const message = Strings.httpCodeResult
|
||||
.replace("{code}", codeInfo.code)
|
||||
.replace("{message}", codeInfo.message)
|
||||
.replace("{description}", codeInfo.description);
|
||||
await ctx.reply(message, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} else {
|
||||
await ctx.reply(Strings.httpCodeNotFound, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
} catch (error) {
|
||||
const message = Strings.httpCodeErr.replace("{error}", error);
|
||||
ctx.reply(message, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
bot.command("httpcat", spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const userInput = ctx.message.text.split(' ').slice(1).join(' ').replace(/\s+/g, '');
|
||||
|
||||
if (!userInput || isNaN(userInput)) {
|
||||
return ctx.reply(Strings.catImgErr, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
|
||||
const apiUrl = `https://http.cat/${userInput}`;
|
||||
|
||||
try {
|
||||
await ctx.replyWithPhoto(apiUrl, {
|
||||
caption: `🐱 ${apiUrl}`,
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} catch (error) {
|
||||
ctx.reply(Strings.catImgErr, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
63
src/commands/info.js
Normal file
63
src/commands/info.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
|
||||
async function getUserInfo(ctx) {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
let lastName = ctx.from.last_name;
|
||||
if (lastName === undefined) {
|
||||
lastName = " ";
|
||||
}
|
||||
|
||||
userInfo = Strings.userInfo
|
||||
.replace('{userName}', `${ctx.from.first_name} ${lastName}` || Strings.unKnown)
|
||||
.replace('{userId}', ctx.from.id || Strings.unKnown)
|
||||
.replace('{userHandle}', ctx.from.username ? `@${ctx.from.username}` : Strings.varNone)
|
||||
.replace('{userPremium}', ctx.from.is_premium ? Strings.varYes : Strings.varNo)
|
||||
.replace('{userLang}', ctx.from.language_code || Strings.unKnown);
|
||||
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
async function getChatInfo(ctx) {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
if (ctx.chat.type === 'group' || ctx.chat.type === 'supergroup') {
|
||||
chatInfo = Strings.chatInfo
|
||||
.replace('{chatId}', ctx.chat.id || Strings.unKnown)
|
||||
.replace('{chatName}', ctx.chat.title || Strings.unKnown)
|
||||
.replace('{chatHandle}', ctx.chat.username ? `@${ctx.chat.username}` : Strings.varNone)
|
||||
.replace('{chatMembersCount}', await ctx.getChatMembersCount(ctx.chat.id || Strings.unKnown))
|
||||
.replace('{chatType}', ctx.chat.type || Strings.unKnown)
|
||||
.replace('{isForum}', ctx.chat.is_forum ? Strings.varYes : Strings.varNo);
|
||||
|
||||
return chatInfo;
|
||||
} else {
|
||||
return ctx.reply(
|
||||
Strings.groupOnly, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command('chatinfo', spamwatchMiddleware, async (ctx) => {
|
||||
const chatInfo = await getChatInfo(ctx);
|
||||
ctx.reply(
|
||||
chatInfo, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
bot.command('userinfo', spamwatchMiddleware, async (ctx) => {
|
||||
const userInfo = await getUserInfo(ctx);
|
||||
ctx.reply(
|
||||
userInfo, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id,
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
182
src/commands/lastfm.js
Normal file
182
src/commands/lastfm.js
Normal file
|
@ -0,0 +1,182 @@
|
|||
const fs = require('fs');
|
||||
const axios = require('axios');
|
||||
const Config = require('../props/config.json');
|
||||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
|
||||
const scrobbler_url = 'http://ws.audioscrobbler.com/2.0/';
|
||||
const api_key = Config.lastKey;
|
||||
|
||||
const dbFile = 'props/lastfm.json';
|
||||
let users = {};
|
||||
|
||||
function loadUsers() {
|
||||
if (!fs.existsSync(dbFile)) {
|
||||
console.log(`WARN: Last.fm user database ${dbFile} not found. Creating a new one.`);
|
||||
saveUsers();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const data = fs.readFileSync(dbFile, 'utf-8');
|
||||
users = JSON.parse(data);
|
||||
} catch (err) {
|
||||
console.log("WARN: Error loading the Last.fm user database:", err);
|
||||
users = {};
|
||||
}
|
||||
}
|
||||
|
||||
function saveUsers() {
|
||||
try {
|
||||
fs.writeFileSync(dbFile, JSON.stringify(users, null, 2), 'utf-8');
|
||||
} catch (err) {
|
||||
console.error("WARN: Error saving Last.fm users:", err);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (bot) => {
|
||||
loadUsers();
|
||||
|
||||
bot.command('setuser', (ctx) => {
|
||||
const userId = ctx.from.id;
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const lastUser = ctx.message.text.split(' ')[1];
|
||||
|
||||
if (!lastUser) {
|
||||
return ctx.reply(Strings.lastFmNoUser, {
|
||||
parse_mode: "Markdown",
|
||||
disable_web_page_preview: true,
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
|
||||
users[userId] = lastUser;
|
||||
saveUsers();
|
||||
|
||||
const message = Strings.lastFmUserSet.replace('{lastUser}', lastUser);
|
||||
|
||||
ctx.reply(message, {
|
||||
parse_mode: "Markdown",
|
||||
disable_web_page_preview: true,
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
});
|
||||
|
||||
bot.command(['lt', 'lmu', 'last', 'lfm'], spamwatchMiddleware, async (ctx) => {
|
||||
const userId = ctx.from.id;
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const lastfmUser = users[userId];
|
||||
|
||||
if (!lastfmUser) {
|
||||
return ctx.reply(Strings.lastFmNoSet, {
|
||||
parse_mode: "Markdown",
|
||||
disable_web_page_preview: true,
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await axios.get(scrobbler_url, {
|
||||
params: {
|
||||
method: 'user.getRecentTracks',
|
||||
user: lastfmUser,
|
||||
api_key,
|
||||
format: 'json',
|
||||
limit: 1
|
||||
},
|
||||
headers: {
|
||||
'User-Agent': "lynx-@LynxBR_bot-node-telegram-bot"
|
||||
}
|
||||
});
|
||||
|
||||
const track = response.data.recenttracks.track[0];
|
||||
|
||||
if (!track) {
|
||||
const noRecent = Strings.lastFmNoRecent.replace('{lastfmUser}', lastfmUser);
|
||||
return ctx.reply(noRecent, {
|
||||
parse_mode: "Markdown",
|
||||
disable_web_page_preview: true,
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
|
||||
const trackName = track.name;
|
||||
const artistName = track.artist['#text'];
|
||||
const nowPlaying = track['@attr'] && track['@attr'].nowplaying ? Strings.lastFmListeningNow : Strings.lastFmLastPlayed;
|
||||
|
||||
|
||||
const imageExtralarge = track.image.find(img => img.size === 'extralarge');
|
||||
const imageMega = track.image.find(img => img.size === 'mega');
|
||||
const imageUrl = (imageExtralarge && imageExtralarge['#text']) || (imageMega && imageMega['#text']) || '';
|
||||
|
||||
const trackUrl = `https://www.last.fm/music/${encodeURIComponent(artistName)}/_/${encodeURIComponent(trackName)}`;
|
||||
const artistUrl = `https://www.last.fm/music/${encodeURIComponent(artistName)}`;
|
||||
const userUrl = `https://www.last.fm/user/${encodeURIComponent(lastfmUser)}`;
|
||||
|
||||
let num_plays = '';
|
||||
try {
|
||||
const response_plays = await axios.get(scrobbler_url, {
|
||||
params: {
|
||||
method: 'track.getInfo',
|
||||
api_key,
|
||||
track: trackName,
|
||||
artist: artistName,
|
||||
username: lastfmUser,
|
||||
format: 'json',
|
||||
},
|
||||
headers: {
|
||||
'User-Agent': "lynx-@LynxBR_bot-node-telegram-bot"
|
||||
}
|
||||
});
|
||||
num_plays = response_plays.data.track.userplaycount;
|
||||
|
||||
if (!num_plays || num_plays === undefined) {
|
||||
num_plays = 0;
|
||||
};
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
const message = Strings.lastFmErr
|
||||
.replace("{lastfmUser}", `[${lastfmUser}](${userUrl})`)
|
||||
.replace("{err}", err);
|
||||
ctx.reply(message, {
|
||||
parse_mode: "Markdown",
|
||||
disable_web_page_preview: true,
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
|
||||
const message = Strings.lastFmStatusFor
|
||||
.replace("{lastfmUser}", `[${lastfmUser}](${userUrl})`)
|
||||
.replace("{nowPlaying}", nowPlaying)
|
||||
.replace("{trackName}", `[${trackName}](${trackUrl})`)
|
||||
.replace("{artistName}", `[${artistName}](${artistUrl})`)
|
||||
.replace("{plays}", `${num_plays}`);
|
||||
|
||||
if (imageUrl) {
|
||||
ctx.replyWithPhoto(imageUrl, {
|
||||
caption: message,
|
||||
parse_mode: "Markdown",
|
||||
disable_web_page_preview: true,
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} else {
|
||||
ctx.reply(message, {
|
||||
parse_mode: "Markdown",
|
||||
disable_web_page_preview: true,
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
} catch (err) {
|
||||
const userUrl = `https://www.last.fm/user/${encodeURIComponent(lastfmUser)}`;
|
||||
const message = Strings.lastFmErr
|
||||
.replace("{lastfmUser}", `[${lastfmUser}](${userUrl})`)
|
||||
.replace("{err}", err);
|
||||
ctx.reply(message, {
|
||||
parse_mode: "Markdown",
|
||||
disable_web_page_preview: true,
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
26
src/commands/main.js
Normal file
26
src/commands/main.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
const resources = require('../props/resources.json');
|
||||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.start(spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
ctx.replyWithPhoto(
|
||||
resources.lunaCat, {
|
||||
caption: Strings.lynxWelcome,
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
});
|
||||
|
||||
bot.command('privacy', spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
ctx.reply(
|
||||
Strings.lynxPrivacy, {
|
||||
parse_mode: 'Markdown',
|
||||
disable_web_page_preview: true,
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
});
|
||||
};
|
73
src/commands/modarchive.js
Normal file
73
src/commands/modarchive.js
Normal file
|
@ -0,0 +1,73 @@
|
|||
const axios = require('axios');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
|
||||
async function downloadModule(moduleId) {
|
||||
try {
|
||||
const downloadUrl = `https://api.modarchive.org/downloads.php?moduleid=${moduleId}`;
|
||||
const response = await axios({
|
||||
url: downloadUrl,
|
||||
method: 'GET',
|
||||
responseType: 'stream',
|
||||
});
|
||||
|
||||
const disposition = response.headers['content-disposition'];
|
||||
let fileName = moduleId;
|
||||
|
||||
if (disposition && disposition.includes('filename=')) {
|
||||
fileName = disposition
|
||||
.split('filename=')[1]
|
||||
.split(';')[0]
|
||||
.replace(/['"]/g, '');
|
||||
}
|
||||
|
||||
const filePath = path.resolve(__dirname, fileName);
|
||||
|
||||
const writer = fs.createWriteStream(filePath);
|
||||
response.data.pipe(writer);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
writer.on('finish', () => resolve({ filePath, fileName }));
|
||||
writer.on('error', reject);
|
||||
});
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command(['modarchive', 'tma'], spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const args = ctx.message.text.split(' ');
|
||||
|
||||
if (args.length !== 2) {
|
||||
return ctx.reply(Strings.maInvalidModule, {
|
||||
parse_mode: "Markdown",
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
|
||||
const moduleId = args[1];
|
||||
|
||||
const result = await downloadModule(moduleId);
|
||||
|
||||
if (result) {
|
||||
const { filePath, fileName } = result;
|
||||
|
||||
await ctx.replyWithDocument({
|
||||
source: filePath,
|
||||
caption: fileName,
|
||||
});
|
||||
|
||||
fs.unlinkSync(filePath);
|
||||
} else {
|
||||
ctx.reply(Strings.maDownloadError, {
|
||||
parse_mode: "Markdown",
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
165
src/commands/ponyapi.js
Normal file
165
src/commands/ponyapi.js
Normal file
|
@ -0,0 +1,165 @@
|
|||
const { spawn } = require('child_process');
|
||||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
const axios = require("axios");
|
||||
|
||||
function capitalizeFirstLetter(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command("mlp", spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
|
||||
ctx.reply(Strings.myLittlePonyDesc, {
|
||||
parse_mode: 'Markdown',
|
||||
disable_web_page_preview: true,
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
});
|
||||
|
||||
bot.command("mlpchar", spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const userInput = ctx.message.text.split(' ').slice(1).join(' ');
|
||||
|
||||
if (!userInput) {
|
||||
ctx.reply(Strings.ponyApiNoCharName, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
return;
|
||||
};
|
||||
|
||||
const capitalizedInput = capitalizeFirstLetter(userInput);
|
||||
const apiUrl = `http://ponyapi.net/v1/character/${capitalizedInput}`;
|
||||
|
||||
try {
|
||||
const response = await axios(apiUrl);
|
||||
const charactersArray = [];
|
||||
|
||||
if (Array.isArray(response.data.data)) {
|
||||
response.data.data.forEach(character => {
|
||||
let aliases = [];
|
||||
if (character.alias) {
|
||||
if (typeof character.alias === 'string') {
|
||||
aliases.push(character.alias);
|
||||
} else if (Array.isArray(character.alias)) {
|
||||
aliases = aliases.concat(character.alias);
|
||||
}
|
||||
}
|
||||
|
||||
charactersArray.push({
|
||||
name: character.name,
|
||||
alias: aliases.length > 0 ? aliases.join(', ') : 'N/A',
|
||||
url: character.url,
|
||||
sex: character.sex,
|
||||
residence: character.residence ? character.residence.replace(/\n/g, ' / ') : 'N/A',
|
||||
occupation: character.occupation ? character.occupation.replace(/\n/g, ' / ') : 'N/A',
|
||||
kind: character.kind ? character.kind.join(', ') : 'N/A',
|
||||
image: character.image
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (charactersArray.length > 0) {
|
||||
const result = Strings.ponyApiCharRes
|
||||
.replace("{input}", userInput)
|
||||
.replace("{name}", charactersArray[0].name)
|
||||
.replace("{alias}", charactersArray[0].alias)
|
||||
.replace("{url}", charactersArray[0].url)
|
||||
.replace("{sex}", charactersArray[0].sex)
|
||||
.replace("{residence}", charactersArray[0].residence)
|
||||
.replace("{occupation}", charactersArray[0].occupation)
|
||||
.replace("{kind}", charactersArray[0].kind);
|
||||
|
||||
ctx.replyWithPhoto(charactersArray[0].image[0], {
|
||||
caption: `${result}`,
|
||||
parse_mode: 'Markdown',
|
||||
disable_web_page_preview: true,
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} else {
|
||||
ctx.reply(Strings.ponyApiNoCharFound, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
ctx.reply(Strings.ponyApiErr, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
bot.command("mlpep", spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
const userInput = ctx.message.text.split(' ').slice(1).join(' ');
|
||||
|
||||
if (!userInput) {
|
||||
ctx.reply(Strings.ponyApiNoEpisodeNum, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
return;
|
||||
};
|
||||
|
||||
const apiUrl = `http://ponyapi.net/v1/episode/by-overall/${userInput}`;
|
||||
|
||||
try {
|
||||
const response = await axios(apiUrl);
|
||||
const episodeArray = [];
|
||||
|
||||
if (Array.isArray(response.data.data)) {
|
||||
response.data.data.forEach(episode => {
|
||||
episodeArray.push({
|
||||
name: episode.name,
|
||||
image: episode.image,
|
||||
url: episode.url,
|
||||
season: episode.season,
|
||||
episode: episode.episode,
|
||||
overall: episode.overall,
|
||||
airdate: episode.airdate,
|
||||
storyby: episode.storyby ? episode.storyby.replace(/\n/g, ' / ') : 'N/A',
|
||||
writtenby: episode.writtenby ? episode.writtenby.replace(/\n/g, ' / ') : 'N/A',
|
||||
storyboard: episode.storyboard ? episode.storyboard.replace(/\n/g, ' / ') : 'N/A',
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (episodeArray.length > 0) {
|
||||
const result = Strings.ponyApiEpRes
|
||||
.replace("{input}", userInput)
|
||||
.replace("{name}", episodeArray[0].name)
|
||||
.replace("{url}", episodeArray[0].url)
|
||||
.replace("{season}", episodeArray[0].season)
|
||||
.replace("{episode}", episodeArray[0].episode)
|
||||
.replace("{overall}", episodeArray[0].overall)
|
||||
.replace("{airdate}", episodeArray[0].airdate)
|
||||
.replace("{storyby}", episodeArray[0].storyby)
|
||||
.replace("{writtenby}", episodeArray[0].writtenby)
|
||||
.replace("{storyboard}", episodeArray[0].storyboard);
|
||||
|
||||
ctx.replyWithPhoto(episodeArray[0].image, {
|
||||
caption: `${result}`,
|
||||
parse_mode: 'Markdown',
|
||||
disable_web_page_preview: true,
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} else {
|
||||
ctx.reply(Strings.ponyApiNoEpisodeFound, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
ctx.reply(Strings.ponyApiErr, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
29
src/commands/quotes.js
Normal file
29
src/commands/quotes.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
const axios = require('axios');
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command("quote", spamwatchMiddleware, async (ctx) => {
|
||||
const Strings = getStrings(ctx.from.language_code);
|
||||
|
||||
try {
|
||||
const response = await axios.get('https://quotes-api-self.vercel.app/quote');
|
||||
const data = response.data;
|
||||
const escapedQuote = data.quote.replace(/([\\_*~`>.!-])/g, '\\$1');
|
||||
const escapedAuthor = `- ${data.author}.`.replace(/([\\_*~`>.!-])/g, '\\$1');
|
||||
const escapedData = `${Strings.quoteResult}\n>*${escapedQuote}*\n_${escapedAuthor}_`;
|
||||
|
||||
ctx.reply(escapedData, {
|
||||
reply_to_message_id: ctx.message.message_id,
|
||||
parse_mode: 'MarkdownV2'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
ctx.reply(Strings.quoteErr, {
|
||||
reply_to_message_id: ctx.message.id,
|
||||
parse_mode: 'MarkdownV2'
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
111
src/commands/weather.js
Normal file
111
src/commands/weather.js
Normal file
|
@ -0,0 +1,111 @@
|
|||
// Ported and improved from BubbalooTeam's PyCoala bot
|
||||
// Copyright (c) 2024 BubbalooTeam. (https://github.com/BubbalooTeam)
|
||||
// Minor code changes by lucmsilva (https://github.com/lucmsilva651)
|
||||
|
||||
const axios = require('axios');
|
||||
const Config = require('../props/config.json');
|
||||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
|
||||
const statusEmojis = {
|
||||
0: '⛈', 1: '⛈', 2: '⛈', 3: '⛈', 4: '⛈', 5: '🌨', 6: '🌨', 7: '🌨',
|
||||
8: '🌨', 9: '🌨', 10: '🌨', 11: '🌧', 12: '🌧', 13: '🌨', 14: '🌨',
|
||||
15: '🌨', 16: '🌨', 17: '⛈', 18: '🌧', 19: '🌫', 20: '🌫', 21: '🌫',
|
||||
22: '🌫', 23: '🌬', 24: '🌬', 25: '🌨', 26: '☁️', 27: '🌥', 28: '🌥',
|
||||
29: '⛅️', 30: '⛅️', 31: '🌙', 32: '☀️', 33: '🌤', 34: '🌤', 35: '⛈',
|
||||
36: '🔥', 37: '🌩', 38: '🌩', 39: '🌧', 40: '🌧', 41: '❄️', 42: '❄️',
|
||||
43: '❄️', 44: 'n/a', 45: '🌧', 46: '🌨', 47: '🌩'
|
||||
};
|
||||
|
||||
const getStatusEmoji = (statusCode) => statusEmojis[statusCode] || 'n/a';
|
||||
|
||||
function getLocaleUnit(userLang) {
|
||||
const fahrenheitCountries = ['US', 'BS', 'BZ', 'KY', 'LR'];
|
||||
const languagePrefix = userLang.split('-')[0];
|
||||
const countryCode = userLang.split('-')[1];
|
||||
|
||||
if (languagePrefix === 'en' || (countryCode && fahrenheitCountries.includes(countryCode))) {
|
||||
return { temperatureUnit: 'F', speedUnit: 'mph', apiUnit: 'e' };
|
||||
} else {
|
||||
return { temperatureUnit: 'C', speedUnit: 'km/h', apiUnit: 'm' };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command(['clima', 'weather'], spamwatchMiddleware, async (ctx) => {
|
||||
const userLang = ctx.from.language_code || "en-US";
|
||||
const Strings = getStrings(userLang);
|
||||
const args = ctx.message.text;
|
||||
|
||||
if (args.length < 9) {
|
||||
return ctx.reply(Strings.provideLocation, {
|
||||
parse_mode: "Markdown",
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
|
||||
const location = args.slice(9);
|
||||
const apiKey = Config.weatherKey;
|
||||
|
||||
try {
|
||||
const locationResponse = await axios.get('https://api.weather.com/v3/location/search', {
|
||||
params: {
|
||||
apiKey: apiKey,
|
||||
format: 'json',
|
||||
language: userLang,
|
||||
query: location,
|
||||
},
|
||||
});
|
||||
|
||||
const locationData = locationResponse.data.location;
|
||||
if (!locationData || !locationData.address) {
|
||||
return ctx.reply(Strings.invalidLocation, {
|
||||
parse_mode: "Markdown",
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
|
||||
const addressFirst = locationData.address[0];
|
||||
const latFirst = locationData.latitude[0];
|
||||
const lonFirst = locationData.longitude[0];
|
||||
const { temperatureUnit, speedUnit, apiUnit } = getLocaleUnit(userLang);
|
||||
|
||||
const weatherResponse = await axios.get('https://api.weather.com/v3/aggcommon/v3-wx-observations-current', {
|
||||
params: {
|
||||
apiKey: apiKey,
|
||||
format: 'json',
|
||||
language: userLang,
|
||||
geocode: `${latFirst},${lonFirst}`,
|
||||
units: apiUnit,
|
||||
},
|
||||
});
|
||||
|
||||
const weatherData = weatherResponse.data['v3-wx-observations-current'];
|
||||
const { temperature, temperatureFeelsLike, relativeHumidity, windSpeed, iconCode, wxPhraseLong } = weatherData;
|
||||
|
||||
const weatherMessage = Strings.weatherStatus
|
||||
.replace('{addressFirst}', addressFirst)
|
||||
.replace('{getStatusEmoji(iconCode)}', getStatusEmoji(iconCode))
|
||||
.replace('{wxPhraseLong}', wxPhraseLong)
|
||||
.replace('{temperature}', temperature)
|
||||
.replace('{temperatureFeelsLike}', temperatureFeelsLike)
|
||||
.replace('{temperatureUnit}', temperatureUnit)
|
||||
.replace('{temperatureUnit2}', temperatureUnit)
|
||||
.replace('{relativeHumidity}', relativeHumidity)
|
||||
.replace('{windSpeed}', windSpeed)
|
||||
.replace('{speedUnit}', speedUnit);
|
||||
|
||||
ctx.reply(weatherMessage, {
|
||||
parse_mode: "Markdown",
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
} catch (error) {
|
||||
const message = Strings.weatherErr.replace('{error}', error.message);
|
||||
ctx.reply(message, {
|
||||
parse_mode: "Markdown",
|
||||
reply_to_message_id: ctx.message.message_id
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
36
src/commands/wiki.js
Normal file
36
src/commands/wiki.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
const axios = require("axios");
|
||||
|
||||
function capitalizeFirstLetter(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
function mediaWikiToMarkdown(input) {
|
||||
input = input.replace(/===(.*?)===/g, '*$1*');
|
||||
input = input.replace(/==(.*?)==/g, '*$1*');
|
||||
input = input.replace(/=(.*?)=/g, '*$1*');
|
||||
input = input.replace(/'''(.*?)'''/g, '**$1**');
|
||||
input = input.replace(/''(.*?)''/g, '_$1_');
|
||||
input = input.replace(/^\*\s/gm, '- ');
|
||||
input = input.replace(/^\#\s/gm, '1. ');
|
||||
input = input.replace(/{{Quote(.*?)}}/g, "```\n$1```\n");
|
||||
input = input.replace(/\[\[(.*?)\|?(.*?)\]\]/g, (_, link, text) => {
|
||||
const sanitizedLink = link.replace(/ /g, '_');
|
||||
return text ? `[${text}](${sanitizedLink})` : `[${sanitizedLink}](${sanitizedLink})`;
|
||||
});
|
||||
input = input.replace(/\[\[File:(.*?)\|.*?\]\]/g, '');
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command("wiki", async (ctx) => {
|
||||
const userInput = capitalizeFirstLetter(ctx.message.text.split(' ')[1]);
|
||||
const apiUrl = `https://en.wikipedia.org/w/index.php?title=${userInput}&action=raw`;
|
||||
const response = await axios(apiUrl, { headers: { 'Accept': "text/plain" } });
|
||||
const convertedResponse = response.data.replace(/<\/?div>/g, "").replace(/{{Infobox.*?}}/s, "");
|
||||
|
||||
const result = mediaWikiToMarkdown(convertedResponse).slice(0, 2048);
|
||||
|
||||
ctx.reply(result, { parse_mode: 'Markdown', disable_web_page_preview: true, reply_to_message_id: ctx.message.message_id });
|
||||
});
|
||||
};
|
169
src/commands/youtube.js
Normal file
169
src/commands/youtube.js
Normal file
|
@ -0,0 +1,169 @@
|
|||
const { getStrings } = require('../plugins/checklang.js');
|
||||
const { isOnSpamWatch } = require('../plugins/lib-spamwatch/spamwatch.js');
|
||||
const spamwatchMiddleware = require('../plugins/lib-spamwatch/Middleware.js')(isOnSpamWatch);
|
||||
const { execFile } = require('child_process');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const ytDlpPaths = {
|
||||
linux: path.resolve(__dirname, '../plugins/yt-dlp/yt-dlp'),
|
||||
win32: path.resolve(__dirname, '../plugins/yt-dlp/yt-dlp.exe'),
|
||||
darwin: path.resolve(__dirname, '../plugins/yt-dlp/yt-dlp_macos'),
|
||||
};
|
||||
|
||||
const getYtDlpPath = () => {
|
||||
const platform = os.platform();
|
||||
return ytDlpPaths[platform] || ytDlpPaths.linux;
|
||||
};
|
||||
|
||||
|
||||
const ffmpegPaths = {
|
||||
linux: '/usr/bin/ffmpeg',
|
||||
win32: path.resolve(__dirname, '../plugins/ffmpeg/bin/ffmpeg.exe'),
|
||||
};
|
||||
|
||||
const getFfmpegPath = () => {
|
||||
const platform = os.platform();
|
||||
return ffmpegPaths[platform] || ffmpegPaths.linux;
|
||||
};
|
||||
|
||||
const downloadFromYoutube = async (command, args) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
execFile(command, args, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject({ error, stdout, stderr });
|
||||
} else {
|
||||
resolve({ stdout, stderr });
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const getApproxSize = async (command, videoUrl) => {
|
||||
const args = [videoUrl, '--compat-opt', 'manifest-filesize-approx', '-O', 'filesize_approx'];
|
||||
try {
|
||||
const { stdout } = await downloadFromYoutube(command, args);
|
||||
const sizeInBytes = parseInt(stdout.trim(), 10);
|
||||
if (!isNaN(sizeInBytes)) {
|
||||
return sizeInBytes / (1024 * 1024);
|
||||
} else {
|
||||
throw new Error('Invalid size received from yt-dlp');
|
||||
}
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = (bot) => {
|
||||
bot.command(['yt', 'ytdl'], spamwatchMiddleware, async (ctx) => {
|
||||
const strings = getStrings(ctx.from.language_code);
|
||||
const ytDlpPath = getYtDlpPath();
|
||||
const userId = ctx.from.id;
|
||||
const videoUrl = ctx.message.text.split(' ').slice(1).join(' ');
|
||||
|
||||
const mp4File = `tmp/${userId}.mp4`;
|
||||
const tempMp4File = `tmp/${userId}.f137.mp4`;
|
||||
const tempWebmFile = `tmp/${userId}.f251.webm`;
|
||||
const cmdArgs = "--max-filesize 2G --no-playlist --cookies props/cookies.txt --merge-output-format mp4 -o";
|
||||
const dlpCommand = ytDlpPath;
|
||||
const ffmpegPath = getFfmpegPath();
|
||||
const ffmpegArgs = ['-i', tempMp4File, '-i', tempWebmFile, '-c:v copy -c:a copy -strict -2', mp4File];
|
||||
|
||||
try {
|
||||
const downloadingMessage = await ctx.reply(strings.ytCheckingSize, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id,
|
||||
});
|
||||
|
||||
if (fs.existsSync(ytDlpPath)) {
|
||||
const approxSizeInMB = await Promise.race([
|
||||
getApproxSize(ytDlpPath, videoUrl)
|
||||
]);
|
||||
|
||||
await ctx.telegram.editMessageText(
|
||||
ctx.chat.id,
|
||||
downloadingMessage.message_id,
|
||||
null,
|
||||
strings.ytDownloading, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id,
|
||||
},
|
||||
);
|
||||
|
||||
const dlpArgs = [videoUrl, ...cmdArgs.split(' '), mp4File];
|
||||
await downloadFromYoutube(dlpCommand, dlpArgs);
|
||||
|
||||
await ctx.telegram.editMessageText(
|
||||
ctx.chat.id,
|
||||
downloadingMessage.message_id,
|
||||
null,
|
||||
strings.ytUploading, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id,
|
||||
},
|
||||
);
|
||||
|
||||
if(fs.existsSync(tempMp4File)){
|
||||
await downloadFromYoutube(ffmpegPath, ffmpegArgs);
|
||||
}
|
||||
|
||||
if (fs.existsSync(mp4File)) {
|
||||
const message = strings.ytUploadDesc
|
||||
.replace("{userId}", userId)
|
||||
.replace("{userName}", ctx.from.first_name);
|
||||
|
||||
try {
|
||||
await ctx.replyWithVideo({
|
||||
source: mp4File,
|
||||
caption: `${message}`,
|
||||
parse_mode: 'Markdown',
|
||||
});
|
||||
|
||||
if (approxSizeInMB >= 50) {
|
||||
await ctx.telegram.editMessageText(
|
||||
ctx.chat.id,
|
||||
downloadingMessage.message_id,
|
||||
null,
|
||||
strings.ytUploadLimit2, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fs.unlinkSync(mp4File);
|
||||
} catch (error) {
|
||||
await ctx.reply(`\`${error.message}\``, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id,
|
||||
});
|
||||
|
||||
fs.unlinkSync(mp4File);
|
||||
}
|
||||
} else {
|
||||
await ctx.reply(mp4File, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
await ctx.telegram.editMessageText(
|
||||
ctx.chat.id,
|
||||
downloadingMessage.message_id,
|
||||
null,
|
||||
strings.ytFileErr, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id,
|
||||
},
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
await ctx.reply(`\`${error.message}\``, {
|
||||
parse_mode: 'Markdown',
|
||||
reply_to_message_id: ctx.message.message_id,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue