Compare commits

..

1 Commits

Author SHA1 Message Date
ImgBotApp
ba3d9e3cf2 [ImgBot] Optimize images
*Total -- 297.94kb -> 267.37kb (10.26%)

/images/megamind/megamind.png -- 215.20kb -> 188.70kb (12.31%)
/images/a/Vinci.png -- 4.73kb -> 4.33kb (8.48%)
/images/a/Paticama.png -- 5.64kb -> 5.23kb (7.25%)
/images/a/ByHGT.png -- 4.32kb -> 4.01kb (7.01%)
/images/a/Boniato64.png -- 4.57kb -> 4.25kb (6.93%)
/images/a/SrIzan.png -- 5.24kb -> 4.88kb (6.73%)
/images/a/ItsAdrian.png -- 4.77kb -> 4.47kb (6.34%)
/images/a/Paula.png -- 7.11kb -> 6.72kb (5.41%)
/images/a/XaviXE.png -- 6.23kb -> 5.92kb (5.11%)
/images/a/Tormentarosa.png -- 6.48kb -> 6.18kb (4.64%)
/images/a/MarioCabrera.png -- 4.77kb -> 4.56kb (4.44%)
/images/a/SpRaY.png -- 6.74kb -> 6.47kb (4.04%)
/images/a/Espejito2500.png -- 5.45kb -> 5.25kb (3.65%)
/images/a/William.png -- 5.90kb -> 5.70kb (3.36%)
/images/a/Irene.png -- 5.81kb -> 5.72kb (1.56%)
/images/a/Wheelook.png -- 4.97kb -> 4.96kb (0.33%)

Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com>
2023-10-09 15:28:55 +00:00
125 changed files with 3606 additions and 1068340 deletions

View File

@@ -1,4 +0,0 @@
node_modules
images
.env*
dist

View File

@@ -22,12 +22,10 @@ jobs:
- name: Check out the repo
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
- name: Log in to Sr Izan's container registry
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
with:
registry: containers.srizan.dev
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
@@ -35,7 +33,7 @@ jobs:
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: srizan10/vinci
images: containers.srizan.dev/vinci
tags: latest
- name: Build and push Docker image
@@ -52,5 +50,5 @@ jobs:
AUTH_HEADER: ${{ secrets.WHSERVER_TOKEN }}
run: |
curl -X POST \
-H "Authorization: $AUTH_HEADER" \
https://webhooks.srizan.dev/hooks/vinci
-H "Authorization: Bearer $AUTH_HEADER" \
https://webhooks.srizan.dev/hooks/vinci

124
.sern/ambient.d.ts vendored
View File

@@ -1,124 +0,0 @@
declare var __DEV__: boolean
declare var __PROD__: boolean
declare var __VERSION__: string
declare namespace NodeJS {
interface ProcessEnv {
SHELL:string
SESSION_MANAGER:string
COLORTERM:string
XDG_CONFIG_DIRS:string
XDG_SESSION_PATH:string
COREPACK_ENABLE_DOWNLOAD_PROMPT:string
NVM_INC:string
XDG_MENU_PREFIX:string
TERM_PROGRAM_VERSION:string
ICEAUTHORITY:string
NODE_OPTIONS:string
LC_ADDRESS:string
LC_NAME:string
MEMORY_PRESSURE_WRITE:string
DESKTOP_SESSION:string
LC_MONETARY:string
GTK_RC_FILES:string
NO_AT_BRIDGE:string
EDITOR:string
XDG_SEAT:string
PWD:string
LOGNAME:string
XDG_SESSION_DESKTOP:string
XDG_SESSION_TYPE:string
SYSTEMD_EXEC_PID:string
_:string
XAUTHORITY:string
VSCODE_GIT_ASKPASS_NODE:string
MOTD_SHOWN:string
GTK2_RC_FILES:string
HOME:string
COREPACK_ROOT:string
LANG:string
LC_PAPER:string
XDG_CURRENT_DESKTOP:string
npm_package_version:string
MEMORY_PRESSURE_WATCH:string
STARSHIP_SHELL:string
WAYLAND_DISPLAY:string
GIT_ASKPASS:string
XDG_SEAT_PATH:string
INVOCATION_ID:string
MANAGERPID:string
INIT_CWD:string
CHROME_DESKTOP:string
STARSHIP_SESSION_KEY:string
KDE_SESSION_UID:string
NVM_DIR:string
VSCODE_GIT_ASKPASS_EXTRA_ARGS:string
XKB_DEFAULT_LAYOUT:string
XDG_ACTIVATION_TOKEN:string
XDG_SESSION_CLASS:string
LC_IDENTIFICATION:string
TERM:string
npm_package_name:string
PROJECT_CWD:string
USER:string
VSCODE_GIT_IPC_HANDLE:string
QT_WAYLAND_RECONNECT:string
KDE_SESSION_VERSION:string
PAM_KWALLET5_LOGIN:string
DISPLAY:string
npm_lifecycle_event:string
SHLVL:string
NVM_CD_FLAGS:string
LC_TELEPHONE:string
LC_MEASUREMENT:string
XDG_VTNR:string
XDG_SESSION_ID:string
npm_config_user_agent:string
npm_execpath:string
XDG_RUNTIME_DIR:string
DEBUGINFOD_URLS:string
npm_package_json:string
LC_TIME:string
BUN_INSTALL:string
BERRY_BIN_FOLDER:string
XKB_DEFAULT_VARIANT:string
VSCODE_GIT_ASKPASS_MAIN:string
QT_AUTO_SCREEN_SCALE_FACTOR:string
JOURNAL_STREAM:string
XDG_DATA_DIRS:string
KDE_FULL_SESSION:string
GDK_BACKEND:string
BROWSER:string
PATH:string
ORIGINAL_XDG_CURRENT_DESKTOP:string
DBUS_SESSION_BUS_ADDRESS:string
KDE_APPLICATIONS_AS_SCOPE:string
MAIL:string
NVM_BIN:string
npm_node_execpath:string
LC_NUMERIC:string
OLDPWD:string
TERM_PROGRAM:string
TOKEN:string
PREFIX:string
MONGODB:string
YOURLS_KEY:string
CATAPI:string
DOGAPI:string
TWITTER:string
MAKESWEET:string
GENIUS:string
SPOTIFY_CLIENT:string
SPOTIFY_SECRET:string
CF_AI_TOKEN:string
CF_AI_ACC:string
GUILDID:string
SUGGESTIONS_CHANNEL:string
MODLOGS_CHANNEL:string
JOINSANDLEAVES_CHANNEL:string
SOCIALS_CHANNEL:string
BIRTHDAYS_CHANNEL:string
MCFORM_CHANNEL:string
CHATGPT_CHANNEL:string
T_CHANNEL:string
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +0,0 @@
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "node16",
"strict": true,
"skipLibCheck": true,
"target": "esnext",
"rootDirs": [
"./generated",
"../src"
]
},
"include": [
"./ambient.d.ts",
"../src"
]
}

Binary file not shown.

View File

@@ -1 +0,0 @@
nodeLinker: node-modules

View File

@@ -7,11 +7,12 @@ WORKDIR /app
RUN apk add --no-cache --virtual .gyp python3 make g++
COPY . .
RUN corepack enable yarn
COPY package.json yarn.lock ./
RUN yarn
COPY . .
RUN yarn build
RUN yarn cache clean
# Final stage
FROM node:lts-alpine AS final
@@ -19,9 +20,9 @@ FROM node:lts-alpine AS final
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/src ./src
COPY --from=build /app/.sern ./.sern
COPY --from=build /app/assets ./assets
COPY --from=build /app/schemas ./schemas
COPY --from=build /app/util ./
COPY --from=build /app/images ./images
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/package.json ./package.json
RUN apk add --no-cache ffmpeg msttcorefonts-installer fontconfig && \

View File

