New option for the moderation bot: forbid duplicate messages (#516).
This commit is contained in:
parent
651641f63c
commit
5225257bb5
@ -2,9 +2,13 @@
|
|||||||
|
|
||||||
## 11.1.0 (Not Released Yet)
|
## 11.1.0 (Not Released Yet)
|
||||||
|
|
||||||
|
TODO Before releasing:
|
||||||
|
* update ConverseJS with latest merges.
|
||||||
|
|
||||||
### New features
|
### New features
|
||||||
|
|
||||||
* #131: Emoji only mode.
|
* #131: Emoji only mode.
|
||||||
|
* #516: new option for the moderation bot: forbid duplicate messages.
|
||||||
* #517: new option for the moderation bot: forbid messages with too many special characters.
|
* #517: new option for the moderation bot: forbid messages with too many special characters.
|
||||||
|
|
||||||
### Minor changes and fixes
|
### Minor changes and fixes
|
||||||
|
5
client/@types/global.d.ts
vendored
5
client/@types/global.d.ts
vendored
@ -155,3 +155,8 @@ declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_SPECIAL_CHARS_LABEL: string
|
|||||||
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_SPECIAL_CHARS_DESC: string
|
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_SPECIAL_CHARS_DESC: string
|
||||||
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_SPECIAL_CHARS_TOLERANCE_LABEL: string
|
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_SPECIAL_CHARS_TOLERANCE_LABEL: string
|
||||||
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_SPECIAL_CHARS_TOLERANCE_DESC: string
|
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_SPECIAL_CHARS_TOLERANCE_DESC: string
|
||||||
|
|
||||||
|
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_NO_DUPLICATE_LABEL: string
|
||||||
|
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_NO_DUPLICATE_DESC: string
|
||||||
|
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_NO_DUPLICATE_DELAY_LABEL: string
|
||||||
|
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_NO_DUPLICATE_DELAY_DESC: string
|
||||||
|
@ -460,6 +460,126 @@ export function tplChannelConfiguration (el: ChannelConfigurationElement): Templ
|
|||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<livechat-configuration-section-header
|
||||||
|
.label=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_NO_DUPLICATE_LABEL)}
|
||||||
|
.description=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_NO_DUPLICATE_DESC)}
|
||||||
|
.helpPage=${'documentation/user/streamers/bot/no_duplicate'}>
|
||||||
|
</livechat-configuration-section-header>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="no_duplicate"
|
||||||
|
id="peertube-livechat-no-duplicate"
|
||||||
|
@input=${(event: InputEvent) => {
|
||||||
|
if (event?.target && el.channelConfiguration) {
|
||||||
|
el.channelConfiguration.configuration.bot.noDuplicate.enabled =
|
||||||
|
(event.target as HTMLInputElement).checked
|
||||||
|
}
|
||||||
|
el.requestUpdate('channelConfiguration')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value="1"
|
||||||
|
?checked=${el.channelConfiguration?.configuration.bot.noDuplicate.enabled}
|
||||||
|
/>
|
||||||
|
${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_NO_DUPLICATE_LABEL)}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
${!el.channelConfiguration?.configuration.bot.noDuplicate.enabled
|
||||||
|
? ''
|
||||||
|
: html`
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_NO_DUPLICATE_DELAY_LABEL)}
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
name="no_duplicate_delay"
|
||||||
|
class=${classMap(
|
||||||
|
Object.assign(
|
||||||
|
{ 'form-control': true },
|
||||||
|
el.getInputValidationClass('bot.noDuplicate.delay')
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
min="0"
|
||||||
|
max="10"
|
||||||
|
id="peertube-livechat-no-duplicate-delay"
|
||||||
|
aria-describedby="peertube-livechat-no-duplicate-delay-feedback"
|
||||||
|
@input=${(event: InputEvent) => {
|
||||||
|
if (event?.target && el.channelConfiguration) {
|
||||||
|
el.channelConfiguration.configuration.bot.noDuplicate.delay =
|
||||||
|
Number((event.target as HTMLInputElement).value)
|
||||||
|
}
|
||||||
|
el.requestUpdate('channelConfiguration')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value="${el.channelConfiguration?.configuration.bot.noDuplicate.delay ?? '0'}"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<small class="form-text text-muted">
|
||||||
|
${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_NO_DUPLICATE_DELAY_DESC)}
|
||||||
|
</small>
|
||||||
|
${el.renderFeedback('peertube-livechat-no-duplicate-delay-feedback',
|
||||||
|
'bot.noDuplicate.delay')
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_RETRACTATION_REASON_LABEL)}
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="no_duplicate_reason"
|
||||||
|
class=${classMap(
|
||||||
|
Object.assign(
|
||||||
|
{ 'form-control': true },
|
||||||
|
el.getInputValidationClass('bot.noDuplicate.reason')
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
id="peertube-livechat-no-duplicate-reason"
|
||||||
|
aria-describedby="peertube-livechat-no-duplicate-reason-feedback"
|
||||||
|
@input=${(event: InputEvent) => {
|
||||||
|
if (event?.target && el.channelConfiguration) {
|
||||||
|
el.channelConfiguration.configuration.bot.noDuplicate.reason =
|
||||||
|
(event.target as HTMLInputElement).value
|
||||||
|
}
|
||||||
|
el.requestUpdate('channelConfiguration')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value="${el.channelConfiguration?.configuration.bot.noDuplicate.reason ?? ''}"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<small class="form-text text-muted">
|
||||||
|
${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_RETRACTATION_REASON_DESC)}
|
||||||
|
</small>
|
||||||
|
${el.renderFeedback('peertube-livechat-no-duplicate-reason-feedback',
|
||||||
|
'bot.noDuplicate.reason')
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="no_duplicate_applyToModerators"
|
||||||
|
id="peertube-livechat-no-duplicate-applyToModerators"
|
||||||
|
@input=${(event: InputEvent) => {
|
||||||
|
if (event?.target && el.channelConfiguration) {
|
||||||
|
el.channelConfiguration.configuration.bot.noDuplicate.applyToModerators =
|
||||||
|
(event.target as HTMLInputElement).checked
|
||||||
|
}
|
||||||
|
el.requestUpdate('channelConfiguration')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value="1"
|
||||||
|
?checked=${el.channelConfiguration?.configuration.bot.noDuplicate.applyToModerators}
|
||||||
|
/>
|
||||||
|
${ptTr(LOC_LIVECHAT_CONFIGURATION_APPLYTOMODERATORS_LABEL)}
|
||||||
|
</label>
|
||||||
|
<small class="form-text text-muted">
|
||||||
|
${ptTr(LOC_LIVECHAT_CONFIGURATION_APPLYTOMODERATORS_DESC)}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
<livechat-configuration-section-header
|
<livechat-configuration-section-header
|
||||||
.label=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_LABEL)}
|
.label=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_LABEL)}
|
||||||
.description=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_DESC)}
|
.description=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_DESC)}
|
||||||
|
@ -68,6 +68,7 @@ export class ChannelDetailsService {
|
|||||||
if (botConf.enabled) {
|
if (botConf.enabled) {
|
||||||
propertiesError['bot.nickname'] = []
|
propertiesError['bot.nickname'] = []
|
||||||
propertiesError['bot.forbidSpecialChars.tolerance'] = []
|
propertiesError['bot.forbidSpecialChars.tolerance'] = []
|
||||||
|
propertiesError['bot.noDuplicate.delay'] = []
|
||||||
|
|
||||||
if (/[^\p{L}\p{N}\p{Z}_-]/u.test(botConf.nickname ?? '')) {
|
if (/[^\p{L}\p{N}\p{Z}_-]/u.test(botConf.nickname ?? '')) {
|
||||||
propertiesError['bot.nickname'].push(ValidationErrorType.WrongFormat)
|
propertiesError['bot.nickname'].push(ValidationErrorType.WrongFormat)
|
||||||
@ -88,6 +89,21 @@ export class ChannelDetailsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (botConf.noDuplicate.enabled) {
|
||||||
|
const noDuplicateDelay = channelConfigurationOptions.bot.noDuplicate.delay
|
||||||
|
if (
|
||||||
|
(typeof noDuplicateDelay !== 'number') ||
|
||||||
|
isNaN(noDuplicateDelay)
|
||||||
|
) {
|
||||||
|
propertiesError['bot.noDuplicate.delay'].push(ValidationErrorType.WrongType)
|
||||||
|
} else if (
|
||||||
|
noDuplicateDelay < 0 ||
|
||||||
|
noDuplicateDelay > 24 * 3600
|
||||||
|
) {
|
||||||
|
propertiesError['bot.noDuplicate.delay'].push(ValidationErrorType.NotInRange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const [i, fw] of botConf.forbiddenWords.entries()) {
|
for (const [i, fw] of botConf.forbiddenWords.entries()) {
|
||||||
for (const v of fw.entries) {
|
for (const v of fw.entries) {
|
||||||
propertiesError[`bot.forbiddenWords.${i}.entries`] = []
|
propertiesError[`bot.forbiddenWords.${i}.entries`] = []
|
||||||
|
@ -662,3 +662,11 @@ livechat_configuration_channel_special_chars_tolerance_label: Tolerance
|
|||||||
livechat_configuration_channel_special_chars_tolerance_desc: Number of special characters to accept before deleting messages.
|
livechat_configuration_channel_special_chars_tolerance_desc: Number of special characters to accept before deleting messages.
|
||||||
|
|
||||||
feature_comes_with: This feature comes with the livechat plugin version X.X.X.
|
feature_comes_with: This feature comes with the livechat plugin version X.X.X.
|
||||||
|
|
||||||
|
livechat_configuration_channel_no_duplicate_label: "No duplicate message"
|
||||||
|
livechat_configuration_channel_no_duplicate_desc: |
|
||||||
|
By enabling this options, the moderation bot will automatically moderate duplicate messages.
|
||||||
|
That means if a user send the same message twice within X seconds, the second message will be deleted.
|
||||||
|
livechat_configuration_channel_no_duplicate_delay_label: Time interval
|
||||||
|
livechat_configuration_channel_no_duplicate_delay_desc: |
|
||||||
|
The interval, in seconds, during which a user can't send again the same message.
|
||||||
|
14
package-lock.json
generated
14
package-lock.json
generated
@ -18,7 +18,7 @@
|
|||||||
"log-rotate": "^0.2.8",
|
"log-rotate": "^0.2.8",
|
||||||
"openid-client": "^5.7.0",
|
"openid-client": "^5.7.0",
|
||||||
"validate-color": "^2.2.4",
|
"validate-color": "^2.2.4",
|
||||||
"xmppjs-chat-bot": "^0.4.0"
|
"xmppjs-chat-bot": "^0.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.10.0",
|
"@eslint/js": "^9.10.0",
|
||||||
@ -12932,9 +12932,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/xmppjs-chat-bot": {
|
"node_modules/xmppjs-chat-bot": {
|
||||||
"version": "0.4.0",
|
"version": "0.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/xmppjs-chat-bot/-/xmppjs-chat-bot-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/xmppjs-chat-bot/-/xmppjs-chat-bot-0.5.0.tgz",
|
||||||
"integrity": "sha512-vN+hWlrSDKmOK+XDOx3VmBffQkEYtfEhLDiovwy8PqPJnyEGESsIcva33hvzWrBYES8hTz1DX320aFYx5tnnNA==",
|
"integrity": "sha512-P+C2x00zS3Zd0PvkKeiT+cPYMQOW/pZu2pEG+iNkUjHU5MYBukn48aMgbzzPwJVQpk/9FuZZeK1m/pl3iD2KFA==",
|
||||||
"funding": [
|
"funding": [
|
||||||
"https://paypal.me/JohnXLivingston",
|
"https://paypal.me/JohnXLivingston",
|
||||||
"https://liberapay.com/JohnLivingston/"
|
"https://liberapay.com/JohnLivingston/"
|
||||||
@ -22351,9 +22351,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"xmppjs-chat-bot": {
|
"xmppjs-chat-bot": {
|
||||||
"version": "0.4.0",
|
"version": "0.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/xmppjs-chat-bot/-/xmppjs-chat-bot-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/xmppjs-chat-bot/-/xmppjs-chat-bot-0.5.0.tgz",
|
||||||
"integrity": "sha512-vN+hWlrSDKmOK+XDOx3VmBffQkEYtfEhLDiovwy8PqPJnyEGESsIcva33hvzWrBYES8hTz1DX320aFYx5tnnNA==",
|
"integrity": "sha512-P+C2x00zS3Zd0PvkKeiT+cPYMQOW/pZu2pEG+iNkUjHU5MYBukn48aMgbzzPwJVQpk/9FuZZeK1m/pl3iD2KFA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@xmpp/client": "^0.13.1",
|
"@xmpp/client": "^0.13.1",
|
||||||
"@xmpp/component": "^0.13.1",
|
"@xmpp/component": "^0.13.1",
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
"log-rotate": "^0.2.8",
|
"log-rotate": "^0.2.8",
|
||||||
"openid-client": "^5.7.0",
|
"openid-client": "^5.7.0",
|
||||||
"validate-color": "^2.2.4",
|
"validate-color": "^2.2.4",
|
||||||
"xmppjs-chat-bot": "^0.4.0"
|
"xmppjs-chat-bot": "^0.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.10.0",
|
"@eslint/js": "^9.10.0",
|
||||||
|
@ -57,7 +57,18 @@ async function sanitizeChannelConfigurationOptions (
|
|||||||
applyToModerators: false
|
applyToModerators: false
|
||||||
}
|
}
|
||||||
if (!_assertObjectType(botData.forbidSpecialChars)) {
|
if (!_assertObjectType(botData.forbidSpecialChars)) {
|
||||||
throw new Error('Invalid data.forbidSpecialChars data type')
|
throw new Error('Invalid data.bot.forbidSpecialChars data type')
|
||||||
|
}
|
||||||
|
|
||||||
|
// noDuplicate comes with livechat 11.1.0
|
||||||
|
botData.noDuplicate ??= {
|
||||||
|
enabled: false,
|
||||||
|
reason: '',
|
||||||
|
delay: 60,
|
||||||
|
applyToModerators: false
|
||||||
|
}
|
||||||
|
if (!_assertObjectType(botData.noDuplicate)) {
|
||||||
|
throw new Error('Invalid data.bot.noDuplicate data type')
|
||||||
}
|
}
|
||||||
|
|
||||||
// terms not present in livechat <= 10.2.0
|
// terms not present in livechat <= 10.2.0
|
||||||
@ -76,6 +87,7 @@ async function sanitizeChannelConfigurationOptions (
|
|||||||
nickname: _readSimpleInput(botData, 'nickname', true),
|
nickname: _readSimpleInput(botData, 'nickname', true),
|
||||||
forbiddenWords: await _readForbiddenWords(botData),
|
forbiddenWords: await _readForbiddenWords(botData),
|
||||||
forbidSpecialChars: await _readForbidSpecialChars(botData),
|
forbidSpecialChars: await _readForbidSpecialChars(botData),
|
||||||
|
noDuplicate: await _readNoDuplicate(botData),
|
||||||
quotes: _readQuotes(botData),
|
quotes: _readQuotes(botData),
|
||||||
commands: _readCommands(botData)
|
commands: _readCommands(botData)
|
||||||
// TODO: bannedJIDs
|
// TODO: bannedJIDs
|
||||||
@ -266,6 +278,21 @@ async function _readForbidSpecialChars (
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function _readNoDuplicate (
|
||||||
|
botData: Record<string, unknown>
|
||||||
|
): Promise<ChannelConfigurationOptions['bot']['noDuplicate']> {
|
||||||
|
if (!_assertObjectType(botData.noDuplicate)) {
|
||||||
|
throw new Error('Invalid forbidSpecialChars data')
|
||||||
|
}
|
||||||
|
const result: ChannelConfigurationOptions['bot']['noDuplicate'] = {
|
||||||
|
enabled: _readBoolean(botData.noDuplicate, 'enabled'),
|
||||||
|
reason: _readSimpleInput(botData.noDuplicate, 'reason'),
|
||||||
|
delay: _readInteger(botData.noDuplicate, 'delay', 0, 24 * 3600),
|
||||||
|
applyToModerators: _readBoolean(botData.noDuplicate, 'applyToModerators')
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
function _readQuotes (botData: Record<string, unknown>): ChannelConfigurationOptions['bot']['quotes'] {
|
function _readQuotes (botData: Record<string, unknown>): ChannelConfigurationOptions['bot']['quotes'] {
|
||||||
if (!Array.isArray(botData.quotes)) {
|
if (!Array.isArray(botData.quotes)) {
|
||||||
throw new Error('Invalid quotes data')
|
throw new Error('Invalid quotes data')
|
||||||
|
@ -50,6 +50,12 @@ function getDefaultChannelConfigurationOptions (_options: RegisterServerOptions)
|
|||||||
tolerance: 0,
|
tolerance: 0,
|
||||||
applyToModerators: false
|
applyToModerators: false
|
||||||
},
|
},
|
||||||
|
noDuplicate: {
|
||||||
|
enabled: false,
|
||||||
|
reason: '',
|
||||||
|
delay: 60,
|
||||||
|
applyToModerators: false
|
||||||
|
},
|
||||||
quotes: [],
|
quotes: [],
|
||||||
commands: []
|
commands: []
|
||||||
},
|
},
|
||||||
@ -124,6 +130,11 @@ function channelConfigurationOptionsToBotRoomConf (
|
|||||||
handlersIds.set(id, true)
|
handlersIds.set(id, true)
|
||||||
handlers.push(_getForbidSpecialCharsHandler(id, channelConfigurationOptions.bot.forbidSpecialChars))
|
handlers.push(_getForbidSpecialCharsHandler(id, channelConfigurationOptions.bot.forbidSpecialChars))
|
||||||
}
|
}
|
||||||
|
if (channelConfigurationOptions.bot.noDuplicate.enabled) {
|
||||||
|
const id = 'no_duplicate'
|
||||||
|
handlersIds.set(id, true)
|
||||||
|
handlers.push(_getNoDuplicateHandler(id, channelConfigurationOptions.bot.noDuplicate))
|
||||||
|
}
|
||||||
channelConfigurationOptions.bot.quotes.forEach((v, i) => {
|
channelConfigurationOptions.bot.quotes.forEach((v, i) => {
|
||||||
const id = 'quote_' + i.toString()
|
const id = 'quote_' + i.toString()
|
||||||
handlersIds.set(id, true)
|
handlersIds.set(id, true)
|
||||||
@ -254,6 +265,23 @@ function _getForbidSpecialCharsHandler (
|
|||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _getNoDuplicateHandler (
|
||||||
|
id: string,
|
||||||
|
noDuplicate: ChannelConfigurationOptions['bot']['noDuplicate']
|
||||||
|
): ConfigHandler {
|
||||||
|
const handler: ConfigHandler = {
|
||||||
|
type: 'no-duplicate',
|
||||||
|
id,
|
||||||
|
enabled: true,
|
||||||
|
options: {
|
||||||
|
reason: noDuplicate.reason,
|
||||||
|
delay: noDuplicate.delay,
|
||||||
|
applyToModerators: !!noDuplicate.applyToModerators
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return handler
|
||||||
|
}
|
||||||
|
|
||||||
function _getQuotesHandler (
|
function _getQuotesHandler (
|
||||||
id: string,
|
id: string,
|
||||||
quotes: ChannelConfigurationOptions['bot']['quotes'][0]
|
quotes: ChannelConfigurationOptions['bot']['quotes'][0]
|
||||||
|
@ -96,7 +96,7 @@ async function initConfigurationApiRouter (options: RegisterServerOptions, route
|
|||||||
req.body.bot = channelOptions.bot
|
req.body.bot = channelOptions.bot
|
||||||
req.body.bot.enabled = false
|
req.body.bot.enabled = false
|
||||||
}
|
}
|
||||||
// TODO: Same for forbidSpecialChars: if disabled, don't save reason and tolerance
|
// TODO: Same for forbidSpecialChars/noDuplicate: if disabled, don't save reason and tolerance
|
||||||
// (disabling for now, because it is not acceptable to load twice the channel configuration.
|
// (disabling for now, because it is not acceptable to load twice the channel configuration.
|
||||||
// Must find better way)
|
// Must find better way)
|
||||||
// if (req.body.bot?.enabled === true && req.body.bot.forbidSpecialChars?.enabled === false) {
|
// if (req.body.bot?.enabled === true && req.body.bot.forbidSpecialChars?.enabled === false) {
|
||||||
@ -108,6 +108,7 @@ async function initConfigurationApiRouter (options: RegisterServerOptions, route
|
|||||||
// req.body.bot.forbidSpecialChars.tolerance = channelOptions.bot.forbidSpecialChars.tolerance
|
// req.body.bot.forbidSpecialChars.tolerance = channelOptions.bot.forbidSpecialChars.tolerance
|
||||||
// req.body.bot.forbidSpecialChars.applyToModerators = channelOptions.bot.forbidSpecialChars.applyToModerators
|
// req.body.bot.forbidSpecialChars.applyToModerators = channelOptions.bot.forbidSpecialChars.applyToModerators
|
||||||
// req.body.bot.forbidSpecialChars.enabled = false
|
// req.body.bot.forbidSpecialChars.enabled = false
|
||||||
|
// ... NoDuplicate...
|
||||||
// }
|
// }
|
||||||
channelOptions = await sanitizeChannelConfigurationOptions(options, channelInfos.id, req.body)
|
channelOptions = await sanitizeChannelConfigurationOptions(options, channelInfos.id, req.body)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -97,6 +97,7 @@ interface ChannelConfigurationOptions {
|
|||||||
quotes: ChannelQuotes[]
|
quotes: ChannelQuotes[]
|
||||||
commands: ChannelCommands[]
|
commands: ChannelCommands[]
|
||||||
forbidSpecialChars: ChannelForbidSpecialChars
|
forbidSpecialChars: ChannelForbidSpecialChars
|
||||||
|
noDuplicate: ChannelNoDuplicate
|
||||||
// TODO: bannedJIDs: string[]
|
// TODO: bannedJIDs: string[]
|
||||||
}
|
}
|
||||||
slowMode: {
|
slowMode: {
|
||||||
@ -140,6 +141,13 @@ interface ChannelForbidSpecialChars {
|
|||||||
applyToModerators: boolean
|
applyToModerators: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ChannelNoDuplicate {
|
||||||
|
enabled: boolean
|
||||||
|
reason: string
|
||||||
|
delay: number
|
||||||
|
applyToModerators: boolean
|
||||||
|
}
|
||||||
|
|
||||||
interface ChannelConfiguration {
|
interface ChannelConfiguration {
|
||||||
channel: ChannelInfos
|
channel: ChannelInfos
|
||||||
configuration: ChannelConfigurationOptions
|
configuration: ChannelConfigurationOptions
|
||||||
|
Loading…
x
Reference in New Issue
Block a user