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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 55 - (show 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 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