Under Settings - Commands
you can add Custom Commands and
customize some Context Menus (and the User Info Dialog) with your own entries.
Check out YouTube for various video tutorials.
Custom commands allow you to specify aliases for anything you could also enter directly into the inputbox, like chat messages or regular commands (with the exception of other custom commands, which is a limitation implemented to prevent infinite loops).
To add a Custom Command add a new entry to the list labeled "Custom Commands", in the following format:
/<commandName> <what the command should do>
Everything up to the first space is the name of the command, and everything after the first space is what the command will do or execute. For example:
/hello Hello World!
If you added that to the Custom Commands list and
enter /hello
in the inputbox, then it would send
Hello World!
to chat, just as if you would have written it
yourself and pressed Enter.
Any entry in the "Custom Commands" list starting with a #
will be completely ignored. For example:
# Hello World!
See Replacements for more advanced usage.
Adding a #
and a channel name you can restrict the command
to that channel:
/hello#joshimuz Hello Joshimuz Chat!
This /hello
command would only be executed in #joshimuz,
however if you still have the version without a channel in the Custom
Commands list as well, it will fallback to that in other channels. This
way to can add variations of commands for specific channels.
Custom Commands that aren't defined in the Custom Commands list do not have a name and can thus only be executed from the context they are defined, for example when adding Inline-Commands to the User Dialog or Context Menus.
You can also execute Anonymous Custom Commands directly from the
inputbox, by prepending //
, which allows you to use
Replacements:
/echo Open Channels: $(chans)
Open Channels: $(chans)
//echo Open Channels: $(chans)
Open Channels: joshimuz lotsofs cirno_tv
Executing several commands in a row is not a feature of Custom Commands, although the /chain command can be used to achieve something like that.
The /foreach command can be used
to run the same command for each entry of a space-separated list, for
example a list of channels from the $1-
replacement.
The /runin command can be used to run a command in a specific open channel.
Anything starting with $
in the <what the command
should do>
section is treated as some sort of replacement.
Each replacement must contain an identifier
which identifies what the replacement should be replaced with.
For the short notation the identifier is written
directly after the dollar sign: $<identifier>
.
In thise case it may only consist of a number and an optional dash:
$<1-9>[-]
. Numeric identifiers refer to the parameters
supplied to the command.
For the regular notation the identifier is written after
the $
in parentheses: $(<identifier>)
.
This type of notation makes a more clear distinction between replacement
and the rest of the (literal) text and may contain numbers (including higher than 9)
and other identifiers, depending on the context.
Put $$
(the $
twice) for any
required replacement (for example $$1
),
which means the whole Custom Command will only be run if that replacement
turns into a non-empty value. This can be used to make sure that a
parameter that is necessary for the command to make sense is actually
being supplied.
If you want to use a dollar sign $
literally, without it
beginning a replacement, you can escape it with a backslash:
\$
. A backslash will always interpret the following
character as a regular character without a special meaning, while
the backslash itself will not show up in the result.
Example: $replace($1-,(\\w+),(\$1\),regRef)
This function (surrounds all consecutive word characters with brackets) contains some escaping:
(\\w+)
turns into the plain text (\w+)
. The backslash needs to be escaped so
it actually shows up for the regex.(\$1\)
turns into the plain text ($1)
. The dollar sign is used for the regex,
not an actual Custom Command replacement and the closing bracket
needs to be escaped here because the following function parameter is
optional, so the bracket would close the function.Alternatively you can use $"<literal text>"
which
interprets everything inside the quotes as literal text without any
special meaning. To use a quote inside the literal text, it can be
doubled: $"This is a dollar sign: ""$"""
turns into the
plain text This is a dollar sign: "$"
. Instead of "
you can also use `
(backquote) or '
(single quote):
$`This is a dollar sign: "$"`
is equivalent to the above.
The previous example could also be written like this: $replace($1-,$"(\w+)",$"($1)",regRef)
A basic use of replacements is using the short notation to put in parameters supplied when executing the command. Consider this Custom Command:
/slap /me slaps $$1 around a bit with a large trout
Then, when you enter /slap moobot
in the inputbox, it will
replace $$1
with the first word after the command, which in
this case would be moobot
, making the resulting command:
/me slaps moobot around a bit with a large trout
This is the syntax for specifying parameters (word in this context means anything separated by a space):
$1, $2, $3
$(1), $(2), $(3)
is the equivalent in the regular notation$1-
$2-, $3-
is also possible$(1-), $(2-), $(3-)
is the equivalent in the regular notation$$1
$$2, $$3-
is also possible$$(1), $$(2), $$(3-)
is the equivalent in the regular notationThe short notation ( $1
) only works for the numbers 1 to 9,
which usually should be enough. For other kinds of replacements you must
use the regular notation including parentheses: $(10)
.
Custom Commands can be used in a number of different places. Depending on
the context there are different pre-defined parameters available. The
following table shows which identifiers can be used in which
context. To use an identifier put it in a replacement, for example
$(chan)
or $$join(1-,/)
.
Context | Identifier | Description |
---|---|---|
All | chan |
The current channel context (without leading #) |
stream |
The stream name of the current channel context (different from
chan for Chatrooms) |
|
chans |
All currently open regular channels (separated by spaces, without leading #) | |
stream... |
Stream Info (e.g. uptime, stream title) identifiers | |
User Context Menu | 1 |
Name of the user |
Various | Various user-related identifiers | |
msg |
Message text of the selected message (depending on the line in chat you opened the User Contex Menu from, not available for your own messages) | |
msg-time |
Message time of the selected message (depending on the line in
chat you opened the User Contex Menu from, not available for
your own messages), as milliseconds since
1970-01-01 00:00:00 UTC, intended to be used with $datetime() ,
e.g. $datetime(datetime,,,$(msg-time)) |
|
msg-id |
Message id of the selected message (depending on the line in chat you opened the User Contex Menu from, not available for your own messages) | |
automod-msg-id |
Message id of the selected message filtered by AutoMod, for approving or denying the message (when opened by clicking on an appropriate message in chat) | |
User Dialog | All from User Context Menu | See above |
2- , reason |
Ban reason (if selected) | |
msg |
Message text of the selected message (> in front
of message, depending on the line in chat you opened it from,
not available for your own messages) |
|
msg-time |
Message time of the selected message (> in front
of message, depending on the line in chat you opened it from,
not available for your own messages), as milliseconds since
1970-01-01 00:00:00 UTC, intended to be used with $datetime() ,
e.g. $datetime(datetime,,,$(msg-time)) |
|
msg-id |
Message id of the selected message (> in front
of message, depending on the line in chat you opened it from,
not available for your own messages) |
|
automod-msg-id |
Message id of the selected message filtered by AutoMod, for approving or denying the message (when opened by clicking on an appropriate message in chat) | |
followage /
accountage |
How long ago (e.g. 3.2 years ) the user has followed
/ has created the Twitch account (only if available) |
|
followdate / accountdate |
The date (e.g. 2012-09-15 17:19:29 +0200 ) the user
has followed / has created the Twitch account (only if available) |
|
Channel Context menu | 1 |
Name of the currently active channel (without leading #) |
Streams Context menu | 1- |
Names of selected streams |
Hotkey | 1 |
The currently selected user (if present) |
Selected Text Context menu | 1- , msg |
The selected text |
Admin Context menu | title |
The stream title currently set in the Admin Dialog |
game |
The game (category) currently set in the Admin Dialog | |
tag-ids |
The tags currently set in the Admin Dialog (ids, comma-separated) | |
tag-names |
The tags currently set in the Admin Dialog (display names, comma-separated) |
These are available where a user is involved, such as the User Dialog and
User Context Menu. In some contexts they may also be available with the
my-
prefix for your own user info (e.g. my-full-nick
).
nick
- Name of the user, maybe capitalizeddisplay-nick
- Same as nick
, but may not match the regular username (spaces, completely different)display-nick2
- Same as display-nick
, but contains the regular username in parentheses if necessarycustom-nick
- Same as display-nick
, but may also be the Custom Name you setfull-nick
- The same name that is displayed in the userlist (includes status symbols)full-nick2
- Same as full-nick
, but contains the regular username in parentheses if necessaryspecial-nick
- Returns true
if the user has a display name not matching the regular usernameuser-id
- The Twitch ID of the user (if available)twitch-badges
- A textual representation of the Twitch badges (if available)twitch-badge-info
- Another textual representation of the Twitch badges (if available)user-stream
- The name of the stream the user talked inuser-stream-id
- The id of the stream the user talked inuser-channel
- The name of the channel the user talked in (with leading # if applicable)The stream info is of the current channel context, if available.
streamstatus
- Stream Status ("Title (Game)" or "Offline")Only available if live:
streamtitle
- Stream Titlestreamgame
- Stream Gamestreamviewers
- Number of viewersstreamuptime
- Stream Uptime, ignoring short breaks as shown in the Chatty titlebarstreamuptime2
- Actual Stream Uptime as reported by Twitch directly/streaminfo /echo [Stream Status] $(streamstatus) [Uptime] $(streamuptime)
/streaminfo
outputs an info message (only for
you) with the current stream status and uptime.In addition, there is an implicit channel context, which means channel-aware
commands like /ban
are executed in the appropriate channel.
Functions are replacements, however they have a function name before the identifier (there is no short notation for functions):
$<functionName>(<identifier>,<some parameters>,[optional parameters])
Note: The <identifier>
parameter
means anything not starting with $
is interpreted as the
identifier only. You can think of it as an extension to the regular
replacement:
$(1-) -> $join(1-,/)
Functions by topic (ones marked with * are not available in every context):
The following functions are always available:
$if(<identifier>,<output if exists>,[output if not])
$if(1,$1,nope)
with command parameters cheese cake
turns into cheese
,
with no parameters turns into nope
, the optional [output if not]
function parameter.$ifeq(<identifier>,<comparison>,<output if equal>,[output if not])
$if
, but instead of just checking for the
existence of a parameter it compares it to a given value
(<comparison>
).$ifeq(1,cheesecake,yummy)
with parameters
cheesecake
turns into yummy
, with parameters
cheese cake
turns into an an empty string, since the
optional [output if not]
has not been specified.$switch(<identifier>,<case1>:<result1>,..,[casen]:[resultn],[default])
$ifeq()
functions.
Compares the value associated with the identifier with the case values and returns the following
result if it matches. If none of the case values match, it will return the default, or an empty value./set fontSize $switch($get(fontSize),25:50,50:18,25)
when added
as a Custom Command alternates between font sizes 18, 25 and 50.$join(<identifier>,<separator>)
$join(1-,/)
with 1-
referring to
flour sugar eggs
turns into flour/sugar/eggs
$lower(<identifier>)
$lower(1)
with 1
referring to Fremily
turns into fremily
.$upper(<identifier>)
$upper(1)
with 1
referring to Fremily
turns into FREMILY
.$trim(<input>)
$trim( abc )
turns into abc
.$quote(<input>,[quote character])
"
) is used.$quote(51° 28' 38" N)
turns into
"51° 28' 38"" N"
and $quote(51° 28' 38" N,')
turns into '51° 28'' 38" N'
.$replace(<input>,<search>,<replace>,[method])
\
(\\
) and $
(\$
)
when they should e.g. be used in regex rather than interpreted as special Custom Command characters.
Instead of escaping each special character individually, you can also
use Literal Text.cs
- Literal case-sensitive searchreg
- Regular Expression searchregRef
- Regular Expression search, with references to groups via \$1
$1
in this case does not refer to a Custom Command replacement, but something that the replaceAll() method uses, so it needs to be escaped in the Custom Command function, either by using \$1
or using Literal Text. In addition, if $
or \
should show up literally instead of being interpreted by the replaceAll() method then they need to be escaped again (e.g. $replace(..,..,Dollar: \\\$1 Ref: \$1,regRef)
, whereas Dollar: \$1 Ref: $1
would be given to the replaceAll() method).regFirst
, refFirstRef
- Same as above, but only replace first occurenceregCustom
- Regular Expression search, the replace parameter has access to match values and is
executed for each match ($1-
full match, $(g1)
first group in the search regex
if available, $(g2)
second group, ..).regFunc
- Regular Expression search, the replace must be the name
of a Custom Replacement which is called with the same values as regCustom
(doesn't always work in Custom Commands, can use regCustom
with e.g. $(_<name>,$1-)
instead).$replace(A b and another B,b,bee)
turns into A bee and another bee
$replace(Was timed out for 30 seconds,.*?(\\d+) seconds,Number of seconds: \$1,regRef)
turns into Number of seconds: 30
$replace($1-,$"~([a-z]+)~",$replace($(g1),$"(\w)",$"$1+",regRef),regCustom)
adds +
behind every character surrounded by ~
(the inner $replace()
is in the replace
parameter and executed for each match)$rand([output1],[output2],[output3],..)
$rand(cheesecake,strawberry cake,$1-)
with 1-
referring to apple pie
turns into
either cheesecake
, strawberry cake
or
apple pie
.$randnum(<from>,<to>)
or $randnum(<to>)
$randnum(600,800)
chooses a random
number between 600 and 800.$randum($$1)
chooses a random number
between 0 and what is the first parameter.$calc(<simple math expression>)
* / % + -
) and functions (sqrt() sin() cos() tan()
).//echo $calc(2^3) $calc( (3+4\) / 2)
when entered into the inputbox returns 8 3.5
(note the
parentheses in the second, as well as how the closing parenthesis
needs to be escaped).//echo $calc($"sqrt(81) * (1 + 4/2)")
outputs 27
(this uses $" "
to specify literal text
instead of escaping the parenthesis with a backslash).$round(<number>,[numDecimalPlaces],[roundingMode],[minNumDecimalPlaces])
ceil
, floor
,
up
, down
or half-down
, with
the given number of minimum decimal places (fills with 0).//echo $round(1.335)
outputs 1
//echo $round(1.335,2)
outputs 1.34
//echo $round(345.5,3,floor,3)
outputs 345.500
(fills up to 3 decimal places)//echo $round(2.565,2,,2)
outputs 2.57
(uses default rounding mode)$urlencode(<input>)
$urlencode($(msg))
in User Dialog
encodes the currently selected message.$sort(<input>,[type],[separator])
$sort(B c a)
turns into a B c
$sort(B c a,Abc)
turns into B a c
$input([message],[intial],[type])
message
is shown in the input dialog, the initial
text will already be in the input field when the dialog opens. The
type
can be set to simple
to use the
previously default simple input dialog.$input()
$input(Enter a number please)
$datetime([format],[timezone],[locale],[unix time])
date
, time
, datetime
date2
, time2
, datetime2
_short
, _medium
,
_long
or _full
, e.g. datetime_full
$datetime()
Wednesday, March 13, 2019 3:11:48 PM CET
$datetime(,,de)
Mittwoch, 13. März 2019 15:12 Uhr MEZ
$datetime(time)
23:31:27
time
".)$datetime(datetime2,Vancouver)
2019-03-12 15:31:45 PDT GMT-0700
datetime2
" pre-defined format, with a timezone specified.)$datetime(datetime_full,Rome,it)
mercoledì 13 marzo 2019 15.32.03 CET
$datetime(,london)
Wednesday, March 13, 2019 2:16:36 PM GMT
$datetime(HH:mm:ss zzzz,Tokyo,en)
07:50:20 Japan Standard Time
$datetime(eeee\, dd. MMMM yyyy,,de)
Dienstag, 12. März 2019
,
escaped since it normally
separates function parameters, empty timezone in order to be
able to specify locale.)$datetime(datetime2,Berlin,,1646937275000)
2022-03-10 19:34:35 MEZ GMT+0100
$json(<input>,<output>)
<input>
and use in <output>
,
where $j(<path>,[default],[sub],...)
can be used to access specific values.
The JSON input could e.g. come from the $request()
function.<path>
specifies what value to return from
the $j(<path>,[default])
function, whereas the optional [default]
value will be returned if the path is not valid or points to an empty value.<path>
you specify keys of JSON objects
separated by ->
(e.g. key1->key2->key3
) or
indices of JSON arrays in brackets [ ]
(e.g. key1[0]
for the first element of the array key1). Additionally the brackets [ ]
can contain:
last
for the last entry of an arraysize
to return the number of elementssort
to sort an array (mainly works for strings)filter:<path>[=regex]
to select only
certain array items/object values based on whether a path exists or if a
regex is provided the value of the pathcollect:<path>[=regex]
iterates over an
array/object values and for each element resolves the path and combines
the resulting values into an arraycombine:<path>[=regex]
iterates over an
array/object values and for each element resolves the path and for each
resulting value that is an array adds all of the array
values into a single result arrayunique
removes duplicate elements from an arrayjoin[:delimiter]
turns an array into a string
by joining all elements together using the given delimiter
(or ",
" if none is provided)'
(for example [collect:abc='[a-z]+']
so that the ]
in the regex doesn't get mistaken
as the end of the regex). To use a '
in a quoted
section you have to double it ''
.[sub]
values can contain additional $j()
replacements, which are applied to the result of the path or previous [sub]
parameter. If prefixed with each:
it will be applied
to each element on an array/object and the result collected into
an array (for objects the $(key)
replacement and
for arrays the $(index)
replacement is available).{ "books":[ {"title":"book1", "author":"author1", "tags":["tag1","tag2"]}, {"title":"book2", "author":"author2", "tags":["tag1"]}, {"title":"book3", "author":"author2", "tags":["tag1", "tag3"]}, {"title":"book4", "author":"author2"} ], "authors":{ "author1":{"name":"name1", "age":24}, "author2":{"name":"name2", "age":62} }, "numBooks": 4, "numAuthors": 2 }
$json($get(var,j),There are $j(numBooks) books of $j(numAuthors) authors.)
$json($get(var,j),There are $j(books[size]) books of $j(books->[collect:author][unique][size]) authors.)
There are 4 books of 2 authors.
$json($get(var,j),The last book is called $j(books[last]->title) by $j(books[last]->author).)
The last book is called book4 by author2.
$json($get(var,j),The first book is $j(books[0]))
The first book is {"author":"author1","title":"book1","tags":["tag1","tag2"]}
$json($get(var,j),$j(books[10]->title,Book not found))
Book not found
10
does not exist, the default
value Book not found
is returned. If no default
value is provided an empty string would be returned.$json($get(var,j),Books of author2: $j(books[filter:author=author2][collect:title]))
Books of author2: ["book2","book3","book4"]
$json($get(var,j),Tags of author2: $j(books[filter:author=author2][combine:tags][unique]))
Tags of author2: ["tag1","tag3"]
$json($get(var,j),Tags of author2: $j(books[filter:author=author2][combine:tags][unique][join]))
Tags of author2: tag1, tag3
$json($get(var,j),$j(authors[collect:name][sort][join]))
name1, name2
$json($get(var,j),$j(authors,,each:$(key): $j(name) \(age $j(age)\),$j([sort][join])))
author1: name1 (age 24), author2: name2 (age 62)
[sub]
parameters of $j()
are used here:
$j( // Path to "authors" JSON object authors, // Skip the optional "[default]" parameter , // Apply to each entry of "authors" and collect result in an array each:$(key): $j(name) \(age $j(age)\), // Sort and join array created from previous parameter $j([sort][join]) )
/set var j copyJSONfromabove
and then use the //echo $json($get(var,j),...)
command
in the chat inputbox
to output an info message with the result in chat. Pasting the JSON
directly into the $json()
function would require
escaping the ,
characters to work.
The following functions are only available in some contexts:
$is(<match input>)
true
if the match succeeds, nothing otherwise.
The match input
is in the Highlight
format, although what can actually be matched against depends on
where the command is ran from, for example the user or message text
is only available from the User Dialog or User Context Menu.$if($is(mystatus:bm),I'm a mod,Not a mod)
will output I'm a mod
in channels where you are the
broadcaster or a moderator, Not a mod
otherwise.$get(<settingName>,[key])
var
,
where you can set a string value using setting commands
(/set var foo bar
) and then retrieve the value with
this function ($get(var,foo)
returns bar
).//echo $get(username)
returns the
name you are logged into Chatty with.$if($get(ontop),ONTOP)
will return
ONTOP
only if "View - Always on top" is enabled.$request(<url>,[options])
error
- A request error will return an error
message instead of an empty response.trim
- Remove leading and trailing space from
the request result. This may be useful if a request returns
any spaces or linebreak characters that cause issues with
what you're using it with. Same as the $trim()
function.$request()
function will be performed asynchronously so that it can complete
the request without freezing the GUI. This means the result of the
Custom Command may be run seconds or more later.Tip: Enter e.g. //echo $datetime()
into the chat inputbox to test a function directly, use arrow up/down
keys to cycle through previous inputs. Of course you won't be able to
use some context dependant parameters this way.
Examples of Custom Commands with these functions:
/slap /me slaps $$1 around a bit with a large $if(2,$2,trout)
/slap Nightbot
turns into /me slaps Nightbot around a bit with a large trout
/slap Nightbot cheesecake
turns into /me slaps Nightbot around a bit with a large cheesecake
/mt /openUrlPrompt http://multitwitch.tv/$$join(1-,/)
/mt
outputs an "insufficient parameters" message
because the $$join
is required to return something,
which it can't from the identifier 1-
if there are no
parameters/mt joshimuz lotsofs
opens the URL http://multitwitch.tv/joshimuz/lotsofs
Note: A backslash can be used to escape parenthesis
in function parameters. Example: $if(streamuptime,$(streamuptime),(n/a\))
.
In this example only the closing one after n/a
has to be
escaped, because the opening one doesn't have a special meaning in this
context and the ones around streamuptime
have a special
meaning that takes precedence (opening/closing the replacement).
You can create your own identifiers for replacements by adding an entry to the Custom Commands list starting with an underscore:
_m $ifeq(1,$(chan),,$$1: )
Instead of a command, this creates an identifier that can be used in a replacement:
/faq $(_m)FAQ: https://pastebin.com/KySx3KDu
When the /faq
command is run, the $(_m)
gets
replaced with whatever is defined in _m
, in this case it
creates a mention if the first parameter isn't equal to the current
channel.
The data that can be accessed via replacements is the same as in the
command it is used in, so in this example the text provided after the
/faq
is available via the $1-
replacement.
Optionally you can also provide a second parameter in a Custom Replacement
that overwrites the default value of the $1-
replacement:
/faq $(_m,$(custom-nick))FAQ: https://pastebin.com/KySx3KDu
This will make whatever value is contained in $(custom-nick)
available in $1-
instead of the default.
Note: Custom Replacement identifiers always start with an underscore.
Note: Custom Replacements don't work when placed
inside eachother. So for example in _abc Abc: $(_m)
the $(_m)
will
always be empty (whether it's defined in the Custom Commands list or not).
Under Settings - Commands
there are several settings that
allow you to add additional entries/buttons in a few different places:
All those settings share the same format (with some slight differences noted separately). A setting can contain several lines, and each line can contain one of the available formats:
/Ban[B] /Unban[U] 5s[1] 2m[2] 10m[3] 30m[4] Spoiler[S]=/timeout $$1 600 No spoilers @b1 ./Message /Report .Warn User=$$1: Plz no spammerino
Note: Command Names/Labels may not contain the
characters [ ] { }
except for their special meaning of
Shortcuts and Positioning.
You can list the name of several Custom Commands in one line, for example:
/Slap /Permit
Which means the command with the name "slap" will be added first, then "permit" after that. These must be existing commands, either pre-defined Chatty commands or Custom Commands you added yourself.
Note that you may only specify the command names, no parameters. The
parameters will be supplied automatically depending on the context. For
example when you have /Slap
added to the User Dialog and
then open the dialog on the user tailsgaming
and click the
"Slap" button, it's as if you entered /slap tailsgaming
.
/Slap /Permit
/
(although it may also work without).//Slap
//
will put the command
in the special submenu More..
(for Context Menus) or in
a second line of buttons (for the User Dialog)./Set_color
is displayed as Set color
In the same line, you can also specify Timeout Buttons:
5 2m 10m
/
and must be a number followed by
an optional suffix. They are interpreted as seconds by default,
unless you add a suffix:
s
- seconds, m
- minutes,
h
- hours, d
- days.120s 120
is displayed as two buttons with the label 120s
and 2m
You can define commands directly in the setting, without having to add them as a named Custom Command first. The syntax for this is:
<label with spaces>=<what the command should do>
Note that as opposed to Custom Command names the label may contain spaces,
and for that purpose the separating character is an equals sign =
.
The label may not contain an equals sign itself. Example:
Warn User=$$1: Plz no spammerino
As with Custom Commands, the <what the command should do>
part can contain replacements using
identifiers for the current context.
Any line starting with @
defines a custom submenu. Any
following lines that start with a dot .
will then be put in
that menu (both command name lists and inline commands). For example:
@Rules ./No_Spam /No_Spoilers .Spoiler=/timeout $$1 600 no spoilers
For Context Menus you can add submenus with custom names
(only 1 level though), or even add entries to existing submenus by
specifying the name (for example @Twitch Stream
).
For User Dialog Buttons there are no named submenus,
however this notation can be used to put the buttons in separate rows.
Any submenu name starting with a
will create a row on the
top, all other ones on the bottom. The menu name a1
is the
default for buttons that don't have a menu defined, and b1
is the default for the //Command
notation. Example:
/Ban /Unban @a1 .Spoiler=/timeout $$1 600 no spoilers @a2 .5s[1] 2m[2] 10m[3] 30m[4] @b1 ./Slap
In this case the Ban
and Unban
commands are in
the default a1
row, which means they are in the same row as
the Spoiler
button (these are just different ways of
writing it). This also adds a second top row a2
for the
timeout buttons as well as a single bottom row for the Slap
command.
In Context menus you can add separators between entries.
When you use a commands list, you can add
a vertical bar (|
) between entries.
You can also add a separator by adding a single dash (-
) on
it's own line.
Example (separator before Timeout
menu, before Message
and before Vods
):
/Ban /Purge - @Timeout .5s 10m - /Message /Report | /Vods
You can add a shortcut to the end of a label or command name by enclosing
it with [ ]
(square brackets):
/Ban[B]
or Spoiler[S]=/timeout $$1 ..
(depending on the line format)
For User Dialog Buttons those can be used while the
dialog is open and focused. They are interpreted by
getKeyStroke()
which means anything that function understands can be used. However
spaces are not allowed, so a plus sign +
can be used instead.
Examples: alt+Q
, shift+1
, INSERT
Note: The lowercase/uppercase matters for it to be parsed correctly.
Adding a vertical bar |
after the shortcut will use the text
after it as label for the shortcut on the button (no spaces allowed). If
you include the |
but don't specify any text, then no label
will be displayed for that shortcut:
/Slap[NUMPAD1|Np1] /Permit[NUMPAD2|]
For the User Dialog Buttons you can also include the string
nokeylabels
anywhere in the setting, which removes any
labels for the shortcuts, unless they are explicitly defined.
For Context Menus a single character can be used as a
Mnemonic, for quick access to menu entries. For this purpose, submenus
may also contain the same syntax: @Rules[R]
(which would
allow you to open that submenu by pressing R on your keyboard when the
context menu is open).
You can define an absolute position in the menu the entry should appear
at by enclosing it with { }
(curly brackets) at the end of
the label or command name (but before a shortcut if there is any):
Mention{1}=/insertword $$1: \
This will put the Mention
menu entry at the second
position in the menu (counting starts from 0).
Another example:
@Twitch Stream[s] .Videos{2}[v]=/openUrlPrompt https://www.twitch.tv/$$1/videos/past-broadcasts @Important{0} .Slap=/me slaps $$1 around a bit with a large trout @Really Important{0} .FAQ=FAQ: https://pastebin.com/KySx3KDu
This puts the Videos
entry into the pre-defined
Twitch Stream
submenu at the third position in the submenu
(also adding the accelerator key s
to the menu and
v
to the entry).
It also adds the Important
submenu at the first position
(since it hasn't been added yet) and after that adds the
Really Important
submenu at the first position as well,
moving down Important
. This demonstrates that the
positioning is based on the current state of the menu, so it can matter
when you add entries with absolute positioning.
Note: This feature must be enabled in the Settings under "Commands" (otherwise replacements in labels have no effect).
You can use Custom Command replacements in the label of inline commands or submenus. The label is updated:
For example if you have a counter command that increases a number, it
could show the current number in the menu entry label by reading it from
the settings via $get()
:
Increase counter ($get(var,c))=/set2 var c $calc($get(var,c) + 1)
You can also use this to hide an entry, by adding a required replacement,
like $$is(mystatus:M)
, which will cause the entire label to
be empty if you are not a mod in the channel and thus will not be added
to the menu. Just adding $$is(mystatus:M)
will add true
if you are a mod, so you can wrap it in an $if()
(in this
example it's a submenu called "Mod Menu"):
@$if($$is(mystatus:M),Mod Menu)
Note: Compared to identifiers for regular commands, some information may be missing in the context of labels and restrictions.
Note: This feature must be enabled in the Settings under "Commands" (otherwise added restrictions have no effect).
You can add restrictions to individual menu entries or a group of entries. The restriction is applied (entries added or removed):
The restriction must always be on it's own line and start and end with a square bracket, which contain a Custom Command that is surrounded by spaces. If the Custom Command returns a non-empty value the menu entries will show up, otherwise they are hidden.
[ <restriction using custom command> ]
[<name> <restriction using custom command> ]
<name>
is used to identify where the section ends. Different restrictions
can be nested inside eachother, causing them all to be applied to
the affected menu entries.[/<name>]
Example:
[mod $is(mystatus:M) ] @Modes .Emoteonly[E]=/emoteonly .Emoteonly Off[O]=/emoteonlyoff .Subsonly[S]=/subscribers .Subsonly Off[D]=/subscribersoff Clear[C]=/clear [ $ifeq($datetime(M),9,true) ] /Subtember [/mod] [ $is(chan:joshimuz\,botimuz) ] /JoshFAQ /JoshSub
The "Modes" submenu, the "Clear" command and the "Subtember" command only
show when you are a mod in the channel. The $is()
function uses Highlight syntax
and returns an empty value if it doesn't match. It's that Custom Command
part that defines the actual restriction, the "mod" in [mod ... ]
is arbitrarily named, it just has to match the closing [/mod]
.
The "Subtember" command has an additional requirement though, defined
directly above it, which uses the functions $ifeq()
and $datetime()
to
only show the menu entry when the month is September.
The "/JoshFAQ" and "/JoshSub" commands only show in the channel #joshimuz
or #botimuz. Note that the \,
between the channel names
requires the backslash to escape the comma,
meaning it tells the Custom Command parser that the comma isn't meant as
a function parameter separator, but rather to separate the channels in
the Highlighting syntax.
Note: Compared to identifiers for regular commands, some information may be missing in the context of labels and restrictions.
In the User Dialog Buttons setting you can use some special commands:
/modunmod
to ada a Mod/Unmod-Button
which automatically changes depending on the selected user and
whether you are the broadcaster on the channel (so the button
doesn't always show up)./Automod_approve
and /Automod_deny
only appear as buttons when you opened the User Dialog by clicking
on the username of a message rejected by AutoMod.To make use of these you only need to enter the command, you don't need
any parameters (Chatty will take care of that). For example simply add
/Modunmod
or Approve=/Automod_approve
to add
it to the layout (using the syntax shown on this help page). Chatty will
then recognize the command names and the buttons will only show up when
they are needed.