UNPKG

aya-helper

Version:

This is a new package, that can help you with moderation, tickets, fun commands, nsfw and anime commands.

815 lines (772 loc) 27.7 kB
import axios from "axios"; import { CacheType, Client, CommandInteraction, Guild, GuildMember, MessageActionRow, MessageButton, TextChannel, User } from "discord.js"; import { Database } from "quickmongo"; import { v5 as uuid } from 'uuid'; export default interface AyaHelper { client: Client; mongoUrl: string; db: Database; moderation: AyaModeration; economy: AyaEconomy; tickets: AyaTickets; fun: AyaFun; nsfw: AyaNsfw; anime: AyaAnime; constructor( client: Client, mongoUrl: string, onConnecting: Function, onConnect: Function, onError: Function, ); } export interface AyaModeration { db: Database; client: Client; constructor(db: Database, client: Client); timeout(member: GuildMember, time: number, reason?: string): Promise<boolean>; ban(member: GuildMember, reason?: string, soft?: boolean): Promise<boolean>; kick(member: GuildMember, reason?: string): Promise<boolean>; purge(channel: TextChannel, amount: number): Promise<boolean>; infractions(member: GuildMember): Promise<Infraction[]>; addInfraction(infraction: Infraction): Promise<void>; removeInfraction(user: User, id: string): Promise<Infraction>; } export interface Infraction { id: string; member: GuildMember; reason?: string; type: 'BAN' | 'KICK' | 'TIMEOUT' | 'UNKNOWN'; constructor(member: GuildMember, type: 'BAN' | 'KICK' | 'TIMEOUT' | 'UNKNOWN', reason?: string); } export interface AyaEconomy { db: Database; client: Client; constructor(db: Database, client: Client); balance(member: GuildMember): Promise<Balance>; add(member: GuildMember, amount: number, type: 'WALLET' | 'BANK' | 'TOTAL_BANK') : Promise<Balance>; remove(member: GuildMember, amount: number, type: 'WALLET' | 'BANK' | 'TOTAL_BANK') : Promise<Balance>; getDefaultBalance() : { wallet: number, bank: number, totalBank: number }; shop() : Promise<Shop>; inventory(member: GuildMember) : Promise<Inventory>; addItem(member: GuildMember, item: Item) : Promise<Inventory>; removeItem(member: GuildMember, name: string, amount: number) : Promise<Inventory>; } export interface Inventory { member: GuildMember; items: Item[]; constructor(member: GuildMember, items: Item[]); } export interface Shop { items: Item[]; constructor(items: Item[]); } export interface Item { name: string; cost: number; amount?: number; icon?: string; owned?: boolean; constructor(name: string, cost: number, amount?: number, icon?: string, owned?: boolean); } export interface Balance { wallet: number; bank: number; totalBank: number; constructor(wallet: number, bank: number, totalBank: number); } export interface AyaTickets { db: Database; client: Client; constructor(db: Database, client: Client); getAll(guildId?: string) : Promise<Ticket[]>; removeAll(guildId?: string) : Promise<boolean>; get(member: GuildMember) : Promise<Ticket>; find(id: string) : Promise<Ticket>; remove(id: string) : Promise<Ticket>; create(member: GuildMember) : Promise<Ticket>; } export interface Ticket { member: GuildMember; channel: TextChannel; id: string; constructor(member: GuildMember, channel: TextChannel); } export interface AyaFun { client: Client; constructor(client: Client); eightBall(answers: []) : string; rps(user: GuildMember, user2: GuildMember, interaction: CommandInteraction<CacheType>) : Promise<void>; coinflip() : 'tails' | 'heads'; bird() : Promise<FunRequest>; cat() : Promise<FunRequest>; dog() : Promise<FunRequest>; fox() : Promise<FunRequest>; panda() : Promise<FunRequest>; birdfact() : Promise<string>; catfact() : Promise<FunRequest>; dogfact() : Promise<string>; pandafact() : Promise<string>; meme() : Promise<MemeRequest>; gayify(member: GuildMember) : FunRequest; jail(member: GuildMember) : FunRequest; triggered(member: GuildMember) : FunRequest; } export interface MemeRequest { title: string; image: string; constructor(title: string, image: string); } export interface FunRequest { image: string; constructor(image: string); } export interface AyaNsfw { client: Client; constructor(client: Client); hentai() : Promise<NsfwRequest>; neko() : Promise<NsfwRequest>; lesbian() : Promise<NsfwRequest>; kuni() : Promise<NsfwRequest>; cumsluts() : Promise<NsfwRequest>; classic() : Promise<NsfwRequest>; boobs() : Promise<NsfwRequest>; blowjob() : Promise<NsfwRequest>; yuri() : Promise<NsfwRequest>; tits() : Promise<NsfwRequest>; solo() : Promise<NsfwRequest>; feet() : Promise<NsfwRequest>; request(type: string) : Promise<NsfwRequest>; } export interface NsfwRequest { type: string; image: string; constructor(type: string, image: string); } export interface AyaAnime { client: Client; constructor(client: Client); slap(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>; poke(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>; pat(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>; tickle(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>; cuddle(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>; kiss(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>; meow(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>; waifu() : Promise<AnimeRequest>; request(type): Promise<AnimeRequest>; } export interface AnimeRequest { type: string; image: string; constructor(type: string, image: string); } export default class AyaHelper { client: Client; mongoUrl: string; db: Database; moderation: AyaModeration; economy: AyaEconomy; tickets: AyaTickets; fun: AyaFun; nsfw: AyaNsfw; anime: AyaAnime; constructor( client: Client, mongoUrl: string, onConnecting: Function, onConnect: Function, onError: Function, ) { this.client = client; this.mongoUrl = mongoUrl; this.db = new Database(mongoUrl); this.db.connect(); this.db.on('connecting', () => onConnecting()); this.db.on('connected', () => onConnect()); this.db.on('error', () => onError()); this.moderation = new AyaModeration(this.db, client); this.economy = new AyaEconomy(this.db, client); this.tickets = new AyaTickets(this.db, client); this.fun = new AyaFun(client); this.nsfw = new AyaNsfw(client); this.anime = new AyaAnime(client); } } export class AyaModeration { db: Database; client: Client; constructor(db: Database, client: Client) { this.db = db; this.client = client; } async timeout(member: GuildMember, time: number, reason: string = 'No Reason') : Promise<boolean> { return member.timeout(time, reason) .then(() => true) .catch(() => false) } async ban(member: GuildMember, reason: string = 'No Reason', soft: boolean = false): Promise<boolean> { return member.ban({ reason: reason }).then(() => { if (soft) { return member.guild.bans.remove(member.user.id, reason) .then(() => true) .then(() => false); } return true; }).catch(() => false); } async kick(member: GuildMember, reason: string = 'No Reason'): Promise<boolean> { return member.kick(reason) .then(() => true) .catch(() => false); } async purge(channel: TextChannel, amount: number): Promise<boolean> { return channel.bulkDelete(amount) .then(() => true) .catch(() => false); } async infractions(member: GuildMember): Promise<Infraction[]> { let inf: any = await this.db.get(`infractions_${member.user.id}`) ?? []; return inf.map(a => new Infraction( member, a.type, a.reason )); } async addInfraction(infraction: Infraction): Promise<void> { let inf: any = await this.db.get(`infractions_${infraction.member.user.id}`) ?? []; inf.push({ id: infraction.id, member: infraction.member.user.id, type: infraction.type, reason: infraction.reason }); await this.db.set(`infractions_${infraction.member.user.id}`, inf); } async removeInfraction(user: User, id: string): Promise<Infraction> { let inf: any = await this.db.get(`infractions_${user.id}`) ?? []; let infraction = inf.find(a => a.id === id); if (!infraction) return null; await this.db.set(`infractions_${user.id}`, inf.filter(a => a.id != id)); return infraction; } } export class Infraction { id: string; member: GuildMember; reason?: string; type: 'BAN' | 'KICK' | 'TIMEOUT' | 'UNKNOWN'; constructor(member: GuildMember, type: 'BAN' | 'KICK' | 'TIMEOUT' | 'UNKNOWN', reason?: string) { this.id = (uuid as any)(); this.member = member; this.type = type ?? 'UNKNOWN'; this.reason = reason || 'No Reason provided'; } } export class AyaEconomy { db: Database; client: Client; constructor(db: Database, client: Client) { this.db = db; this.client = client; } async balance(member: GuildMember): Promise<Balance> { let balance: any = await this.db.get(`balance_${member.user.id}`) ?? this.getDefaultBalance(); return new Balance( balance.wallet, balance.bank, balance.totalBank ) } async add(member: GuildMember, amount: number, type: 'WALLET' | 'BANK' | 'TOTAL_BANK'): Promise<Balance> { let balance: any = await this.db.get(`balance_${member.user.id}`) ?? this.getDefaultBalance(); if (type === 'WALLET') balance.wallet = (balance.wallet ?? 0) + amount; if (type === 'BANK') balance.bank = (balance.bank ?? 0) + amount; if (type === 'TOTAL_BANK') balance.totalBank = (balance.totalBank ?? 0) + amount; await this.db.set(`balance_${member.user.id}`, balance); return new Balance( balance.wallet, balance.bank, balance.totalBank ) } async remove(member: GuildMember, amount: number, type: 'WALLET' | 'BANK' | 'TOTAL_BANK'): Promise<Balance> { let balance: any = await this.db.get(`balance_${member.user.id}`) ?? this.getDefaultBalance(); if (type === 'WALLET') balance.wallet = (balance.wallet ?? 0) - amount; if (type === 'BANK') balance.bank = (balance.bank ?? 0) - amount; if (type === 'TOTAL_BANK') balance.totalBank = (balance.totalBank ?? 0) - amount; await this.db.set(`balance_${member.user.id}`, balance); return new Balance( balance.wallet, balance.bank, balance.totalBank ) } getDefaultBalance() { return { wallet: 0, bank: 0, totalBank: 0 } } async shop(): Promise<Shop> { return new Shop( [ new Item('coming soon', 200) ] ); } async inventory(member: GuildMember): Promise<Inventory> { let inventory: any = await this.db.get(`inventory_${member.user.id}`) ?? { member: null, items: [] } return new Inventory( member, inventory.items ); } async addItem(member: GuildMember, item: Item): Promise<Inventory> { let inventory: any = await this.db.get(`inventory_${member.user.id}`) ?? { member: null, items: [], } inventory.items.push(item); await this.db.set(`inventory_${member.user.id}`, inventory); return new Inventory( member, inventory.items ) } async removeItem(member: GuildMember, name: string, amount: number): Promise<Inventory> { let inventory: any = await this.db.get(`inventory_${member.user.id}`) ?? { member: null, items: [] } inventory.items = inventory.items.map(a => { if (a.name === name) { a.amount = a.amount - amount; if (a.amount <= 0) { return null; } } return a; }).filter(a => a != null); await this.db.set(`inventory_${member.user.id}`, inventory); return new Inventory( member, inventory.items ); } } export class Inventory { member: GuildMember; items: Item[]; constructor(member: GuildMember, items: Item[]) { this.member = member; this.items = items; } } export class Shop { items: Item[]; constructor(items: Item[]) { this.items = items; } } export class Item { icon?: string; name: string; cost: number; amount?: number; owned?: boolean; constructor(name: string, cost: number, amount?: number, icon?: string, owned?: boolean) { this.name = name; this.cost = cost; this.amount = amount; this.icon = icon; this.owned = owned; } } export class Balance { wallet: number; bank: number; totalBank: number; constructor(wallet: number, bank: number, totalBank: number) { this.wallet = wallet; this.bank = bank; this.totalBank = totalBank; } } export class AyaTickets { db: Database; client: Client; constructor(db: Database, client: Client) { this.db = db; this.client = client; } async getAll(guildId?: string): Promise<Ticket[]> { let all = (await this.db.all()).filter((a: any) => { return guildId ? (a.ID.startsWith('ticket-') && a.data.guild === guildId) : a.ID.startsWith('ticket-') }); return all.map((a: any) => { let guild = this.client.guilds.cache.get(a.data.guild); return new Ticket( guild, guild.members.cache.get(a.data.user).user, (guild.channels.cache.get(a.data.channel) as TextChannel) ); }) } async removeAll(guildId: string): Promise<boolean> { let all = (await this.db.all()).filter((a: any) => a.ID.startsWith('ticket-') && a.data.guild === guildId); try { all.forEach((a: any) => { this.db.delete(a.ID); }); return true; } catch (err) { return false; } } async get(member: GuildMember): Promise<Ticket> { let t: any = await this.db.get(`ticket-${member.user.id}`); let guild = this.client.guilds.cache.get(t.guild); return new Ticket( guild, member.user, (guild.channels.cache.get(t.channel) as TextChannel) ) } async find(id: string): Promise<Ticket> { let t: any = await this.db.get(`ticket-${id}`); let guild = this.client.guilds.cache.get(t.guild); return new Ticket( guild, guild.members.cache.get(id).user, (guild.channels.cache.get(t.channel) as TextChannel) ); } async remove(id: string): Promise<Ticket> { let tickets = await this.getAll(); let ticket = tickets.find(a => a.id === id); if (!ticket) return null; await this.db.delete(`ticket-${id}`); return ticket; } async create(member: GuildMember): Promise<Ticket> { let g = member.guild; return g.channels.create(`ticket-${member.user.id}`, { permissionOverwrites: [{ type: 'role', id: g.id, deny: ['VIEW_CHANNEL', 'SEND_MESSAGES'] }, { type: 'member', id: member.user.id, allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES'] }] }).then((c) => { let ticket = new Ticket( g, member.user, (c as TextChannel) ); this.db.set(`ticket-${member.user.id}`, { guild: g.id, user: member.user.id, channel: c.id }, -1); return ticket; }).catch(() => null); } } export class Ticket { guild: Guild; user: User; channel: TextChannel; id: string; constructor(guild: Guild, user: User, channel: TextChannel) { this.guild = guild; this.user = user; this.channel = channel; this.id = user.id; } } export class AyaFun { client: Client; constructor(client: Client) { this.client = client; } eightBall(answers: []): string { return answers[Math.floor(Math.random() * answers.length)]; } async rps(user: GuildMember, user2: GuildMember, interaction: CommandInteraction<CacheType>): Promise<void> { let rps = ['Rock', 'Paper', 'Scissors']; let icons = ['🗻', '📰', '✂']; await interaction.deferReply(); let msg = await interaction.editReply({ embeds: [{ title: 'Rock Paper Scissors', description: `${user.user} vs. ${user2.user}\n??? - ???\nWinner: ???`, color: 'BLURPLE', timestamp: new Date() }] }); let answered = [false, false]; let chosen = ['???', '???']; [user, user2].forEach(async (u, i) => { let other: GuildMember = null; if (i === 1) other = user; other = user2; let d = await u.user.send({ embeds: [{ title: 'Choose', description: `Choose between ${icons[0]} (Rock), ${icons[1]} (Paper), ${icons[2]} (Scissors)`, color: 'GREEN', timestamp: new Date(), footer: { text: `You are against ${other.user.tag}`, iconURL: other.user.displayAvatarURL({ dynamic: true, format: 'png' }) } }], components: [new MessageActionRow().addComponents([ new MessageButton() .setEmoji(icons[0]) .setLabel(rps[0]) .setStyle('PRIMARY') .setCustomId(rps[0]) ])] }); d.awaitMessageComponent({ filter: (m) => rps.includes(m.customId), componentType: 'BUTTON' }).then(async bt => { bt.reply(`Thanks for choosing! Wait for your opponent to choose! <#${interaction.channelId}>`); let random = Math.floor(Math.random() * rps.length); answered[i] = true; chosen[i] = `${icons[random]} ${rps[random]}`; if (answered[0] === true && answered[1] === true) { let winner = '???'; let c1 = chosen[0]; let c2 = chosen[1]; if ( (c1.includes('Rock') && c2.includes('Paper')) || (c1.includes('Scissors') && c2.includes('Paper')) || (c1.includes('Rock') && c2.includes('Scissors')) ) { winner = c1; } else if ( (c2.includes('Rock') && c1.includes('Paper')) || (c2.includes('Scissors') && c1.includes('Paper')) || (c2.includes('Rock') && c1.includes('Scissors')) ) { winner = c2; } else { winner = 'No one'; } await interaction.editReply({ embeds: [{ title: 'Rock Paper Scissors', description: `${user.user} vs. ${user2.user}\n${chosen[0]} - ${chosen[1]}\nWinner: ${winner === '???' ? 'Couldn\'t find a winner' : (winner === 'No one' ? 'It\'s a tie!' : winner)}`, color: 'BLURPLE', timestamp: new Date() }] }); } }); }) } coinflip(): 'tails' | 'heads' { let sides = ['tails', 'heads']; return (sides[Math.floor(Math.random() * sides.length)] as any); } async bird() { return axios('http://shibe.online/api/birds') .then((r) => new FunRequest(r.data[0])); } async birdfact() { return axios('https://some-random-api.ml/animal/fox') .then((r) => r.data.fact); } async cat() { return axios('http://shibe.online/api/cats') .then(r => new FunRequest(r.data[0])); } async dog() { return axios('http://shibe.online/api/shibes') .then(r => new FunRequest(r.data[0])); } async fox() { return axios('https://randomfox.ca/floof') .then(r => new FunRequest(r.data.image)); } async foxfact() { return axios('https://some-random-api.ml/animal/fox') .then(r => r.data.fact); } async panda() { return axios('https://some-random-api.ml/animal/panda') .then(r => new FunRequest(r.data.image)); } async pandafact() { return axios('https://some-random-api.ml/animal/panda') .then(r => r.data.fact); } async catfact() { return axios('https://some-random-api.ml/animal/cat') .then(r => r.data.fact); } async dogfact() { return axios('https://some-random-api.ml/animal/dog') .then(r => r.data.fact); } async meme() { return axios('https://some-random-api.ml/meme') .then(r => new MemeRequest(r.data.caption, r.data.image)); } gayify(member: GuildMember): FunRequest { let link = 'https://some-random-api.ml/canvas/gay?avatar=' + member.user.displayAvatarURL({ dynamic: false, format: 'png' }); return new FunRequest(link); } jail(member: GuildMember): FunRequest { let link = 'https://some-random-api.ml/canvas/jail?avatar=' + member.user.displayAvatarURL({ dynamic: false, format: 'png' }); return new FunRequest(link); } triggered(member: GuildMember): FunRequest { let link = 'https://some-random-api.ml/canvas/triggered?avatar=' + member.user.displayAvatarURL({ dynamic: false, format: 'png' }); return new FunRequest(link); } } export class MemeRequest { title: string; image: string; constructor(title, image) { this.title = title; this.image = image; } } export class FunRequest { image: string; constructor(image) { this.image = image } } export class AyaNsfw { client: Client; constructor(client: Client) { this.client = client; } async hentai(): Promise<NsfwRequest> { return await this.request('Random_hentai_gif'); } async neko(): Promise<NsfwRequest> { return await this.request('nsfw_neko_gif'); } async lesbian(): Promise<NsfwRequest> { return await this.request('les'); } async kuni(): Promise<NsfwRequest> { return await this.request('les'); } async cumsluts(): Promise<NsfwRequest> { return await this.request('cum'); } async classic(): Promise<NsfwRequest> { return await this.request('classic'); } async boobs(): Promise<NsfwRequest> { return await this.request('boobs'); } async blowjob(): Promise<NsfwRequest> { return await this.request('bj'); } async yuri(): Promise<NsfwRequest> { return await this.request('yuri'); } async tits(): Promise<NsfwRequest> { return await this.request('tits'); } async solo(): Promise<NsfwRequest> { return await this.request('solog'); } async feet(): Promise<NsfwRequest> { return await this.request('feetg'); } async request(type: string): Promise<NsfwRequest> { return await axios({ url: `https://nekos.life/api/v2/img/` + type, }).then(r => { return new NsfwRequest(type, r.data.url); }).catch(e => { console.log(e.isAxiosError ? e.toJSON() : e); return new NsfwRequest(type, null); }); } } export class NsfwRequest { type: string; image: string; constructor(type, image) { this.type = type; this.image = image; } } export class AyaAnime { client: Client; constructor(client: Client) { this.client = client; } async slap(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> { return await this.request('slap'); } async poke(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> { return await this.request('poke'); } async pat(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> { return await this.request('pat'); } async tickle(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> { return await this.request('tickle'); } async cuddle(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> { return await this.request('cuddle'); } async kiss(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> { return await this.request('kiss'); } async meow(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> { return await this.request('meow'); } async waifu(): Promise<AnimeRequest> { return await this.request('waifu'); } async request(type: string): Promise<AnimeRequest> { return await axios({ url: `https://nekos.life/api/v2/img/` + type, }).then(r => { return new AnimeRequest(type, r.data.url); }).catch(e => { console.log(e.isAxiosError ? e.toJSON() : e); return new AnimeRequest(type, null); }); } } export class AnimeRequest { type: string; image: string; constructor(type: string, image: string) { this.type = type; this.image = image } }