Skip to content
This repository has been archived by the owner on Aug 26, 2022. It is now read-only.

Commit

Permalink
Merge pull request #206 from BanklessDAO/hotfix/1.8.2
Browse files Browse the repository at this point in the history
Hotfix/1.8.2
  • Loading branch information
Joshua Alexander authored Oct 23, 2021
2 parents 2139914 + b5c22e8 commit 71ef6c1
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 48 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 1.8.2-RELEASE (2021-10-23)

1. Fix poap attendee duration time
2. Fix failed to send poaps message

## 1.8.1-RELEASE (2021-10-21)

1. Fix removal of guest pass users by wraping in try/catch block in case of error
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "degen",
"version": "1.8.1",
"version": "1.8.2",
"description": "Administrative and Utilitarian bot for the Bankless Discord Server.",
"main": "app.js",
"private": true,
Expand Down
7 changes: 4 additions & 3 deletions src/app/schema/poap/poapSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"voiceChannelName",
"discordServerId",
"startTime",
"endTime"
],
"properties": {
"event": {
Expand All @@ -19,11 +20,11 @@
"description": "Indicator whether the call is currently active."
},
"startTime": {
"bsonType": ["string", "null"],
"bsonType": ["string"],
"description": "ISO8601 of when the meeting started."
},
"endTime": {
"bsonType": ["string", "null"],
"bsonType": ["string"],
"description": "ISO8601 of when the meeting ended."
},
"discordUserId": {
Expand All @@ -43,7 +44,7 @@
"description": "Identifier for the discord guild"
},
"minAttendance": {
"bsonType": "string",
"bsonType": ["string", "null"],
"description": "Minimum attendance time required in minutes."
}
}
Expand Down
11 changes: 7 additions & 4 deletions src/app/service/poap/EndPOAP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { POAPSettings } from '../../types/poap/POAPSettings';
import POAPUtils, { FailedPOAPAttendee, POAPFileParticipant } from '../../utils/POAPUtils';
import { CommandContext } from 'slash-create';
import Log from '../../utils/Log';
import dayjs from 'dayjs';

export default async (guildMember: GuildMember, ctx?: CommandContext): Promise<any> => {
const db: Db = await dbInstance.dbConnect(constants.DB_NAME_DEGEN);
Expand All @@ -22,18 +23,20 @@ export default async (guildMember: GuildMember, ctx?: CommandContext): Promise<a
});

if (poapSettingsDoc == null) {
throw new ValidationError(`No active event found for <@${guildMember.id}>.`);
throw new ValidationError(`<@${guildMember.id}> Hmm it doesn't seem you are hosting an active event.`);
}
const currentDateISO = dayjs().toISOString();
const updateSettingsResult: UpdateWriteOpResult = await poapSettingsDB.updateOne(poapSettingsDoc, {
$set: {
isActive: false,
endTime: currentDateISO,
},
});

