(client, state, config)
| 138 | } |
| 139 | |
| 140 | async function createTemporaryChannel(client, state, config) { |
| 141 | const { channel: triggerChannel, member, guild } = state; |
| 142 | |
| 143 | try { |
| 144 | const me = guild.members.me; |
| 145 | if (!me) { |
| 146 | logger.warn(`Bot member cache unavailable while creating temporary channel in guild ${guild.id}`); |
| 147 | channelCreationCooldown.delete(cooldownKey); |
| 148 | return; |
| 149 | } |
| 150 | |
| 151 | const triggerPermissions = triggerChannel.permissionsFor(me); |
| 152 | if (!triggerPermissions?.has([PermissionFlagsBits.ManageChannels, PermissionFlagsBits.MoveMembers, PermissionFlagsBits.Connect])) { |
| 153 | logger.warn(`Missing required permissions for temporary channel creation in guild ${guild.id} (trigger channel ${triggerChannel.id})`); |
| 154 | channelCreationCooldown.delete(cooldownKey); |
| 155 | return; |
| 156 | } |
| 157 | |
| 158 | const channelOptions = config.channelOptions?.[triggerChannel.id] || {}; |
| 159 | const nameTemplate = channelOptions.nameTemplate || config.channelNameTemplate || "{username}'s Room"; |
| 160 | |
| 161 | let userLimit = channelOptions.userLimit ?? config.userLimit ?? 0; |
| 162 | const bitrate = clampVoiceBitrate(channelOptions.bitrate ?? config.bitrate ?? DEFAULT_VOICE_BITRATE); |
| 163 | |
| 164 | userLimit = Math.max(0, Math.min(99, userLimit || 0)); |
| 165 | |
| 166 | logger.info(`Creating temporary channel for user ${member.id} with user limit: ${userLimit}`); |
| 167 | |
| 168 | const existingChannels = guild.channels.cache.filter(c => |
| 169 | c.parentId === triggerChannel.parentId && |
| 170 | c.name.startsWith(triggerChannel.name) |
| 171 | ).size; |
| 172 | |
| 173 | let finalName; |
| 174 | |
| 175 | if ( |
| 176 | nameTemplate.includes('{username}') || |
| 177 | nameTemplate.includes('{displayName}') |
| 178 | ) { |
| 179 | finalName = formatChannelName(nameTemplate, { |
| 180 | username: member.user.username, |
| 181 | userTag: member.user.tag, |
| 182 | displayName: member.displayName, |
| 183 | guildName: guild.name, |
| 184 | channelName: triggerChannel.name |
| 185 | }); |
| 186 | } else { |
| 187 | finalName = `${triggerChannel.name} ${existingChannels + 1}`; |
| 188 | } |
| 189 | |
| 190 | const channelName = sanitizeVoiceChannelName(finalName); |
| 191 | |
| 192 | if (!member.voice?.channel || member.voice.channel.id !== triggerChannel.id) { |
| 193 | logger.debug(`Member ${member.id} no longer in trigger channel ${triggerChannel.id}, aborting temporary channel creation`); |
| 194 | channelCreationCooldown.delete(cooldownKey); |
| 195 | return; |
| 196 | } |
| 197 |
no test coverage detected