@@ -26,5 +26,10 @@ the code is here for transparency purposes and it's not made to be hosted by thi
- ~~socials notification system~~ DONE!
- chatbot using IBM's AI (thanks @gosevil for the idea)
- ~~joke command~~
<!--<img src="https://srizan.s-ul.eu/RddzT2f9">-->
<img src="https://cdn.discordapp.com/attachments/928230817673641995/1036390945945559140/makesweet-hbt4h3.gif">
by @Oliverlg8
10 stars! tysm!

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,16 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";
import { ApplicationCommandOptionType } from "discord.js";
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
name: '8ball',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Preguntale a la 8-ball cosas.',
//alias : [],
options: [{
@@ -13,8 +19,8 @@ export default commandModule({
type: ApplicationCommandOptionType.String,
required: true
}],
execute: async (ctx) => {
// yes, the question argument is never used. There is no reason to use it.
execute: async (ctx, options) => {
// yes, the question argument is never used. There is no reason to use it in the code.
var eightballwords = [
'Probablemente',
'Sí',

View File

@@ -2,8 +2,10 @@ import { commandModule, CommandType } from '@sern/handler';
import {
ApplicationCommandOptionType,
AttachmentBuilder,
AutocompleteInteraction,
EmbedBuilder,
} from 'discord.js';
import { publish } from '#plugins';
const choices = [
'XaviXE',
'Paula',
@@ -26,8 +28,9 @@ const choices = [
export default commandModule({
name: 'a',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'A',
//alias : [],
options: [
{
name: 'usuario',
@@ -36,7 +39,7 @@ export default commandModule({
autocomplete: true,
command: {
onEvent: [],
async execute(ctx) {
async execute(ctx: AutocompleteInteraction) {
const focusedValue = ctx.options.getFocused();
const filtered = choices.filter((choice) =>
choice.startsWith(focusedValue)
@@ -45,10 +48,10 @@ export default commandModule({
filtered.map((choice) => ({ name: choice, value: choice }))
);
},
}
},
},
],
execute: async (ctx) => {
execute: async (ctx, options) => {
const option = ctx.interaction.options.getString('usuario');
if (!option) {
const imagesArray = [
@@ -74,9 +77,9 @@ export default commandModule({
await ctx.reply({ content: 'A', files: [images] });
} else {
if (choices.indexOf(option) > -1) {
if (choices.indexOf(options[1].getString('usuario', true)) > -1) {
const attachmentbuilder = new AttachmentBuilder(
`./images/a/${option}.png`
`./images/a/${options[1].getString('usuario', true)}.png`
);
await ctx.reply({ content: 'A', files: [attachmentbuilder] });
} else {

View File

@@ -1,11 +1,16 @@
import { commandModule, CommandType } from '@sern/handler'
import axios from "axios";
import { ActionRowBuilder, ApplicationCommandOptionType, ButtonBuilder, ButtonStyle, ComponentType, EmbedBuilder } from "discord.js";
import { publish } from "#plugins";
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
name: 'animal',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Enseña un animal',
//alias : [],
options: [
@@ -35,8 +40,8 @@ export default commandModule({
type: ApplicationCommandOptionType.Subcommand
}
],
execute: async (ctx) => {
switch (ctx.options.getSubcommand()) {
execute: async (ctx, options) => {
switch (options[1].getSubcommand()) {
case 'gato': {
const request = await axios.get(`https://api.thecatapi.com/v1/images/search?api_key=${process.env.CATAPI}`).then(res => res.data)
const embed = new EmbedBuilder()
@@ -87,7 +92,7 @@ export default commandModule({
"sub_id": i.user.id,
"value": -1
})
i.editReply({content: `Has votado negativamente al gato con ID \`${request[0].id}\``})
i.editReply({content: "Has votado negativamente al gato con ID " + "`" + request[0].id + "`"})
}
})
collector.on('end', async (i) => {
@@ -95,11 +100,15 @@ export default commandModule({
})
}
case 'capybara': {
const request = await axios('https://api.capybara-api.xyz/v1/image/random').then(res => res.data)
const requestfacts = await axios('https://api.capybara-api.xyz/v1/facts/random').then(res => res.data)
const embed = new EmbedBuilder()
.setAuthor({name: ctx.user.username, iconURL: ctx.user.displayAvatarURL()})
.setTitle('Capybara')
.setDescription(`Fun fact: ${requestfacts.fact}`)
.setColor('Random')
.setImage('https://api.capy.lol/v1/capybara');
.setImage(request.image_urls.medium)
.setFooter({text: `ID: ${request.id}`})
await ctx.interaction.reply({embeds: [embed]})
}
case 'zorro': {
@@ -169,7 +178,7 @@ export default commandModule({
})
}
case 'mapache': {
const request = await axios('https://some-random-api.com/animal/raccoon').then(res => res.data)
const request = await axios('https://some-random-api.ml/animal/raccoon').then(res => res.data)
const embed = new EmbedBuilder()
.setAuthor({name: ctx.user.username, iconURL: ctx.user.displayAvatarURL()})
.setTitle('Mapache')

View File

@@ -1,9 +1,14 @@
import { commandModule, CommandType } from '@sern/handler';
import { publish } from '#plugins';
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
name: 'cursivify',
type: CommandType.CtxMsg,
plugins: [],
plugins: [publish()],
execute: async (ctx) => {
await ctx.deferReply()
const trimmedstring = ctx.targetMessage.content.replaceAll('*', '');

View File

@@ -10,13 +10,13 @@ import {
EmbedBuilder,
} from 'discord.js';
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'busca cosas en gogoanime',
//alias : [],
options: [
@@ -91,10 +91,10 @@ export default commandModule({
execute: async (ctx, options) => {
const gogoanime = new ANIME.Gogoanime();
const doubleslashregex = new RegExp('(?<!:)\/\/+')
switch (ctx.options.getSubcommand()) {
switch (options[1].getSubcommand()) {
case 'buscar': {
await ctx.interaction.deferReply()
const option = ctx.options.getString('palabra-clave', true);
const option = options[1].getString('palabra-clave', true);
const search = await gogoanime.search(option);
const editedarray = await Promise.all(
search.results
@@ -132,7 +132,7 @@ export default commandModule({
})
} break;
case 'capitulo': {
const selepisode = ctx.options.getString('id-capitulo', true)
const selepisode = options[1].getString('id-capitulo', true)
try {
const search = await gogoanime.fetchEpisodeServers(selepisode)
const arrayed = await Promise.all(search.map((server) => `[${server.name}](<${server.url!.replace(doubleslashregex, '/')}>)`))
@@ -143,7 +143,7 @@ export default commandModule({
} break;
case 'info': {
try {
const option = ctx.options.getString('id', true)
const option = options[1].getString('id', true)
const info = await gogoanime.fetchAnimeInfo(option)
const embed = new EmbedBuilder()
.setColor('Random')

View File

@@ -1,13 +1,13 @@
import { commandModule, CommandType } from '@sern/handler'
import axios from "axios";
import { publish } from "#plugins";
export default commandModule({
name: 'chiste',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Enseña un chiste en inglés.',
execute: async (ctx) => {
execute: async (ctx, args) => {
const jokeJSON = await axios(
'https://v2.jokeapi.dev/joke/Programming,Miscellaneous,Spooky,Christmas?blacklistFlags=nsfw,religious,racist,sexist,explicit'
).then((res) => res.data);

View File

@@ -11,13 +11,13 @@ import {
import axios from 'axios';
import https from 'node:https'
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
//alias : [],
description: 'no one will read this (i hope)',
options: [
@@ -40,15 +40,15 @@ export default commandModule({
],
},
],
execute: async (ctx) => {
execute: async (ctx, options) => {
await ctx.interaction.deferReply();
switch (ctx.options.getSubcommand()) {
switch (options[1].getSubcommand()) {
case 'heartlocket':
{
try {
// get all options
const text = ctx.options.getString('texto', true);
const image = ctx.options.getAttachment('imagen', true);
const text = options[1].getString('texto');
const image = options[1].getAttachment('imagen', true);
// check file extension of attachment
if (
@@ -110,7 +110,6 @@ export default commandModule({
Authorization: process.env.MAKESWEET!,
},
responseType: 'arraybuffer',
httpsAgent: new https.Agent({ rejectUnauthorized: false })
}
)
.then((res) => res.data);
@@ -121,7 +120,6 @@ export default commandModule({
Authorization: process.env.MAKESWEET!,
},
responseType: 'arraybuffer',
httpsAgent: new https.Agent({ rejectUnauthorized: false })
})
.then((res) => res.data);
}

View File

@@ -1,16 +1,16 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";
import Canvas from '@napi-rs/canvas';
import { ApplicationCommandOptionType, AttachmentBuilder } from 'discord.js';
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
// , '928018226330337280'
description: 'Añade a una imagen de megamind "No ...?"',
//alias : [],
@@ -22,8 +22,8 @@ export default commandModule({
required: true
}
],
execute: async (ctx) => {
const option = ctx.options.getString('texto', true)
execute: async (ctx, options) => {
const option = options[1].getString('texto', true)
await ctx.reply({content: 'Cargando...'})

View File

@@ -1,12 +1,12 @@
import { commandModule, CommandType } from '@sern/handler'
import { ActionRowBuilder, ApplicationCommandOptionType, ButtonBuilder, ButtonStyle, ComponentType, EmbedBuilder, GuildMember } from "discord.js";
import { publish } from "#plugins";
import rockpaperscissors from "rockpaperscissors-checker";
export default commandModule({
name: 'rps',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Juega piedra papel tijeras con los panas',
//alias : [],
options: [
@@ -17,10 +17,10 @@ export default commandModule({
required: true
}
],
execute: async (ctx) => {
execute: async (ctx, options) => {
// also the code is mine, I didn't steal from anyone
let player1: number, player2: number, winner, bothResponded: boolean
const option = ctx.options.getMember('usuario') as unknown as GuildMember
let player1, player2, winner, bothResponded
const option = options[1].getMember('usuario') as GuildMember
if (ctx.user.id === option.id) {
return await ctx.reply({content: `no puedes jugar contigo mismo 💀`, ephemeral: true})
} else if (option.user.bot) {

View File

@@ -1,13 +1,14 @@
import TicTacToe from 'discord-tictactoe';
import { commandModule, CommandType } from '@sern/handler'
import { ApplicationCommandOptionType } from "discord.js";
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";
import { ApplicationCommandOptionType, ChatInputCommandInteraction, CommandInteraction, Interaction } from "discord.js";
const game = new TicTacToe({language: 'en'})
export default commandModule({
name: 'tictactoe',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'tres en raya',
//alias : [],
options: [

View File

@@ -8,7 +8,7 @@ import { execa } from 'execa';
export default commandModule({
type: CommandType.CtxMsg,
plugins: [],
plugins: [publish()],
execute: async (ctx) => {
await ctx.deferReply({ fetchReply: true })
@@ -22,11 +22,11 @@ export default commandModule({
const randomnumber = random(5)
const randomnumber_wav = `bonzi-wav-${randomnumber}.wav`
const randomnumber_mp3 = `bonzi-mp3-${randomnumber}.mp3`
fs.writeFileSync(`./src/util/bonzi_temp/${randomnumber_wav}`, new Uint8Array(request))
fs.writeFileSync(`./util/bonzi_temp/${randomnumber_wav}`, new Uint8Array(request))
const command = execa('ffmpeg', [
'-i', `./src/util/bonzi_temp/${randomnumber_wav}`,
'-i', `./util/bonzi_temp/${randomnumber_wav}`,
'-vn',
`./src/util/bonzi_temp/${randomnumber_mp3}`
`./util/bonzi_temp/${randomnumber_mp3}`
], { shell: true })
await new Promise((resolve) => {
command.on('close', resolve)
@@ -34,12 +34,12 @@ export default commandModule({
const stream = new Readable();
stream._read = () => {};
stream.push(Buffer.from(new Uint8Array(fs.readFileSync(`./src/util/bonzi_temp/${randomnumber_mp3}`))));
stream.push(Buffer.from(new Uint8Array(fs.readFileSync(`./util/bonzi_temp/${randomnumber_mp3}`))));
stream.push(null)
const attachment = new AttachmentBuilder(stream, { name: 'bonzied.mp3' })
fs.unlinkSync(`./src/util/bonzi_temp/${randomnumber_mp3}`)
fs.unlinkSync(`./src/util/bonzi_temp/${randomnumber_wav}`)
fs.unlinkSync(`./util/bonzi_temp/${randomnumber_mp3}`)
fs.unlinkSync(`./util/bonzi_temp/${randomnumber_wav}`)
await ctx.editReply({ files: [attachment] })
},

View File

@@ -5,6 +5,7 @@ import {
ButtonBuilder,
ButtonStyle,
EmbedBuilder,
TextChannel,
} from 'discord.js';
export default commandModule({
@@ -52,14 +53,11 @@ export default commandModule({
.setLabel('Añadido a la whitelist!')
.setStyle(ButtonStyle.Success)
);
const guild = await modal.client.guilds.fetch(process.env.GUILDID!);
const channel = await guild.channels.fetch(process.env.MCFORM_CHANNEL!);
if (channel && channel.isTextBased()) {
await channel.send({
embeds: [embed],
components: [button],
});
}
(
(await (
await modal.client.guilds.fetch(process.env.GUILDID!)
).channels.fetch(process.env.MCFORM_CHANNEL!)) as TextChannel
).send({ embeds: [embed], components: [button] });
} catch {
await modal.reply({
content:

View File

@@ -0,0 +1,15 @@
import { commandModule, CommandType } from '@sern/handler';
import axios from 'axios';
export default commandModule({
type: CommandType.Button,
plugins: [],
execute: async (ctx) => {
await ctx.deferReply({ ephemeral: true })
const request = await axios.get('https://api.minetools.eu/query/minecraft.maraturing.com/25565').then(res => res.data)
await ctx.editReply({
content: ``
})
},
});

View File

@@ -15,7 +15,7 @@ export default commandModule({
// @ts-ignore
).options.map((o: { label: string; value: string }) => o.value);
const member = interaction.member! as unknown as GuildMember;
const member = interaction.member as GuildMember;
if (!member) return;
let content = `Los roles han sido actualizados. Te he dado estos:\n${roles

View File

@@ -1,6 +1,7 @@
import { commandModule, CommandType } from '@sern/handler';
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from 'discord.js';
import {
TextChannel,
ThreadAutoArchiveDuration,
} from 'discord.js';
@@ -51,17 +52,10 @@ export default commandModule({
.setStyle(ButtonStyle.Secondary),
)
const guild = await modal.client.guilds.fetch(process.env.GUILDID!);
const channel = await guild.channels.fetch(process.env.SUGGESTIONS_CHANNEL!);
if (!channel || !channel.isTextBased()) {
return await modal.reply({
content: 'ERROR: Canal de sugerencias no encontrado.',
ephemeral: true,
});
}
const msg = await channel.send({ embeds: [embed], components: [row, row2] });
msg.startThread({
const message1 = await (await modal.client.guilds.fetch(process.env.GUILDID!))
.channels.fetch(process.env.SUGGESTIONS_CHANNEL!) as TextChannel;
const message2 = await message1.send({ embeds: [embed], components: [row, row2] });
message2.startThread({
name: `Sugerencia de ${modal.user.username}`,
autoArchiveDuration: ThreadAutoArchiveDuration.ThreeDays,
reason: 'AUTOMATIZADO: Hilo para discutir sobre la sugerencia.',

View File

@@ -1,11 +1,11 @@
import { commandModule, CommandType } from "@sern/handler";
import { ActionRowBuilder, ButtonBuilder, ButtonComponent, ButtonComponentData, ButtonStyle } from "discord.js";
import { ActionRowBuilder, ButtonBuilder, ButtonComponentData, ButtonInteraction, ButtonStyle, ComponentType } from "discord.js";
import db from "../../schemas/suggestions.js";
export default commandModule({
type: CommandType.Button,
async execute(interaction) {
const convertToNumber = Number((interaction.component as ButtonComponent).label!)
const convertToNumber = Number(interaction.component.label!)
const row2 = new ActionRowBuilder<ButtonBuilder>().setComponents(
new ButtonBuilder(interaction.message!.components[1].components[0].data as ButtonComponentData),
new ButtonBuilder(interaction.message!.components[1].components[1].data as ButtonComponentData)

View File

@@ -1,4 +1,5 @@
import { commandModule, CommandType } from "@sern/handler";
import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, ComponentType } from "discord.js";
import db from "../../schemas/suggestions.js";
export default commandModule({

View File

@@ -1,11 +1,11 @@
import { commandModule, CommandType } from "@sern/handler";
import { ActionRowBuilder, ButtonBuilder, ButtonComponent, ButtonComponentData, ButtonStyle } from "discord.js";
import { ActionRowBuilder, ButtonBuilder, ButtonComponentData, ButtonInteraction, ButtonStyle, ComponentType } from "discord.js";
import db from "../../schemas/suggestions.js";
export default commandModule({
type: CommandType.Button,
async execute(interaction) {
const convertToNumber = Number((interaction.component as ButtonComponent).label!)
const convertToNumber = Number(interaction.component.label!)
const row2 = new ActionRowBuilder<ButtonBuilder>().setComponents(
new ButtonBuilder(interaction.message!.components[1].components[0].data as ButtonComponentData),
new ButtonBuilder(interaction.message!.components[1].components[1].data as ButtonComponentData)

View File

@@ -1,10 +1,16 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";
import { ApplicationCommandOptionType } from "discord.js";
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
name: 'ip',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
//
description: 'La IP del servidor de Minecraft',
options: [
@@ -16,7 +22,7 @@ export default commandModule({
],
//alias : [],
execute: async (ctx, options) => {
const usuario = ctx.options.getMember('usuario');
const usuario = options[1].getMember('usuario');
if (!usuario) {
await ctx.reply({content: "La IP del servidor de Minecraft es `minecraft.maraturing.com`,\nPide acceso con el comando </mcform:1000747672690499594>.", ephemeral: true})

View File

@@ -6,11 +6,13 @@ import {
TextInputStyle,
ModalActionRowComponentBuilder,
} from 'discord.js';
import { publish } from '#plugins';
import { ownerOnly } from '#plugins';
export default commandModule({
name: 'mcform',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Envia el formulario para entrar al servidor.',
//alias : [],
execute: async (ctx) => {

View File

@@ -1,10 +1,16 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
import db from '../../schemas/afk.js';
import { ApplicationCommandOptionType, EmbedBuilder } from 'discord.js';
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'afk command',
//alias : [],
options: [
@@ -32,11 +38,11 @@ export default commandModule({
type: ApplicationCommandOptionType.Subcommand
}
],
execute: async (ctx) => {
switch (ctx.options.getSubcommand()) {
execute: async (ctx, options) => {
switch (options[1].getSubcommand()) {
case 'añadir': {
if (await db.exists({ id: ctx.user.id })) return ctx.reply({ content: 'Ya existes en la base de datos!', ephemeral: true })
const reason = ctx.options.getString('motivo');
const reason = options[1].getString('motivo', true);
await (new db({ id: ctx.user.id, reason: reason })).save()
const embed = new EmbedBuilder()

19
commands/misc/askjavi.ts Normal file
View File

@@ -0,0 +1,19 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";
import { ApplicationCommandOptionType } from "discord.js";
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
name: 'askjavi',
type: CommandType.Slash,
plugins: [publish()],
description: 'DESACTIVADO: Pregunta a Javi LO QUE SEA!',
//alias : [],
execute: async (ctx, options) => {
await ctx.reply({content: `Este comando ha sido desactivado ya que era para un evento que ya ha ocurrido.\nGracias por haber participado!`, ephemeral: true})
},
});

View File

@@ -11,15 +11,16 @@ import {
ModalSubmitInteraction,
ApplicationCommandOptionType,
} from 'discord.js';
import { publish } from '#plugins';
import { ownerOnly } from '#plugins';
import padyama from '../../schemas/padyama.js';
import { random } from '../../util/randomstring.js';
import { disable } from '#plugins';
export default commandModule({
name: 'askjavi',
type: CommandType.Slash,
plugins: [
disable()
// publish(),
],
description: 'TEMP: Pregunta a Javi LO QUE SEA!',
//alias : [],
@@ -62,7 +63,7 @@ export default commandModule({
],
},
],
execute: async (ctx) => {
execute: async (ctx, options) => {
switch (ctx.interaction.options.getSubcommand()) {
case 'new': {
const modal = new ModalBuilder()
@@ -109,7 +110,7 @@ export default commandModule({
time: 180000,
filter: (i) => i.user.id === ctx.user.id,
})
.catch((error) => {})) as unknown as ModalSubmitInteraction;
.catch((error) => {})) as ModalSubmitInteraction;
const db = new padyama({
id: i.user.id,
user: i.user.username,
@@ -131,7 +132,7 @@ export default commandModule({
});
}
case 'get': {
const option = ctx.options.getString('id');
const option = options[1].getString('id');
const db = await padyama.findOne({ suggestionid: option });
if (db?.suggestion !== undefined)
return await ctx.reply({
@@ -159,7 +160,7 @@ export default commandModule({
content: `No puedes usar este comando.`,
ephemeral: true,
});
const option = ctx.options.getString('id');
const option = options[1].getString('id');
const db = await padyama.findOne({ suggestionid: option });
if (db?.user !== undefined) {
try {

View File

@@ -1,14 +1,16 @@
import { commandModule, CommandType } from '@sern/handler'
import { Context, SlashOptions } from "@sern/handler";
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js";
import { publish } from "#plugins";
export default commandModule({
name: 'creditos',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Créditos del bot (en inglés)',
//alias : [],
options: [],
execute: async (ctx) => {
execute: async (ctx, options) => {
const baseEmbed = new EmbedBuilder()
.setColor('Blurple')
.setTitle(`Without these people, the bot wouldn't exist!`)

View File

@@ -1,13 +1,18 @@
import { commandModule, CommandType } from "@sern/handler";
import { publish } from "#plugins";
import { ApplicationCommandOptionType } from "discord.js";
import { readFileSync } from "node:fs";
import birthdays from "../../schemas/birthdays.js";
import { acceptingBirthday } from "#plugins";
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
name: "cumple",
type: CommandType.Slash,
plugins: [acceptingBirthday()],
plugins: [publish(), acceptingBirthday()],
description: "Pon tu cumpleaños en la base de datos para ser felicitado!",
//alias : [],
options: [
@@ -38,7 +43,7 @@ export default commandModule({
},
},
],
execute: async (ctx) => {
execute: async (ctx, options) => {
const option = ctx.interaction.options.getString("fecha")
const array = JSON.parse(
String(readFileSync("./util/daysinyear.txt"))

View File

@@ -1,10 +1,12 @@
import { commandModule, CommandType } from '@sern/handler'
import { ApplicationCommandOptionType, ColorResolvable, EmbedBuilder } from 'discord.js';
import mctags from '../../../assets/mcTags.json' with { type: "json" };
import { publish } from "#plugins";
import fs from 'node:fs';
import mctags from '../../util/tags/minecraft.json' assert { type: 'json' }
export default commandModule({
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Preguntas normalmente preguntadas :pepega:',
//alias : [],
options: [
@@ -38,11 +40,11 @@ export default commandModule({
]
}
],
execute: async (ctx) => {
switch (ctx.options.getSubcommand()) {
execute: async (ctx, options) => {
switch (options[1].getSubcommand()) {
case 'minecraft': {
const option = ctx.options.getString('pregunta', true)
const forusr = ctx.options.getMember('para')
const option = options[1].getString('pregunta', true)
const forusr = options[1].getMember('para')
const filter = mctags.filter(obj => obj.title.includes(option))[0]
const embed = new EmbedBuilder()

View File

@@ -1,10 +1,15 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import google from 'googlethis'
import { ApplicationCommandOptionType } from 'discord.js';
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Busca cosas en Google.',
//alias : [],
options: [
@@ -15,9 +20,9 @@ export default commandModule({
required: true,
}
],
execute: async (ctx) => {
execute: async (ctx, options) => {
await ctx.interaction.deferReply()
const prompt = ctx.options.getString('busqueda', true)
const prompt = options[1].getString('busqueda', true)
const search = await Promise.all((await google.search(prompt)).results.map(res => {
return `[${res.title}](<${res.url}>)`

View File

@@ -1,4 +1,5 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import Genius from 'genius-lyrics'
import { ActionRowBuilder, ApplicationCommandOptionType, ButtonBuilder, ButtonStyle, EmbedBuilder } from 'discord.js';
@@ -6,7 +7,7 @@ const genius = new Genius.Client(process.env.GENIUS)
export default commandModule({
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Busca la letra de una canción (Genius)',
//alias : [],
options: [
@@ -33,9 +34,9 @@ export default commandModule({
}
}
],
execute: async (ctx) => {
execute: async (ctx, options) => {
await ctx.interaction.deferReply({ ephemeral: true })
const prompt = ctx.options.getString('busqueda', true)
const prompt = options[1].getString('busqueda', true)
const result = await genius.songs.get(Number(prompt))

View File

@@ -1,13 +1,17 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { createAudioPlayer, createAudioResource, DiscordGatewayAdapterCreator, joinVoiceChannel } from "@discordjs/voice";
import got from "got";
import { ApplicationCommandOptionType, EmbedBuilder } from "discord.js";
const choices = ['Rock FM', 'Cadena 100', 'Cadena Dial', 'Gensokyo Radio', 'BBC 1', 'RNE 1', 'RNE 5', 'Los 40'];
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
name: 'radio',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Reproduce la radio',
options: [
{
@@ -20,6 +24,7 @@ export default commandModule({
onEvent: [],
async execute(ctx){
const focusedValue = ctx.options.getFocused();
const choices = ['Rock FM', 'Cadena 100', 'Cadena Dial', 'Gensokyo Radio', 'BBC 1', 'RNE 1', 'RNE 5', 'Los 40', 'Flaixbac', 'FlaixFM'];
const filtered = choices.filter(choice => choice.startsWith(focusedValue));
await ctx.respond(
filtered.map(choice => ({ name: choice, value: choice })),
@@ -28,9 +33,8 @@ export default commandModule({
}
}
],
execute: async (ctx) => {
const radioname = ctx.options.getString("reproducir", true)
if (!choices.includes(radioname)) return await ctx.reply('Asegúrate de escoger una radio de la lista.')
execute: async (ctx, options) => {
const radioname = options[1].getString("reproducir", true)
const embed = new EmbedBuilder()
.setColor("Green")
.setTitle(`Reproduciendo ${radioname} en Vinci Radio.`)
@@ -40,14 +44,18 @@ export default commandModule({
.setTitle(`Radio ${radioname} no encontrada.`)
.setDescription(`La radio no ha sido encontrada, asegúrate que la radio está escogida de la lista.`);
async function playRadio(radioname: string) {
async function playRadio(radioname: string, isFlaix?: boolean) {
const stream = got.stream(radioname)
const connection = joinVoiceChannel({adapterCreator: ctx.interaction.guild!.voiceAdapterCreator as DiscordGatewayAdapterCreator, channelId: '1008730592835281009',guildId: '928018226330337280',selfDeaf: true});
const resource = createAudioResource(stream, { inlineVolume: true });
const player = createAudioPlayer();
connection.subscribe(player)
player.play(resource)
resource.volume!.setVolume(0.7)
if (isFlaix === true) {
resource.volume!.setVolume(0.3)
} else {
resource.volume!.setVolume(0.7)
}
await ctx.reply({embeds: [embed], ephemeral: true})
}
@@ -76,6 +84,12 @@ export default commandModule({
case 'Gensokyo Radio': {
playRadio('https://stream.gensokyoradio.net/3')
} break;
case 'Flaixbac': {
playRadio('https://nodo07-cloud01.streaming-pro.com:8005/flaixbac.mp3', true)
} break;
case 'FlaixFM': {
playRadio('https://nodo07-cloud01.streaming-pro.com:8001/flaixfm.mp3', true)
} break;
default: {
await ctx.reply({embeds: [notFoundEmbed], ephemeral: true})
} break;

View File

@@ -1,13 +1,13 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";
import { ActionRowBuilder, ApplicationCommandOptionType, ChannelType, ChatInputCommandInteraction, Collection, EmbedBuilder, Role, StringSelectMenuBuilder, TextChannel } from "discord.js";
import { ActionRowBuilder, ApplicationCommandOptionType, ChannelType, Collection, EmbedBuilder, Role, SelectMenuBuilder, TextChannel } from "discord.js";
import { Resolver } from "../../util/resolver.js";
export default commandModule({
name: 'rolemenu',
type: CommandType.Slash,
plugins: [ownerOnly()],
plugins: [publish(), ownerOnly()],
description: 'ADMIN: Spawnea un menú de roles',
//alias : [],
options: [
@@ -31,13 +31,11 @@ export default commandModule({
required: true,
},
],
execute: async (ctx) => {
const channel = ctx.options.getChannel("channel", true) as unknown as TextChannel;
if (!channel.isSendable()) return ctx.reply("Channel is not sendable");
// @ts-ignore it should still be a correct interaction
const role = new Resolver(ctx.options.getString("role", true), ctx.interaction)
execute: async (ctx, options) => {
const channel = options[1].getChannel("channel", true) as TextChannel;
const role = new Resolver(options[1].getString("role", true), ctx.interaction)
.roles;
const message = ctx.options.getString("message", true);
const message = options[1].getString("message", true);
if (role.size > 25) return ctx.reply("Too many roles");
@@ -52,7 +50,6 @@ export default commandModule({
);
}
await ctx.interaction.deferReply();
// @ts-ignore it should still be a textchannel
const row = createMenu(channel, role);
const embed = new EmbedBuilder()
.setTitle(message)
@@ -70,7 +67,7 @@ export default commandModule({
function createMenu(channel: TextChannel, role: Collection<string, Role>) {
if (!channel || !role) throw new Error("Missing channel or role");
const menu = new StringSelectMenuBuilder()
const menu = new SelectMenuBuilder()
.setCustomId("role-menu")
.setMaxValues(role.size)
.setMinValues(0)
@@ -83,6 +80,6 @@ function createMenu(channel: TextChannel, role: Collection<string, Role>) {
};
})
);
const row = new ActionRowBuilder<StringSelectMenuBuilder>().setComponents(menu);
const row = new ActionRowBuilder<SelectMenuBuilder>().setComponents(menu);
return row;
};

View File

@@ -1,13 +1,13 @@
import { commandModule, CommandType } from "@sern/handler";
import axios, { AxiosResponse } from "axios";
import axios, { AxiosError, AxiosResponse } from "axios";
import { ApplicationCommandOptionType } from "discord.js";
import { disable } from "#plugins";
import { publish } from "#plugins";
export default commandModule({
name: "acortar",
type: CommandType.Slash,
plugins: [
disable()
publish(),
],
description: "Acorta una URL a vinci.tk",
options: [
@@ -20,7 +20,7 @@ export default commandModule({
],
//alias : [],
execute: async (ctx, options) => {
const url = ctx.options.getString("url", true);
const url = options[1].getString("url", true);
const request = await axios(
`https://vinci.tk/yourls-api.php?signature=${process.env.YOURLS_KEY}&action=shorturl&format=json&url=${url}`,
{

View File

@@ -1,14 +1,14 @@
import { commandModule, CommandType } from '@sern/handler'
import { disable } from "#plugins";
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";
import { EmbedBuilder } from "discord.js";
import axios from "axios";
// @ts-ignore
import prettySeconds from 'pretty-seconds-spanish'
export default commandModule({
name: 'stats',
type: CommandType.Slash,
plugins: [disable()],
plugins: [publish()],
description: 'Enseña estadísticas del bot.',
//alias : [],
options: [],

View File

@@ -1,11 +1,13 @@
import { commandModule, CommandType } from '@sern/handler'
import { ActionRowBuilder, ModalBuilder, TextInputBuilder, TextInputStyle, ModalActionRowComponentBuilder } from 'discord.js'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";
export default commandModule({
name: 'sugerencias',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Envia una sugerencia.',
//alias : [],
execute: async (ctx) => {

View File

@@ -1,12 +1,18 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";
import axios from 'axios';
import { readFileSync } from 'node:fs'
import { ActionRowBuilder, ApplicationCommandOptionType, ButtonBuilder, ButtonStyle, ComponentType, EmbedBuilder } from 'discord.js';
const choices = ['es', 'en', 'fr', 'de', 'hi', 'it', 'ja', 'ko', 'pl']
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
// , '928018226330337280'
description: 'Traduce lo que quieras!',
//alias : [],
@@ -38,9 +44,9 @@ export default commandModule({
}
}
],
execute: async (ctx) => {
const langToTranslate = ctx.options.getString('idioma', true)
const stringToTranslate = ctx.options.getString('frase', true)
execute: async (ctx, options) => {
const langToTranslate = options[1].getString('idioma', true)
const stringToTranslate = options[1].getString('frase', true)
if (choices.indexOf(langToTranslate) === -1)
return ctx.reply({content: 'Elige un idioma del autocompletado.'})

View File

@@ -1,15 +1,15 @@
import { commandModule, CommandType } from '@sern/handler'
// @ts-ignore
import { publish } from "#plugins";
import prettySeconds from 'pretty-seconds-spanish'
export default commandModule({
name: 'uptime',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Enseña el tiempo que ha estado encendido el bot.',
//alias : [],
options: [],
execute: async (ctx) => {
execute: async (ctx, options) => {
// const uptime = prettyMilliseconds(ctx.client.uptime!)
const uptime = prettySeconds(process.uptime())
await ctx.reply(`El bot lleva encendido ${uptime}`);

View File

@@ -1,10 +1,11 @@
import { commandModule, CommandType } from '@sern/handler'
import { ApplicationCommandOptionType, AutocompleteInteraction, CacheType, CommandInteractionOptionResolver } from 'discord.js';
import { getWikipedia, searchWikipedia } from '../../util/wikipedia.js';
import { publish } from "#plugins";
import { ApplicationCommandOptionType } from 'discord.js';
import { getWikipedia, searchWikipedia, SearchWikipediaObject } from '../../util/wikipedia.js';
export default commandModule({
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'Busca cosas por wikipedia',
//alias : [],
options: [
@@ -22,7 +23,7 @@ export default commandModule({
command: {
onEvent: [],
execute: async (ctx) => {
const search = await searchWikipedia('es', ctx as unknown as AutocompleteInteraction)
const search = await searchWikipedia('es', ctx)
await ctx.respond(
search.map(res => ({ name: res.title.toString(), value: res.pageid.toString() }))
)
@@ -45,7 +46,7 @@ export default commandModule({
command: {
onEvent: [],
execute: async (ctx) => {
const search = await searchWikipedia('en', ctx as unknown as AutocompleteInteraction)
const search = await searchWikipedia('en', ctx)
await ctx.respond(
search.map(res => ({ name: res.title.toString(), value: res.pageid.toString() }))
)
@@ -55,14 +56,13 @@ export default commandModule({
]
}
],
execute: async (ctx) => {
const options = ctx.options as unknown as CommandInteractionOptionResolver<CacheType>
switch (ctx.options.getSubcommand()) {
execute: async (ctx, [, options]) => {
switch (options.getSubcommand()) {
case 'español': {
getWikipedia('es', ctx, options);
getWikipedia('es', ctx, options)
} break;
case 'ingles': {
getWikipedia('en', ctx, options);
getWikipedia('en', ctx, options)
} break;
}
},

View File

@@ -0,0 +1,36 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";;
import { ApplicationCommandOptionType, EmbedBuilder, GuildMember, TextChannel } from 'discord.js'
export default commandModule({
name: 'ban',
type: CommandType.Slash,
plugins: [publish(), ownerOnly()],
description: 'ADMIN: Banea usuarios.',
options: [{
name: 'usuario',
description: 'Escribe un usuario.',
type: ApplicationCommandOptionType.User,
required: true
},
{
name: 'razon',
description: 'Escribe la razón.',
type: ApplicationCommandOptionType.String,
required: true
}],
//alias : [],
execute: async (ctx, options) => {
try {
const userToBan = options[1].getMember('usuario') as GuildMember
const reason = options[1].getString('razon') as string
userToBan.ban({reason: reason})
const sendToMods = ctx.client.guilds.cache.get(process.env.GUILDID!)!.channels.cache.get(process.env.MODLOGS_CHANNEL!) as TextChannel
await sendToMods.send({content: `Se ha baneado a ${userToBan}.\nBan efectuado por ${ctx.user} con razón "${reason}."`})
await ctx.reply({content: 'Baneado correctamente!', ephemeral: true})
} catch {
await ctx.reply({content: `ERROR: No puedo hacer este comando porque a lo mejor soy inferior que el rol de esa persona o estoy usándolo contra admins.`})
}
},
});

View File

@@ -0,0 +1,42 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "../../plugins/index.js";
import { ownerOnly } from "#plugins";
import { ApplicationCommandOptionType, TextChannel } from "discord.js";
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
name: 'eliminarmensaje',
type: CommandType.Slash,
plugins: [publish(), ownerOnly()],
description: 'ADMIN: Elimina comandos por su ID.',
//alias : [],
options: [
{
name: 'canal',
type: ApplicationCommandOptionType.Channel,
description: 'El canal de texto.',
required: true
},
{
name: 'id',
type: ApplicationCommandOptionType.String,
description: 'El ID del mensaje.',
required: true
}
],
execute: async (ctx, options) => {
try {
const idMensaje = options[1].getString('id', true);
const guildId = ctx.guild!.id
const guild = await ctx.client.guilds.fetch(guildId);
const channel = await guild.channels.fetch(ctx.channel!.id);
(await (channel as TextChannel).messages.fetch(idMensaje)).delete();
await ctx.reply({content: 'Mensaje eliminado correctamente.', ephemeral: true});
} catch {
await ctx.reply({content: `ERROR: No se ha podido eliminar el mensaje, asegúrate que estás usando el ID y el canal correcto.`})
}
},
});

View File

@@ -0,0 +1,38 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";;
import { ApplicationCommandOptionType, EmbedBuilder, GuildMember, TextChannel } from 'discord.js'
export default commandModule({
name: 'kick',
type: CommandType.Slash,
plugins: [publish(), ownerOnly()],
description: 'ADMIN: Expulsa usuarios.',
options: [
{
name: 'usuario',
description: 'Escribe un usuario.',
type: ApplicationCommandOptionType.User,
required: true
},
{
name: 'razon',
description: 'Escribe la razón.',
type: ApplicationCommandOptionType.String,
required: true
}
],
//alias : [],
execute: async (ctx, options) => {
try {
const userToKick = options[1].getMember('usuario');
const reason = options[1].getString('razon') as string;
(userToKick as GuildMember).kick(reason)
const sendToMods = ctx.client.guilds.cache.get(process.env.GUILDID!)!.channels.cache.get(process.env.MODLOGS_CHANNEL!) as TextChannel
await sendToMods!.send({content: `Se ha expulsado a ${userToKick}.\nKick efectuado por ${ctx.user} con razón "${reason}."`})
await ctx.reply({content: 'Expulsado correctamente!'})
} catch {
await ctx.reply({content: `ERROR: No puedo hacer este comando porque a lo mejor soy inferior que el rol de esa persona o estoy usándolo contra admins.`})
}
},
});

View File

@@ -1,12 +1,12 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";;
import { ApplicationCommandOptionType, TextChannel } from 'discord.js'
export default commandModule({
name: 'prune',
type: CommandType.Slash,
plugins: [ownerOnly()],
plugins: [publish(), ownerOnly()],
description: 'ADMIN: Elimina hasta 100 mensajes',
options: [{
name: 'numero',
@@ -17,14 +17,14 @@ export default commandModule({
max_value: 100
}],
//alias : [],
execute: async (ctx) => {
execute: async (ctx, options) => {
try {
const amount = ctx.options.getNumber('numero', true) as number
(ctx.channel as unknown as TextChannel).bulkDelete(amount).catch(err => {
const amount = options[1].getNumber('numero', true) as number
(ctx.channel as TextChannel).bulkDelete(amount).catch(err => {
console.error(err);
ctx.reply({content: 'Ha habido un error eliminando mensajes! (mira la consola, Sr Izan)', ephemeral: true});});
await ctx.reply({content: `Se han eliminado ${amount} mensajes.`})
const sendToMods = ctx.client.guilds.cache.get(process.env.GUILDID!)!.channels.cache.get(process.env.MODLOGS_CHANNEL!) as unknown as TextChannel
const sendToMods = ctx.client.guilds.cache.get(process.env.GUILDID!)!.channels.cache.get(process.env.MODLOGS_CHANNEL!) as TextChannel
await sendToMods.send({content: `Se han eliminado ${amount} mensajes en ${ctx.channel}\nEfectuado por ${ctx.user}.`})
} catch {
ctx.reply({content: 'Ha habido un error eliminando mensajes! Error reportado automáticamente.', ephemeral: true})};

View File

@@ -1,12 +1,12 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";
import { ApplicationCommandOptionType, TextChannel } from "discord.js";
export default commandModule({
name: 'slowmode',
type: CommandType.Slash,
plugins: [ownerOnly()],
plugins: [publish(), ownerOnly()],
description: 'ADMIN: Pon modo lento a canales de texto',
options: [
{
@@ -23,15 +23,15 @@ export default commandModule({
}
],
//alias : [],
execute: async (ctx) => {
execute: async (ctx, options) => {
try {
const seconds = ctx.options.getNumber("segundos", true);
const reason = ctx.options.getString("razon", true);
const seconds = options[1].getNumber("segundos", true);
const reason = options[1].getString("razon", true);
(ctx.channel as unknown as TextChannel).setRateLimitPerUser(seconds, reason)
(ctx.channel as TextChannel).setRateLimitPerUser(seconds, reason)
ctx.reply({content: `Se han añadido ${seconds} segundos de modo lento al canal de voz actual`})
const sendToMods = ctx.client.guilds.cache.get(process.env.GUILDID!)!.channels.cache.get(process.env.MODLOGS_CHANNEL!) as unknown as TextChannel
const sendToMods = ctx.client.guilds.cache.get(process.env.GUILDID!)!.channels.cache.get(process.env.MODLOGS_CHANNEL!) as TextChannel
await sendToMods.send({content: `Se ha aplicado modo lento al canal ${ctx.channel}.\nEfectuado por ${ctx.user} con ${seconds} segundos de retardo.\nRazón: ${reason}`})
} catch {
ctx.reply({content: `No se ha podido aplicar modo lento al canal.`})

View File

@@ -0,0 +1,50 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";
import { ApplicationCommandOptionType, GuildMember, TextChannel } from "discord.js";
/*
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
*/
export default commandModule({
name: 'timeout',
type: CommandType.Slash,
plugins: [publish(), ownerOnly()],
description: 'ADMIN: Silencia a usuarios.',
options: [
{
name: "usuario",
description: "Escribe el usuario que silenciar.",
type: ApplicationCommandOptionType.User,
required: true
},
{
name: "razon",
description: "Escribe el razon que vas a silenciar.",
type: ApplicationCommandOptionType.String,
required: true
},
{
name: "minutos",
description: "Escribe los minutos que estará silenciado.",
type: ApplicationCommandOptionType.Number,
min_value: 0,
required: true
}
],
//alias : [],
execute: async (ctx, options) => {
try {
const usuario = options[1].getMember('usuario') as GuildMember
const minutos = options[1].getNumber('minutos') as number
const razon = options[1].getString('razon', true);
const minutosToMilisegundos = minutos * 60 * 1000
usuario.timeout(minutosToMilisegundos, razon).then(() => {ctx.reply({content: `Se ha silenciado a ${usuario} correctamente.`, ephemeral: true})})
const sendToMods = ctx.client.guilds.cache.get(process.env.GUILDID!)!.channels.cache.get(process.env.MODLOGS_CHANNEL!) as TextChannel
await sendToMods.send({content: `Se ha silenciado a ${usuario}.\nSlencio efectuado por ${ctx.user} con ${minutos} minutos de duración.\nRazón: ${razon}`})
} catch {
await ctx.reply({content: `ERROR: No puedo hacer este comando porque a lo mejor soy inferior que el rol de esa persona o estoy usándolo contra admins.`})
}
},
});

212
commands/moderation/warn.ts Normal file
View File

@@ -0,0 +1,212 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins";;
import { ActionRowBuilder, ApplicationCommandOptionType, ButtonBuilder, ButtonInteraction, ButtonStyle, ComponentType, EmbedBuilder, GuildMember } from "discord.js";
import db from '../../schemas/warn.js';
export default commandModule({
name: 'warn',
type: CommandType.Slash,
plugins: [publish(), ownerOnly()],
description: 'ADMIN: Avisa a usuarios.',
//alias : [],
options: [
{
name: 'leve',
description: 'Aviso leve.',
type: ApplicationCommandOptionType.Subcommand,
options: [
{
name: 'usuario',
description: 'el usuario al que avisar.',
type: ApplicationCommandOptionType.User,
required: true
},
{
name: 'razon',
description: 'la razón aviso.',
type: ApplicationCommandOptionType.String,
required: true
}
]
},
{
name: 'grave',
description: 'Aviso grave.',
type: ApplicationCommandOptionType.Subcommand,
options: [
{
name: 'usuario',
description: 'el usuario al que avisar.',
type: ApplicationCommandOptionType.User,
required: true
},
{
name: 'razon',
description: 'la razón del aviso.',
type: ApplicationCommandOptionType.String,
required: true
}
]
},
{
name: 'clear',
description: 'Elimina los avisos de una persona.',
type: ApplicationCommandOptionType.Subcommand,
options: [
{
name: 'usuario',
description: 'el usuario al que quitar el aviso.',
type: ApplicationCommandOptionType.User,
required: true
}
]
}
],
execute: async (ctx, options) => {
const subcommand = options[1].getSubcommand()
const user = (options[1].getMember('usuario') as GuildMember).id
const usermember = options[1].getMember('usuario') as GuildMember
const reason = options[1].getString('razon', true) as string
const times = await db.findOne({id: `${user}`}) as any
const buttons = new ActionRowBuilder<ButtonBuilder>()
.addComponents(
new ButtonBuilder()
.setCustomId('1hour')
.setLabel('1 hora')
.setStyle(ButtonStyle.Danger),
new ButtonBuilder()
.setCustomId('30mins')
.setLabel('30 minutos')
.setStyle(ButtonStyle.Danger),
new ButtonBuilder()
.setCustomId('15mins')
.setLabel('15 minutos')
.setStyle(ButtonStyle.Danger),
new ButtonBuilder()
.setCustomId('pardon')
.setLabel('Perdonar')
.setStyle(ButtonStyle.Primary)
);
const dmEmbed = new EmbedBuilder()
.setAuthor({name: `${ctx.user.username}`, iconURL: `${ctx.user.displayAvatarURL()}`})
.setColor('Red')
.setTitle('Tienes un aviso.')
.setDescription(`Has sido avisado en el servidor de Discord.\nRazón: ${reason}.`)
const dmEmbedTimeout = new EmbedBuilder()
.setAuthor({name: `${ctx.user.username}`, iconURL: `${ctx.user.displayAvatarURL()}`})
.setColor('Red')
.setTitle('Acabas de ser muteado del servidor.')
.setDescription(`Ve al servidor de Discord para ver el tiempo que estarás bloqueado.\nRazón: ${reason}.\n**Puede durar hasta una hora.**`)
switch (subcommand) {
case "leve": {
return db.exists({id: `${user}`}, async function (err, doc) {
if (err) {
console.log(err)
} else {
if (doc === null) {
const warn = new db({id: `${user}`, times: 1})
warn.save()
ctx.reply({content: `Se ha avisado a ${usermember} correctamente y añadido a la base de datos.`, ephemeral: true})
ctx.client.users.fetch(user).then((user) => {
user.send({embeds: [dmEmbed]})
}).catch(() => console.log(`couldn't send a DM to user ID ${user}.`));
} else {
if (times.times > 2) {
const msg = await ctx.reply({content: `El usuario ha excedido 3 avisos, ¿qué hacer?`, ephemeral: true, components: [buttons]})
const collector = msg.createMessageComponentCollector({ time: 15000, max: 1, componentType: ComponentType.Button });
collector.on('collect', async (i) => {
await i.deferReply({ephemeral: true})
if (i.customId === '1hour') {
await i.editReply({content: `Se ha silenciado a ${usermember} durante 1 hora correctamente. ;-;`})
usermember.timeout(60 * 60 * 1000, reason)
times.times = 0
times.save()
} else if (i.customId === '30mins') {
await i.editReply({content: `Se ha silenciado a ${usermember} durante 30 minutos correctamente. ;-;`})
usermember.timeout(30 * 60 * 1000, reason)
times.times = 0
times.save()
} else if (i.customId === '15mins') {
await i.editReply({content: `Se ha silenciado a ${usermember} durante 15 minutos correctamente. ;-;`})
usermember.timeout(15 * 60 * 1000, reason)
times.times = 0
times.save()
} else if (i.customId === 'pardon') {
await i.editReply({content: `Se ha perdonado a ${usermember} correctamente.\nSeguro que la persona te lo agradecerá! :'D`})
times.times = 0
times.save()
}
ctx.client.users.fetch(user).then((user) => {
user.send({embeds: [dmEmbedTimeout]})
}).catch(() => console.log(`couldn't send a DM to user ID ${user}.`));
});
} else {
ctx.reply({content: `se ha añadido un aviso con el motivo ${reason}.\navisos que tiene ahora: ${times.times + 1}`, ephemeral: true})
times.times = times.times + 1
times.save()
ctx.client.users.fetch(user).then((user) => {
user.send({embeds: [dmEmbed]});
}).catch(() => console.log(`couldn't send a DM to user ID ${user}.`))
}
}
}
});
}
case "grave": {
return db.exists({id: `${user}`}, async function (err, doc) {
if (err) {
console.log(err)
} else {
if (doc === null) {
const warn = new db({id: `${user}`, times: 2})
warn.save()
ctx.reply({content: `Se ha avisado a ${usermember} correctamente y añadido a la base de datos.`, ephemeral: true})
ctx.client.users.fetch(user).then((user) => {
user.send({embeds: [dmEmbed]});
}).catch(() => console.log(`couldn't send a DM to user ID ${user}.`))
} else {
if (times.times >= 4) {
const msg = await ctx.reply({content: `El usuario ha excedido 3 avisos, ¿qué hacer?`, ephemeral: true, components: [buttons]})
const collector = msg.createMessageComponentCollector({ time: 1000, max: 1, componentType: ComponentType.Button });
collector.on('collect', async (i: any) => {
if (i.customId === '1hour') {
await i.channel!.send({content: `Se ha silenciado a ${usermember} durante 1 hora correctamente. ;-;`})
usermember.timeout(60 * 60 * 1000, reason)
times.times = 0
times.save()
} else if (i.customId === '30mins') {
await i.channel!.send({content: `Se ha silenciado a ${usermember} durante 30 minutos correctamente. ;-;`})
usermember.timeout(30 * 60 * 1000, reason)
times.times = 0
times.save()
} else if (i.customId === '15mins') {
await i.channel!.send({content: `Se ha silenciado a ${usermember} durante 15 minutos correctamente. ;-;`})
usermember.timeout(15 * 60 * 1000, reason)
times.times = 0
times.save()
} else if (i.customId === 'pardon') {
await i.channel!.send({content: `Se ha perdonado a ${usermember} correctamente.\nSeguro que la persona te lo agradecerá! :'D`})
times.times = 0
times.save()
}
ctx.client.users.fetch(user).then((user) => {
user.send({embeds: [dmEmbedTimeout]})
}).catch(() => console.log(`couldn't send a DM to user ID ${user}.`));
});
} else {
ctx.reply({content: `se ha añadido un aviso con el motivo ${reason}.\navisos que tiene ahora: ${times.times + 2}`, ephemeral: true})
times.times = times.times + 2
times.save()
ctx.client.users.fetch(user).then((user) => {
user.send({embeds: [dmEmbed]});
}).catch(() => console.log(`couldn't send a DM to user ID ${user}.`))
}
}
}
});
}
}
}
})

View File

@@ -1,11 +1,11 @@
import { commandModule, CommandType } from '@sern/handler'
import { publish } from "#plugins";
import { ownerOnly } from "#plugins"
export default commandModule({
name: 'ping',
type: CommandType.Slash,
plugins: [],
plugins: [publish()],
description: 'A ping command',
//alias : [],
options: [],

2
dependencies.d.ts vendored
View File

@@ -1,11 +1,9 @@
import { SernEmitter, Logging, CoreModuleStore, ModuleManager, ErrorHandling, CoreDependencies, Singleton } from '@sern/handler'
import { Client } from 'discord.js'
import Spotify from 'spotify-api.js'
declare global {
interface Dependencies extends CoreDependencies {
'@sern/client': Singleton<Client>
'spotify-api-client': Singleton<Spotify.Client>
}
}

10
deploy.sh Normal file
View File

@@ -0,0 +1,10 @@
#!/bin/bash
git pull
docker build . -t srizan10/vinci
docker stop vinci
docker rm vinci
docker run -d -t --name vinci -p 7272:7272 --restart unless-stopped srizan10/vinci

View File

@@ -1,10 +1,11 @@
import { EventType, discordEvent, eventModule } from '@sern/handler';
import { EventType, eventModule } from '@sern/handler';
import { EmbedBuilder, Message } from 'discord.js';
import db from '../schemas/afk.js';
export default discordEvent({
export default eventModule({
type: EventType.Discord,
name: 'messageCreate',
execute: async (message) => {
execute: async (message: Message) => {
const dbEntries = await db.find()
dbEntries.forEach(async (doc) => {

41
events/chatgptMessage.ts Normal file
View File

@@ -0,0 +1,41 @@
import { discordEvent } from '@sern/handler';
import axios from 'axios';
import { TextChannel } from 'discord.js';
import db from '../schemas/chatgpt.js';
export default discordEvent({
name: 'messageCreate',
async execute(message) {
if (message.channel.id !== process.env.CHATGPT_CHANNEL) return;
if (message.author.bot) return;
if (message.content.includes('ig')) return;
try {
await (message.channel as TextChannel).sendTyping()
const response = await axios.post('https://chatgpt-api.shn.hk/v1/', {
"model": "gpt-3.5-turbo",
"messages": [{ "role": "user", "content": message.content }]
}).then(res => res.data)
const titleResponse = await axios.post('https://chatgpt-api.shn.hk/v1/', {
"model": "gpt-3.5-turbo",
"messages": [{ "role": "user", "content": `Generate a title in less than 6 words for the following message, also remove the quotes if you are going to add them AND don't put Title in the beginning:\nUser: ${message.content}\nAssistant: ${response.choices[0].message.content}` }]
}).then(res => res.data.choices[0].message.content.replaceAll('"', '') as string)
const botMsg = await message.reply({ content: response.choices[0].message.content.slice(0, 2000) })
const thread = await botMsg.startThread({ name: titleResponse })
const dbData = new db({
messageid: message.id,
threadid: thread.id,
messages: [
{ role: 'user', content: message.content },
{ role: 'assistant', content: response.choices[0].message.content.replace(/^\n{2}/, '') }
]
})
await dbData.save()
} catch (e) {
await message.reply({ content: 'Algo ha ido mal.' }).catch(() => {})
console.log(e)
}
},
});

53
events/chatgptThread.ts Normal file
View File

@@ -0,0 +1,53 @@
import { discordEvent } from '@sern/handler';
import axios from 'axios';
import { ThreadChannel } from 'discord.js';
import database from '../schemas/chatgpt.js';
export default discordEvent({
name: 'messageCreate',
async execute(message) {
const thread = message.channel as ThreadChannel
if (thread.parentId !== process.env.CHATGPT_CHANNEL) return;
if (message.author.bot) return;
if (message.content.includes('ig')) return;
try {
await thread.sendTyping()
let newObj = { role: 'user', content: message.content }
let db = await database.findOneAndUpdate({ threadid: thread.id }, {
$push: {
messages: newObj
}
})
const messages = db!.messages.map((message) => {
const { _id, ...rest } = message.toObject(); // Convert Mongoose document to plain object and remove _id field
return rest
})
const response = await axios.post('https://chatgpt-api.shn.hk/v1/', {
"model": "gpt-3.5-turbo",
"messages": messages
}, {
headers: {
'Content-Type': 'application/json'
}
}).then(res => res.data.choices[0].message.content as string)
newObj = { role: 'assistant', content: response }
db = await database.findOneAndUpdate({ threadid: thread.id }, {
$push: {
messages: newObj
}
})
await message.reply({ content: response.slice(0, 2000) })
} catch (e) {
await message.reply('Algo ha ido mal.')
console.log(e)
}
},
});
function replacer(key, value) {
return value.replace(/[^\w\s]/gi, '');
}

View File

@@ -6,4 +6,4 @@ export default eventModule({
execute(err) {
console.log(err);
}
})
})

View File

@@ -1,19 +1,20 @@
import { EmbedBuilder, GuildMember, TextChannel } from "discord.js";
import { EventType, discordEvent, eventModule } from "@sern/handler";
import { EventType, eventModule } from "@sern/handler";
export default discordEvent({
export default eventModule({
type: EventType.Discord,
name: 'guildMemberAdd',
execute(member) {
execute(member: GuildMember) {
if (member.guild.id !== process.env.GUILDID) return;
const newMemberEmbed = new EmbedBuilder()
const newMemberEmbed = new EmbedBuilder()
.setColor("Random")
.setTitle("Nuevo miembro!")
.setDescription(`${member.user} acaba de entrar al servidor!`)
.setThumbnail(member.user.displayAvatarURL())
.setTimestamp();
const channel = member.client.guilds.cache.get(process.env.GUILDID!)!.channels.cache.get(process.env.JOINSANDLEAVES_CHANNEL!) as unknown as TextChannel
const channel = member.client.guilds.cache.get(process.env.GUILDID!)!.channels.cache.get(process.env.JOINSANDLEAVES_CHANNEL!) as TextChannel
channel.send({embeds: [newMemberEmbed]})
}
});

View File

@@ -1,19 +1,20 @@
import { EmbedBuilder, GuildMember, TextChannel } from "discord.js";
import { EventType, discordEvent, eventModule } from "@sern/handler";
import { EventType, eventModule } from "@sern/handler";
export default discordEvent({
export default eventModule({
type: EventType.Discord,
name: 'guildMemberRemove',
execute(member) {
execute(member: GuildMember) {
if (member.guild.id !== process.env.GUILDID) return;
const leaveEmbed = new EmbedBuilder()
const leaveEmbed = new EmbedBuilder()
.setColor("Random")
.setTitle("Un miembro se ha ido :(")
.setDescription(`${member.user} acaba de salir del servidor!`)
.setThumbnail(member.user.displayAvatarURL())
.setTimestamp();
const channel = member.client.guilds.cache.get(process.env.GUILDID!)!.channels.cache.get(process.env.JOINSANDLEAVES_CHANNEL!) as unknown as TextChannel
const channel = member.client.guilds.cache.get(process.env.GUILDID!)!.channels.cache.get(process.env.JOINSANDLEAVES_CHANNEL!) as TextChannel
channel.send({embeds: [leaveEmbed]})
}
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

After

Width:  |  Height:  |  Size: 189 KiB

View File

@@ -1,4 +1,4 @@
import { makeDependencies } from '@sern/handler';
import { DefaultLogging, makeDependencies, single, Singleton } from '@sern/handler';
import { ActivityOptions, ActivityType } from 'discord.js';
import { Client, GatewayIntentBits } from 'discord.js';
import { Sern } from '@sern/handler';
@@ -8,11 +8,10 @@ import youtubenotifications from './util/youtubenotifications.js';
import { setIntervalAsync } from 'set-interval-async';
import birthdays from './util/birthdays.js';
import minecraftstatus from './util/minecraftstatus.js';
import Spotify from 'spotify-api.js';
import { Publisher } from '@sern/publisher';
import * as sernconfig from './config.js'
import axios from 'axios';
// import giveawaychecker from './util/giveawaychecker.js';
export let devMode: boolean
let devMode: boolean
if (process.argv[2] === '--dev') {
devMode = true
dotenv({path: '.env.dev'})
@@ -37,21 +36,20 @@ mongoose.connect(process.env.MONGODB!).then(() => {
console.log('Connected to MongoDB');
});
const spotifyClient = await Spotify.Client.create({
token: { clientID: process.env.SPOTIFY_CLIENT!, clientSecret: process.env.SPOTIFY_SECRET! },
})
interface MyDependencies extends Dependencies {
'@sern/client' : Singleton<Client>;
'@sern/logger' : Singleton<DefaultLogging>
}
await makeDependencies(({ add }) => {
add('@sern/client', client);
add('publisher', deps => new Publisher(
deps['@sern/modules'],
deps['@sern/emitter'],
deps['@sern/logger']!
));
add('spotify-api-client', spotifyClient);
await makeDependencies<MyDependencies>({
build: (root) => root.add({ '@sern/client': single(() => client) }),
});
Sern.init(sernconfig);
Sern.init({
commands: 'dist/commands',
events: 'dist/events',
defaultPrefix: process.env.PREFIX,
});
client.on('ready', async () => {
console.log('Logged on!');
@@ -60,14 +58,14 @@ client.on('ready', async () => {
const statuses = [
{ name: 'Minecraft', type: ActivityType.Playing },
{ name: 'cómo escribe Javi', type: ActivityType.Watching },
{ name: 'sexto libro when', type: ActivityType.Watching },
{ name: 'quinto libro when', type: ActivityType.Watching },
{ name: 'a Hermes', type: ActivityType.Watching },
{ name: 'tus comandos', type: ActivityType.Listening },
{ name: 'tu voz', type: ActivityType.Listening },
{ name: 'ahora v1.0!', type: ActivityType.Playing },
] as ActivityOptions[];
const randomStatus = statuses[Math.floor(Math.random() * statuses.length)];
client.user!.setActivity(randomStatus);
client.user.setActivity(randomStatus);
}, 10000);
if (!devMode) {
@@ -87,6 +85,6 @@ client.on('ready', async () => {
}
});
// export const scamLinks = await axios.get('https://api.hyperphish.com/gimme-domains').then(res => res.data as Array<string>)
export const scamLinks = await axios.get('https://api.hyperphish.com/gimme-domains').then(res => res.data as Array<string>)
client.login();
client.login(process.env.TOKEN);

View File

@@ -1,14 +1,13 @@
{
"name": "vinci",
"version": "1.1.0",
"version": "1.0.0",
"description": "Vinci Discord Bot for Mara Turing",
"main": "dist/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "sern build && node ./dist/index.js --dev",
"prod": "tsc-watch -p \"./tsconfig.json\" --onSuccess \"node ./dist/index.js\"",
"dev": "tsc-watch -p \"./tsconfig.json\" --onSuccess \"node ./dist/index.js --dev\"",
"compile": "tsc --build",
"build": "sern build",
"build": "tsc --build",
"web": "node webserver.js",
"watch": "tsc --watch",
"start": "nodemon dist/index.js"
@@ -33,25 +32,21 @@
},
"homepage": "https://github.com/SrIzan10/vinci#readme",
"dependencies": {
"@ai-zen/node-fetch-event-source": "^2.1.4",
"@consumet/extensions": "^1.7.0",
"@consumet/extensions": "1.3.5",
"@discordjs/opus": "^0.9.0",
"@discordjs/voice": "^0.15.0",
"@microsoft/fetch-event-source": "^2.0.1",
"@napi-rs/canvas": "^0.1.52",
"@sern/handler": "^4.0.2",
"@sern/publisher": "^1.1.2",
"axios": "^1.6.8",
"@napi-rs/canvas": "^0.1.30",
"@sern/handler": "^3.0.3",
"axios": "^1.1.3",
"dayjs": "^1.11.6",
"discord-tictactoe": "^4.0.0",
"discord.js": "^14.16.2",
"discord.js": "^14.13.0",
"dotenv": "^16.0.1",
"execa": "^6.1.0",
"express": "^4.18.1",
"extended-eventsource": "^1.4.6",
"form-data": "^4.0.0",
"genius-lyrics": "^4.4.3",
"googlethis": "^1.8.0",
"googlethis": "^1.7.1",
"got": "^12.5.3",
"libsodium-wrappers": "^0.7.10",
"mongoose": "^6.11.3",
@@ -59,18 +54,13 @@
"pretty-seconds-spanish": "^2.1.1",
"rockpaperscissors-checker": "^1.2.0",
"set-interval-async": "^3.0.2",
"sharp": "^0.33.3",
"spotify-api.js": "^9.2.5",
"stringify-safe": "^1.0.3",
"systeminformation": "^5.21.7"
"systeminformation": "^5.12.6"
},
"devDependencies": {
"@sern/cli": "^1.3.3",
"@types/express": "^4.17.14",
"@types/node": "^20.12.7",
"ts-node": "10.9.1",
"tsc-watch": "^5.0.3",
"typescript": "^5.6.2"
},
"packageManager": "yarn@4.1.1"
"typescript": "^5.2.2"
}
}

View File

@@ -2,4 +2,3 @@ export * from './publish.js'
export * from './ownerOnly.js'
export * from './srIzanOnly.js'
export * from './acceptingBirthday.js'
export * from './disable.js'

View File

@@ -1,7 +1,7 @@
import mongoose from 'mongoose'
const messageSchema = new mongoose.Schema({
role: { type: String, required: true },
content: { type: String, reqmuired: true },
content: { type: String, required: true },
});
const schema = new mongoose.Schema({
messageid: { type: String, required: true },

9
schemas/counting.js Normal file
View File

@@ -0,0 +1,9 @@
const mongoose = require('mongoose');
const schema = new mongoose.Schema({
number: {type: Number, required: true}
})
const db = new mongoose.Model('counting', schema)
module.exports = db;

View File

@@ -1,7 +1,7 @@
{
"language": "typescript",
"paths": {
"base": "src",
"base": ".",
"commands": "commands"
}
}

View File

@@ -1,56 +0,0 @@
import { commandModule, CommandType } from '@sern/handler';
import { publish } from '#plugins';
import { AttachmentBuilder, codeBlock } from 'discord.js';
import { createCanvas, loadImage } from '@napi-rs/canvas';
import sharp from 'sharp';
export default commandModule({
name: 'Clasifica una imagen',
type: CommandType.CtxMsg,
plugins: [],
execute: async (ctx) => {
await ctx.deferReply()
if (ctx.targetMessage.attachments.size === 0) return ctx.editReply('No hay ninguna imagen para clasificar!');
const image = ctx.targetMessage.attachments.first()!;
if (!image.contentType!.startsWith('image/') && image.contentType !== 'image/gif') return ctx.editReply('El archivo no es una imagen!');
const imageBuffer = await fetch(image.url).then(async res => await res.arrayBuffer());
const compressed = sharp(imageBuffer)
.png({quality: 70})
.jpeg({quality: 70})
.webp({quality: 70})
.tiff({quality: 70});
const metadata = await compressed.metadata();
const imageUint8Array = new Uint8Array(await compressed.toBuffer());
const request = await fetch(`https://api.cloudflare.com/client/v4/accounts/${process.env.CF_AI_ACC}/ai/run/@cf/facebook/detr-resnet-50`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CF_AI_TOKEN}`,
},
body: imageUint8Array,
}).then(async res => await res.json());
if (request.errors.length > 0) return ctx.editReply(`Hubo un error! ${codeBlock(JSON.stringify(request.errors))}`);
// all canvas stuff, this was fun to make
const canvas = createCanvas(metadata.width!, metadata.height!);
const ctxCanvas = canvas.getContext('2d');
const img = await loadImage(image.url);
ctxCanvas.drawImage(img, 0, 0, metadata.width!, metadata.height!);
ctxCanvas.font = '40px sans-serif';
ctxCanvas.fillStyle = 'red';
ctxCanvas.strokeStyle = 'red';
ctxCanvas.lineWidth = 3;
for (const result of request.result) {
if (result.score < 0.5) continue;
const box = result.box;
ctxCanvas.strokeRect(box.xmin, box.ymin, box.xmax - box.xmin, box.ymax - box.ymin);
ctxCanvas.fillText(result.label, box.xmin, box.ymin - 5);
}
const canvasBuffer = canvas.toBuffer('image/png');
const attachment = new AttachmentBuilder(canvasBuffer, { name: 'generatedImage.png' });
await ctx.editReply({ files: [attachment] })
},
});

Some files were not shown because too many files have changed in this diff Show More