Replies: 30 comments 33 replies
-
|
A plugin that allows for dynamic filtering & highlighting of messages. This can be more extensible than we currently allow in Chatterino, applying your own logic and storing previous messages from the specific user etc |
Beta Was this translation helpful? Give feedback.
-
|
summarizing some of the previous ideas: #4885 - add buttons to profile card that can open web links #4449 - read message (tags) and play sound #2091 - replace message content (or add message) #4931 - open a websocket & populate some custom split with system messages |
Beta Was this translation helpful? Give feedback.
-
|
Many of my ideas are related to what I'm missing in Chatterino, because it doesn't use GraphQL. But I think this can be implemented using plugins. Here is my list of ideas:
From the Chatterino API, the following would be required for this:
This is just what recently came to my mind. 🫠 |
Beta Was this translation helpful? Give feedback.
-
|
Possibly move IRC support to a plugin. We already want to have plugins be able to create messages. For this we also would need for plugins to be able to grab a channel like |
Beta Was this translation helpful? Give feedback.
-
|
A few plugin ideas:
|
Beta Was this translation helpful? Give feedback.
-
|
game/title change alerts (e.g., alert me when x streamer switches to y category) |
Beta Was this translation helpful? Give feedback.
-
|
Chat history for a channel in the plugins channel object would be cool |
Beta Was this translation helpful? Give feedback.
-
|
API Feature
Channel-specific commands or text/emote replacements. An example of this would be setting a replacement for
Another plugin feature would be a similar feature, except global replacements but this time matching specific [emoteId, emoteName] and replacing it with [emoteIds...] where emoteIds[0] > emotesId[1] > emotesId[2] > etc.
|
Beta Was this translation helpful? Give feedback.
-
|
QtCreator added a C++ plugin to load Lua plugins (blog article). The source can be found here (permalink). It uses sol3 in C++. It provides the following features (also kinda applicable to Chatterino): Especially for something like GUI, sol3 seems to be easier to use than manually working with the C API of Lua, thus allows more people to contribute. |
Beta Was this translation helpful? Give feedback.
-
Custom completion APIsGoal: I want to create some completion engine, mainly for custom emote completion, but current API has significant limitations
|
Beta Was this translation helpful? Give feedback.
-
|
#2091 (mentioned in #4999 (comment)) wants to build a chat translator. To do this, plugins need the ability to add rich messages (not just system messages). I'm proposing a minimal API as a start. With this API, plugins can create the same messages as the C++ code. Currently, a few things like links and images are hidden, so only text and linebreaks can be added. Plugins can't introspect or change messages once they're created. These can be future additions. I haven't implemented this in C++ yet. The following should be possible with the proposed API: c2.register_command("/hello-world", function (ctx)
local msg = c2.Message.new({
elements = {
{
type = "text",
text = "Hello,",
color = "#ff0000",
},
{
type = "text",
text = "world",
color = "#00ff00",
trailing_space = false,
},
{
type = "text",
text = "!",
color = "#0000ff",
}
},
id = "my-unique-message",
flags = c2.MessageFlag.System
})
ctx.channel:add_message(msg)
end)Type definitions---@class c2.Message
c2.Message = {}
---@class MessageInit A table to initialize a new message
---@field flags? c2.MessageFlag Message flags (see `c2.MessageFlags`)
---@field id? string The (ideally unique) message ID
---@field parse_time? number Time the message was parsed
---@field search_text? string Text to that is compared when searching for messages
---@field message_text? string The message text (used for filters for example)
---@field login_name? string The login name of the sender
---@field display_name? string The display name of the sender
---@field localized_name? string The localized name of the sender (this is used for CJK names, otherwise it's empty)
---@field username_color? string The color of the username
---@field server_received_time? number The time the server received the message
---@field highlight_color? string|nil The color of the highlight (if any)
---@field elements MessageElementInit[] The elements of the message
---@class MessageElementInitBase A base table to initialize a new message element
---@field flags? c2.MessageElementFlag Message element flags (see `c2.MessageElementFlags`)
---@field tooltip? string Tooltip text
---@field trailing_space? boolean Whether to add a trailing space after the element (default: true)
---@alias MessageColor "text"|"system"|string A color for a text element - "text" and "system" are special values that take the current theme into account
---@class (exact) TextElementInit : MessageElementInitBase A table to initialize a new message text element
---@field type "text" The type of the element
---@field text string The text of this element
---@field color? MessageColor The color of the text
---@field font_style? c2.FontStyle The font style of the text
---@class (exact) SingleLineTextElementInit : MessageElementInitBase A table to initialize a new message single-line text element
---@field type "single-line-text" The type of the element
---@field text string The text of this element
---@field color? MessageColor The color of the text
---@field font_style? c2.FontStyle The font style of the text
---@class (exact) MentionElementInit : MessageElementInitBase A table to initialize a new mention element
---@field type "mention" The type of the element
---@field display_name string The display name of the mentioned user
---@field login_name string The login name of the mentioned user
---@field fallback_color MessageColor The color of the element in case the "Colorize @usernames" is disabled
---@field user_color MessageColor The color of the element in case the "Colorize @usernames" is enabled
---@class (exact) TimestampElementInit : MessageElementInitBase A table to initialize a new timestamp element
---@field type "timestamp" The type of the element
---@field time number? The time of the timestamp (in milliseconds since epoch). If not provided, the current time is used.
---@class (exact) TwitchModerationElementInit : MessageElementInitBase A table to initialize a new Twitch moderation element (all the custom moderation buttons)
---@field type "twitch-moderation" The type of the element
---@class (exact) LinebreakElementInit : MessageElementInitBase A table to initialize a new linebreak element
---@field type "linebreak" The type of the element
---@class (exact) ReplyCurveElementInit : MessageElementInitBase A table to initialize a new reply curve element
---@field type "reply-curve" The type of the element
---@alias MessageElementInit TextElementInit|SingleLineTextElementInit|MentionElementInit|TimestampElementInit|TwitchModerationElementInit|LinebreakElementInit|ReplyCurveElementInit
---@enum c2.MessageFlag
c2.MessageFlag = {
None = 0,
System = 0,
Timeout = 0,
Highlighted = 0,
-- ...
}
---@enum c2.MessageElementFlag
c2.MessageElementFlag = {
None = 0,
Misc = 0,
Text = 0,
Username = 0,
Timestamp = 0,
-- ...
}
---@enum c2.FontStyle
c2.FontStyle = {
Tiny = {}, ---@type c2.FontStyle.Tiny
ChatSmall = {}, ---@type c2.FontStyle.ChatSmall
-- ...
}
--- Creates a new message
---
---@param init MessageInit The message initialization table
---@return c2.Message msg The new message
function c2.Message.new(init) end
---@enum c2.MessageContext Context of the message being added to a channel
c2.MessageContext = {
--- This message is the original
Original = {}, ---@type c2.MessageContext.Original
--- This message is a repost of a message that has already been added in a channel
Repost = {}, ---@type c2.MessageContext.Repost
}
--- Adds a message to the channel
---
---@param message c2.Message The message to add
---@param context? c2.MessageContext The context of the message being added
---@param override_flags? c2.MessageFlag|nil Flags to override the message's flags (some splits might filter for this)
function c2.Channel:add_message(message, context, override_flags) end |
Beta Was this translation helpful? Give feedback.
-
|
Auto !join for Marbles On Stream. |
Beta Was this translation helpful? Give feedback.
-
|
/nuke command to timeout or ban messages sent in the last X seconds containing specific word |
Beta Was this translation helpful? Give feedback.
-
|
A feed for new livestreams in a given directory/game as a channel. |
Beta Was this translation helpful? Give feedback.
-
|
Now that #5997 is merged where we can allow third party browser extensions to interact with Chatterino, we could allow plugins to add custom handlers for actions (done here right now). With more APIs, plugins could support |
Beta Was this translation helpful? Give feedback.
This comment was marked as off-topic.
This comment was marked as off-topic.
-
|
It would be nice for plugins to be able to register custom settings that can be edited through the existing settings GUI for easy configuration. Currently, the only way to have plugin-specific settings is to manage a custom settings file in the plugin's |
Beta Was this translation helpful? Give feedback.
-
|
A broadcast function (global system message) would be useful for feed/event based plugins, similar to #4931. An example use case could be a sports notifications plugin, where you'd want to see updates regardless of your selected tab. This would also be useful for displaying plugin startup messages (successes and or failures) |
Beta Was this translation helpful? Give feedback.
-
|
A plugin that will automatically refresh your token for you when it's close to expiration either with credentials set via environment variables or directly. Furthermore, it would be nice if the plugin would
|
Beta Was this translation helpful? Give feedback.
-
|
Embed channel points (and its redeems) into chatterino. |
Beta Was this translation helpful? Give feedback.
-
|
Embed VLC inside Chatterino, so you can open it (with streamlink) and have everything in a single window. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
|
Not really a plugin idea, but I want to check if my plugin is out of date. For this, I would think of reading the Tl;dr: Support reading |
Beta Was this translation helpful? Give feedback.
-
|
There are a few suggestions here already. To make a small overview, I made a dependency graph of the ideas and the current efforts: GraphSourcedigraph G {
rankdir = LR;
node [shape = box;];
subgraph cluster_emotes {
label = "Emotes"
emote [label = "c2.Emote\n(#6930)";style = filled;fillcolor = "lightgreen";];
emotemap [label = "c2.EmoteMap";];
cemoteacc [label = "Channel Emote Access";];
gemoteacc [label = "Global Emote Access";];
custom_emotes [label = "Custom Emote Providers";];
emoteintf [label = "Consolidating Emote Providers\n(#6570+)";style = filled;fillcolor = "lightgreen";];
emotemap -> cemoteacc;
emotemap -> gemoteacc;
emotemap -> custom_emotes;
emoteintf -> cemoteacc;
emoteintf -> gemoteacc;
emoteintf -> custom_emotes;
}
subgraph cluster_badges {
label = "Badges"
badge_provider[label = "Badge Providers\n(generalize how we handle badges)"];
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-14477133
cbadges [label = "Custom Badge Providers"];
emote -> cbadges;
badge_provider -> cbadges;
}
subgraph cluster_messages {
label = "c2.Message"
emoteel [label = "EmoteElement\n(#6930)";style = filled;fillcolor = "lightgreen";];
badgeel [label = "BadgeElement\n(#6930)";style = filled;fillcolor = "lightgreen";];
modbadgeel [label = "ModBadgeElement\n(#6930)";style = filled;fillcolor = "lightgreen";];
vipbadgeel [label = "VipBadgeElement\n(#6930)";style = filled;fillcolor = "lightgreen";];
ffzbadgeel [label = "FfzBadgeElement\n(#6930)";style = filled;fillcolor = "lightgreen";];
ergo_msg [label = "More Ergonomic Message Functions\n(add text with emotes and emojis etc.)";];
emote -> emotemap;
emote -> emoteel;
emote -> badgeel;
emote -> modbadgeel;
emote -> vipbadgeel;
emote -> ffzbadgeel;
}
subgraph cluster_chan_events {
label = "Channels"
# "game/title change alerts"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-10116564
chan_on_stream_status_changed [label = "Channel:on_stream_status_changed";];
chan_on_joined [label = "Channel:on_joined";];
chan_on_room_modes_changed [label = "Channel:on_room_modes_changed";];
chan_on_destroyed [label = "Channel:on_destroyed\n(this is probably unsafe)";];
# "get the color of a user"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-14779372
chan_get_user_color [label = "Channel:get_user_color"];
subgraph cluster_custom_channels {
label = "Custom Channels";
# "populate custom split"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-7747236
# "feed for livestreams in directory/game as a channel"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-11988676
chan_prov [label = "Channel Providers\n(declare how a plugin channel is created)\n(#6947)";style = filled;fillcolor = "lightgreen";];
usercard_provider [label = "Usercard Info Providers";];
# "add button to profile card"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-7747236
custom_uc_fields [label = "Custom Usercard fields/menus\n(probably nice for Twitch channels too?)";];
# very loose: "access the list of viewers if not a mod"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-9120630
# very loose: "output the current bitrate in the chat title"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-9120630
chan_info_provider [label = "Channel Info Providers";];
chan_info_events [label = "Channel Info Events"];
usercard_provider -> custom_uc_fields;
chan_info_provider -> chan_info_events;
}
}
subgraph cluster_windows_split {
label = "Windows/Tabs/Splits"
win_scroll_to_msg [label = "c2.windows.scroll_to_message";];
# "savable layouts"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-10112187
# "add all followed channels"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-15533398
# very loose: "apply filters to channel view"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-10112187
win_modify [label = "Split/Window API (Modify)";];
}
subgraph cluster_ui_ux {
label = "UI/UX Extensions";
# hotkey to paste opened username in input box
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-14329142
hotkeys [label = "Custom Hotkeys";];
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-14025713
split_ctx [label = "SplitHeader Context Menu Items";];
# "adding 7TV / BetterTTV emotes using the context menu on links"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-9120630
# for users: "filter/highlight/hide/block/ignore/follow"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-10112187
chanview_on_context_menu [label = "ChannelView Context Menu Items";];
# "dynamic filtering"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-7746245
plugin_filters [label = "Filters";];
# "highlighting of messages"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-7746245
highlights [label = "Custom Highlights";];
}
subgraph cluster_custom_ui {
label = "Custom UI"
gui_msgbox [label = "Message Boxes";];
# "prompting basic user input"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-14329142
gui_forms [label = "Declarative UI Forms\n(basic input)";];
# very loose: "regex creator"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-10112187
gui_full [label = "Custom UI/Widgets";];
# "Display ... at the top of the chat as it's done on Twitch"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-9120630
gui_split_header [label = "Display below SplitHeader"];
gui_split [label = "Custom Splits"];
gui_full -> gui_split_header;
gui_full -> gui_split;
}
subgraph cluster_completion {
label = "Input"
# "CompletionRequested" not fired when typing emote with colon
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-10912895
inp_completion [label="Control Input Completion Popup\n(when completing with ':')"];
# "entry object that can show icons"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-10912895
inp_images [label = "Add Images to Completions"];
# "text/emote replacements"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-10173688
inp_replacements [label = "Modify text before sending"];
inp_completion -> inp_images;
}
subgraph cluster_distribution {
label = "Distribution"
Plugin_Packaging [label = "Plugin Packaging";];
Plugin_Hub [label = "Plugin Hub/Repositories";];
Plugin_Packaging -> Plugin_Hub;
}
# "get the current time"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-14779372
datetime [label = "Date and Time API";];
# "read message (tags)"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-7747236
t_irc [label = "Twitch IRC parsing hooks";];
# "and play sound"
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-7747236
play_sound [label = "Play Sound/Notifications";];
# TODO: There are a lot more items at the bottom of the following comment.
# I'm not sure how well we can support this:
# https://github.com/Chatterino/chatterino2/discussions/4999#discussioncomment-10112187
}Nodes without incoming edges don't have any dependencies and could be implemented today. I left out some items where I wasn't sure how we'd go about exposing an API for them (namely VLC/external program embedding and user token refresh). Furthermore, some items need to be broken down further (like GUI). Some items also would benefit from someone proposing a Lua API for them (in a separate discussion). Then we'd have something concrete to discuss. |
Beta Was this translation helpful? Give feedback.
-
|
I'd love an API for prompting for basic user input. It would fill the gap nicely between commands, which can take arguments, and hotkeys which need to hardcode them. My immediate use-case is a command that brings up a text input for a username, then opens their usercard, so you can bind it to a shortcut and execute it without having to go to the message box. An interactive user input API would also compose well with the HTTP API for making more complex integrations. |
Beta Was this translation helpful? Give feedback.
-
|
Hoping for API support for a custom badges plugin. |
Beta Was this translation helpful? Give feedback.
-
|
One of the most frustrating things about the current UX for me is that when hopping between streams or while discovering streams, you need to manually type and open that particular stream in Chatterino. A plugin to automatically switch to a Chatterino tab with the channel that is open in the browser or create a new tab with the channel if it's not open already would be great. This friction causes me to revert back to Twitch's built-in chat for such cases. How does everyone else handle this... is there some other workaround that already exists? |
Beta Was this translation helpful? Give feedback.
-
|
I'd like to see an API to return a Example use: c2.register_command("/logs", function (ctx)
-- Usage: /logs [username] [channelname]
local msg = ("/openurl https://logs.zonian.dev/rdr/%s/%s"):format(
-- fallback to current channel's name
ctx.words[3] or ctx.channel:get_name(),
-- fallback to current user's name
ctx.words[2] or ctx.executor:get_name()
)
ctx.channel:send_message(msg, true)
end)I used Additional ideas (Added 17/11/2025):
|
Beta Was this translation helpful? Give feedback.
-
|
plugin for Streamer.bot integration that makes possible to use commands for execute different actions could be cool (maybe it would be needed to do in the Streamer.bot side, they have a really good API with HTTP, UDP and WebSocket API |
Beta Was this translation helpful? Give feedback.
-
|
an option to automatically add all followed channels |
Beta Was this translation helpful? Give feedback.




Uh oh!
There was an error while loading. Please reload this page.
-
Got an idea for a plugin that you feel like would be useful in Chatterino, but might not make sense in Chatterino itself?
Post it here - we're looking to see how the API should be designed, so getting some ideas as to what you'd like to be able to do with plugins is useful.
Beta Was this translation helpful? Give feedback.
All reactions