Skip to content

Commit 01a38c4

Browse files
committed
Commands for hiding and unhiding text channels
1 parent 13ed34e commit 01a38c4

File tree

11 files changed

+168
-1
lines changed

11 files changed

+168
-1
lines changed

documentation/commands.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ Command | Description | Example
3030
`/edit_course` | Edit course information, e.g. course code, fullname, or nickname. Must be used inside a course. | `/edit_course nickname ohpe`
3131
`/edit_topic` | Edit channel topic, replacing an already existing topic. | `/edit_topic perusteet`
3232
`/enable_bridge` | Enable bridge in a Discord text channel. Must be used inside a course and in a non-default text channel. | `/enable_bridge`
33+
`/hide_channel` | Make the channel hidden from regular users. Also disables the bridge in the channel. Must be used inside a course and in a non-default text channel. | `/hide_channel`
3334
`/hide_course` | Make the given course private, disabling joining with `/join` | `/hide_course ohpe`
3435
`/lock_chat` | Lock the given course, disabling messaging by regular users | `/lock_chat ohpe`
3536
`/rename_channel` | Rename a Discord text channel. Must be used inside a course and in a non-default text channel. | `/rename_channel questions`
3637
`/status` | Get full status of course. Must be used inside a course. | `/status`
38+
`/unhide_channel` | Make the channel visible to regular users. Also enables the bridge in the channel. Must be used inside a course and in a non-default text channel. | `/unhide_channel`
3739
`/unhide_course` | Make the given course public, enabling joining with `/join`. | `/unhide_course ohpe`
3840
`/unlock_chat` | Unlock the given course, enabling messaging by regular users. | `/unlock_chat ohpe`
3941

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## /hide_channel
2+
3+
- :heavy_check_mark: Must be used in a non-default text channel.
4+
- :heavy_check_mark: Reply with an ephemeral message - is only visible to the user of the interaction.
5+
- :heavy_check_mark: Response includes the interaction status.
6+
7+
- :x: All members can use this command.
8+
- :x: Needs arguments.
9+
- :x: Can be used in every channel.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## /unhide_channel
2+
3+
- :heavy_check_mark: Must be used in a non-default text channel.
4+
- :heavy_check_mark: Reply with an ephemeral message - is only visible to the user of the interaction.
5+
- :heavy_check_mark: Response includes the interaction status.
6+
7+
- :x: All members can use this command.
8+
- :x: Needs arguments.
9+
- :x: Can be used in every channel.

documentation/usermanual-admin.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,13 @@ Command | Explanation | Arguments
124124
[/edit_course](./commands/faculty/edit_course.md) | Edit course information, options; coursecode, full name, nickname | :heavy_check_mark:
125125
[/edit_topic](./commands/faculty/edit_topic.md) | Edit topic, must be used in a course channel, e.g., /edit_topic A new topic. | :heavy_check_mark:
126126
[/enable_bridge](./commands/faculty/enable_bridge.md) | Enable the bridge between Telegram and the (non-default) course channel it is used in. | :x:
127+
[/hide_channel](./commands/faculty/hide_channel.md)| Make the channel hidden from regular users, e.g., /hide_channel. Also disables the bridge in the channel. | :x:
127128
[/hide_course](./commands/faculty/hide_course.md)| Make given course private, e.g., /hide_course weba. | :heavy_check_mark:
128129
[/lock_chat](./commands/faculty/lock_chat.md) | Lock the chat (meaning only instructors and faculty can post messages) of a given course | :heavy_check_mark:
129130
[/remove_instructors](./commands/faculty/remove_instructors.md) | Remove instructor role from (multiple) users, e.g., /remove_instructors @user1 @user2. | :heavy_check_mark:
130131
[/rename_channel](./commands/faculty/rename_channel.md) | Rename the non-default course text channel the command is used in, e.g., /rename_channel feedback. | :heavy_check_mark:
131132
[/status](./commands/faculty/status.md) | Used in course channel returns general info about the course | :heavy_check_mark:
133+
[/unhide_channel](./commands/faculty/unhide_channel.md)| Make the channel visible to regular users, e.g., /unhide_channel. Also enables the bridge in the channel. | :x:
132134
[/unhide_course](./commands/faculty/unhide_course.md) | Make given course public, e.g., /unhide_course weba. | :heavy_check_mark:
133135
[/unlock_chat](./commands/faculty/unlock_chat.md) | Unlock the chat of a given course | :heavy_check_mark:
134136

