Skip to content
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

feat(network): thread and forum post support #19

Merged
merged 5 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
25 changes: 10 additions & 15 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
{
"ignorePatterns": ["build/"],
"env": {
"node": true,
"es2021": true
},
"ignorePatterns": ["build/", "node_modules/"],
"env": { "node": true, "es6": true },
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest"
},
"plugins": [
"@typescript-eslint"
],
"parserOptions": { "ecmaVersion": "latest" },
"plugins": [ "@typescript-eslint" ],
"root": true,

"rules": {
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/indent": ["error", 2],
"@typescript-eslint/no-explicit-any": "warn",

"arrow-spacing": "error",
"brace-style": [
"error",
"stroustrup",
{
"allowSingleLine": true
}
{ "allowSingleLine": true }
],
"comma-dangle": [
"error",
Expand All @@ -43,7 +39,6 @@
],
"handle-callback-err": "off",
"indent": "off",
"@typescript-eslint/indent": ["error", 2],
"keyword-spacing": "error",
"max-nested-callbacks": [
"error",
Expand Down
3 changes: 2 additions & 1 deletion prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ model blacklistedUsers {

model connectedList {
id String @id @default(auto()) @map("_id") @db.ObjectId
channelId String @unique
channelId String @unique // channel can be thread, or a normal channel
parentId String? // ID of the parent channel, if it's a thread @map("parentChannelId")
serverId String
connected Boolean
compact Boolean
Expand Down
8 changes: 3 additions & 5 deletions src/Commands/Main/hub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default {
.addChannelOption(channelOption =>
channelOption
.setName('channel')
.addChannelTypes(ChannelType.GuildText)
.addChannelTypes(ChannelType.GuildText, ChannelType.PublicThread, ChannelType.PrivateThread)
.setDescription('The channel that will be used to connect to the hub')
.setRequired(true),
)
Expand Down Expand Up @@ -242,11 +242,9 @@ export default {
async execute(interaction: ChatInputCommandInteraction) {
const subcommand = interaction.options.getSubcommand();
const subcommandGroup = interaction.options.getSubcommandGroup();
const extra = subcommand === 'leave'
const extra = subcommand === 'leave' || subcommand === 'delete'
? interaction.options.getString('hub', true)
: subcommand === 'delete'
? interaction.options.getString('hub', true)
: null;
: null;

require(`../../Scripts/hub/${subcommandGroup || subcommand}`).execute(interaction, extra);
},
Expand Down
2 changes: 2 additions & 0 deletions src/Events/messageCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export default {
content: connection?.profFilter ? message.censored_content : message.content,
embeds: replyEmbed ? [replyEmbed] : undefined,
files: attachment ? [attachment] : [],
threadId: connection.parentId ? connection.channelId : undefined,
allowedMentions: { parse: [] },
};
}
Expand All @@ -115,6 +116,7 @@ export default {
username: message.client.user.username,
avatarURL: message.client.user.avatarURL() || undefined,
files: attachment ? [attachment] : [],
threadId: connection.parentId ? connection.channelId : undefined,
allowedMentions: { parse: [] },
};
}
Expand Down
26 changes: 13 additions & 13 deletions src/Scripts/hub/join.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { ChatInputCommandInteraction, ChannelType } from 'discord.js';
import { getDb } from '../../Utils/functions/utils';
import initialize from '../network/initialize';
import createConnection from '../network/createConnection';
import displaySettings from '../network/displaySettings';
import { connectedList, hubs } from '@prisma/client';

export async function execute(interaction: ChatInputCommandInteraction) {
if (!interaction.inCachedGuild()) return;

const db = getDb();
const name = interaction.options.getString('name') || undefined;
const invite = interaction.options.getString('invite') || undefined;
const channel = interaction.options.getChannel('channel', true, [ChannelType.GuildText]);
const channelConnected = await db.connectedList.findFirst({ where: { channelId: channel.id } });
let hubExists: hubs | null = null;
const channel = interaction.options.getChannel('channel', true, [ChannelType.GuildText, ChannelType.PublicThread, ChannelType.PrivateThread]);
let hubExists;

if (!interaction.member.permissionsIn(channel).has(['ManageChannels'])) {
return await interaction.reply({
Expand All @@ -27,9 +25,10 @@ export async function execute(interaction: ChatInputCommandInteraction) {
ephemeral: true,
});
}
const channelConnected = await db.connectedList.findFirst({ where: { channelId: channel.id } });
if (channelConnected) {
return await interaction.reply({
content: `${channel} is already connected to a hub! Please leave the hub or choose a different channel.`,
content: `${channel} is already part of a hub! Please leave the hub or choose a different channel.`,
ephemeral: true,
});
}
Expand All @@ -46,9 +45,10 @@ export async function execute(interaction: ChatInputCommandInteraction) {
ephemeral: true,
});
}
else if (inviteExists.hub.connections.find((c) => c.channelId === channel.id)) {
const guildInHub = inviteExists.hub.connections.find((c) => c.serverId === channel.guildId);
if (guildInHub) {
return await interaction.reply({
content: `This server is already connected to hub **${inviteExists.hub.name}** from another channel!`,
content: `This server has already joined hub **${inviteExists.hub.name}** from from <#${guildInHub.channelId}>! Please leave the hub from that channel first, or change the channel using \`/network manage\`.!`,
ephemeral: true,
});
}
Expand All @@ -69,9 +69,10 @@ export async function execute(interaction: ChatInputCommandInteraction) {
});
}

else if ((hubExists as hubs & { connections: connectedList}).connections.channelId === channel.id) {
const guildInHub = hubExists.connections.find(c => c.serverId === channel.guildId);
if (guildInHub) {
return await interaction.reply({
content: `This server is already connected to hub **${hubExists?.name}** from another channel!`,
content: `This server has already joined hub **${hubExists?.name}** from <#${guildInHub.channelId}>! Please leave the hub from that channel first, or change the channel using \`/network manage\`.`,
ephemeral: true,
});
}
Expand Down Expand Up @@ -110,7 +111,6 @@ export async function execute(interaction: ChatInputCommandInteraction) {
return;
}

// TODO: make an onboarding function and show them rules and stuff
initialize.execute(interaction, hubExists, channel)
.then(success => { if (success) displaySettings.execute(interaction, channel.id); });
createConnection.execute(interaction, hubExists, channel)
.then(success => { if (success) displaySettings.execute(interaction, success.channelId); });
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { stripIndents } from 'common-tags';
import { ChannelType, ChatInputCommandInteraction, Collection, GuildTextBasedChannel } from 'discord.js';
import { ChannelType, ChatInputCommandInteraction, Collection, TextChannel, ThreadChannel } from 'discord.js';
import { disconnect } from '../../Structures/network';
import { hubs } from '@prisma/client';
import logger from '../../Utils/logger';
Expand All @@ -8,13 +8,16 @@ import { getDb } from '../../Utils/functions/utils';

const onboardingInProgress = new Collection<string, string>();

export = {
async execute(interaction: ChatInputCommandInteraction, hub: hubs, networkChannel: GuildTextBasedChannel) {
export default {
async execute(interaction: ChatInputCommandInteraction, hub: hubs, networkChannel: TextChannel | ThreadChannel) {
const emoji = interaction.client.emotes.normal;

// Check if server is already attempting to join a hub
if (onboardingInProgress.has(networkChannel.id)) {
const err = `${emoji.no} There has already been an attempt to join a hub in ${networkChannel}. Please wait for that to finish before trying again!`;
const err = {
content: `${emoji.no} There has already been an attempt to join a hub in ${networkChannel}. Please wait for that to finish before trying again!`,
ephemeral: true,
};
interaction.deferred || interaction.replied
? interaction.followUp(err)
: interaction.reply(err);
Expand All @@ -24,43 +27,60 @@ export = {
onboardingInProgress.set(networkChannel.id, networkChannel.id);

// Show new users rules & info about network
const onboardingStatus = await onboarding.execute(interaction);
if (!onboardingStatus) {
onboardingInProgress.delete(networkChannel.id);
return;
}
const onboardingStatus = await onboarding.execute(interaction, hub.name);
// remove in-progress marker as onboarding has either been cancelled or completed
onboardingInProgress.delete(networkChannel.id);
// if user cancelled onboarding or didn't click any buttons, stop here
if (!onboardingStatus) return;

let createdConnection;
try {
if (networkChannel.type !== ChannelType.GuildText) {
interaction.followUp(`${emoji.no} You can only connect **text channels** to the InterChat network!`);
return;
let webhook;
if (networkChannel.isThread() && networkChannel.parent) {
const webhooks = await networkChannel.parent.fetchWebhooks();
const webhookCreated = webhooks.find(w => w.owner?.id === interaction.client.user?.id);

if (webhookCreated) {
webhook = webhookCreated;
}
else {
webhook = await networkChannel.parent.createWebhook({
name: 'InterChat Network',
avatar: interaction.client.user?.avatarURL(),
});
}
}
else if (networkChannel.type === ChannelType.GuildText) {
webhook = await networkChannel.createWebhook({
name: 'InterChat Network',
avatar: interaction.client.user?.avatarURL(),
});
}
else {
return interaction.followUp('This channel is not supported for InterChat. Please use a text channel or a thread.');
}

const webhook = await networkChannel.createWebhook({
name: 'InterChat Network',
avatar: interaction.client.user?.avatarURL(),
});

const { connectedList } = getDb();
await connectedList.create({
createdConnection = await connectedList.create({
data:{
channelId: networkChannel.id,
parentId: networkChannel.isThread() ? networkChannel.id : undefined,
serverId: networkChannel.guild.id,
webhookURL: webhook.url,
connected: true,
profFilter: true,
compact: false,
webhookURL: webhook.url,
hub: { connect: { id: hub.id } },
},
});

const numOfConnections = await connectedList.count({ where: { hub: { id: hub.id } } });
if (numOfConnections > 1) {
await networkChannel?.send(`This channel has been connected with ${hub.name}. You are currently with ${numOfConnections - 1} other servers, Enjoy! ${emoji.clipart}`);
}
else {
await networkChannel?.send(`This channel has been connected with ${hub.name}, though no one else is there currently... *cricket noises* ${emoji.clipart}`);
}
await networkChannel?.send(`This channel has been connected with **${hub.name}**. ${
numOfConnections > 1
? `You are currently with ${numOfConnections - 1} other servers, Enjoy! ${emoji.clipart}`
: `It seems no one else is there currently... *cricket noises* ${emoji.clipart}`
}`);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
catch (err: any) {
Expand All @@ -72,7 +92,7 @@ export = {
: interaction.reply(errMsg);
}
else {
const errMsg = `An error occurred while connecting to the InterChat network! \`\`\`js\n${err.message}\`\`\``;
const errMsg = `An error occurred while connecting to the InterChat network! Please report this to the developers: \`\`\`js\n${err.message}\`\`\``;
interaction.deferred || interaction.replied
? interaction.followUp(errMsg)
: interaction.reply(errMsg);
Expand All @@ -88,6 +108,8 @@ export = {
**Server Name:** __${interaction.guild?.name}__
**Member Count:** __${interaction.guild?.memberCount}__
`, { id: hub.id });
return true; // just a marker to show that the setup was successful

// return the created connection so we can use it in the next step
return createdConnection;
},
};
Loading