feat: Make chat cooldown adjustable

This commit is contained in:
Ash Keel 2023-05-25 19:48:32 +02:00
parent 823d9b14d1
commit b4e05220e7
No known key found for this signature in database
GPG Key ID: 53A9E9A6035DD109
10 changed files with 81 additions and 40 deletions

View File

@ -74,7 +74,7 @@
"bot-oauth-note": "You can get this by logging in with the bot account and going here: <1>https://twitchapps.com/tmi/</1>",
"bot-info-header": "Bot account info",
"bot-settings-copy": "A bot can interact with chat messages and provide extra events for the platform (chat events, some notifications) but requires access to a Twitch account. You can use your own or make a new one (if enabled on your main account, you can re-use the same email for your second account!)",
"bot-chat-header": "Chat logging",
"bot-chat-header": "Chat settings",
"bot-chat-history": "How many messages to keep in history (0 to disable)",
"events": {
"loading-data": "Querying user data from Twitch APIs…",
@ -99,7 +99,8 @@
"app-oauth-redirect-url": "OAuth Redirect URLs",
"test-button": "Test connection",
"test-failed": "Test failed: \"{{0}}\". Check your app client IDs and secret!",
"test-succeeded": "Test succeeded!"
"test-succeeded": "Test succeeded!",
"bot-chat-cooldown-tip": "Global chat cooldown for commands (in seconds)"
},
"botcommands": {
"title": "Bot commands",

View File

@ -326,7 +326,7 @@
"app-client-secret": "Segreto client",
"app-oauth-redirect-url": "Reindirizzamento URL OAuth",
"bot-channel": "Canale Twitch",
"bot-chat-header": "Storico chat",
"bot-chat-header": "Impostazioni chat",
"bot-chat-history": "Quanti messaggi tenere nello storico (0 per disabilitare)",
"bot-info-header": "Informazioni account del bot",
"bot-oauth": "Token di autorizzazione",
@ -360,7 +360,8 @@
},
"test-button": "Test connessione",
"test-failed": "Test fallito: \"{{0}}\". \nControlla ID e segreto client dell'app!",
"test-succeeded": "Test riuscito!"
"test-succeeded": "Test riuscito!",
"bot-chat-cooldown-tip": "Tempo minimo di attesa tra comandi (in secondi)"
},
"uiconfig": {
"language": "Lingua",

View File

@ -22,6 +22,7 @@ export interface TwitchBotConfig {
oauth: string;
channel: string;
chat_history: number;
command_cooldown: number;
}
export const accessLevels = [

View File

@ -10,6 +10,7 @@ import {
ReplyType,
TwitchBotCustomCommand,
} from '~/store/api/types';
import { TestCommandTemplate } from '@wailsapp/go/main/App';
import AlertContent from '../components/AlertContent';
import DialogContent from '../components/DialogContent';
import {
@ -35,7 +36,6 @@ import {
TextBlock,
} from '../theme';
import { Alert, AlertTrigger } from '../theme/alert';
import { TestCommandTemplate } from '@wailsapp/go/main/App';
const CommandList = styled('div', { marginTop: '1rem' });
const CommandItemContainer = styled('article', {
@ -112,7 +112,7 @@ const CommandType = styled('div', {
variants: {
type: {
chat: {
display:'none'
display: 'none',
},
whisper: {
backgroundColor: '$amber4',
@ -125,10 +125,10 @@ const CommandType = styled('div', {
reply: {
backgroundColor: '$gray2',
color: '$gray12',
}
}
}
})
},
},
},
});
const ACLIndicator = styled('span', {
fontFamily: 'Space Mono',
fontSize: '10pt',
@ -201,7 +201,11 @@ function CommandItem({
</CommandActions>
</CommandHeader>
<CommandText>
<CommandType type={item.response_type}>{t(`pages.botcommands.response-types.${item.response_type}`)}</CommandType>{item.response}</CommandText>
<CommandType type={item.response_type ?? 'chat'}>
{t(`pages.botcommands.response-types.${item.response_type}`)}
</CommandType>
{item.response}
</CommandText>
</CommandItemContainer>
);
}
@ -242,29 +246,30 @@ function CommandDialog({
closeButton={true}
>
<form
onSubmit={async (e) => {
onSubmit={(e) => {
if (!(e.target as HTMLFormElement).checkValidity()) {
return;
return false;
}
e.preventDefault();
try {
await TestCommandTemplate(response);
if (onSubmit) {
onSubmit(commandName, {
...item,
description,
response,
response_type: responseType,
access_level: accessLevel,
});
void (async () => {
try {
await TestCommandTemplate(response);
if (onSubmit) {
onSubmit(commandName, {
...item,
description,
response,
response_type: responseType,
access_level: accessLevel,
});
}
} catch (error: unknown) {
setResponseError(error as string);
responseRef.current?.setCustomValidity(
t('pages.botcommands.command-invalid-format'),
);
}
} catch (e) {
setResponseError(e);
responseRef.current?.setCustomValidity(
t('pages.botcommands.command-invalid-format'),
);
}
})();
}}
>
<Field spacing="narrow" size="fullWidth">
@ -323,7 +328,7 @@ function CommandDialog({
required={true}
onChange={(e) => {
responseRef.current?.setCustomValidity('');
setResponse(e.target.value)
setResponse(e.target.value);
}}
id="command-response"
ref={responseRef}
@ -332,9 +337,13 @@ function CommandDialog({
{item?.response}
</Textarea>
{responseError && (
<FieldNote css={{
color: '$red10'
}}>{responseError}</FieldNote>
<FieldNote
css={{
color: '$red10',
}}
>
{responseError}
</FieldNote>
)}
</Field>
<Field spacing="narrow" size="fullWidth">

View File

@ -191,6 +191,26 @@ function TwitchBotSettings() {
}
/>
</Field>
<Field size="fullWidth">
<Label htmlFor="bot-chat-history">
{t('pages.twitch-settings.bot-chat-cooldown-tip')}
</Label>
<InputBox
type="number"
id="bot-chat-history"
required={active}
disabled={disabled}
defaultValue={botConfig ? botConfig.command_cooldown ?? 2 : undefined}
onChange={(ev) =>
dispatch(
apiReducer.actions.twitchBotConfigChanged({
...botConfig,
command_cooldown: parseInt(ev.target.value, 10),
}),
)
}
/>
</Field>
<SaveButton status={status} />
</form>
);

2
go.mod
View File

@ -16,7 +16,7 @@ require (
github.com/strimertul/kilovolt/v10 v10.0.0
github.com/strimertul/kv-pebble v1.2.2
github.com/urfave/cli/v2 v2.25.1
github.com/wailsapp/wails/v2 v2.5.1
github.com/wailsapp/wails/v2 v2.4.1
go.uber.org/zap v1.24.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)

4
go.sum
View File

@ -321,8 +321,8 @@ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
github.com/wailsapp/wails/v2 v2.5.1 h1:mfG+2kWqQXYOwdgI43HEILjOZDXbk5woPYI3jP2b+js=
github.com/wailsapp/wails/v2 v2.5.1/go.mod h1:jbOZbcr/zm79PxXxAjP8UoVlDd9wLW3uDs+isIthDfs=
github.com/wailsapp/wails/v2 v2.4.1 h1:Ns7MOKWQM6l0ttBxpd5VcgYrH+GNPOnoDfnsBpbDnzM=
github.com/wailsapp/wails/v2 v2.4.1/go.mod h1:jbOZbcr/zm79PxXxAjP8UoVlDd9wLW3uDs+isIthDfs=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=

View File

@ -142,7 +142,7 @@ func (b *Bot) onMessageHandler(message irc.PrivateMessage) {
}
// Ignore messages for a while or twitch will get mad!
if message.Time.Before(b.lastMessage.Get().Add(time.Second * 2)) {
if time.Now().Before(b.lastMessage.Get().Add(time.Second * time.Duration(b.Config.CommandCooldown))) {
b.logger.Debug("Message received too soon, ignoring")
return
}
@ -305,3 +305,9 @@ func getUserAccessLevel(user irc.User) AccessLevelType {
return ALTEveryone
}
func defaultBotConfig() BotConfig {
return BotConfig{
CommandCooldown: 2,
}
}

View File

@ -34,7 +34,7 @@ func NewManager(db *database.LocalDBClient, server *http.Server, logger *zap.Log
}
// Get Twitch bot config
var botConfig BotConfig
botConfig := defaultBotConfig()
if err := db.GetJSON(BotConfigKey, &botConfig); err != nil {
if !errors.Is(err, database.ErrEmptyKey) {
return nil, fmt.Errorf("failed to get bot config: %w", err)
@ -89,7 +89,7 @@ func NewManager(db *database.LocalDBClient, server *http.Server, logger *zap.Log
// Listen for bot config changes
err, cancelBotSub := db.SubscribeKey(BotConfigKey, func(value string) {
var newBotConfig BotConfig
newBotConfig := defaultBotConfig()
if err := json.UnmarshalFromString(value, &newBotConfig); err != nil {
logger.Error("Failed to decode bot config", zap.Error(err))
return

View File

@ -36,6 +36,9 @@ type BotConfig struct {
// How many messages to keep in twitch/chat-history
ChatHistory int `json:"chat_history" desc:"How many messages to keep in twitch/chat-history"`
// Global command cooldown in seconds
CommandCooldown int `json:"command_cooldown" desc:"Global command cooldown in seconds"`
}
const (