Skip to content

Update help channel embed when channel is occupied #117

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions src/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@ let db: Connection | undefined;
export async function getDB() {
if (db) return db;

// Require ssl in production
const extraOpts =
process.env.NODE_ENV === 'production'
? {
ssl: true,
extra: {
ssl: {
rejectUnauthorized: false,
},
},
}
: {};

db = await createConnection({
type: 'postgres',
url: dbUrl,
synchronize: true,
logging: false,
entities: [RepUser, RepGive, HelpUser],
ssl: true,
extra: {
ssl: {
rejectUnauthorized: false,
},
},
...extraOpts,
});
console.log('Connected to DB');
return db;
Expand Down
2 changes: 2 additions & 0 deletions src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ export const ongoingEmptyTimeout = parseInt(process.env.ONGOING_EMPTY_TIMEOUT!);

export const TS_BLUE = '#007ACC';
export const GREEN = '#77b155';
// Picked from Discord's "hourglass" emoji (in ⌛ | Occupied Help Channels)
export const HOURGLASS_ORANGE = '#ffa647';
94 changes: 73 additions & 21 deletions src/modules/helpchan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,21 @@ import {
Guild,
TextChannel,
GuildMember,
User,
} from 'discord.js';
import { HelpUser } from '../entities/HelpUser';
import {
categories,
TS_BLUE,
GREEN,
HOURGLASS_ORANGE,
askCooldownRoleId,
channelNames,
dormantChannelTimeout,
dormantChannelLoop,
askHelpChannelId,
ongoingEmptyTimeout,
trustedRoleId,
} from '../env';
import { isTrustedMember } from '../util/inhibitors';

Expand All @@ -39,6 +42,20 @@ This channel will be dedicated to answering your question only. Others will try
For more tips, check out StackOverflow's guide on **[asking good questions](https://stackoverflow.com/help/how-to-ask)**.
`;

const occupiedMessage = (asker: User) => `
**This channel is claimed by ${asker.toString()}.**
It is dedicated to answering their questions only.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little late on this, but maybe

Suggested change
It is dedicated to answering their questions only.
It is dedicated to answering their questions only; see <#${askHelpChannelId}> to claim your own.

Copy link
Contributor Author

@smichel17 smichel17 Mar 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added just "More info: <#${askHelpChannelId}>", so it will fit on one line. Two lines distracts a little from the "This channel is claimed by" message on the line above, in my opinion (fixable by adding a newline, but then the message starts to become longer than I think it should be).


**${asker.toString()} You'll get better and faster answers if you:**
• Describe the context. What are you trying to accomplish?
• Copy-paste a short snippet (5-15 lines) that includes the problem. Start code blocks with \`\\\`\`ts for syntax highlighting.
• Try to reproduce your problem in the **[TypeScript Playground](https://www.typescriptlang.org/play)**.

Usually someone will try to answer and help solve the issue within a few hours. If not, and you have followed the bullets above, you may ping the <@&${trustedRoleId}> role.

For more tips, check out StackOverflow's guide on **[asking good questions](https://stackoverflow.com/help/how-to-ask)**.
`;

const DORMANT_MESSAGE = `
This help channel has been marked as **dormant**, and has been moved into the **Help: Dormant** category at the bottom of the channel list. It is no longer possible to send messages in this channel until it becomes available again.

Expand All @@ -62,7 +79,22 @@ export class HelpChanModule extends Module {
} hours of inactivity or when you send !close.`,
);

OCCUPIED_EMBED_BASE = new MessageEmbed()
.setTitle('⌛ Occupied Help Channel')
.setColor(HOURGLASS_ORANGE);

occupiedEmbed(asker: User) {
return new MessageEmbed(this.OCCUPIED_EMBED_BASE)
.setDescription(occupiedMessage(asker))
.setFooter(
`Closes after ${
dormantChannelTimeout / 60 / 60 / 1000
} hours of inactivity or when ${asker.username} sends !close.`,
);
}

DORMANT_EMBED = new MessageEmbed()
.setTitle('💤 Dormant Help Channel')
.setColor(TS_BLUE)
.setDescription(DORMANT_MESSAGE);

Expand Down Expand Up @@ -117,9 +149,8 @@ export class HelpChanModule extends Module {
const embed = messages.first()?.embeds[0];

return (
embed &&
embed.description?.trim() ===
this.AVAILABLE_EMBED.description?.trim()
embed?.title &&
embed.title.trim() === this.OCCUPIED_EMBED_BASE.title?.trim()
);
}

Expand Down Expand Up @@ -176,6 +207,9 @@ export class HelpChanModule extends Module {

this.busyChannels.add(msg.channel.id);

let embed = this.occupiedEmbed(msg.author);

await this.updateStatusEmbed(msg.channel, embed);
await msg.pin();
await this.addCooldown(msg.member, msg.channel);
await this.moveChannel(msg.channel, categories.ongoing);
Expand Down Expand Up @@ -244,24 +278,7 @@ export class HelpChanModule extends Module {
);
if (dormant && dormant instanceof TextChannel) {
await this.moveChannel(dormant, categories.ask);

let lastMessage = dormant.messages.cache
.array()
.reverse()
.find(m => m.author.id === this.client.user?.id);

if (!lastMessage)
lastMessage = (await dormant.messages.fetch({ limit: 5 }))
.array()
.find(m => m.author.id === this.client.user?.id);

if (lastMessage) {
// If there is a last message (the dormant message) by the bot, just edit it
await lastMessage.edit(this.AVAILABLE_EMBED);
} else {
// Otherwise, just send a new message
await dormant.send(this.AVAILABLE_EMBED);
}
await this.updateStatusEmbed(dormant, this.AVAILABLE_EMBED);
} else {
const chan = await guild.channels.create(
this.getChannelName(guild),
Expand Down Expand Up @@ -321,6 +338,38 @@ export class HelpChanModule extends Module {
}
}

private async updateStatusEmbed(channel: TextChannel, embed: MessageEmbed) {
const isStatusEmbed = (embed: MessageEmbed) =>
[
this.AVAILABLE_EMBED.title,
this.OCCUPIED_EMBED_BASE.title,
this.DORMANT_EMBED.title,
].includes(embed.title);

// The message cache does not have a stable order (at least with respect
// to creation date), so sorting is needed to find the latest embed.
let lastMessage = channel.messages.cache
.array()
.filter(m => m.author.id === this.client.user?.id)
.sort((m1, m2) => m2.createdTimestamp - m1.createdTimestamp)
.find(m => m.embeds.some(isStatusEmbed));

if (!lastMessage)
// Fetch has a stable order, with recent messages first
lastMessage = (await channel.messages.fetch({ limit: 5 }))
.array()
.filter(m => m.author.id === this.client.user?.id)
.find(m => m.embeds.some(isStatusEmbed));

if (lastMessage) {
// If there is a last message (the status message) by the bot, edit it
await lastMessage.edit(embed);
} else {
// Otherwise, just send a new message
await channel.send(embed);
}
}

private async addCooldown(member: GuildMember, channel: TextChannel) {
await member.roles.add(askCooldownRoleId);
const helpUser = new HelpUser();
Expand Down Expand Up @@ -415,7 +464,10 @@ export class HelpChanModule extends Module {
.setAuthor(member.displayName, member.user.displayAvatarURL())
.setDescription(msgContent),
);

await toPin.pin();
const occupied = this.occupiedEmbed(msg.author);
await this.updateStatusEmbed(claimedChannel, occupied);
await this.addCooldown(member, claimedChannel);
await this.moveChannel(claimedChannel, categories.ongoing);
await claimedChannel.send(
Expand Down