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
text/typescript
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 }
}