Skip to content

Commit 26a1a14

Browse files
committed
Updated cosmetics, minor changes
1 parent 1d92489 commit 26a1a14

File tree

3 files changed

+101
-19
lines changed

3 files changed

+101
-19
lines changed

README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
# Analyst Poll Bot
22

3+
Clone of my public [analyst-poll-bot](https://github.com/just-rich/analyst-poll-bot) make any updates to it if any are done here.
4+
5+
## Overview
6+
37
Analyst Poll Bot is a Discord bot designed to facilitate daily polls in specific channels of a Discord server. It automates the process of collecting user feedback on whether they were "green" or "red" for the day following a specific analyst. The bot also logs these results, providing both daily and all-time statistics for each poll. It stores all the poll results in a database using SQLite.
48

59
It updates the poll message in real-time to show the current results. It sends a message to a specified log channel that updates in real-time to show daily & all time results for each channel a poll is in.
610

711
## Features
812

9-
- **Automated Polls**: Polls are automatically posted daily at 1:15 PM PST in specified channels.
13+
- **Automated Polls**: Polls are automatically posted Monday-Friday at 1:05 PM PST in specified channels.
1014
- **Manual Poll Trigger**: Polls can be manually triggered using the `!startpolls` command. *This simulates as if a daily poll has been sent, for testing.*
1115
- **User Interaction**: Users can interact with the poll by selecting one of the options: "Green", "Red", or "Did not follow/trade".
1216
- **Result Logging**: Daily and all-time results are logged in a specified channel, including the number of votes and their percentages.

index.js

+49-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,55 @@ let simulatedDayCounter = 0; // Counter to simulate a new day each time !startpo
1515
client.once('ready', () => {
1616
console.log(`Logged in as ${client.user.tag}!`);
1717

18-
// Schedule the poll to be posted daily at 1:15 PM PST
19-
cron.schedule('15 13 * * *', () => {
18+
// Schedule the poll to be posted Monday-Friday at 1:05 PM PST on weekdays (Monday to Friday)
19+
cron.schedule('05 13 * * 1-5', () => {
20+
const date = new Date().toISOString().split('T')[0]; // Get current date in YYYY-MM-DD format
21+
22+
if (lastPollDate !== date) {
23+
startPolls(date);
24+
lastPollDate = date;
25+
console.log('Polls have been started.');
26+
} else {
27+
console.log('Polls have already been started for today.');
28+
}
29+
}, {
30+
timezone: "America/Los_Angeles"
31+
});
32+
});
33+
34+
// Listen for messages
35+
client.on('messageCreate', async (message) => {
36+
if (message.content === '!startpolls') {
37+
// Check if the user has the "Administrator" permission
38+
if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) {
39+
return message.reply('You do not have permission to use this command.');
40+
}
41+
42+
const simulatedDate = new Date().toISOString().split('T')[0] + `-simulated-${simulatedDayCounter++}`;
43+
startPolls(simulatedDate);
44+
message.channel.send('Polls have been started for simulated date: ' + simulatedDate);
45+
}
46+
});
47+
48+
client.login(config.token);1~const { Client, GatewayIntentBits, PermissionsBitField } = require('discord.js');
49+
const config = require('./config.json');
50+
const { startPolls } = require('./pollHandler');
51+
const cron = require('node-cron');
52+
53+
// Initialize the Discord client
54+
const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] });
55+
56+
// Set the client as a global variable to be accessible in other modules
57+
global.client = client;
58+
59+
let lastPollDate = null; // Store the date of the last started poll
60+
let simulatedDayCounter = 0; // Counter to simulate a new day each time !startpolls is used
61+
62+
client.once('ready', () => {
63+
console.log(`Logged in as ${client.user.tag}!`);
64+
65+
// Schedule the poll to be posted Monday-Friday at 1:05 PM PST on weekdays (Monday to Friday)
66+
cron.schedule('05 13 * * 1-5', () => {
2067
const date = new Date().toISOString().split('T')[0]; // Get current date in YYYY-MM-DD format
2168

2269
if (lastPollDate !== date) {

pollHandler.js

+47-16
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ async function postPoll(channelId, date) {
88
const channel = await client.channels.fetch(channelId);
99
const embed = new EmbedBuilder()
1010
.setTitle('Were you green or red for the day following this analyst?')
11+
.setColor('#9cfa05')
1112
.addFields(
1213
{ name: 'Total', value: '0', inline: false },
1314
{ name: 'Green', value: '0 (0%)', inline: true },
@@ -19,9 +20,9 @@ async function postPoll(channelId, date) {
1920
embeds: [embed],
2021
components: [
2122
new ActionRowBuilder().addComponents(
22-
new ButtonBuilder().setCustomId('green').setLabel('Green').setStyle(ButtonStyle.Success),
23-
new ButtonBuilder().setCustomId('red').setLabel('Red').setStyle(ButtonStyle.Danger),
24-
new ButtonBuilder().setCustomId('no_trade').setLabel('Did not follow/trade').setStyle(ButtonStyle.Secondary)
23+
new ButtonBuilder().setCustomId('green').setLabel('📈 Green').setStyle(ButtonStyle.Success),
24+
new ButtonBuilder().setCustomId('red').setLabel('📉 Red').setStyle(ButtonStyle.Danger),
25+
new ButtonBuilder().setCustomId('no_trade').setLabel('Did not follow/trade').setStyle(ButtonStyle.Secondary)
2526
)
2627
]
2728
});
@@ -33,7 +34,7 @@ async function postPoll(channelId, date) {
3334

3435
collector.on('collect', async (interaction) => {
3536
if (userVotes.has(interaction.user.id)) {
36-
await interaction.reply({ content: 'You have already voted in this poll.', ephemeral: true });
37+
await interaction.reply({ content: 'You have already voted in this poll.', ephemeral: true }).catch(console.error);
3738
return;
3839
}
3940

@@ -62,16 +63,33 @@ async function startPolls(date) {
6263

6364
async function sendInitialLogMessage(date) {
6465
const logChannel = await client.channels.fetch(config.logChannelId);
65-
let initialContent = `${date} Poll Results\n\n`;
66-
for (const channelId of config.pollChannels) {
67-
initialContent += `
66+
const logEmbeds = [];
67+
68+
let currentEmbed = new EmbedBuilder().setTitle(`${date} Poll Results`).setColor('#9cfa05');
69+
let currentDescription = '';
70+
71+
for (const [index, channelId] of config.pollChannels.entries()) {
72+
currentDescription += `
6873
Results for <#${channelId}>:
6974
Green: \`0\` **0%** for the day. (All time: \`0\` **0%**)
7075
Red: \`0\` **0%** for the day. (All time: \`0\` **0%**)
7176
Did not follow/trade: \`0\` **0%** for the day. (All time: \`0\` **0%**)\n\n`;
77+
78+
if ((index + 1) % 10 === 0 || index === config.pollChannels.length - 1) {
79+
currentEmbed.setDescription(currentDescription.trim());
80+
logEmbeds.push(currentEmbed);
81+
currentEmbed = new EmbedBuilder().setTitle(`${date} Poll Results`).setColor('#9cfa05');
82+
currentDescription = '';
83+
}
84+
}
85+
86+
const logMessagesSent = [];
87+
for (const logEmbed of logEmbeds) {
88+
const sentMessage = await logChannel.send({ embeds: [logEmbed] });
89+
logMessagesSent.push(sentMessage);
7290
}
73-
const logMessage = await logChannel.send(initialContent.trim());
74-
logMessages[date] = logMessage;
91+
92+
logMessages[date] = logMessagesSent;
7593
}
7694

7795
async function updatePollMessage(pollMessage, channelId, date) {
@@ -87,21 +105,25 @@ async function updatePollMessage(pollMessage, channelId, date) {
87105

88106
const embed = new EmbedBuilder()
89107
.setTitle('Were you green or red for the day following this analyst?')
108+
.setColor('#9cfa05')
90109
.addFields(
91110
{ name: 'Total', value: `${totalVotes}`, inline: false },
92111
{ name: 'Green', value: `${greenVotes} (${greenPercentage}%)`, inline: true },
93112
{ name: 'Red', value: `${redVotes} (${redPercentage}%)`, inline: true },
94113
{ name: 'Did not follow/trade', value: `${noTradeVotes} (${noTradePercentage}%)`, inline: true }
95114
);
96115

97-
await pollMessage.edit({ embeds: [embed] });
116+
await pollMessage.edit({ embeds: [embed] }).catch(console.error);
98117
}
99118

100119
async function updateLogChannel(date) {
101-
const logMessage = logMessages[date];
102-
let logContent = `${date} Poll Results\n\n`;
120+
const logMessagesSent = logMessages[date];
121+
const logEmbeds = [];
103122

104-
for (const channelId of config.pollChannels) {
123+
let currentEmbed = new EmbedBuilder().setTitle(`${date} Poll Results`).setColor('#9cfa05');
124+
let currentDescription = '';
125+
126+
for (const [index, channelId] of config.pollChannels.entries()) {
105127
const results = await getPollResults(channelId, date);
106128
const totalVotes = results.reduce((acc, result) => acc + result.count, 0);
107129
const greenVotes = results.find(result => result.answer === 'green')?.count || 0;
@@ -122,18 +144,27 @@ async function updateLogChannel(date) {
122144
const allTimeRedPercentage = allTimeVotes > 0 ? ((allTimeRed / allTimeVotes) * 100).toFixed(2) : 0;
123145
const allTimeNoTradePercentage = allTimeVotes > 0 ? ((allTimeNoTrade / allTimeVotes) * 100).toFixed(2) : 0;
124146

125-
logContent += `
147+
currentDescription += `
126148
Results for <#${channelId}>:
127149
Green: \`${greenVotes}\` **${greenPercentage}%** for the day. (All time: \`${allTimeGreen}\` **${allTimeGreenPercentage}%**)
128150
Red: \`${redVotes}\` **${redPercentage}%** for the day. (All time: \`${allTimeRed}\` **${allTimeRedPercentage}%**)
129151
Did not follow/trade: \`${noTradeVotes}\` **${noTradePercentage}%** for the day. (All time: \`${allTimeNoTrade}\` **${allTimeNoTradePercentage}%**)\n\n`;
152+
153+
if ((index + 1) % 10 === 0 || index === config.pollChannels.length - 1) {
154+
currentEmbed.setDescription(currentDescription.trim());
155+
logEmbeds.push(currentEmbed);
156+
currentEmbed = new EmbedBuilder().setTitle(`${date} Poll Results`).setColor('#9cfa05');
157+
currentDescription = '';
158+
}
130159
}
131160

132-
await logMessage.edit(logContent.trim());
161+
for (let i = 0; i < logMessagesSent.length; i++) {
162+
await logMessagesSent[i].edit({ embeds: [logEmbeds[i]] }).catch(console.error);
163+
}
133164
}
134165

135166
async function disablePoll(pollMessage) {
136-
await pollMessage.edit({ components: [] });
167+
await pollMessage.edit({ components: [] }).catch(console.error);
137168
}
138169

139170
module.exports = { startPolls, disablePoll };

0 commit comments

Comments
 (0)