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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26