/[sudobot]/branches/4.x/src/commands/automation/BallotCommand.ts
ViewVC logotype

Annotation of /branches/4.x/src/commands/automation/BallotCommand.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (hide annotations)
Mon Jul 29 18:52:37 2024 UTC (8 months, 1 week ago) by rakinar2
File MIME type: application/typescript
File size: 8080 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 rakinar2 577 /**
2     * This file is part of SudoBot.
3     *
4     * Copyright (C) 2021-2022 OSN Inc.
5     *
6     * SudoBot is free software; you can redistribute it and/or modify it
7     * under the terms of the GNU Affero General Public License as published by
8     * the Free Software Foundation, either version 3 of the License, or
9     * (at your option) any later version.
10     *
11     * SudoBot is distributed in the hope that it will be useful, but
12     * WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU Affero General Public License for more details.
15     *
16     * You should have received a copy of the GNU Affero General Public License
17     * along with SudoBot. If not, see <https://www.gnu.org/licenses/>.
18     */
19    
20     import { CommandInteraction, EmojiIdentifierResolvable, GuildMember, Message, Permissions, TextChannel, User } from 'discord.js';
21     import BaseCommand from '../../utils/structures/BaseCommand';
22     import DiscordClient from '../../client/Client';
23     import MessageEmbed from '../../client/MessageEmbed';
24     import CommandOptions from '../../types/CommandOptions';
25     import InteractionOptions from '../../types/InteractionOptions';
26     import { fetchEmoji } from '../../utils/Emoji';
27     import Ballot from '../../models/Ballot';
28    
29     export default class BallotCommand extends BaseCommand {
30     permissions = [Permissions.FLAGS.MANAGE_MESSAGES];
31    
32     supportsInteractions = true;
33    
34     constructor() {
35     super('ballot', 'automation', []);
36     }
37    
38     async ballotCreate(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) {
39     if (!options.isInteraction && typeof options.args[0] === 'undefined') {
40     await msg.reply({
41     embeds: [
42     new MessageEmbed()
43     .setColor('#f14a60')
44     .setDescription(`This command requires at least one argument.`)
45     ]
46     });
47    
48     return;
49     }
50    
51     if (msg instanceof CommandInteraction)
52     await msg.deferReply({
53     ephemeral: true
54     });
55    
56     let content: string;
57     let channel: TextChannel = msg.channel as TextChannel;
58     let anonymous = false;
59    
60     if (options.isInteraction) {
61     content = <string> await options.options.getString('content');
62    
63     if (options.options.getChannel('channel'))
64     channel = <TextChannel> await options.options.getChannel('channel');
65    
66     if (options.options.getBoolean('anonymous'))
67     anonymous = <boolean> await options.options.getBoolean('anonymous');
68     }
69     else {
70     if ((msg as Message).mentions.channels.last() && /\<#(\d+)\>/g.test([...options.args].pop()!)) {
71     channel = <TextChannel> (msg as Message).mentions.channels.last();
72     options.args.pop();
73     }
74    
75     content = await options.args.join(' ').trim();
76     }
77    
78     if (!channel.send) {
79     await this.deferReply(msg, {
80     content: 'Invalid text channel.'
81     });
82    
83     return;
84     }
85    
86     const message = await channel.send({
87     embeds: [
88     new MessageEmbed()
89     .setAuthor({
90     name: anonymous ? 'Staff' : (msg.member?.user as User).tag!,
91     iconURL: anonymous ? msg.guild!.iconURL()! : (msg.member as GuildMember)?.displayAvatarURL()
92     })
93     .setDescription(content)
94     .setTimestamp()
95     ]
96     });
97    
98     const ballot = new Ballot({
99     content,
100     author: anonymous ? null : msg.member?.user.id,
101     msg_id: message.id,
102     guild_id: msg.guild!.id,
103     date: new Date(),
104     channel_id: msg.channel!.id
105     });
106    
107     await ballot.save();
108    
109     await message.react(<EmojiIdentifierResolvable> await fetchEmoji('check'));
110     await message.react(<EmojiIdentifierResolvable> await fetchEmoji('error'));
111    
112     await this.deferReply(msg, {
113     content: `${(await fetchEmoji('check'))!.toString()} Your message has been delivered. The ballot ID is ${ballot.get('id')}.`,
114     });
115     }
116    
117     async ballotView(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) {
118     if (!options.isInteraction && typeof options.args[0] === 'undefined') {
119     await msg.reply({
120     embeds: [
121     new MessageEmbed()
122     .setColor('#f14a60')
123     .setDescription(`This command requires at least one argument.`)
124     ]
125     });
126    
127     return;
128     }
129    
130     try {
131     const id = options.isInteraction ? options.options.getString('id') : options.args[0];
132     //const ballot = await client.db.getAsync("SELECT * FROM ballots WHERE id = ? ORDER BY id DESC LIMIT 0, 1", [id]);
133     const ballot = await Ballot.findById(id);
134    
135     if (!ballot)
136     throw new Error();
137    
138     const ballotAuthor = ballot.author ? (await msg.guild!.members.fetch(ballot.author)) : null;
139    
140     const channel = <TextChannel> await msg.guild?.channels.fetch(ballot.channel_id);
141    
142     if (!channel)
143     throw new Error();
144    
145     const message = await channel.messages.fetch(ballot.msg_id);
146    
147     if (!message)
148     throw new Error();
149    
150     const upEmote = await fetchEmoji('check');
151     const downEmote = await fetchEmoji('error');
152     const upVotes = message.reactions.cache.find(r => r.emoji.id === upEmote!.id)!.count - 1;
153     const downVotes = message.reactions.cache.find(r => r.emoji.id === downEmote!.id)!.count - 1;
154    
155     await msg.reply({
156     embeds: [
157     new MessageEmbed()
158     .setAuthor({
159     name: ballot.author ? ballotAuthor!.user!.tag! : 'Staff',
160     iconURL: ballot.author ? ballotAuthor?.displayAvatarURL()! : msg.guild!.iconURL()!
161     })
162     .setDescription(ballot.content)
163     .addFields([
164     {
165     name: 'Upvotes',
166     value: `${upVotes}`
167     },
168     {
169     name: 'Downvotes',
170     value: `${downVotes}`
171     }
172     ])
173     .setTimestamp()
174     ]
175     });
176     }
177     catch (e) {
178     console.log(e);
179    
180     await msg.reply({
181     embeds: [
182     new MessageEmbed()
183     .setColor('#f14a60')
184     .setDescription(`Invalid ID or failed to fetch data.`)
185     ]
186     });
187     }
188     }
189    
190     async run(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) {
191     if (!options.isInteraction && typeof options.args[0] === 'undefined') {
192     await msg.reply({
193     embeds: [
194     new MessageEmbed()
195     .setColor('#f14a60')
196     .setDescription(`This command requires at least one subcommand.`)
197     ]
198     });
199    
200     return;
201     }
202    
203     const subcmd = options.isInteraction ? options.options.getSubcommand(true) : options.args[0];
204    
205     if (!options.isInteraction)
206     await options.args.shift();
207    
208     if (subcmd === 'create')
209     await this.ballotCreate(client, msg, options);
210     else if (subcmd === 'view')
211     await this.ballotView(client, msg, options);
212     else {
213     await msg.reply({
214     embeds: [
215     new MessageEmbed()
216     .setColor('#f14a60')
217     .setDescription(`Invalid subcommand provided.`)
218     ]
219     });
220     }
221     }
222     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26