documentation/usermanual-faculty.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,16 @@ The `/create_poll` command allows you to create a poll that is placed in the sam
120120

121121
## Disabling the bridge on a text channel
122122

123-
Users with faculty rights can disable the bridge between a certain course channel and Telegram. This can be used e.g. on off-topic course channels where there's a lot of discussion that could flood the Telegram chat with messages not directly related to the course. Note that the bridge can be disabled only on non-default channels, that is channels which were created individually with `/create_channel` after the course was created. You can check in which channels the bridge is disabled with the command `/status`.
123+
Users with faculty rights can disable the bridge between a certain course channel and Telegram. This can be used e.g. on off-topic course channels where there's a lot of discussion that could flood the Telegram chat with messages not directly related to the course. Note that the bridge can be disabled only on non-default channels, that is channels which were created individually with `/create_channel` after the course was created. To disable the bridge on a channel, write the command `/disable_bridge` on that channel. You can check in which channels the bridge is disabled with the command `/status`.
124124

125125
To enable the bridge on a channel, write the command `/enable_bridge` on that channel.
126126

127+
## Hiding a text channel from regular users
128+
129+
Users with faculty rights can hide a text channel from regular users inside a course. This can be used to e.g. make a private chat for course instructors. Note that the bridge can be disabled only on non-default channels, that is channels which were created individually with `/create_channel` after the course was created. To hide a text channel, write the command `/hide_channel` on that channel. Note that the command also disables the bridge on that channel, so that instructor specific conversations won't accidentally leak to Telegram.
130+
131+
To reveal the channel to regular users, write the command `/unhide_channel` on that channel. Note that the command also enables the bridge on that channel.
132+
127133
#### Faculty specific commands ####
128134

129135
Command | Explanation | Arguments
@@ -138,11 +144,13 @@ Command | Explanation | Arguments
138144
[/edit_course](./commands/faculty/edit_course.md) | Edit course information, options; coursecode, full name, nickname | :heavy_check_mark:
139145
[/edit_topic](./commands/faculty/edit_topic.md) | Edit topic, must be used in a course channel, e.g., /edit_topic A new topic. | :heavy_check_mark:
140146
[/enable_bridge](./commands/faculty/enable_bridge.md) | Enable the bridge between Telegram and the (non-default) course channel it is used in. | :x:
147+
[/hide_channel](./commands/faculty/hide_channel.md)| Make the channel hidden from regular users, e.g., /hide_channel. Also disables the bridge in the channel. | :x:
141148
[/hide_course](./commands/faculty/hide_course.md)| Make given course private, e.g., /hide_course weba. | :heavy_check_mark:
142149
[/lock_chat](./commands/faculty/lock_chat.md) | Lock the chat (meaning only instructors and faculty can post messages) of a given course | :heavy_check_mark:
143150
[/remove_instructors](./commands/faculty/remove_instructors.md) | Remove instructor role from (multiple) users, e.g., /remove_instructors @user1 @user2. | :heavy_check_mark:
144151
[/rename_channel](./commands/faculty/rename_channel.md) | Rename the non-default course text channel the command is used in, e.g., /rename_channel feedback. | :heavy_check_mark:
145152
[/status](./commands/faculty/status.md) | Used in course channel returns general info about the course | :heavy_check_mark:
153+
[/unhide_channel](./commands/faculty/unhide_channel.md)| Make the channel visible to regular users, e.g., /unhide_channel. Also enables the bridge in the channel. | :x:
146154
[/unhide_course](./commands/faculty/unhide_course.md) | Make given course public, e.g., /unhide_course weba. | :heavy_check_mark:
147155
[/unlock_chat](./commands/faculty/unlock_chat.md) | Unlock the chat of a given course | :heavy_check_mark:
148156

