/[sudobot]/trunk/src/commands/automation/BallotCommand.ts
ViewVC logotype

Annotation of /trunk/src/commands/automation/BallotCommand.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 55 - (hide annotations)
Mon Jul 29 17:28:24 2024 UTC (8 months, 1 week ago) by rakin
File MIME type: application/typescript
File size: 7298 byte(s)
Added -ballot command
1 rakin 55 import { CommandInteraction, EmojiIdentifierResolvable, GuildMember, Message, TextChannel, User } from 'discord.js';
2     import BaseCommand from '../../utils/structures/BaseCommand';
3     import DiscordClient from '../../client/Client';
4     import MessageEmbed from '../../client/MessageEmbed';
5     import CommandOptions from '../../types/CommandOptions';
6     import InteractionOptions from '../../types/InteractionOptions';
7     import { fetchEmoji } from '../../utils/Emoji';
8    
9     export default class BallotCommand extends BaseCommand {
10     supportsInteractions = true;
11    
12     constructor() {
13     super('ballot', 'automation', []);
14     }
15    
16     async ballotCreate(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) {
17     if (!options.isInteraction && typeof options.args[0] === 'undefined') {
18     await msg.reply({
19     embeds: [
20     new MessageEmbed()
21     .setColor('#f14a60')
22     .setDescription(`This command requires at least one argument.`)
23     ]
24     });
25    
26     return;
27     }
28    
29     if (msg instanceof CommandInteraction)
30     await msg.deferReply({
31     ephemeral: true
32     });
33    
34     let content: string;
35     let channel: TextChannel = msg.channel as TextChannel;
36     let anonymous = false;
37    
38     if (options.isInteraction) {
39     content = <string> await options.options.getString('content');
40    
41     if (options.options.getChannel('channel'))
42     channel = <TextChannel> await options.options.getChannel('channel');
43    
44     if (options.options.getBoolean('anonymous'))
45     anonymous = <boolean> await options.options.getBoolean('anonymous');
46     }
47     else {
48     if ((msg as Message).mentions.channels.last() && /\<#(\d+)\>/g.test([...options.args].pop()!)) {
49     channel = <TextChannel> (msg as Message).mentions.channels.last();
50     options.args.pop();
51     }
52    
53     content = await options.args.join(' ').trim();
54     }
55    
56     if (!channel.send) {
57     await this.deferReply(msg, {
58     content: 'Invalid text channel.'
59     });
60    
61     return;
62     }
63    
64     const message = await channel.send({
65     embeds: [
66     new MessageEmbed()
67     .setAuthor({
68     name: anonymous ? 'Staff' : (msg.member?.user as User).tag!,
69     iconURL: anonymous ? msg.guild!.iconURL()! : (msg.member as GuildMember)?.displayAvatarURL()
70     })
71     .setDescription(content)
72     .setTimestamp()
73     ]
74     });
75    
76     await client.db.runAsync('INSERT INTO ballots(content, author, msg_id, guild_id, date, channel_id) VALUES(?, ?, ?, ?, ?, ?)', [content, anonymous ? null : msg.member?.user.id, message.id, msg.guild!.id, new Date().toISOString(), msg.channel!.id]);
77     const ballot = await client.db.getAsync("SELECT * FROM ballots WHERE msg_id = ? AND guild_id = ? ORDER BY id DESC LIMIT 0, 1", [message.id, msg.guild!.id]);
78    
79     await message.react(<EmojiIdentifierResolvable> await fetchEmoji('check'));
80     await message.react(<EmojiIdentifierResolvable> await fetchEmoji('error'));
81    
82     await this.deferReply(msg, {
83     content: `${(await fetchEmoji('check'))!.toString()} Your message has been delivered. The ballot ID is ${ballot.id}.`,
84     });
85     }
86    
87     async ballotView(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) {
88     if (!options.isInteraction && typeof options.args[0] === 'undefined') {
89     await msg.reply({
90     embeds: [
91     new MessageEmbed()
92     .setColor('#f14a60')
93     .setDescription(`This command requires at least one argument.`)
94     ]
95     });
96    
97     return;
98     }
99    
100     try {
101     const id = options.isInteraction ? options.options.getInteger('id') : options.args[0];
102     const ballot = await client.db.getAsync("SELECT * FROM ballots WHERE id = ? ORDER BY id DESC LIMIT 0, 1", [id]);
103    
104     if (!ballot)
105     throw new Error();
106    
107     const ballotAuthor = ballot.author ? (await msg.guild!.members.fetch(ballot.author)) : null;
108    
109     const channel = <TextChannel> await msg.guild?.channels.fetch(ballot.channel_id);
110    
111     if (!channel)
112     throw new Error();
113    
114     const message = await channel.messages.fetch(ballot.msg_id);
115    
116     if (!message)
117     throw new Error();
118    
119     const upEmote = await fetchEmoji('check');
120     const downEmote = await fetchEmoji('error');
121     const upVotes = message.reactions.cache.find(r => r.emoji.id === upEmote!.id)!.count - 1;
122     const downVotes = message.reactions.cache.find(r => r.emoji.id === downEmote!.id)!.count - 1;
123    
124     await msg.reply({
125     embeds: [
126     new MessageEmbed()
127     .setAuthor({
128     name: ballot.author ? ballotAuthor!.user!.tag! : 'Staff',
129     iconURL: ballot.author ? ballotAuthor?.displayAvatarURL()! : msg.guild!.iconURL()!
130     })
131     .setDescription(ballot.content)
132     .addFields([
133     {
134     name: 'Upvotes',
135     value: `${upVotes}`
136     },
137     {
138     name: 'Downvotes',
139     value: `${downVotes}`
140     }
141     ])
142     .setTimestamp()
143     ]
144     });
145     }
146     catch (e) {
147     console.log(e);
148    
149     await msg.reply({
150     embeds: [
151     new MessageEmbed()
152     .setColor('#f14a60')
153     .setDescription(`Invalid ID or failed to fetch data.`)
154     ]
155     });
156     }
157     }
158    
159     async run(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) {
160     if (!options.isInteraction && typeof options.args[0] === 'undefined') {
161     await msg.reply({
162     embeds: [
163     new MessageEmbed()
164     .setColor('#f14a60')
165     .setDescription(`This command requires at least one subcommand.`)
166     ]
167     });
168    
169     return;
170     }
171    
172     const subcmd = options.isInteraction ? options.options.getSubcommand(true) : options.args[0];
173    
174     if (!options.isInteraction)
175     await options.args.shift();
176    
177     if (subcmd === 'create')
178     await this.ballotCreate(client, msg, options);
179     else if (subcmd === 'view')
180     await this.ballotView(client, msg, options);
181     else {
182     await msg.reply({
183     embeds: [
184     new MessageEmbed()
185     .setColor('#f14a60')
186     .setDescription(`Invalid subcommand provided.`)
187     ]
188     });
189     }
190     }
191     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26