mirror of https://git.sr.ht/~ashkeel/strimertul
Compare commits
3 Commits
422c70c9d4
...
fe02999663
Author | SHA1 | Date |
---|---|---|
Ash Keel | fe02999663 | |
Ash Keel | 7f6e14cd48 | |
Ash Keel | c186c0b942 |
|
@ -22,10 +22,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- The Twitch chat integration has been rewritten from the ground up to not use an IRC bot and rely on EventSub. This means that you will need to reconfigure your twitch account, especially if you used a different account as the "bot" account. Because of this rewrite, the terminology around chat functionalities have been renamed from "Bot" to "Chat" (e.g. "Bot commands" are now "Chat commands").
|
||||
- The (i) icon next to "Recent events" in the dashboard now uses a custom tooltip that shows up more consistently.
|
||||
- The "strimertul is already running" message now pops up from the currently running instance.
|
||||
- Setting up a secondary user for chat interactions is now much simpler through an auth flow much like the one for setting up the main user.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Updated Kilovolt to a version that fixes an annoying crash when managing subscriptions.
|
||||
- A new cleanup routine will remove old eventsub subscriptions that are no longer used. This should remove most of the errors when trying to set new API keys about "too many subscriptions".
|
||||
|
||||
### Removed
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
"chat": {
|
||||
"header": "Chat settings",
|
||||
"cooldown-tip": "Global chat cooldown for commands (in seconds)",
|
||||
"default-user": "Using stream account, use the button below to authenticate with a different account.",
|
||||
"default-user": "Currently using stream account, use the button above to authenticate with a different account.",
|
||||
"chat-account": "Chat account",
|
||||
"clear-button": "Revert to default account",
|
||||
"account-copy": "You can use a different account for repling to chat commands and writing alerts instead of your channel one. To do so, click the button below and authenticate and authorize using your secondary account."
|
||||
|
|
|
@ -341,7 +341,7 @@
|
|||
"cooldown-tip": "Tempo minimo di attesa tra comandi (in secondi)",
|
||||
"chat-account": "Account chat",
|
||||
"header": "Impostazioni chat",
|
||||
"default-user": "Utilizzando l'account principale, usa il pulsante qui sotto per autenticarti con un account diverso per le funzionalità di chat.",
|
||||
"default-user": "Utilizzando l'account principale, usa il pulsante qui sopra per autenticarti con un account diverso per le funzionalità di chat.",
|
||||
"clear-button": "Torna ad usare l'account principale",
|
||||
"account-copy": "Puoi utilizzare un account diverso per rispondendere ai comandi della chat e invia notifiche al posto di quello del tuo canale. \nPer fare ciò, fai clic sul pulsante in basso e autentica e autorizza l'utilizzo del tuo account secondario."
|
||||
},
|
||||
|
|
|
@ -20,7 +20,6 @@ export default function TwitchChatSettings() {
|
|||
const [chatConfig, setChatConfig, loadStatus] = useModule(
|
||||
modules.twitchChatConfig,
|
||||
);
|
||||
const [twitchConfig, setTwitchConfig] = useModule(modules.twitchConfig);
|
||||
const kv = useAppSelector((state) => state.api.client);
|
||||
const authKey = 'twitch/chat/chatter-account';
|
||||
const authKeyValue = useLiveKeyString('twitch/chat/chatter-account');
|
||||
|
@ -32,7 +31,6 @@ export default function TwitchChatSettings() {
|
|||
return (
|
||||
<form
|
||||
onSubmit={(ev) => {
|
||||
void dispatch(setTwitchConfig(twitchConfig));
|
||||
void dispatch(setChatConfig(chatConfig));
|
||||
ev.preventDefault();
|
||||
}}
|
||||
|
@ -44,6 +42,7 @@ export default function TwitchChatSettings() {
|
|||
<FlexRow align="left" spacing="1" css={{ marginBottom: '1rem' }}>
|
||||
<Button
|
||||
variation="primary"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
void startAuthFlow('chat');
|
||||
}}
|
||||
|
@ -53,6 +52,7 @@ export default function TwitchChatSettings() {
|
|||
{authKeyValue && (
|
||||
<Button
|
||||
variation="danger"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
kv.deleteKey(authKey);
|
||||
}}
|
||||
|
|
4
go.mod
4
go.mod
|
@ -4,8 +4,8 @@ go 1.22
|
|||
|
||||
require (
|
||||
git.sr.ht/~ashkeel/containers v0.3.6
|
||||
git.sr.ht/~ashkeel/kilovolt-driver-pebble v1.3.3
|
||||
git.sr.ht/~ashkeel/kilovolt/v12 v12.0.2
|
||||
git.sr.ht/~ashkeel/kilovolt-driver-pebble v1.3.4
|
||||
git.sr.ht/~ashkeel/kilovolt/v12 v12.0.3
|
||||
github.com/Masterminds/sprig/v3 v3.2.3
|
||||
github.com/apenwarr/fixconsole v0.0.0-20191012055117-5a9f6489cc29
|
||||
github.com/cockroachdb/pebble v1.1.0
|
||||
|
|
8
go.sum
8
go.sum
|
@ -33,10 +33,10 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
|
|||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
git.sr.ht/~ashkeel/containers v0.3.6 h1:+umWlQGKhLxGQlaEUt/F6rBZGpeBd1T01fM3wro+qTY=
|
||||
git.sr.ht/~ashkeel/containers v0.3.6/go.mod h1:i2KocnJfRH0FwfgPi4nw7/ehYLEoLlP3iwdDoBeVdME=
|
||||
git.sr.ht/~ashkeel/kilovolt-driver-pebble v1.3.3 h1:+tu5DBT150HRR2gpVEpQwpTclE3niEsy9IyGqLfUZbQ=
|
||||
git.sr.ht/~ashkeel/kilovolt-driver-pebble v1.3.3/go.mod h1:Jdf48ldD5UTw8m1AB72H3t0ryUotSeobVkkzrxikYVY=
|
||||
git.sr.ht/~ashkeel/kilovolt/v12 v12.0.2 h1:8NMO/sKsB9rlkFWxeBwv5mKrUvFEQ4RN7/BOcTgrnqU=
|
||||
git.sr.ht/~ashkeel/kilovolt/v12 v12.0.2/go.mod h1:dRSJpl6ZXNoTAF3pTMC4AO7MLkRgzQqaZYR8S5a46TI=
|
||||
git.sr.ht/~ashkeel/kilovolt-driver-pebble v1.3.4 h1:Yi1SqnHBHOMqdKAK7PpWt97vyq6JTytlxCU+Q8JfJ/g=
|
||||
git.sr.ht/~ashkeel/kilovolt-driver-pebble v1.3.4/go.mod h1:O3o7hvyVwH+AFFk7vWU3YN86dKIGrstii2NJv34MgZc=
|
||||
git.sr.ht/~ashkeel/kilovolt/v12 v12.0.3 h1:ag9MK/qVLbT5Vq4faJyMg5iUHP+XoRZTHyHgs0lKGak=
|
||||
git.sr.ht/~ashkeel/kilovolt/v12 v12.0.3/go.mod h1:dRSJpl6ZXNoTAF3pTMC4AO7MLkRgzQqaZYR8S5a46TI=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
|
||||
|
|
|
@ -51,6 +51,9 @@ func Setup(ctx context.Context, twitchAPI *helix.Client, user helix.User, db dat
|
|||
}
|
||||
|
||||
func (c *Client) eventSubLoop() {
|
||||
// Cleanup subscriptions for dead sessions so we don't get hit by the sub limit
|
||||
go c.cleanupSubscriptions()
|
||||
|
||||
endpoint := websocketEndpoint
|
||||
var err error
|
||||
var connection *websocket.Conn
|
||||
|
@ -231,6 +234,48 @@ func (c *Client) addSubscriptionsForSession(session string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) cleanupSubscriptions() {
|
||||
// Clear all subscriptions for dead/broken sessions
|
||||
c.cleanupSubscriptionForStatus("websocket_disconnected")
|
||||
c.cleanupSubscriptionForStatus("websocket_failed_ping_pong")
|
||||
c.cleanupSubscriptionForStatus("websocket_received_inbound_traffic")
|
||||
c.cleanupSubscriptionForStatus("websocket_connection_unused")
|
||||
c.cleanupSubscriptionForStatus("websocket_internal_error")
|
||||
c.cleanupSubscriptionForStatus("websocket_network_timeout")
|
||||
c.cleanupSubscriptionForStatus("websocket_network_error")
|
||||
c.cleanupSubscriptionForStatus("websocket_failed_to_reconnect")
|
||||
}
|
||||
|
||||
func (c *Client) cleanupSubscriptionForStatus(status string) {
|
||||
var cursor string
|
||||
for {
|
||||
subscriptions, err := c.twitchAPI.GetEventSubSubscriptions(&helix.EventSubSubscriptionsParams{
|
||||
Status: status,
|
||||
After: cursor,
|
||||
})
|
||||
if err != nil {
|
||||
c.logger.Warn("Could not get subscriptions for status", slog.String("status", status), log.Error(err))
|
||||
}
|
||||
|
||||
// Unsubscribe from all subscriptions for dead sessions
|
||||
for _, sub := range subscriptions.Data.EventSubSubscriptions {
|
||||
res, err := c.twitchAPI.RemoveEventSubSubscription(sub.ID)
|
||||
if err != nil {
|
||||
c.logger.Warn("Could not unsubscribe from dead session", slog.String("session-id", sub.Transport.SessionID), slog.String("subscription-id", sub.ID), log.Error(err))
|
||||
}
|
||||
if res.ErrorMessage != "" {
|
||||
c.logger.Warn("Could not unsubscribe from dead session", slog.String("session-id", sub.Transport.SessionID), slog.String("subscription-id", sub.ID), slog.String("message", res.ErrorMessage), slog.Int("messageCode", res.ErrorStatus))
|
||||
}
|
||||
}
|
||||
|
||||
// Check for cursor
|
||||
if subscriptions.Data.Pagination.Cursor == "" {
|
||||
break
|
||||
}
|
||||
cursor = subscriptions.Data.Pagination.Cursor
|
||||
}
|
||||
}
|
||||
|
||||
func topicCondition(topic string, id string) helix.EventSubCondition {
|
||||
switch topic {
|
||||
case helix.EventSubTypeChannelRaid:
|
||||
|
|
Loading…
Reference in New Issue