diff --git a/content/api/v34.md b/content/api/v40.md similarity index 84% rename from content/api/v34.md rename to content/api/v40.md index 75e3b2d..0c9a8f5 100644 --- a/content/api/v34.md +++ b/content/api/v40.md @@ -2,7 +2,7 @@ menu: apiversions title: indev -version: v34 +version: v40 aliases: - latest - api/ diff --git a/content/features/_index.md b/content/features/_index.md new file mode 100644 index 0000000..d65061a --- /dev/null +++ b/content/features/_index.md @@ -0,0 +1,7 @@ +--- +menu: main +title: Features +layout: features +weight: 10 +draft: true +--- \ No newline at end of file diff --git a/content/guide/_index.md b/content/guide/_index.md index 87cb0de..c651c9c 100644 --- a/content/guide/_index.md +++ b/content/guide/_index.md @@ -1,7 +1,7 @@ --- menu: main title: User guide -weight: 10 +weight: 11 --- Welcome to strimertül! This software might be a bit hard to use, so this user guide will try to guide you through setting it up and using its main features. diff --git a/content/releases/media/v4-chat-account.png b/content/releases/media/v4-chat-account.png new file mode 100644 index 0000000..f09e5eb Binary files /dev/null and b/content/releases/media/v4-chat-account.png differ diff --git a/content/releases/media/v4-permission.png b/content/releases/media/v4-permission.png new file mode 100644 index 0000000..13c3a27 Binary files /dev/null and b/content/releases/media/v4-permission.png differ diff --git a/content/releases/media/v4-small.png b/content/releases/media/v4-small.png new file mode 100644 index 0000000..d0f9af9 Binary files /dev/null and b/content/releases/media/v4-small.png differ diff --git a/content/releases/v3.3.1.md b/content/releases/v3.3.1.md index 972b35c..623830b 100644 --- a/content/releases/v3.3.1.md +++ b/content/releases/v3.3.1.md @@ -4,12 +4,12 @@ title: v3.3.1 date: 2023-11-12T02:01:35.286Z prerelease: false downloads: - - target: Windows 64bit - url: https://downloads.strimertul.stream/v3.3.1/strimertul.exe - - target: Linux amd64 - url: https://downloads.strimertul.stream/v3.3.1/strimertul-amd64 - - target: Linux arm64 - url: https://downloads.strimertul.stream/v3.3.1/strimertul-arm64 + - target: Windows 64bit + url: https://downloads.strimertul.stream/v3.3.1/strimertul.exe + - target: Linux amd64 + url: https://downloads.strimertul.stream/v3.3.1/strimertul-amd64 + - target: Linux arm64 + url: https://downloads.strimertul.stream/v3.3.1/strimertul-arm64 --- ## Release notes diff --git a/content/releases/v4.0.0-alpha.6.md b/content/releases/v4.0.0-alpha.6.md new file mode 100644 index 0000000..080747a --- /dev/null +++ b/content/releases/v4.0.0-alpha.6.md @@ -0,0 +1,81 @@ +--- +tag: v4.0.0-alpha.6 +title: v4.0.0-alpha.6 +date: 2024-04-20T21:13:34.580Z +prerelease: true +downloads: + - target: Windows 64bit + url: https://downloads.strimertul.stream/v3.3.1/strimertul.exe + - target: Linux amd64 + url: https://downloads.strimertul.stream/v3.3.1/strimertul-amd64 + - target: Linux arm64 + url: https://downloads.strimertul.stream/v3.3.1/strimertul-arm64 +--- + +## Release notes + +First public (pre)release of v4! There is one major change and a lot of small things. Not all features are in this release but the big one is and I'd like people to start trying it out. + +If you built any software using the kilovolt API: Woops, you gotta re-do a lot of that. Most of the keys have changed in naming and some in format as well. + +Two important things: back up your `data` folder and re-authenticate your user (it should tell you to, more on that below). + +### The IRC bot is dead + +With Twitch finally pushing out the latest EventSub APIs for chat interaction I could finally kiss the IRC bot goodbye. All the existing chat functionality works as before but you'll notice it be way more stable. + +Setting a secondary user as the chatting user is now done through the API (with a similar flow) +![The new chat user configuration showing up a secondary user as authenticated](../media/v4-chat-account.png) + +### New permissions required warning + +v4.0.0 sets up the foundation for a "problem detection system" aimed at finding configuration problems. I will be adding checks as I find them but for now the only one will be to check if a user is authorized to the Twitch app and if the scope of that authorization is valid. As Twitch adds new features and strimertül adopts them the scope of authorization will change and this warning will tell you to re-authenticate when needed. + +![The window shows a yellow warning telling the user to re-authenticate](../media/v4-permission.png) + +### Compact sidebar with narrow window + +To accomodate people with not that much screen estate the strimertül window can now make better use of narrow spaces by compressing the sidebar to only show icons. You can still hover over the icons to check which page they link to. + +![The main window with only icons in the sidebar to better accomodate content in a small window](../media/v4-small.png) + +### Internal API overhaul + +As v4.0.0 was going to be a big breaking change I took the opportunity to rename a lot of the kilovolt keys. You can check the changelog for a key-by-key breakdown or just take a look at the new API reference (since this is a pre-release, you'll need to check [indev](/api/v40/)). If you have built integrations such as overlays or extensions it's very much likely that you'll need to at least change the keys. If you wrote any chat integrations you'll definitely have to update the formats as well. + +### Overall stability improvements + +While developing v4.0.0 I found a lot of random crashes and I could fix most of the causes. There's still work to do on a lot of tickets that are still open but this should be much more stable than v3 even as an alpha. You can check the list of tickets still open [here](https://todo.sr.ht/~ashkeel/strimertul). Not all of them will be addressed in this release but all the bugs should be! + +## Changelog + +### Added + +- The UI sidebar has been modified to better adapt to small window sizes +- A new part of the dashboard will now inform the user if any configuration problems have been detected. + +### Changed + +- The required set of permissions has changed. Existing users must re-authenticate their users to the app connected to strimertül. +- The `twitch/ev/eventsub-event` and `twitch/eventsub-history` keys have been replaced by a set of keys in the format `twitch/ev/eventsub-event/` and `twitch/eventsub-history/`. Users of the old system will have to adjust their logic. A simple trick is to change from get/subscribing from a single key to the entire prefix. The data structure is the same. +- The `twitch/bot/@send-message` key has been renamed to `twitch/chat/@send-message`. The data structure is the same. +- A lot of keys for internal use have been changed, make sure to check the new reference for fixing up any integrations you might have. A migration process will convert v3 keys to v4 keys. +- The log format has changed significantly as the internal logging library has been replaced. +- 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 + +- `twitch/@send-chat-message` has been removed. Use `twitch/chat/@send-message` instead. +- The `twitch/ev/chat-message` and `twitch/chat-history` keys have been removed. Use the EventSub keys `twitch/ev/eventsub-event/channel.chat.message` and `twitch/eventsub-history/channel.chat.message` instead. The data structure will be different! + +## Downloads + +{{< release-dl "https://downloads.strimertul.stream/v4.0.0-alpha.6/" >}} diff --git a/data/api/v34/api.json b/data/api/v40/api.json similarity index 79% rename from data/api/v34/api.json rename to data/api/v40/api.json index 000c3f7..1f48811 100644 --- a/data/api/v34/api.json +++ b/data/api/v40/api.json @@ -1,4 +1,29 @@ { + "http/config": { + "description": "General server configuration", + "schema": { + "name": "ServerConfig", + "kind": "object", + "keys": [ + { + "name": "bind", + "kind": "string" + }, + { + "name": "enable_static_server", + "kind": "boolean" + }, + { + "name": "path", + "kind": "string" + }, + { + "name": "kv_password", + "kind": "string" + } + ] + } + }, "loyalty/@create-redeem": { "description": "Create a new pending redeem", "schema": { @@ -78,429 +103,6 @@ "rpc" ] }, - "strimertul/@log": { - "description": "Adds a log entry", - "schema": { - "name": "ExternalLog", - "kind": "object", - "keys": [ - { - "name": "level", - "kind": "enum", - "enumValues": [ - "debug", - "info", - "warn", - "error" - ] - }, - { - "name": "message", - "kind": "string" - }, - { - "name": "data", - "kind": "dictionary", - "key": { - "name": "string", - "kind": "string" - }, - "element": { - "name": "", - "kind": "unknown" - } - } - ] - }, - "tags": [ - "rpc" - ] - }, - "twitch/chat-activity": { - "description": "Number of chat messages in the last minute", - "schema": { - "name": "int", - "kind": "int" - } - }, - "twitch/bot-modules/timers/config": { - "description": "Configuration of chat bot timers", - "schema": { - "name": "BotTimersConfig", - "kind": "object", - "keys": [ - { - "name": "timers", - "description": "List of timers as a dictionary", - "kind": "dictionary", - "key": { - "name": "string", - "kind": "string" - }, - "element": { - "name": "BotTimer", - "kind": "object", - "keys": [ - { - "name": "enabled", - "description": "Enable the timer", - "kind": "boolean" - }, - { - "name": "name", - "description": "Timer name (must be unique)", - "kind": "string" - }, - { - "name": "minimum_chat_activity", - "description": "Minimum chat messages in the last 5 minutes for timer to trigger", - "kind": "int" - }, - { - "name": "minimum_delay", - "description": "Minimum amount of time (in seconds) that needs to pass before it triggers again", - "kind": "int" - }, - { - "name": "messages", - "description": "Messages to write (randomly chosen)", - "kind": "array", - "element": { - "name": "string", - "kind": "string" - } - } - ] - } - } - ] - } - }, - "twitch/@send-chat-message": { - "description": "Send plain text chat message (this will be deprecated or renamed someday, please use the other one!)", - "schema": { - "name": "string", - "kind": "string" - }, - "tags": [ - "rpc" - ] - }, - "twitch/auth-keys": { - "description": "User access token for the twitch subsystem", - "schema": { - "name": "AuthResponse", - "kind": "object", - "keys": [ - { - "name": "access_token", - "kind": "string" - }, - { - "name": "refresh_token", - "kind": "string" - }, - { - "name": "expires_in", - "kind": "int" - }, - { - "name": "scope", - "kind": "array", - "element": { - "name": "string", - "kind": "string" - } - }, - { - "name": "Time", - "kind": "datetime" - } - ] - } - }, - "http/config": { - "description": "General server configuration", - "schema": { - "name": "ServerConfig", - "kind": "object", - "keys": [ - { - "name": "bind", - "kind": "string" - }, - { - "name": "enable_static_server", - "kind": "boolean" - }, - { - "name": "path", - "kind": "string" - }, - { - "name": "kv_password", - "kind": "string" - } - ] - } - }, - "loyalty/goals": { - "description": "List of all goals", - "schema": { - "name": "", - "kind": "array", - "element": { - "name": "Goal", - "kind": "object", - "keys": [ - { - "name": "enabled", - "description": "Is the goal enabled?", - "kind": "boolean" - }, - { - "name": "id", - "description": "Community goal ID", - "kind": "string" - }, - { - "name": "name", - "description": "Name of the community goal", - "kind": "string" - }, - { - "name": "description", - "description": "Description of the goal", - "kind": "string" - }, - { - "name": "image", - "description": "Goal icon URL", - "kind": "string" - }, - { - "name": "total", - "description": "How many points does the goal need to be met in total", - "kind": "int" - }, - { - "name": "contributed", - "description": "How many points have been contributed so far", - "kind": "int" - }, - { - "name": "contributors", - "description": "Dictionary of how much every viewer has contributed", - "kind": "dictionary", - "key": { - "name": "string", - "kind": "string" - }, - "element": { - "name": "int64", - "kind": "int" - } - } - ] - } - } - }, - "strimertul/version": { - "description": "Strimertul version (semantic version, e.g. v3.4.0-alpha.1)", - "schema": { - "name": "string", - "kind": "string" - } - }, - "twitch/config": { - "description": "General configuration for the Twitch subsystem", - "schema": { - "name": "Config", - "kind": "object", - "keys": [ - { - "name": "enabled", - "description": "Enable subsystem", - "kind": "boolean" - }, - { - "name": "enable_bot", - "description": "Enable the chatbot", - "kind": "boolean" - }, - { - "name": "api_client_id", - "description": "Twitch API App Client ID", - "kind": "string" - }, - { - "name": "api_client_secret", - "description": "Twitch API App Client Secret", - "kind": "string" - } - ] - } - }, - "twitch/stream-info": { - "description": "List of active twitch streams (1 element if live, 0 otherwise)", - "schema": { - "name": "", - "kind": "array", - "element": { - "name": "Stream", - "kind": "object", - "keys": [ - { - "name": "id", - "kind": "string" - }, - { - "name": "user_id", - "kind": "string" - }, - { - "name": "user_login", - "kind": "string" - }, - { - "name": "user_name", - "kind": "string" - }, - { - "name": "game_id", - "kind": "string" - }, - { - "name": "game_name", - "kind": "string" - }, - { - "name": "tag_ids", - "kind": "array", - "element": { - "name": "string", - "kind": "string" - } - }, - { - "name": "tags", - "kind": "array", - "element": { - "name": "string", - "kind": "string" - } - }, - { - "name": "is_mature", - "kind": "boolean" - }, - { - "name": "type", - "kind": "string" - }, - { - "name": "title", - "kind": "string" - }, - { - "name": "viewer_count", - "kind": "int" - }, - { - "name": "started_at", - "kind": "datetime" - }, - { - "name": "language", - "kind": "string" - }, - { - "name": "thumbnail_url", - "kind": "string" - } - ] - } - } - }, - "loyalty/ev/new-redeem": { - "description": "On reward redeemed", - "schema": { - "name": "Redeem", - "kind": "object", - "keys": [ - { - "name": "username", - "description": "Username of who redeemed the reward", - "kind": "string" - }, - { - "name": "display_name", - "description": "Display name of who redeemed the reward", - "kind": "string" - }, - { - "name": "reward", - "description": "Reward that was redeemed", - "kind": "object", - "keys": [ - { - "name": "enabled", - "description": "Is the reward enabled (redeemable)?", - "kind": "boolean" - }, - { - "name": "id", - "description": "Reward ID", - "kind": "string" - }, - { - "name": "name", - "description": "Name of the reward", - "kind": "string" - }, - { - "name": "description", - "description": "Description of the reward", - "kind": "string" - }, - { - "name": "image", - "description": "Reward icon URL", - "kind": "string" - }, - { - "name": "price", - "description": "How much does is cost", - "kind": "int" - }, - { - "name": "required_info", - "description": "If present, reward requires user input and this field is the help text", - "kind": "string" - }, - { - "name": "cooldown", - "description": "Time in seconds to wait before this reward can be redeemed again", - "kind": "int" - } - ] - }, - { - "name": "when", - "description": "Time of the redeem", - "kind": "datetime" - }, - { - "name": "request_text", - "description": "If the reward required user input it will be here", - "kind": "string" - } - ] - }, - "tags": [ - "event" - ] - }, "loyalty/@remove-redeem": { "description": "Remove a redeem from the queue", "schema": { @@ -580,206 +182,127 @@ "rpc" ] }, - "twitch/bot-config": { - "description": "General configuration for the Twitch chatbot", + "loyalty/config": { + "description": "General configuration for the loyalty system", "schema": { - "name": "BotConfig", + "name": "Config", "kind": "object", "keys": [ { - "name": "username", - "description": "Chatbot username (for internal use, ignored by Twitch)", + "name": "enabled", + "description": "Enable the loyalty system", + "kind": "boolean" + }, + { + "name": "currency", + "description": "Name of the currency", "kind": "string" }, { - "name": "oauth", - "description": "OAuth key for IRC authentication", - "kind": "string" - }, - { - "name": "channel", - "description": "Twitch channel to join and use", - "kind": "string" - }, - { - "name": "chat_history", - "description": "How many messages to keep in twitch/chat-history", - "kind": "int" - }, - { - "name": "command_cooldown", - "description": "Global command cooldown in seconds", - "kind": "int" - } - ] - } - }, - "twitch/ev/chat-message": { - "description": "On chat message received", - "schema": { - "name": "PrivateMessage", - "kind": "object", - "keys": [ - { - "name": "User", + "name": "points", + "description": "Settings for distributing currency to online viewers", "kind": "object", "keys": [ { - "name": "ID", - "kind": "string" + "name": "interval", + "description": "How often to distribute points, in seconds", + "kind": "int" }, { - "name": "Name", - "kind": "string" + "name": "amount", + "description": "How many points to award every interval", + "kind": "int" }, { - "name": "DisplayName", - "kind": "string" - }, - { - "name": "Color", - "kind": "string" - }, - { - "name": "Badges", - "kind": "dictionary", - "key": { - "name": "string", - "kind": "string" - }, - "element": { - "name": "int", - "kind": "int" - } + "name": "activity_bonus", + "description": "Extra points for active chatters", + "kind": "int" } ] }, { - "name": "Raw", - "kind": "string" - }, - { - "name": "Type", - "kind": "int" - }, - { - "name": "RawType", - "kind": "string" - }, - { - "name": "Tags", - "kind": "dictionary", - "key": { - "name": "string", - "kind": "string" - }, - "element": { - "name": "string", - "kind": "string" - } - }, - { - "name": "Message", - "kind": "string" - }, - { - "name": "Channel", - "kind": "string" - }, - { - "name": "RoomID", - "kind": "string" - }, - { - "name": "ID", - "kind": "string" - }, - { - "name": "Time", - "kind": "datetime" - }, - { - "name": "Emotes", + "name": "banlist", + "description": "Usernames to exclude from currency distribution", "kind": "array", "element": { - "name": "", - "kind": "object", - "keys": [ - { - "name": "Name", - "kind": "string" - }, - { - "name": "ID", - "kind": "string" - }, - { - "name": "Count", - "kind": "int" - }, - { - "name": "Positions", - "kind": "array", - "element": { - "name": "EmotePosition", - "kind": "object", - "keys": [ - { - "name": "Start", - "kind": "int" - }, - { - "name": "End", - "kind": "int" - } - ] - } - } - ], - "isPointer": true + "name": "string", + "kind": "string" } + } + ] + } + }, + "loyalty/ev/new-redeem": { + "description": "On reward redeemed", + "schema": { + "name": "Redeem", + "kind": "object", + "keys": [ + { + "name": "username", + "description": "Username of who redeemed the reward", + "kind": "string" }, { - "name": "Bits", - "kind": "int" + "name": "display_name", + "description": "Display name of who redeemed the reward", + "kind": "string" }, { - "name": "Action", - "kind": "boolean" - }, - { - "name": "FirstMessage", - "kind": "boolean" - }, - { - "name": "Reply", + "name": "reward", + "description": "Reward that was redeemed", "kind": "object", "keys": [ { - "name": "ParentMsgID", + "name": "enabled", + "description": "Is the reward enabled (redeemable)?", + "kind": "boolean" + }, + { + "name": "id", + "description": "Reward ID", "kind": "string" }, { - "name": "ParentUserID", + "name": "name", + "description": "Name of the reward", "kind": "string" }, { - "name": "ParentUserLogin", + "name": "description", + "description": "Description of the reward", "kind": "string" }, { - "name": "ParentDisplayName", + "name": "image", + "description": "Reward icon URL", "kind": "string" }, { - "name": "ParentMsgBody", + "name": "price", + "description": "How much does is cost", + "kind": "int" + }, + { + "name": "required_info", + "description": "If present, reward requires user input and this field is the help text", "kind": "string" + }, + { + "name": "cooldown", + "description": "Time in seconds to wait before this reward can be redeemed again", + "kind": "int" } - ], - "isPointer": true + ] }, { - "name": "CustomRewardID", + "name": "when", + "description": "Time of the redeem", + "kind": "datetime" + }, + { + "name": "request_text", + "description": "If the reward required user input it will be here", "kind": "string" } ] @@ -788,10 +311,263 @@ "event" ] }, - "twitch/bot-modules/alerts/config": { - "description": "Configuration of chat bot alerts", + "loyalty/goals": { + "description": "List of all goals", "schema": { - "name": "BotAlertsConfig", + "name": "", + "kind": "array", + "element": { + "name": "Goal", + "kind": "object", + "keys": [ + { + "name": "enabled", + "description": "Is the goal enabled?", + "kind": "boolean" + }, + { + "name": "id", + "description": "Community goal ID", + "kind": "string" + }, + { + "name": "name", + "description": "Name of the community goal", + "kind": "string" + }, + { + "name": "description", + "description": "Description of the goal", + "kind": "string" + }, + { + "name": "image", + "description": "Goal icon URL", + "kind": "string" + }, + { + "name": "total", + "description": "How many points does the goal need to be met in total", + "kind": "int" + }, + { + "name": "contributed", + "description": "How many points have been contributed so far", + "kind": "int" + }, + { + "name": "contributors", + "description": "Dictionary of how much every viewer has contributed", + "kind": "dictionary", + "key": { + "name": "string", + "kind": "string" + }, + "element": { + "name": "int64", + "kind": "int" + } + } + ] + } + } + }, + "loyalty/points/\u003cuser\u003e": { + "description": "Point entry for a given user", + "schema": { + "name": "PointsEntry", + "kind": "object", + "keys": [ + { + "name": "points", + "description": "Currency balance", + "kind": "int" + } + ] + } + }, + "loyalty/redeem-queue": { + "description": "All pending redeems", + "schema": { + "name": "", + "kind": "array", + "element": { + "name": "Redeem", + "kind": "object", + "keys": [ + { + "name": "username", + "description": "Username of who redeemed the reward", + "kind": "string" + }, + { + "name": "display_name", + "description": "Display name of who redeemed the reward", + "kind": "string" + }, + { + "name": "reward", + "description": "Reward that was redeemed", + "kind": "object", + "keys": [ + { + "name": "enabled", + "description": "Is the reward enabled (redeemable)?", + "kind": "boolean" + }, + { + "name": "id", + "description": "Reward ID", + "kind": "string" + }, + { + "name": "name", + "description": "Name of the reward", + "kind": "string" + }, + { + "name": "description", + "description": "Description of the reward", + "kind": "string" + }, + { + "name": "image", + "description": "Reward icon URL", + "kind": "string" + }, + { + "name": "price", + "description": "How much does is cost", + "kind": "int" + }, + { + "name": "required_info", + "description": "If present, reward requires user input and this field is the help text", + "kind": "string" + }, + { + "name": "cooldown", + "description": "Time in seconds to wait before this reward can be redeemed again", + "kind": "int" + } + ] + }, + { + "name": "when", + "description": "Time of the redeem", + "kind": "datetime" + }, + { + "name": "request_text", + "description": "If the reward required user input it will be here", + "kind": "string" + } + ] + } + } + }, + "loyalty/rewards": { + "description": "List of available rewards", + "schema": { + "name": "", + "kind": "array", + "element": { + "name": "Reward", + "kind": "object", + "keys": [ + { + "name": "enabled", + "description": "Is the reward enabled (redeemable)?", + "kind": "boolean" + }, + { + "name": "id", + "description": "Reward ID", + "kind": "string" + }, + { + "name": "name", + "description": "Name of the reward", + "kind": "string" + }, + { + "name": "description", + "description": "Description of the reward", + "kind": "string" + }, + { + "name": "image", + "description": "Reward icon URL", + "kind": "string" + }, + { + "name": "price", + "description": "How much does is cost", + "kind": "int" + }, + { + "name": "required_info", + "description": "If present, reward requires user input and this field is the help text", + "kind": "string" + }, + { + "name": "cooldown", + "description": "Time in seconds to wait before this reward can be redeemed again", + "kind": "int" + } + ] + } + } + }, + "strimertul/@log": { + "description": "Add a log entry", + "schema": { + "name": "ExternalLog", + "kind": "object", + "keys": [ + { + "name": "level", + "kind": "enum", + "enumValues": [ + "debug", + "info", + "warn", + "error" + ] + }, + { + "name": "message", + "kind": "string" + }, + { + "name": "data", + "kind": "dictionary", + "key": { + "name": "string", + "kind": "string" + }, + "element": { + "name": "", + "kind": "unknown" + } + } + ] + }, + "tags": [ + "rpc" + ] + }, + "strimertul/version": { + "description": "Strimertul version (semantic version, e.g. v3.4.0-alpha.1)", + "schema": { + "name": "string", + "kind": "string" + } + }, + "twitch/alerts/config": { + "description": "Configuration of chat alerts", + "schema": { + "name": "Config", "kind": "object", "keys": [ { @@ -811,6 +587,11 @@ "name": "string", "kind": "string" } + }, + { + "name": "announce", + "description": "If true, send as announcement", + "kind": "boolean" } ] }, @@ -832,6 +613,11 @@ "kind": "string" } }, + { + "name": "announce", + "description": "If true, send as announcement", + "kind": "boolean" + }, { "name": "variations", "kind": "array", @@ -883,6 +669,11 @@ "kind": "string" } }, + { + "name": "announce", + "description": "If true, send as announcement", + "kind": "boolean" + }, { "name": "variations", "kind": "array", @@ -934,6 +725,11 @@ "kind": "string" } }, + { + "name": "announce", + "description": "If true, send as announcement", + "kind": "boolean" + }, { "name": "variations", "kind": "array", @@ -979,6 +775,11 @@ "kind": "string" } }, + { + "name": "announce", + "description": "If true, send as announcement", + "kind": "boolean" + }, { "name": "variations", "kind": "array", @@ -1009,8 +810,127 @@ ] } }, - "twitch/bot-custom-commands": { - "description": "Chatbot custom commands", + "twitch/auth-keys": { + "description": "User access token for the twitch subsystem", + "schema": { + "name": "AuthResponse", + "kind": "object", + "keys": [ + { + "name": "access_token", + "kind": "string" + }, + { + "name": "refresh_token", + "kind": "string" + }, + { + "name": "expires_in", + "kind": "int" + }, + { + "name": "scope", + "kind": "array", + "element": { + "name": "string", + "kind": "string" + } + }, + { + "name": "Time", + "kind": "datetime" + } + ] + } + }, + "twitch/chat/@send-message": { + "description": "Send chat message with extra options (as reply, whisper, etc)", + "schema": { + "name": "WriteMessageRequest", + "kind": "object", + "keys": [ + { + "name": "message", + "description": "Chat message to send", + "kind": "string" + }, + { + "name": "reply_to", + "description": "If specified, send as reply to a message ID", + "kind": "string" + }, + { + "name": "whisper_to", + "description": "If specified, send as whisper to user ID", + "kind": "string" + }, + { + "name": "announce", + "description": "If true, send as announcement", + "kind": "boolean" + } + ] + }, + "tags": [ + "rpc" + ] + }, + "twitch/chat/activity": { + "description": "Number of chat messages in the last minute", + "schema": { + "name": "int", + "kind": "int" + } + }, + "twitch/chat/chatter-account": { + "description": "User access token for the chat account (if not using the main one)", + "schema": { + "name": "AuthResponse", + "kind": "object", + "keys": [ + { + "name": "access_token", + "kind": "string" + }, + { + "name": "refresh_token", + "kind": "string" + }, + { + "name": "expires_in", + "kind": "int" + }, + { + "name": "scope", + "kind": "array", + "element": { + "name": "string", + "kind": "string" + } + }, + { + "name": "Time", + "kind": "datetime" + } + ] + } + }, + "twitch/chat/config": { + "description": "Configuration for chat-related features", + "schema": { + "name": "Config", + "kind": "object", + "keys": [ + { + "name": "command_cooldown", + "description": "Global command cooldown in seconds", + "kind": "int" + } + ] + } + }, + "twitch/chat/custom-commands": { + "description": "Chat custom commands", "schema": { "name": "", "kind": "dictionary", @@ -1019,7 +939,7 @@ "kind": "string" }, "element": { - "name": "BotCustomCommand", + "name": "CustomCommand", "kind": "object", "keys": [ { @@ -1064,8 +984,32 @@ } } }, - "twitch/ev/eventsub-event": { - "description": "On Eventsub event received", + "twitch/config": { + "description": "General configuration for the Twitch subsystem", + "schema": { + "name": "Config", + "kind": "object", + "keys": [ + { + "name": "enabled", + "description": "Enable subsystem", + "kind": "boolean" + }, + { + "name": "api_client_id", + "description": "Twitch API App Client ID", + "kind": "string" + }, + { + "name": "api_client_secret", + "description": "Twitch API App Client Secret", + "kind": "string" + } + ] + } + }, + "twitch/ev/eventsub-event/[event-name]": { + "description": "On Eventsub event [event-name] received", "schema": { "name": "NotificationMessagePayload", "kind": "object", @@ -1184,8 +1128,8 @@ "event" ] }, - "twitch/eventsub-history": { - "description": "Last eventsub notifications received", + "twitch/eventsub-history/[event-name]": { + "description": "Last eventsub notifications received for [event-name]", "schema": { "name": "", "kind": "array", @@ -1308,413 +1252,143 @@ "history" ] }, - "loyalty/points/": { - "description": "Point entry for a given user", - "schema": { - "name": "PointsEntry", - "kind": "object", - "keys": [ - { - "name": "points", - "description": "Currency balance", - "kind": "int" - } - ] - } - }, - "loyalty/redeem-queue": { - "description": "All pending redeems", + "twitch/stream-info": { + "description": "List of active twitch streams (1 element if live, 0 otherwise)", "schema": { "name": "", "kind": "array", "element": { - "name": "Redeem", + "name": "Stream", "kind": "object", "keys": [ { - "name": "username", - "description": "Username of who redeemed the reward", + "name": "id", "kind": "string" }, { - "name": "display_name", - "description": "Display name of who redeemed the reward", + "name": "user_id", "kind": "string" }, { - "name": "reward", - "description": "Reward that was redeemed", - "kind": "object", - "keys": [ - { - "name": "enabled", - "description": "Is the reward enabled (redeemable)?", - "kind": "boolean" - }, - { - "name": "id", - "description": "Reward ID", - "kind": "string" - }, - { - "name": "name", - "description": "Name of the reward", - "kind": "string" - }, - { - "name": "description", - "description": "Description of the reward", - "kind": "string" - }, - { - "name": "image", - "description": "Reward icon URL", - "kind": "string" - }, - { - "name": "price", - "description": "How much does is cost", - "kind": "int" - }, - { - "name": "required_info", - "description": "If present, reward requires user input and this field is the help text", - "kind": "string" - }, - { - "name": "cooldown", - "description": "Time in seconds to wait before this reward can be redeemed again", - "kind": "int" - } - ] + "name": "user_login", + "kind": "string" }, { - "name": "when", - "description": "Time of the redeem", + "name": "user_name", + "kind": "string" + }, + { + "name": "game_id", + "kind": "string" + }, + { + "name": "game_name", + "kind": "string" + }, + { + "name": "tag_ids", + "kind": "array", + "element": { + "name": "string", + "kind": "string" + } + }, + { + "name": "tags", + "kind": "array", + "element": { + "name": "string", + "kind": "string" + } + }, + { + "name": "is_mature", + "kind": "boolean" + }, + { + "name": "type", + "kind": "string" + }, + { + "name": "title", + "kind": "string" + }, + { + "name": "viewer_count", + "kind": "int" + }, + { + "name": "started_at", "kind": "datetime" }, { - "name": "request_text", - "description": "If the reward required user input it will be here", + "name": "language", + "kind": "string" + }, + { + "name": "thumbnail_url", "kind": "string" } ] } } }, - "loyalty/config": { - "description": "General configuration for the loyalty system", + "twitch/timers/config": { + "description": "Configuration of chat timers", "schema": { "name": "Config", "kind": "object", "keys": [ { - "name": "enabled", - "description": "Enable the loyalty system", - "kind": "boolean" - }, - { - "name": "currency", - "description": "Name of the currency", - "kind": "string" - }, - { - "name": "points", - "description": "Settings for distributing currency to online viewers", - "kind": "object", - "keys": [ - { - "name": "interval", - "description": "How often to distribute points, in seconds", - "kind": "int" - }, - { - "name": "amount", - "description": "How many points to award every interval", - "kind": "int" - }, - { - "name": "activity_bonus", - "description": "Extra points for active chatters", - "kind": "int" - } - ] - }, - { - "name": "banlist", - "description": "Usernames to exclude from currency distribution", - "kind": "array", - "element": { + "name": "timers", + "description": "List of timers as a dictionary", + "kind": "dictionary", + "key": { "name": "string", "kind": "string" - } - } - ] - } - }, - "loyalty/rewards": { - "description": "List of available rewards", - "schema": { - "name": "", - "kind": "array", - "element": { - "name": "Reward", - "kind": "object", - "keys": [ - { - "name": "enabled", - "description": "Is the reward enabled (redeemable)?", - "kind": "boolean" }, - { - "name": "id", - "description": "Reward ID", - "kind": "string" - }, - { - "name": "name", - "description": "Name of the reward", - "kind": "string" - }, - { - "name": "description", - "description": "Description of the reward", - "kind": "string" - }, - { - "name": "image", - "description": "Reward icon URL", - "kind": "string" - }, - { - "name": "price", - "description": "How much does is cost", - "kind": "int" - }, - { - "name": "required_info", - "description": "If present, reward requires user input and this field is the help text", - "kind": "string" - }, - { - "name": "cooldown", - "description": "Time in seconds to wait before this reward can be redeemed again", - "kind": "int" - } - ] - } - } - }, - "twitch/chat-history": { - "description": "Last chat messages received", - "schema": { - "name": "", - "kind": "array", - "element": { - "name": "PrivateMessage", - "kind": "object", - "keys": [ - { - "name": "User", + "element": { + "name": "ChatTimer", "kind": "object", "keys": [ { - "name": "ID", + "name": "enabled", + "description": "Enable the timer", + "kind": "boolean" + }, + { + "name": "name", + "description": "Timer name (must be unique)", "kind": "string" }, { - "name": "Name", - "kind": "string" + "name": "minimum_chat_activity", + "description": "Minimum chat messages in the last 5 minutes for timer to trigger", + "kind": "int" }, { - "name": "DisplayName", - "kind": "string" + "name": "minimum_delay", + "description": "Minimum amount of time (in seconds) that needs to pass before it triggers again", + "kind": "int" }, { - "name": "Color", - "kind": "string" - }, - { - "name": "Badges", - "kind": "dictionary", - "key": { + "name": "messages", + "description": "Messages to write (randomly chosen)", + "kind": "array", + "element": { "name": "string", "kind": "string" - }, - "element": { - "name": "int", - "kind": "int" } + }, + { + "name": "announce", + "description": "If true, send as announcement", + "kind": "boolean" } ] - }, - { - "name": "Raw", - "kind": "string" - }, - { - "name": "Type", - "kind": "int" - }, - { - "name": "RawType", - "kind": "string" - }, - { - "name": "Tags", - "kind": "dictionary", - "key": { - "name": "string", - "kind": "string" - }, - "element": { - "name": "string", - "kind": "string" - } - }, - { - "name": "Message", - "kind": "string" - }, - { - "name": "Channel", - "kind": "string" - }, - { - "name": "RoomID", - "kind": "string" - }, - { - "name": "ID", - "kind": "string" - }, - { - "name": "Time", - "kind": "datetime" - }, - { - "name": "Emotes", - "kind": "array", - "element": { - "name": "", - "kind": "object", - "keys": [ - { - "name": "Name", - "kind": "string" - }, - { - "name": "ID", - "kind": "string" - }, - { - "name": "Count", - "kind": "int" - }, - { - "name": "Positions", - "kind": "array", - "element": { - "name": "EmotePosition", - "kind": "object", - "keys": [ - { - "name": "Start", - "kind": "int" - }, - { - "name": "End", - "kind": "int" - } - ] - } - } - ], - "isPointer": true - } - }, - { - "name": "Bits", - "kind": "int" - }, - { - "name": "Action", - "kind": "boolean" - }, - { - "name": "FirstMessage", - "kind": "boolean" - }, - { - "name": "Reply", - "kind": "object", - "keys": [ - { - "name": "ParentMsgID", - "kind": "string" - }, - { - "name": "ParentUserID", - "kind": "string" - }, - { - "name": "ParentUserLogin", - "kind": "string" - }, - { - "name": "ParentDisplayName", - "kind": "string" - }, - { - "name": "ParentMsgBody", - "kind": "string" - } - ], - "isPointer": true - }, - { - "name": "CustomRewardID", - "kind": "string" } - ] - } - }, - "tags": [ - "history" - ] - }, - "twitch/bot/@send-message": { - "description": "Send chat message with extra options (as reply, whisper, etc)", - "schema": { - "name": "WriteMessageRequest", - "kind": "object", - "keys": [ - { - "name": "message", - "description": "Chat message to send", - "kind": "string" - }, - { - "name": "reply_to", - "description": "If specified, send as reply to a message ID", - "kind": "string", - "isPointer": true - }, - { - "name": "whisper_to", - "description": "If specified, send as whisper to user ID", - "kind": "string", - "isPointer": true - }, - { - "name": "announce", - "description": "If true, send as announcement", - "kind": "boolean" } ] - }, - "tags": [ - "rpc" - ] + } } } diff --git a/layouts/_default/features.html b/layouts/_default/features.html new file mode 100644 index 0000000..e4e4a83 --- /dev/null +++ b/layouts/_default/features.html @@ -0,0 +1,2 @@ +{{ define "main" }} +{{ end }} diff --git a/layouts/shortcodes/release-dl.html b/layouts/shortcodes/release-dl.html index a73e17e..d2c14d0 100644 --- a/layouts/shortcodes/release-dl.html +++ b/layouts/shortcodes/release-dl.html @@ -1,28 +1,16 @@ {{ $url := .Get 0 }} -{{ $files := getJSON $url }} {{ with .Page.Params.downloads }} {{ range . }} {{ $filename := index (split .url "/") (sub (len (split .url "/")) 1) }} - {{ $record := where $files "name" $filename | first 1 }} {{ $target := .target }} - {{ range $record }} - - - - - {{ else }} - - - - - {{ end }} + + + + {{ end }}
{{ $target }} - {{ .name }} - ({{ printf "%.2f" (div .size 1e6) }} MiB) -
{{ .target }} - {{ .name }} -
{{ .target }} + {{ $filename }} +
diff --git a/themes/strimertul/assets/scss/landing.scss b/themes/strimertul/assets/scss/landing.scss index 57c5fcb..04df8fb 100644 --- a/themes/strimertul/assets/scss/landing.scss +++ b/themes/strimertul/assets/scss/landing.scss @@ -1,4 +1,7 @@ .landing { + .hero.maxw { + padding: 0 10pt; + } .flex { display: flex; gap: 30px; diff --git a/themes/strimertul/assets/scss/layout.scss b/themes/strimertul/assets/scss/layout.scss index faba87f..2796cd1 100644 --- a/themes/strimertul/assets/scss/layout.scss +++ b/themes/strimertul/assets/scss/layout.scss @@ -9,7 +9,6 @@ body { .maxw { max-width: 1000px; margin: 0 auto; - width: 100%; } a, @@ -154,3 +153,14 @@ figure { background: rgba(0, 0, 0, 0.8); } } + +.site-footer { + padding: 20pt; + background-color: $gray3; + font-size: 11pt; + color: $gray11; + .maxw { + display: grid; + gap: 0.5rem; + } +} diff --git a/themes/strimertul/layouts/_default/baseof.html b/themes/strimertul/layouts/_default/baseof.html index 22ef748..47e8226 100644 --- a/themes/strimertul/layouts/_default/baseof.html +++ b/themes/strimertul/layouts/_default/baseof.html @@ -4,9 +4,10 @@
- {{- partial "header.html" . -}} {{- block "main" . }}{{- end }} - {{- partial "footer.html" . -}} + {{- partial "header.html" . -}} + {{- block "main" . }}{{- end }}
+ {{- partial "footer.html" . -}} diff --git a/themes/strimertul/layouts/partials/footer.html b/themes/strimertul/layouts/partials/footer.html index e69de29..a0820d1 100644 --- a/themes/strimertul/layouts/partials/footer.html +++ b/themes/strimertul/layouts/partials/footer.html @@ -0,0 +1,22 @@ +