rf: js -> ts

This commit is contained in:
Aidan 2025-04-24 18:49:51 -04:00
parent 33c9120361
commit efadb51905
32 changed files with 333 additions and 246 deletions

View File

@ -3,6 +3,5 @@ npm-debug.log
.git
.gitignore
.env
config.env
*.md
!README.md

5
.gitignore vendored
View File

@ -136,11 +136,12 @@ dist
lastfm.json
sw-blocklist.txt
package-lock.json
bun.lock
bun.lockb
tmp/
# Executables
*.exe
yt-dlp
ffmpeg
# Bun
bun.lock*

View File

@ -13,6 +13,6 @@ COPY . .
RUN chmod +x /usr/src/app/src/plugins/yt-dlp/yt-dlp
VOLUME /usr/src/app/config.env
VOLUME /usr/src/app/.env
CMD ["npm", "start"]

View File

@ -27,7 +27,7 @@ First, clone the repo with Git:
git clone --recurse-submodules https://github.com/ABOCN/TelegramBot
```
Next, inside the repository directory, create a `config.env` file with some content, which you can see the [example .env file](config.env.example) to fill info with. To see the meaning of each one, see [the Functions section](#configenv-functions).
Next, inside the repository directory, create an `.env` file with some content, which you can see the [example .env file](.env.example) to fill info with. To see the meaning of each one, see [the Functions section](#env-functions).
After editing the file, save all changes and run the bot with ``bun start``.
@ -48,7 +48,7 @@ You can also run Kowalski using Docker, which simplifies the setup process. Make
### Using Docker Compose
1. **Make sure to setup your `config.env` file first!**
1. **Make sure to setup your `.env` file first!**
2. **Run the container**
@ -60,7 +60,7 @@ You can also run Kowalski using Docker, which simplifies the setup process. Make
If you prefer to use Docker directly, you can use these instructions instead.
1. **Make sure to setup your `config.env` file first!**
1. **Make sure to setup your `.env` file first!**
2. **Build the image**
@ -71,13 +71,13 @@ If you prefer to use Docker directly, you can use these instructions instead.
3. **Run the container**
```bash
docker run -d --name kowalski --restart unless-stopped -v $(pwd)/config.env:/usr/src/app/config.env:ro kowalski
docker run -d --name kowalski --restart unless-stopped -v $(pwd)/.env:/usr/src/app/.env:ro kowalski
```
## config.env Functions
## .env Functions
> [!IMPORTANT]
> Take care of your ``config.env`` file, as it is so much important and needs to be secret (like your passwords), as anyone can do whatever they want to the bot with this token!
> Take care of your ``.env`` file, as it is so much important and needs to be secret (like your passwords), as anyone can do whatever they want to the bot with this token!
- **botSource**: Put the link to your bot source code.
- **botPrivacy**: Put the link to your bot privacy policy.

View File

@ -4,6 +4,6 @@ services:
container_name: kowalski
restart: unless-stopped
volumes:
- ./config.env:/usr/src/app/config.env:ro
- ./.env:/usr/src/app/.env:ro
environment:
- NODE_ENV=production

View File

@ -1,3 +1,6 @@
{
"ignore": ["src/props/*.json", "src/props/*.txt"]
"ignore": ["src/props/*.json", "src/props/*.txt"],
"watch": ["src"],
"ext": "ts,js",
"exec": "bun src/bot.ts"
}

View File

@ -4,6 +4,7 @@
},
"dependencies": {
"@dotenvx/dotenvx": "^1.28.0",
"@types/node": "^22.15.0",
"axios": "^1.7.9",
"node-html-parser": "^7.0.1",
"nodemon": "^3.1.7",

View File

@ -1,13 +1,13 @@
const { Telegraf } = require('telegraf');
const path = require('path');
const fs = require('fs');
const { isOnSpamWatch } = require('./spamwatch/spamwatch.js');
require('@dotenvx/dotenvx').config({ path: "config.env" });
require('./plugins/ytDlpWrapper.js');
import { Telegraf } from 'telegraf';
import path from 'path';
import fs from 'fs';
import { isOnSpamWatch } from './spamwatch/spamwatch';
import '@dotenvx/dotenvx';
import './plugins/ytDlpWrapper';
// Ensures bot token is set, and not default value
if (!process.env.botToken || process.env.botToken === 'InsertYourBotTokenHere') {
console.error('Bot token is not set. Please set the bot token in the config.env file.')
console.error('Bot token is not set. Please set the bot token in the .env file.')
process.exit(1)
}
@ -19,10 +19,13 @@ const loadCommands = () => {
const commandsPath = path.join(__dirname, 'commands');
try {
const files = fs.readdirSync(commandsPath);
const files = fs.readdirSync(commandsPath)
.filter(file => file.endsWith('.ts') || file.endsWith('.js'));
files.forEach((file) => {
try {
const command = require(path.join(commandsPath, file));
const commandPath = path.join(commandsPath, file);
const command = require(commandPath).default || require(commandPath);
if (typeof command === 'function') {
command(bot, isOnSpamWatch);
}
@ -43,7 +46,7 @@ const startBot = async () => {
restartCount = 0;
} catch (error) {
console.error('Failed to start bot:', error.message);
if (restartCount < maxRetries) {
if (restartCount < Number(maxRetries)) {
restartCount++;
console.log(`Retrying to start bot... Attempt ${restartCount}`);
setTimeout(startBot, 5000);

View File

@ -1,10 +1,12 @@
const Resources = require('../props/resources.json');
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
const axios = require("axios");
import Resources from '../props/resources.json';
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
import axios from 'axios';
module.exports = (bot) => {
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
export default (bot) => {
bot.command("duck", spamwatchMiddleware, async (ctx) => {
const Strings = getStrings(ctx.from.language_code);
try {

View File

@ -1,11 +1,13 @@
const Resources = require('../props/resources.json');
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
const axios = require('axios');
const { verifyInput } = require('../plugins/verifyInput.js');
import Resources from '../props/resources.json';
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
import axios from 'axios';
import verifyInput from '../plugins/verifyInput';
async function getDeviceList() {
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
async function getDeviceList({ Strings, ctx }) {
try {
const response = await axios.get(Resources.codenameApi);
return response.data
@ -20,7 +22,7 @@ async function getDeviceList() {
}
}
module.exports = (bot) => {
export default (bot) => {
bot.command(['codename', 'whatis'], spamwatchMiddleware, async (ctx) => {
const userInput = ctx.message.text.split(" ").slice(1).join(" ");
const Strings = getStrings(ctx.from.language_code);
@ -30,7 +32,7 @@ module.exports = (bot) => {
return;
}
const jsonRes = await getDeviceList()
const jsonRes = await getDeviceList({ Strings, ctx })
const phoneSearch = Object.keys(jsonRes).find((codename) => codename === userInput);
if (!phoneSearch) {

View File

@ -1,9 +1,11 @@
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
const os = require('os');
const { exec } = require('child_process');
const { error } = require('console');
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
import os from 'os';
import { exec } from 'child_process';
import { error } from 'console';
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
function getGitCommitHash() {
return new Promise((resolve, reject) => {
@ -74,7 +76,7 @@ async function handleAdminCommand(ctx, action, successMessage, errorMessage) {
}
}
module.exports = (bot) => {
export default (bot) => {
bot.command('getbotstats', spamwatchMiddleware, async (ctx) => {
const Strings = getStrings(ctx.from.language_code);
handleAdminCommand(ctx, async () => {

View File

@ -1,7 +1,9 @@
const Resources = require('../props/resources.json');
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
import Resources from '../props/resources.json';
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
function sendRandomReply(ctx, gifUrl, textKey) {
const Strings = getStrings(ctx.from.language_code);
@ -16,8 +18,8 @@ function sendRandomReply(ctx, gifUrl, textKey) {
parse_mode: 'Markdown',
reply_to_message_id: ctx.message.message_id
}).catch(err => {
gifErr = gifErr.replace('{err}', err);
ctx.reply(Strings.gifErr, {
const gifErr = Strings.gifErr.replace('{err}', err);
ctx.reply(gifErr, {
parse_mode: 'Markdown',
reply_to_message_id: ctx.message.message_id
});
@ -51,7 +53,7 @@ function getRandomInt(max) {
return Math.floor(Math.random() * (max + 1));
}
module.exports = (bot) => {
export default (bot) => {
bot.command('random', spamwatchMiddleware, async (ctx) => {
const Strings = getStrings(ctx.from.language_code);
const randomValue = getRandomInt(11);

View File

@ -4,18 +4,23 @@
// 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('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
import axios from 'axios';
import { parse } from 'node-html-parser';
const axios = require('axios');
const { parse } = require('node-html-parser');
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
class PhoneSearchResult {
constructor(name, url) {
this.name = name;
this.url = url;
Object.freeze(this);
}
interface PhoneSearchResult {
name: string;
url: string;
}
interface PhoneDetails {
specs: Record<string, Record<string, string>>;
name?: string;
url?: string;
picture?: string;
}
const HEADERS = {
@ -32,7 +37,7 @@ function getDataFromSpecs(specsData, category, attributes) {
.join("\n");
}
function parseSpecs(specsData) {
function parseSpecs(specsData: PhoneDetails): PhoneDetails {
const categories = {
"status": ["Launch", ["Status"]],
"network": ["Network", ["Technology"]],
@ -69,7 +74,7 @@ function parseSpecs(specsData) {
const [cat, attrs] = categories[key];
acc[key] = getDataFromSpecs(specsData, cat, attrs) || "";
return acc;
}, {});
}, { specs: {} } as PhoneDetails);
parsedData["name"] = specsData.name || "";
parsedData["url"] = specsData.url || "";
@ -77,7 +82,7 @@ function parseSpecs(specsData) {
return parsedData;
}
function formatPhone(phone) {
function formatPhone(phone: PhoneDetails) {
const formattedPhone = parseSpecs(phone);
const attributesDict = {
"Status": "status",
@ -132,7 +137,7 @@ async function fetchHtml(url) {
}
}
async function searchPhone(phone) {
async function searchPhone(phone: string): Promise<PhoneSearchResult[]> {
try {
const searchUrl = `https://m.gsmarena.com/results.php3?sQuickSearch=yes&sName=${encodeURIComponent(phone)}`;
const htmlContent = await fetchHtml(searchUrl);
@ -142,7 +147,7 @@ async function searchPhone(phone) {
return foundPhones.map((phoneTag) => {
const name = phoneTag.querySelector('img')?.getAttribute('title') || "";
const url = phoneTag.querySelector('a')?.getAttribute('href') || "";
return new PhoneSearchResult(name, url);
return { name, url };
});
} catch (error) {
console.error("Error searching for phone:", error);
@ -164,7 +169,7 @@ async function checkPhoneDetails(url) {
return { ...specsData, name, picture, url: `https://www.gsmarena.com/${url}` };
} catch (error) {
console.error("Error fetching phone details:", error);
return {};
return { specs: {}, name: "", url: "", picture: "" };
}
}
@ -201,7 +206,7 @@ function getUsername(ctx){
return userName;
}
module.exports = (bot) => {
export default (bot) => {
bot.command(['d', 'device'], spamwatchMiddleware, async (ctx) => {
const userId = ctx.from.id;
const userName = getUsername(ctx);

View File

@ -1,6 +1,17 @@
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
interface MessageOptions {
parse_mode: string;
disable_web_page_preview: boolean;
reply_markup: {
inline_keyboard: { text: any; callback_data: string; }[][];
};
reply_to_message_id?: number;
}
async function sendHelpMessage(ctx, isEditing) {
const Strings = getStrings(ctx.from.language_code);
@ -11,8 +22,8 @@ async function sendHelpMessage(ctx, isEditing) {
function getMessageId(ctx) {
return ctx.message?.message_id || ctx.callbackQuery?.message?.message_id;
};
const createOptions = (ctx, includeReplyTo = false) => {
const options = {
const createOptions = (ctx, includeReplyTo = false): MessageOptions => {
const options: MessageOptions = {
parse_mode: 'Markdown',
disable_web_page_preview: true,
reply_markup: {
@ -39,9 +50,9 @@ async function sendHelpMessage(ctx, isEditing) {
};
}
module.exports = (bot) => {
export default (bot) => {
bot.help(spamwatchMiddleware, async (ctx) => {
await sendHelpMessage(ctx);
await sendHelpMessage(ctx, false);
});
bot.command("about", spamwatchMiddleware, async (ctx) => {

View File

@ -1,11 +1,13 @@
const Resources = require('../props/resources.json');
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
const axios = require('axios');
const { verifyInput } = require('../plugins/verifyInput.js');
import Resources from '../props/resources.json';
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
import axios from 'axios';
import verifyInput from '../plugins/verifyInput';
module.exports = (bot) => {
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
export default (bot) => {
bot.command("http", spamwatchMiddleware, async (ctx) => {
const Strings = getStrings(ctx.from.language_code);
const userInput = ctx.message.text.split(' ')[1];

View File

@ -1,6 +1,8 @@
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
async function getUserInfo(ctx) {
const Strings = getStrings(ctx.from.language_code);
@ -9,7 +11,7 @@ async function getUserInfo(ctx) {
lastName = " ";
}
userInfo = Strings.userInfo
const userInfo = Strings.userInfo
.replace('{userName}', `${ctx.from.first_name} ${lastName}` || Strings.varStrings.varUnknown)
.replace('{userId}', ctx.from.id || Strings.varStrings.varUnknown)
.replace('{userHandle}', ctx.from.username ? `@${ctx.from.username}` : Strings.varStrings.varNone)
@ -22,7 +24,7 @@ async function getUserInfo(ctx) {
async function getChatInfo(ctx) {
const Strings = getStrings(ctx.from.language_code);
if (ctx.chat.type === 'group' || ctx.chat.type === 'supergroup') {
chatInfo = Strings.chatInfo
const chatInfo = Strings.chatInfo
.replace('{chatId}', ctx.chat.id || Strings.varStrings.varUnknown)
.replace('{chatName}', ctx.chat.title || Strings.varStrings.varUnknown)
.replace('{chatHandle}', ctx.chat.username ? `@${ctx.chat.username}` : Strings.varStrings.varNone)
@ -40,7 +42,7 @@ async function getChatInfo(ctx) {
}
}
module.exports = (bot) => {
export default (bot) => {
bot.command('chatinfo', spamwatchMiddleware, async (ctx) => {
const chatInfo = await getChatInfo(ctx);
ctx.reply(

View File

@ -1,9 +1,11 @@
const Resources = require('../props/resources.json');
const fs = require('fs');
const axios = require('axios');
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
import Resources from '../props/resources.json';
import fs from 'fs';
import axios from 'axios';
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
const scrobbler_url = Resources.lastFmApi;
const api_key = process.env.lastKey;
@ -35,7 +37,7 @@ function saveUsers() {
}
}
async function getFromMusicBrainz(mbid) {
async function getFromMusicBrainz(mbid: string) {
try {
const response = await axios.get(`${Resources.musicBrainzApi}${mbid}`);
const imgObjLarge = response.data.images[0]?.thumbnails?.['1200'];
@ -58,7 +60,7 @@ function getFromLast(track) {
return imageUrl;
}
module.exports = (bot) => {
export default (bot) => {
loadUsers();
bot.command('setuser', (ctx) => {
@ -149,7 +151,7 @@ module.exports = (bot) => {
const artistUrl = `https://www.last.fm/music/${encodeURIComponent(artistName)}`;
const userUrl = `https://www.last.fm/user/${encodeURIComponent(lastfmUser)}`;
let num_plays = '';
let num_plays = 0;
try {
const response_plays = await axios.get(scrobbler_url, {
params: {
@ -164,11 +166,8 @@ module.exports = (bot) => {
'User-Agent': `@${botInfo.username}-node-telegram-bot`
}
});
num_plays = response_plays.data.track.userplaycount;
if (!num_plays || num_plays === undefined) {
num_plays = 0;
};
num_plays = response_plays.data.track.userplaycount;
} catch (err) {
console.log(err)
const message = Strings.lastFm.apiErr

View File

@ -1,9 +1,11 @@
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
module.exports = (bot) => {
bot.start(spamwatchMiddleware, async (ctx) => {
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
export default (bot: any) => {
bot.start(spamwatchMiddleware, async (ctx: any) => {
const Strings = getStrings(ctx.from.language_code);
const botInfo = await ctx.telegram.getMe();
const startMsg = Strings.botWelcome.replace(/{botName}/g, botInfo.first_name);
@ -14,7 +16,7 @@ module.exports = (bot) => {
});
});
bot.command('privacy', spamwatchMiddleware, async (ctx) => {
bot.command('privacy', spamwatchMiddleware, async (ctx: any) => {
const Strings = getStrings(ctx.from.language_code);
const message = Strings.botPrivacy.replace("{botPrivacy}", process.env.botPrivacy);

View File

@ -1,12 +1,19 @@
const Resources = require('../props/resources.json');
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
import Resources from '../props/resources.json';
import axios from 'axios';
import fs from 'fs';
import path from 'path';
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
async function downloadModule(moduleId) {
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
interface ModuleResult {
filePath: string;
fileName: string;
}
async function downloadModule(moduleId: string): Promise<ModuleResult | null> {
try {
const downloadUrl = `${Resources.modArchiveApi}${moduleId}`;
const response = await axios({
@ -39,12 +46,12 @@ async function downloadModule(moduleId) {
}
}
module.exports = (bot) => {
export default (bot) => {
bot.command(['modarchive', 'tma'], spamwatchMiddleware, async (ctx) => {
const Strings = getStrings(ctx.from.language_code);
const moduleId = ctx.message.text.split(' ')[1];
if (moduleId == NaN || null) {
if (Number.isNaN(moduleId) || null) {
return ctx.reply(Strings.maInvalidModule, {
parse_mode: "Markdown",
reply_to_message_id: ctx.message.message_id

View File

@ -1,15 +1,56 @@
const Resources = require('../props/resources.json');
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
const axios = require("axios");
const { verifyInput } = require('../plugins/verifyInput.js');
import Resources from '../props/resources.json';
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
import axios from 'axios';
import verifyInput from '../plugins/verifyInput';
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
interface Character {
id: string;
name: string;
alias: string;
url: string;
sex: string;
residence: string;
occupation: string;
kind: string;
image: string[];
}
interface Episode {
id: string;
name: string;
image: string;
url: string;
season: string;
episode: string;
overall: string;
airdate: string;
storyby: string;
writtenby: string;
storyboard: string;
}
interface Comic {
id: string;
name: string;
series: string;
image: string;
url: string;
writer: string;
artist: string;
colorist: string;
letterer: string;
editor: string;
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
module.exports = (bot) => {
export default (bot) => {
bot.command("mlp", spamwatchMiddleware, async (ctx) => {
const Strings = getStrings(ctx.from.language_code);
@ -34,11 +75,11 @@ module.exports = (bot) => {
try {
const response = await axios(apiUrl);
const charactersArray = [];
const charactersArray: Character[] = [];
if (Array.isArray(response.data.data)) {
response.data.data.forEach(character => {
let aliases = [];
let aliases: string[] = [];
if (character.alias) {
if (typeof character.alias === 'string') {
aliases.push(character.alias);
@ -107,7 +148,7 @@ module.exports = (bot) => {
try {
const response = await axios(apiUrl);
const episodeArray = [];
const episodeArray: Episode[] = [];
if (Array.isArray(response.data.data)) {
response.data.data.forEach(episode => {
@ -175,15 +216,15 @@ module.exports = (bot) => {
try {
const response = await axios(apiUrl);
const comicArray = [];
const comicArray: Comic[] = [];
if (Array.isArray(response.data.data)) {
response.data.data.forEach(comic => {
let letterers = [];
let letterers: string[] = [];
if (comic.letterer) {
if (typeof comic.letterer === 'string') {
letterers.push(comic.letterer);
} else if (Array.isArray(comic.letterer)) {
letterers = aliases.concat(comic.letterer);
letterers = letterers.concat(comic.letterer);
}
}
comicArray.push({

View File

@ -1,28 +0,0 @@
// const Resources = require('../props/resources.json');
// const { getStrings } = require('../plugins/checkLang.js');
// const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
// const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
// const escape = require('markdown-escape');
// 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(Resources.quoteApi);
// const data = response.data;
// ctx.reply(escape(`${escape(Strings.quoteResult)}\n> *${escape(data.quote)}*\n_${escape(data.author)}_`), {
// reply_to_message_id: ctx.message.message_id,
// parse_mode: 'Markdown'
// });
// } catch (error) {
// console.error(error);
// ctx.reply(Strings.quoteErr, {
// reply_to_message_id: ctx.message.id,
// parse_mode: 'MarkdownV2'
// });
// };
// });
// };

32
src/commands/quotes.ts Normal file
View File

@ -0,0 +1,32 @@
/*
import Resources from '../props/resources.json';
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
import escape from 'markdown-escape';
import axios from 'axios';
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
export default (bot) => {
bot.command("quote", spamwatchMiddleware, async (ctx) => {
const Strings = getStrings(ctx.from.language_code);
try {
const response = await axios.get(Resources.quoteApi);
const data = response.data;
ctx.reply(escape(`${escape(Strings.quoteResult)}\n> *${escape(data.quote)}*\n_${escape(data.author)}_`), {
reply_to_message_id: ctx.message.message_id,
parse_mode: 'Markdown'
});
} catch (error) {
console.error(error);
ctx.reply(Strings.quoteErr, {
reply_to_message_id: ctx.message.id,
parse_mode: 'MarkdownV2'
});
};
});
};
*/

View File

@ -1,15 +1,17 @@
const Resources = require('../props/resources.json');
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
const axios = require("axios");
import Resources from '../props/resources.json';
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
import axios from 'axios';
module.exports = (bot) => {
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
export default (bot) => {
bot.command(["rpony", "randompony", "mlpart"], spamwatchMiddleware, async (ctx) => {
const Strings = getStrings(ctx.from.language_code);
try {
const response = await axios(Resources.randomPonyApi);
let tags = [];
let tags: string[] = [];
if (response.data.pony.tags) {
if (typeof response.data.pony.tags === 'string') {

View File

@ -2,12 +2,14 @@
// Copyright (c) 2024 BubbalooTeam. (https://github.com/BubbalooTeam)
// Minor code changes by lucmsilva (https://github.com/lucmsilva651)
const Resources = require('../props/resources.json');
const axios = require('axios');
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
const { verifyInput } = require('../plugins/verifyInput.js');
import Resources from '../props/resources.json';
import axios from 'axios';
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
import verifyInput from '../plugins/verifyInput';
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
const statusEmojis = {
0: '⛈', 1: '⛈', 2: '⛈', 3: '⛈', 4: '⛈', 5: '🌨', 6: '🌨', 7: '🌨',
@ -31,7 +33,7 @@ function getLocaleUnit(countryCode) {
}
}
module.exports = (bot) => {
export default (bot) => {
bot.command(['clima', 'weather'], spamwatchMiddleware, async (ctx) => {
const userLang = ctx.from.language_code || "en-US";
const Strings = getStrings(userLang);

View File

@ -1,36 +0,0 @@
// 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, '![$1](https://en.wikipedia.org/wiki/File:$1)');
// 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 });
// });
// };

38
src/commands/wiki.ts Normal file
View File

@ -0,0 +1,38 @@
/*
import axios from "axios";
function capitalizeFirstLetter(string: string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function mediaWikiToMarkdown(input: string) {
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, '![$1](https://en.wikipedia.org/wiki/File:$1)');
return input;
}
export default (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 });
});
};
*/

View File

@ -1,10 +1,12 @@
const { getStrings } = require('../plugins/checkLang.js');
const { isOnSpamWatch } = require('../spamwatch/spamwatch.js');
const spamwatchMiddleware = require('../spamwatch/Middleware.js')(isOnSpamWatch);
const { execFile } = require('child_process');
const os = require('os');
const fs = require('fs');
const path = require('path');
import { getStrings } from '../plugins/checklang';
import { isOnSpamWatch } from '../spamwatch/spamwatch';
import spamwatchMiddlewareModule from '../spamwatch/Middleware';
import { execFile } from 'child_process';
import os from 'os';
import fs from 'fs';
import path from 'path';
const spamwatchMiddleware = spamwatchMiddlewareModule(isOnSpamWatch);
const ytDlpPaths = {
linux: path.resolve(__dirname, '../plugins/yt-dlp/yt-dlp'),
@ -28,7 +30,7 @@ const getFfmpegPath = () => {
return ffmpegPaths[platform] || ffmpegPaths.linux;
};
const downloadFromYoutube = async (command, args) => {
const downloadFromYoutube = async (command: string, args: string[]): Promise<{ stdout: string; stderr: string }> => {
return new Promise((resolve, reject) => {
execFile(command, args, (error, stdout, stderr) => {
if (error) {
@ -40,8 +42,8 @@ const downloadFromYoutube = async (command, args) => {
});
};
const getApproxSize = async (command, videoUrl) => {
let args = [];
const getApproxSize = async (command: string, videoUrl: string): Promise<number> => {
let args: string[] = [];
if (fs.existsSync(path.resolve(__dirname, "../props/cookies.txt"))) {
args = [videoUrl, '--compat-opt', 'manifest-filesize-approx', '-O', 'filesize_approx', '--cookies', path.resolve(__dirname, "../props/cookies.txt")];
} else {
@ -60,7 +62,7 @@ const getApproxSize = async (command, videoUrl) => {
}
};
module.exports = (bot) => {
export default (bot) => {
bot.command(['yt', 'ytdl', 'sdl', 'video', 'dl'], spamwatchMiddleware, async (ctx) => {
const Strings = getStrings(ctx.from.language_code);
const ytDlpPath = getYtDlpPath();
@ -198,11 +200,8 @@ module.exports = (bot) => {
}
} catch (error) {
const errMsg = Strings.ytDownload.uploadErr.replace("{error}", error)
await ctx.telegram.editMessageText(
ctx.chat.id,
downloadingMessage.message_id,
null,
errMsg, {
// will no longer edit the message as the message context is not outside the try block
await ctx.reply(errMsg, {
parse_mode: 'Markdown',
reply_to_message_id: ctx.message.message_id,
},

View File

@ -17,6 +17,4 @@ function getStrings(languageCode) {
}
}
module.exports = {
getStrings
};
export { getStrings };

View File

@ -1,14 +0,0 @@
function verifyInput(ctx, userInput, message, verifyNaN = false) {
if (!userInput || (verifyNaN && isNaN(userInput))) {
ctx.reply(message, {
parse_mode: "Markdown",
reply_to_message_id: ctx.message.message_id
});
return true;
}
return false;
}
module.exports = {
verifyInput
};

View File

@ -0,0 +1,10 @@
export default function verifyInput(ctx: any, userInput: string, message: string, verifyNaN = false) {
if (!userInput || (verifyNaN && isNaN(Number(userInput)))) { // not sure why isNaN is used here, but the input should be a number
ctx.reply(message, {
parse_mode: "Markdown",
reply_to_message_id: ctx.message.message_id
});
return true;
}
return false;
}

View File

@ -1,7 +1,7 @@
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const os = require('os');
import axios from 'axios';
import fs from 'fs';
import path from 'path';
import os from 'os';
const downloadDir = path.resolve(__dirname, 'yt-dlp');