src/db/hookInit.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,23 @@ const initChannelHooks = (guild, models) => {
8383
const channelObject = guild.channels.cache.find(c => c.name === channel.name);
8484
await channelObject.setTopic(channel.topic);
8585
}
86+
87+
if (channel._changed.has("hidden")) {
88+
const course = await findCourseFromDbById(channel.courseId, courseModel);
89+
const student = await findOrCreateRoleWithName(course.name, guild);
90+
const channelObject = guild.channels.cache
91+
.find(c => c.name === channel.dataValues.name);
92+
if (channel.hidden) {
93+
await channelObject.permissionOverwrites.create(student, {
94+
VIEW_CHANNEL: false,
95+
});
96+
}
97+
else {
98+
await channelObject.permissionOverwrites.create(student, {
99+
VIEW_CHANNEL: true,
100+
});
101+
}
102+
}
86103
});
87104
};
88105

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"use strict";
2+
const { BOOLEAN } = require("sequelize");
3+
4+
module.exports = {
5+
up: async (queryInterface) => {
6+
await queryInterface.addColumn("channel", "hidden", {
7+
type: BOOLEAN,
8+
defaultValue: false,
9+
});
10+
},
11+
down: async (queryInterface) => {
12+
await queryInterface.removeColumn("channel", "hidden");
13+
},
14+
};

src/db/models/Channel.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ module.exports = (sequelize, DataTypes) => {
3535
allowNull: true,
3636
unique: true,
3737
},
38+
hidden: {
39+
type: DataTypes.BOOLEAN,
40+
defaultValue: false,
41+
unique: false,
42+
},
3843
}, {
3944
timestamps: false,
4045
freezeTableName: true,

src/db/services/channelService.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ const saveChannelIdWithName = async (id, channelName, Channel) => {
107107
{ where: { name: channelName } });
108108
};
109109

110+
const editChannelHiddenStatus = async (discordId, hiddenStatus, Channel) => {
111+
const channel = await findChannelFromDbByDiscordId(discordId, Channel);
112+
113+
if (channel) {
114+
channel.hidden = hiddenStatus;
115+
channel.bridged = !hiddenStatus;
116+
await channel.save();
117+
}
118+
};
119+
110120
module.exports = {
111121
findChannelFromDbByName,
112122
findChannelFromDbByDiscordId,
@@ -121,4 +131,5 @@ module.exports = {
121131
getAllChannels,
122132
editChannelName,
123133
saveChannelTopicToDb,
134+
editChannelHiddenStatus,
124135
};
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const { SlashCommandBuilder } = require("@discordjs/builders");
2+
const { getChannelByDiscordId, editChannelHiddenStatus } = require("../../../db/services/channelService");
3+
const { sendEphemeral, editEphemeral, editErrorEphemeral } = require("../../services/message");
4+
const { facultyRole } = require("../../../../config.json");
5+
const { confirmChoice } = require("../../services/confirm");
6+
7+
const execute = async (interaction, client, models) => {
8+
await sendEphemeral(interaction, "Hiding text channel...");
9+
10+
const channelModel = models.Channel;
11+
12+
const channel = await getChannelByDiscordId(interaction.channelId, channelModel);
13+
14+
if (!channel || !channel.courseId) {
15+
return await editErrorEphemeral(interaction, "Course not found, can not hide the channel.");
16+
}
17+
18+
const confirm = await confirmChoice(interaction, "Confirm command: Hide channel");
19+
20+
if (!confirm) {
21+
return await editEphemeral(interaction, "Command declined");
22+
}
23+
24+
if (channel.defaultChannel) {
25+
return await editErrorEphemeral(interaction, "Command can't be performed on default course channels!");
26+
}
27+
28+
if (channel.hidden) {
29+
return await editErrorEphemeral(interaction, "The channel is already hidden.");
30+
}
31+
32+
await editChannelHiddenStatus(channel.discordId, true, channelModel);
33+
await editEphemeral(interaction, `Hid channel ${channel.name}`);
34+
};
35+
36+
module.exports = {
37+
data: new SlashCommandBuilder()
38+
.setName("hide_channel")
39+
.setDescription("Hide text channel the command was used in from regular users.")
40+
.setDefaultPermission(false),
41+
execute,
42+
usage: "/hide_channel",
43+
description: "Hide text channel the command was used in from regular users.*",
44+
roles: ["admin", facultyRole],
45+
};

0 commit comments

Comments
 (0)