if (updateSettingsResult.modifiedCount !== 1) {
throw new ValidationError('Event is not active.');
throw new Error('failed to end event');
}
Log.info('event ended', {
Log.debug(`event ended for ${guildMember.user.tag}`, {
indexMeta: true,
meta: {
discordId: poapSettingsDoc.discordServerId,
Expand All @@ -42,7 +45,7 @@ export default async (guildMember: GuildMember, ctx?: CommandContext): Promise<a
},
});
const channel: GuildChannel = await guildMember.guild.channels.fetch(poapSettingsDoc.voiceChannelId);
const listOfParticipants: POAPFileParticipant[] = await POAPUtils.getListOfParticipants(guildMember, db, channel);
const listOfParticipants: POAPFileParticipant[] = await POAPUtils.getListOfParticipants(db, channel);

if (listOfParticipants.length <= 0) {
await guildMember.send({ content: `Event ended. No participants found for \`${channel.name}\` in \`${channel.guild.name}\`.` });
Expand Down
48 changes: 31 additions & 17 deletions src/app/service/poap/StartPOAP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,29 +62,40 @@ export default async (ctx: CommandContext, guildMember: GuildMember, event?: str
await guildMember.send({ content: 'Event is already active.' });
throw new ValidationError(`\`${channelChoice.name}\` is already active. Please reach out to <@${poapSettingsDoc.discordUserId}> to end event.`);
}

if (poapSettingsDoc == null) {
Log.info(`setting up first time poap configuration for ${guildMember.user.tag}`);
await setupPoapSetting(guildMember, poapSettingsDB, channelChoice, event);
}

const dmChannel: DMChannel = await guildMember.createDM();

Log.debug(`asking ${guildMember.user.tag} for duration`);
if (duration == null) {
await guildMember.send({ content: 'Would you like the event to end automatically? (y/n)' });
const isManualEnd = (await ServiceUtils.getFirstUserReply(dmChannel)) == 'n';
if (!isManualEnd) {
await guildMember.send({ content: 'Would you like to set the duration of the event? `(y/n)`' });
const setDurationFlag = (await ServiceUtils.getFirstUserReply(dmChannel)) == 'y';
Log.debug(`isManualEnd: ${setDurationFlag}`);
if (setDurationFlag) {
duration = await askForEventMinutes(guildMember, dmChannel);
} else {
duration = constants.POAP_MAX_DURATION_MINUTES;
}
Log.debug(`poap event duration: ${duration}, `, {
indexMeta: true,
meta: {
discordId: guildMember.guild.id,
discordUserId: guildMember.guild.id,
},
});
}

await clearPOAPParticipants(db, channelChoice);
const currentDate: Dayjs = dayjs();
const currentDateISO: string = currentDate.toISOString();
const endDateISO: string = currentDate.add(duration, 'minute').toISOString();

if (poapSettingsDoc == null) {
Log.debug(`setting up first time poap configuration for ${guildMember.user.tag}`);
await setupPoapSetting(guildMember, poapSettingsDB, channelChoice, currentDateISO, endDateISO, event);
} else {
Log.debug(`existing poapSettings found for ${guildMember.user.tag}`);
}

await clearPOAPParticipants(db, channelChoice);

const activeEvent: FindAndModifyWriteOpResultObject<POAPSettings> = await poapSettingsDB.findOneAndUpdate({
discordServerId: channelChoice.guild.id,
voiceChannelId: channelChoice.id,
Expand All @@ -109,7 +120,7 @@ export default async (ctx: CommandContext, guildMember: GuildMember, event?: str
{
title: 'Event Started',
fields: [
{ name: 'Event', value: `${event} `, inline: true },
{ name: 'Event', value: `${event == null ? '-' : event} `, inline: true },
{ name: 'Organizer', value: `${guildMember.user.tag} `, inline: true },
{ name: 'Discord Server', value: `${guildMember.guild.name} `, inline: true },
{ name: 'Location', value: `${channelChoice.name} `, inline: true },
Expand All @@ -121,12 +132,15 @@ export default async (ctx: CommandContext, guildMember: GuildMember, event?: str
return;
};

export const setupPoapSetting = async (guildMember: GuildMember, poapSettingsDB: Collection, guildChannel: GuildChannel, event?: string): Promise<POAPSettings> => {
const currentDateStr = (new Date()).toISOString();
export const setupPoapSetting = async (
guildMember: GuildMember, poapSettingsDB: Collection, guildChannel: GuildChannel, startDateISO: string,
endDateISO: string, event?: string,
): Promise<POAPSettings> => {
const poapSetting = {
event: event,
isActive: true,
startTime: currentDateStr,
startTime: startDateISO,
endTime: endDateISO,
discordUserId: guildMember.user.id.toString(),
voiceChannelId: guildChannel.id.toString(),
voiceChannelName: guildChannel.name.toString(),
Expand All @@ -140,13 +154,13 @@ export const setupPoapSetting = async (guildMember: GuildMember, poapSettingsDB:
};

export const clearPOAPParticipants = async (db: Db, guildChannel: GuildChannel): Promise<void> => {
Log.info(`attempting to delete all previous participants for ${guildChannel.guild.name} on channel: ${guildChannel.name}`);
Log.debug(`attempting to delete all previous participants for ${guildChannel.guild.name} on channel: ${guildChannel.name}`);
const poapParticipantsDB: Collection = db.collection(constants.DB_COLLECTION_POAP_PARTICIPANTS);
await poapParticipantsDB.deleteMany({
voiceChannelId: guildChannel.id,
discordServerId: guildChannel.guild.id,
});
Log.info('removed all previous participants.', {
Log.debug('removed all previous participants.', {
indexMeta: true,
meta: {
guildId: guildChannel.guild.id,
Expand Down Expand Up @@ -237,7 +251,7 @@ export const askUserForChannel = async (guildMember: GuildMember, dmMessage: Mes

const askForEventMinutes = async (guildMember: GuildMember, dmChannel: DMChannel): Promise<number> => {
try {
await guildMember.send({ content: `How long should the event stay active? (max: ${constants.POAP_MAX_DURATION_MINUTES} minutes)` });
await guildMember.send({ content: `How long should the event stay active? \`(max: ${constants.POAP_MAX_DURATION_MINUTES} minutes)\`` });
const durationOfEventInMinutes: string = await ServiceUtils.getFirstUserReply(dmChannel);
const duration = Number(durationOfEventInMinutes);
await POAPUtils.validateDuration(guildMember, duration);
Expand Down
62 changes: 39 additions & 23 deletions src/app/utils/POAPUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import axios from 'axios';
import ValidationError from '../errors/ValidationError';
import { POAPAdmin } from '../types/poap/POAPAdmin';
import Log, { LogUtils } from './Log';
import { Dayjs } from 'dayjs';
import dayjs, { Dayjs } from 'dayjs';
import DateUtils from './DateUtils';

export type POAPFileParticipant = {
Expand All @@ -23,25 +23,47 @@ export type FailedPOAPAttendee = {

const POAPUtils = {

async getListOfParticipants(guildMember: GuildMember, db: Db, voiceChannel: GuildChannel): Promise<POAPFileParticipant[]> {
async getListOfParticipants(db: Db, voiceChannel: GuildChannel): Promise<POAPFileParticipant[]> {
const poapParticipants: MongoCollection = db.collection(constants.DB_COLLECTION_POAP_PARTICIPANTS);
const resultCursor: Cursor<POAPParticipant> = await poapParticipants.find({
voiceChannelId: voiceChannel.id,
discordServerId: voiceChannel.guild.id,
});

if ((await resultCursor.count()) === 0) {
Log.info(`no participants found for ${voiceChannel.name} in ${voiceChannel.guild.name}`);
Log.debug(`no participants found for ${voiceChannel.name} in ${voiceChannel.guild.name}`);
return [];
}

let endTime: number = Date.now();
const currentDateStr = (new Date()).toISOString();
await POAPUtils.setEndDateForPresentParticipants(poapParticipants, resultCursor);

const participants = [];
for await (const participant of resultCursor) {
await resultCursor.forEach((participant: POAPParticipant) => {
const endTime = new Date(participant.endTime).getTime();
let durationInMinutes: number = (endTime - (new Date(participant.startTime)).getTime());
durationInMinutes = (durationInMinutes <= 0) ? 0 : durationInMinutes / (1000 * 60);
if (durationInMinutes >= constants.POAP_REQUIRED_PARTICIPATION_DURATION) {
participants.push({
id: participant.discordUserId,
tag: participant.discordUserTag,
duration: durationInMinutes,
});
}
});
return participants;
},

async setEndDateForPresentParticipants(poapParticipantsCollection: MongoCollection, poapParticipantsCursor: Cursor<POAPParticipant>): Promise<void> {
Log.debug('starting to set endDate for present participants in db');
const currentDateStr = dayjs().toISOString();
for await (const participant of poapParticipantsCursor) {
if (participant.endTime != null) {
// skip setting endDate for present endTime;
continue;
}
let result: UpdateWriteOpResult;
try {
result = await poapParticipants.updateOne(participant, {
result = await poapParticipantsCollection.updateOne(participant, {
$set: {
endTime: currentDateStr,
},
Expand All @@ -53,21 +75,7 @@ const POAPUtils = {
throw new Error('Mongodb operation failed');
}
}
await resultCursor.forEach((participant: POAPParticipant) => {
if (participant.endTime) {
endTime = new Date(participant.endTime).getTime();
}
let durationInMinutes: number = (endTime - (new Date(participant.startTime)).getTime());
durationInMinutes = (durationInMinutes <= 0) ? 0 : durationInMinutes / (1000 * 60);
if (durationInMinutes >= constants.POAP_REQUIRED_PARTICIPATION_DURATION) {
participants.push({
id: participant.discordUserId,
tag: participant.discordUserTag,
duration: durationInMinutes,
});
}
});
return participants;
Log.debug('finished setting endDate for present participants in db');
},

async sendOutPOAPLinks(guildMember: GuildMember, listOfParticipants: POAPFileParticipant[], attachment: MessageAttachment, event?: string): Promise<FailedPOAPAttendee[]> {
Expand All @@ -85,6 +93,14 @@ const POAPUtils = {
}
for (let i = 0; i < listOfParticipants.length; i++) {
try {
if (listOfPOAPLinks[i] == null || listOfPOAPLinks[i] == '') {
failedPOAPsList.push({
discordUserId: listOfParticipants[i].id,
discordUserTag: listOfParticipants[i].tag,
poapLink: 'n/a',
});
continue;
}
await guildMember.guild.members.fetch(listOfParticipants[i].id)
.then(async (participantMember: GuildMember) => {
await participantMember.send({ content: `Thank you for participating in the ${event} from ${guildName}! Here is your POAP: ${listOfPOAPLinks[i]}` }).catch((e) => {
Expand Down Expand Up @@ -144,7 +160,7 @@ const POAPUtils = {
if (duration == null) {
return;
}
if (duration > constants.POAP_MAX_DURATION_MINUTES || duration < 10 || duration < constants.POAP_REQUIRED_PARTICIPATION_DURATION) {
if (duration > constants.POAP_MAX_DURATION_MINUTES || duration < constants.POAP_REQUIRED_PARTICIPATION_DURATION) {
await guildMember.send({
content: `<@${guildMember.user.id}>\n` +
`A minimum of ${constants.POAP_REQUIRED_PARTICIPATION_DURATION} minutes is required for an event to be active and no more than ${constants.POAP_MAX_DURATION_MINUTES} minutes.`,
Expand Down

0 comments on commit 71ef6c1

Please sign in to comment.