Blocks
Blocks are the core concept of TagScript. Each block encapsulates a specific behaviour,
like the CaseBlock, which can transform input text to UPPERCASE or lowercase.
Action Blocks
A group of blocks that can be used to signal some sort of action to be taken by the
client. Characterised by adding data to the the
actions attribute of the Interpreter’s
Response return value.
- class ya_tagscript.blocks.CommandBlock(limit: int = 3)[source]
Bases:
BlockABCRun a command as if the tag invoker had run it.
By default, only 3 command blocks can be used in a tag.
Usage:
{command:<command text>}Aliases:
c,com,cmd,commandParameter:
NonePayload:
command text(required)Examples:
{c:ping} # adds "ping" to the "commands" list of the Response's actions attribute {c:ban {target(id)} flooding/spam} # (Assuming target is a user with ID 123) # adds "ban 123 flooding/spam"Response Attribute:
This block sets the following attribute on the
Responseobject:Note
This block will only add the processed command strings to the
commandsactionskey as shown above. It is up to the client to implement actual command execution behaviour as desired.
- class ya_tagscript.blocks.DeleteBlock[source]
Bases:
BlockABCSignal that the input message should be deleted.
If no expression is provided (just
{delete}is used), it will always signal that the message should be deleted.If an expression is provided, it is processed. If it evaluates to be True, the block will signal that the message should be deleted.
The block is idempotent, i.e. only one is ever needed for a given script. Once one block has set the “delete” actions key, subsequent copies are ignored, even if they provide other expressions with a different outcome.
Usage:
{delete(<expression>)}Aliases:
delete,delParameter:
expression(optional)Payload:
NoneExamples:
{delete} {del(true==true)}Response Attribute:
This block sets the following attribute on the
Responseobject:
- class ya_tagscript.blocks.OverrideBlock[source]
Bases:
BlockABCOverride a command’s permission requirements.
This block can override the permission requirements attached to a CommandBlock.
- Possible overrides are:
“admin”: admin permissions
“mod”: mod permissions
“permissions”: general user permissions
Usage:
{override(["admin"|"mod"|"permissions"])}Aliases:
overrideParameter: One of
admin,mod,permissions(optional)Payload:
NoneExamples:
{override} # overrides all commands and permissions {override(admin)} # overrides commands that require the admin role {override(permissions)} {override(mod)} # overrides commands that require the mod role or have user permission requirementsResponse Attribute:
This block sets the following attribute on the
Responseobject:Note
This block only sets the
overridesactionskey as shown above, combining the provided parameters across the entire script. It is up to the client to implement actual permission override behaviour as desired, including what permissions qualify for “admin”, “mod”, or “permissions”.
- class ya_tagscript.blocks.ReactBlock(limit: int = 5)[source]
Bases:
BlockABCProvide a list of reactions to be added to either the input message or the script output.
By default, only 5 emoji can be specified for either the input or output message, for a total of 10 emoji (max. 5 for input + max. 5 for output).
When providing several emoji, they have to be separated by a space.
Behaviour differs between aliases:
react: Emoji to add as reactions to the output messagereactu: (“react-up”) Emoji to add as reactions to the input message
Note
The emoji can be any strings, regardless of their validity as standard emoji or Discord server emotes. It is up to the client to validate the provided list of emoji.
If the same alias is used again in the script, the previous emoji are overwritten, so only the latest set of emoji is retained.
Usage:
{react:<emoji>}Aliases:
react,reactuParameter:
NonePayload:
emoji(required)Examples:
{react:💩} # 💩 is added to the list of reactions for the output message {react:💩 :)} # both "💩" and ":)" are added to the list of reactions for the output message {reactu:🤔 :) :D} # "🤔", ":)", and ":D" are added to the list of reactions for the input messageResponse Attribute:
This block sets the following attribute on the
Responseobject:actionsactions["reactions"]:dict[Literal["input", "output"], list[str]]— A dictionary like{"input": [...], "output": [...]}(each key may be missing if it wasn’t used in the script)
Note
This block will only set the provided string(s) in the
reactionsactionskey under the appropriate dictionary key as shown above. Each of the keys may be missing if not used in the script. It is up to the client to implement actual reaction adding behaviour as desired.
- class ya_tagscript.blocks.RedirectBlock[source]
Bases:
BlockABCRedirect the script output to a given channel, to the invoking user’s DMs, or set it to be a reply to the invoking message.
If it is used more than once in a script, only the latest redirection target will be retained.
Usage:
{redirect(<"dm"|"reply"|channel>)}Aliases:
redirectParameter: One of
"dm","reply", orchannel(required)Payload:
Nonechannelrepresents a way to refer to a text channel (e.g. channel name, mention string, ID, etc).Note
To avoid breaking scripts due to changing channel names, it is generally recommended to use channel IDs or mention strings to reference channels.
Examples:
{redirect(dm)} # Signals to redirect the output to the user's DMs {redirect(reply)} # Signals that the output should be a reply to the invoking message {redirect(#general)} # Signals to redirect the output to the #general channel {redirect(123)} # Signals to redirect the output to the channel with the ID 123Response Attribute:
This block sets the following attribute on the
Responseobject:Note
This block will only set the
targetactionskey as shown above. It is up to the client to implement actual redirection behaviour, including what constitutes a validchannelinput (a client may choose to only accept IDs and reject channel names, for example).
- class ya_tagscript.blocks.SilenceBlock[source]
Bases:
BlockABCSignal to suppress the output of command blocks in this script. This should not affect the normal output of the script.
This block may be placed anywhere in a script.
The block is idempotent, so it only needs to be used once. Additional uses have the same effect of setting the “silent” actions key to
True.There is no way to “unset” this key once a silence block has been used.
Usage:
{silent}Aliases:
silent,silenceParameter:
NonePayload:
NoneExamples:
{silent} # Signals to suppress the outputs of all command blocks in the scriptResponse Attribute:
This block sets the following attribute on the
Responseobject:
Conditional Blocks
- class ya_tagscript.blocks.AllBlock[source]
Bases:
BlockABCThis block checks that all provided expressions are true.
Multiple boolean expressions in the parameter must be separated by
|at “zero-depth”, meaning|cannot be added dynamically. See the examples for clarification.The payload includes the message the block should output.
To provide outputs for both the success and failure cases, the payload must be split by
|at “zero-depth”. The part before the|represents the success case, the part after represents the failure case.If no
|can be found at “zero-depth”, the entire payload represents the success case, with no output being returned for the failure case.If the string for a given case is empty, no output is returned for it.
Usage:
{all(<expression|expression|...>):<message>}Aliases:
all,andParameter:
expression(required)Payload:
message(required)Examples:
# note how | is at "zero-depth" for the expressions and the responses {all({args}>=100|{args}<=1000):You picked {args}.|You must provide a number between 100 and 1000.} # if {args} is 52 You must provide a number between 100 and 1000. # if {args} is 282 You picked 282. {all(1==1|2==1):This is my success case message} # since these conditions fail and no failure case message is defined, no output # is produced {all(1==1|hi==hi):|This is my failure case message} # since the message is empty before the |, meaning no success case message is # defined, no output is produced # If the payload is fully nested, it is considered the success case message # Here, it is obviously _intended_ to be split by the IfBlock but that does not # happen due to the "zero-depth" separator requirement in payloads {=(msgs):Success msg|Failure msg} {all(true|1==1):{msgs}} # Success msg|Failure msg
- class ya_tagscript.blocks.AnyBlock[source]
Bases:
BlockABCThis block checks that at least one of the provided expressions is true.
Multiple boolean expressions in the parameter must be separated by
|at “zero-depth”, meaning|cannot be added dynamically. See the examples for clarification.The payload includes the message the block should output.
To provide outputs for both the success and failure cases, the payload must be split by
|at “zero-depth”. The part before the|represents the success case, the part after represents the failure case.If no
|can be found at “zero-depth”, the entire payload represents the success case, with no output being returned for the failure case.If the string for a given case is empty, no output is returned for it.
Usage:
{any(<expression|expression|...>):<message>}Aliases:
any,orParameter:
expression(required)Payload:
message(required)Examples:
# note how | is at "zero-depth" for the expressions and the responses {any({args}==hi|{args}==hello|{args}==heyy):Hello {user}!|How rude.} # if {args} is hi Hello username#1234! # if {args} is what's up! How rude. {any(1==2|0>1):This is my success case message} # since these conditions fail and no failure case message is defined, no output # is produced {any(1==1|2<5):|This is my failure case message} # since the message is empty before the |, meaning no success case message is # defined, no output is produced # If the payload is fully nested, it is considered the success case message # Here, it is obviously _intended_ to be split by the IfBlock but that does not # happen due to the "zero-depth" separator requirement in payloads {=(msgs):Success msg|Failure msg} {any(1==1|abc!=abc):{msgs}} # Success msg|Failure msg
- class ya_tagscript.blocks.IfBlock[source]
Bases:
BlockABCThis block checks whether the provided condition is true or not and then returns the appropriate message.
The payload includes the message the block should output.
To provide outputs for both the success and failure cases, the payload must be split by
|at “zero-depth”. The part before the|represents the success case, the part after represents the failure case.If no
|can be found at “zero-depth”, the entire payload represents the success case, with no output being returned for the failure case.If the string for a given case is empty, no output is returned for it.
Usage:
{if(<condition>):<message>}Aliases:
ifParameter:
condition(required)Payload:
message(required)Examples:
{if({args}==63):You guessed it! The number I was thinking of was 63!|Too {if({args}<63):low|high}, try again.} # if args is 63 You guessed it! The number I was thinking of was 63! # if {args} is 73 Too high, try again. # if {args} is 14 Too low, try again. {if(false):This is my success case message} # since this condition fails and no failure case message is defined, no output # is produced {if(true):|This is my failure case message} # since the message is empty before the |, meaning no success case message is # defined, no output is produced # If the payload is fully nested, it is considered the success case message # Here, it is obviously _intended_ to be split by the IfBlock but that does not # happen due to the "zero-depth" separator requirement in payloads {=(msgs):Success msg|Failure msg} {if(true):{msgs}} # Success msg|Failure msgSupported condition operators:
Operator
Check
Example
Description
==equality
a==a
value 1 is equal to value 2
!=inequality
a!=b
value 1 is not equal to value 2
>greater than
5>3
value 1 is greater than value 2
<less than
4<8
value 1 is less than value 2
>=greater than or equality
10>=10
value 1 is greater than or equal to value 2
<=less than or equality
5<=6
value 1 is less than or equal to value 2
trueconstant true
true
always true
falseconstant false
false
always false
Discord Blocks
- class ya_tagscript.blocks.CooldownBlock[source]
Bases:
BlockABCThis block implements cooldowns for running a tag.
The parameter requires two values:
rateandper, split by|such that the parameter looks likerate|per.ratespecifies the number of times the tag can be used withinperseconds.The payload requires a
keyvalue, which is used to store the cooldown. The key should be a unique string. For example, if a channel’s ID is used as the key, the cooldown will apply to that channel. Using the same tag in a different channel will have a separate cooldown with the samerateandpervalues.The payload also supports an optional
messagevalue, which is displayed when the cooldown is exceeded. If provided, it must be split from thekeyby|such that the payload iskey|message. If no message is provided, a default message is used. The cooldown message supports two placeholders:{key}and{retry_after}.Usage:
{cooldown(<rate>|<per>):<key>[|message]}Aliases:
cooldownParameter:
rate(required),per(required)Payload:
key(required),message(optional)Examples:
{cooldown(1|10):{user(id)}} # If the tag user uses the tag more than once in 10 seconds: # The bucket for 741074175875088424 has reached its cooldown. Retry in 3.25 seconds. {cooldown(3|3):{channel(id)}|Slow down! This tag can only be used 3 times per 3 seconds per channel. Try again in **{retry_after}** seconds.} # If the tag is used more than 3 times in 3 seconds in a channel: # Slow down! This tag can only be used 3 times per 3 seconds per channel. Try again in **0.74** seconds.
- class ya_tagscript.blocks.EmbedBlock[source]
Bases:
BlockABCThis block includes an embed in the tag response.
There are two ways to use the embed block: manually inputting the accepted embed attributes or using properly formatted embed JSON from an embed generator.
The JSON method allows complete embed customization (including setting attributes not supported by the manual method here), while the manual method provides control over individual attributes without requiring the entire block to be defined at once.
Manual:
The following embed attributes can be set manually:
author(see notes below)titledescriptioncolorurlthumbnailimagefooter(see notes below)field(see notes below)timestamp
Note
Some attributes expect a specially formed payload, these are explained below:
author: The payload must be 1, 2, or 3 parts in size, with parts split by|. The name is required, the other attributes are optional. If a name and an icon should be used without providing a website URL, leave the website URL empty but keep the|on either side.Valid
authorformats:{embed(author):name} {embed(author):name|website url} {embed(author):name|website url|icon url} # Note how the website url is left empty but the | are kept on either side {embed(author):name||icon url}footer: The payload must be 1 or 2 parts in size, with parts split by|. The text is required, the icon URL is optional.Valid
footerformats:{embed(footer):text} {embed(footer):text|icon URL}field: The payload must be 2 or 3 parts in size, with parts split by|. The name and value are required, the inline status is optional. If inline is not set explicitly, it defaults toFalse.Valid
fieldformats:{embed(field):name|value} {embed(field):name|value|true} {embed(field):name|value|false}
Changed in version 1.5: The specially formed attributes (
author,footer,field) now have a “zero-depth” requirement for the|separating their attributes (see below).Caution
With the introduction of zero-depth restrictions on the
EmbedBlockin v1.5.0, nested payloads are no longer supported. Because bothauthorandfooterhave valid formats which don’t require|at all (i.e. justnameforauthoror justtextforfooter), they will treat any payload without|at zero-depth as data for theirnameortextattribute only.Incorrect example:
{assign(author_payload):some name|https://website.example} {assign(footer_payload):some text|https://website.example/icon.png} {embed(author):{author_payload}} {embed(footer):{footer_payload}}This would result in the following Embed attributes:
embed.author.name:"some name|https://website.example"embed.author.url:Noneembed.author.icon_url:None(expected)embed.footer.text:"some text|https://website.example/icon.png"embed.footer.icon_url:None
The correct thing to do is this:
{embed(author):some name|https://website.example} {embed(footer):some text|https://website.example/icon.png}This would result in the following correct Embed attributes:
embed.author.name:"some name"embed.author.url:"https://website.example"embed.author.icon_url:None(expected)embed.footer.text:"some text"embed.footer.icon_url:"https://website.example/icon.png"
Usage:
{embed(<attribute>):<value>}Aliases:
embedParameter:
attribute(required)Payload:
value(required)Examples:
{embed(color):#37b2cb} {embed(title):Rules} {embed(description):Follow these rules to ensure a good experience in our server!} {embed(field):Rule 1|Respect everyone you speak to.|false} {embed(footer):Thanks for reading!|{guild(icon)}} {embed(timestamp):1681234567}
JSON:
Usage:
{embed(<json>)}Aliases:
embedParameter:
json(required)Payload:
None(ignored if JSON is used)Examples:
# Note how the JSON sits entirely within the block's parameter section, even # when split across several lines. {embed({"title":"Hello!", "description":"This is a test embed."})} {embed({ "title":"Here's a random duck!", "image":{"url":"https://random-d.uk/api/randomimg"}, "color":15194415 })}Both methods can be combined to create an embed in a tag. For example, JSON can be used to create an embed with fields, and the embed title can be set later.
Examples:
{embed({"fields":[{"name":"Field 1","value":"field description","inline":false}]})} {embed(title):my embed title}Response Attribute:
This block sets the following attribute on the
Responseobject:actionsactions["embed"]:discord.Embed— The constructeddiscord.Embed
Note
This block only sets the
embedactions key as shown above. It is up to the client to actually send thediscord.Embedobject being constructed.
Flow Blocks
- class ya_tagscript.blocks.BreakBlock[source]
Bases:
BlockABCThis block forces the tag output to only include the payload of this block if the provided condition evaluates to true. If no payload is provided, the tag output will be empty.
Caution
Unlike the
StopBlock, which halts all TagScript processing and returns its message, theBreakBlockcontinues the processing of subsequent blocks.This means all subsequent blocks may still result in their side effects (if any). For example, a
CommandBlockthat follows a triggeredBreakBlockwill still cause the command to be listed in the"commands"key of theResponse’sactionsattribute, which could cause erroneous command execution by a consuming client.Usage:
{break(<condition>):[message]}Aliases:
break,short,shortcircuitParameter:
condition(required)Payload:
message(optional)Examples:
{break({args}==):You did not provide any input.}
- class ya_tagscript.blocks.ShortcutRedirectBlock(shortcut_for: str)[source]
Bases:
BlockABCThis block acts as a shortcut to redirect processing to another block.
Specifically, this block behaves as if the number was passed as the parameter to the other block (see examples). The
declarationmust be a number, any otherdeclarationwill be rejected.Usage:
{<number>}Aliases: N/A
Parameter:
NonePayload:
NoneExamples:
# (Python) With a ShortcutRedirectBlock defined and provided to an interpreter instance as such: ShortcutRedirectBlock("args") # (TagScript) this block redirects to the "args" variable which contains "hello world" {1} # hello # (TagScript) this is a shortcut to the functionally identical version: {args(1)} # hello
- class ya_tagscript.blocks.StopBlock[source]
Bases:
BlockABCThis block stops tag processing if the provided parameter evaluates to true.
If a payload is provided and the parameter condition evaluates to True, the payload will be returned as the response message. Otherwise, an empty string will be returned.
Caution
Unlike the
BreakBlock, which continues processing, theStopBlockimmediately aborts all further processing if its condition evaluates toTrueby means of raising an internal exception that is caught by the interpreter.This means no subsequent blocks will be interpreted and none of their side effects will occur. For example, a
CommandBlockthat comes after a triggeredStopBlockwill NOT have its commands added to theResponse’sactionsattribute.Usage:
{stop(<condition>):[message]}Aliases:
stop,halt,errorParameter:
condition(required)Payload:
message(optional)Examples:
{stop({args}==):You must provide arguments for this tag.} # Enforces providing arguments for a tag
Limiter Blocks
- class ya_tagscript.blocks.BlacklistBlock[source]
Bases:
BlockABCSignals to blacklist specific channels or roles, preventing the tag from being used in the specified channels or by users with the specified roles.
If an invocation should be blocked, the optional response payload can be sent.
Note
The blacklist items can be any strings, regardless of their validity as channel or role identifiers. It is up the client to validate the list of blacklisted items.
This block does not interrupt the interpretation of the tag; subsequent blocks are still executed, and the response output continues to be built.
Usage:
{blacklist(<blocked>):[response]}Aliases:
blacklistParameter:
blocked(required)Payload:
response(optional)Examples:
{blacklist(Muted)} # Blacklists the "Muted" channel or role {blacklist(#support):This tag is not allowed in #support.} # Blacklists the #support channel or role with a custom response message {blacklist(Tag Blacklist, 668713062186090506):You are blacklisted from using tags.} # Blacklists multiple roles or channels with a custom response messageResponse Attribute:
This block sets the following attribute on the
Responseobject:Note
This block only adds the blacklist information in the
blacklistactions key as shown above. It is the responsibility of the client to implement the actual blacklist blocking system. It is also the client’s responsibility to prevent side effects like commands, reactions, etc. from being executed if the tag execution is blacklisted somehow.
- class ya_tagscript.blocks.RequireBlock[source]
Bases:
BlockABCSignals to require specific channels or roles, ensuring the tag can only be used in the specified channels or by users with the specified roles or in the specified channels.
If an invocation should be blocked, the optional response payload can be sent.
Note
The required items can be any strings, regardless of their validity as channel or role identifiers. It is up the client to validate the list of required items.
This block does not interrupt the interpretation of the tag; subsequent blocks are still executed, and the response output continues to be built. If the user does not meet the requirements, an optional response message can be sent.
Usage:
{require(<required>):[response]}Aliases:
require,whitelistParameter:
required(required)Payload:
response(optional)Examples:
{require(Moderator)} # Requires the "Moderator" channel or role {require(#general, #bot-cmds):This tag can only be run in #general and #bot-cmds.} # Requires the #general and #bot-cmds channels or roles with a custom response message {require(757425366209134764, 668713062186090506, 737961895356792882):You aren't allowed to use this tag.} # Requires the specified channel or role IDs with a custom response messageResponse Attribute:
This block sets the following attribute on the
Responseobject:Note
This block only adds the requirement information in the
requiresactions key as shown above. It is the responsibility of the client to implement the actual requirement enforcement system. It is also the client’s responsibility to prevent side effects like commands, reactions, etc. from being executed if the tag execution does not meet the requirements and is therefore blocked.
List Blocks
- class ya_tagscript.blocks.CycleBlock[source]
Bases:
BlockABCThis block retrieves the element from the payload at the index specified by the parameter, looping around to the beginning of the payload if the index is out of bounds (roughly:
index = index % len(payload)).This block is 0-indexed (index 0 returns the first element) and allows for backwards indexing using negative values.
Caution
The payload is interpreted in its entirety before it is split on tildes (
~) and the entry at the provided index is returned. This means any blocks contained in the payload will be interpreted as well.Usage:
{cycle(<number>):<payload>}Aliases:
cycleParameter:
number(required)Payload:
payload(required)Examples:
{cycle(1):apple~banana~secret third thing} # banana {cycle(-3):apple~banana~secret third thing} # apple {cycle(10):apple~banana~secret third thing} # banana # (assume {items} = "1st~2nd~3rd") {cycle(0):{items}} # 1stChanged in version 1.1: The block no longer has a “zero-depth” restriction (see Caution above)
- class ya_tagscript.blocks.ListBlock[source]
Bases:
BlockABCThis block retrieves the element from the payload at the index specified by the parameter. If the index is out of bounds, it returns an empty string.
This block is 0-indexed and allows for backwards indexing using negative values.
Caution
The payload is interpreted in its entirety before it is split on tildes (
~) and the entry at the provided index is returned. This means any blocks contained in the payload will be interpreted as well.Usage:
{list(<number>):<payload>}Aliases:
listParameter:
number(required)Payload:
payload(required)Examples:
{list(1):apple~banana~secret third thing} # banana {list(-2):apple~banana~secret third thing} # banana {list(10):apple~banana~secret third thing} # (empty string) # (assume {items} = "1st~2nd~3rd") {list(0):{items}} # 1stChanged in version 1.1: The block no longer has a “zero-depth” restriction (see Caution above)
Math Blocks
- class ya_tagscript.blocks.MathBlock[source]
Bases:
BlockABCThis block evaluates mathematical expressions provided in the payload.
All supported constants and functions are listed below.
The output is always rounded to 15 decimal places, unless one of the decimal-free methods mentioned below is used, in which case no decimal places are returned.
For most operations and functions, if a whole number is returned, the number will still carry a
.0with it (e.g.1+2=3.0). The only functions which will never output trailing decimals like that are:sgn— (only returns-1for negative numbers,0for zero, or1for positive numbers)trunc(a)— (Truncates a by throwing away all decimal places, e.g.4.999->4)round(a)— (with no precision argument,ais rounded to the nearest integer, so4.7->5)
Note
round(a, n)will always return decimal places, including.0for precision 0, i.e.round(4, 0)->4.0)Usage:
{math:<payload>}Aliases:
math,m,+,calcParameter:
NonePayload:
payload(required)Examples:
{math:1 + 2 * 3} # 7.0 {math:PI * 2} # 6.283185307179586 {math:round(10 / 3, 2)} # 3.33Supported Mathematical Expressions:
Expression
Description
Notes
a + bAddition
a - bSubtraction
a * bMultiplication
a / bDivision
a % bModulo operation (remainder of
a / b)a ^ bExponentiation (
ato the power ofb)sin(a)Sine function
sinh(a)Hyperbolic sine function
cos(a)Cosine function
cosh(a)Hyperbolic Cosine function
tan(a)Tangens function
tanh(a)Hyperbolic Tangens function
exp(a)Exponential function (
e^a)ln(a)Natural logarithm function (log base e)
log(a)Logarithmic function (log base 10)
log2(a)Logarithmic function (log base 2)
sqrt(a)Square root of
ahypot(a,b)Hypotenuse of a right triangle with sides
aandbabs(a)Absolute value of
asgn(a)Signum function:
-1ifa<0,0ifa==0,1ifa>0no decimals (-1 or 0 or 1)
round(a)Rounds
ato the nearest integerno decimals
round(a,n)Rounds
atondecimal placestrunc(a)Truncates
ato its integer partno decimals
E,eEuler’s number, rounded to 15 decimal places
2.718281828459045
PI,pi,πPi, rounded to 15 decimal places
3.141592653589793
TAU,tau,τTau, rounded to 15 decimal places
6.283185307179586
If you’re curious, here is The Numeric String Parser.
- class ya_tagscript.blocks.OrdinalBlock[source]
Bases:
BlockABCReturns the ordinal form of a number, including commas as thousands separators.
If the payload is not a number, the block is rejected.
If a parameter is provided, it must be one of the following:
corcomma: Adds commas as thousands separators but no indicatoriorindicator: Appends the ordinal indicator (e.g.,stfor 1st,ndfor 2nd) but does not include commas as thousands separators
Usage:
{ord(["c"|"comma"|"i"|"indicator"]):<number>}Aliases:
o,ordParameter: one of
c,comma,i,indicator(optional)Payload:
number(required)Examples:
{ord:1000} # Returns: 1,000th {ord(c):1213123} # Returns: 1,213,123 {ord(i):2022} # Returns: 2022nd
Meta Blocks
- class ya_tagscript.blocks.CommentBlock[source]
Bases:
BlockABCThis block can be used to add comments in the script that are ignored during processing and removed from the output.
Caution
Everything inside this block is ignored, including nested blocks.
Usage:
{comment([parameter]):[text]}Aliases:
/,//,commentParameter:
parameter(ignored)Payload:
text(ignored)Examples:
{comment:My Comment!} # outputs nothing {comment(Something):My Comment!} # outputs nothing {comment:{cmd:echo hello world}}{cmd:ping} # outputs nothing and the "echo" command block will NOT be triggered BUT the # "ping" command WILL be set correctly because it is not nested inside the # comment block
- class ya_tagscript.blocks.DebugBlock[source]
Bases:
BlockABCThis block will output a dictionary of all variables known at the time of processing under the
debugkey of theextra_kwargsattribute of theResponseobject.Separate the variables you want to include or exclude with a comma (
,) or a tilde (~). These separations must be consistent (only commas or only tildes) and be located at “zero-depth”, i.e. only separators present before interpretation will be used for splitting..If no parameter and no payload are provided, all variables will be included. (
{debug}, which is equivalent to{debug(exclude):})If no parameter is provided but a payload exists, only variables included in the payload will be included. (
{debug:my_var}, which is equivalent to:{debug(include):my_var})Note
This should always be placed at the very bottom, it will not include any variables (re-)defined after its location in the script.
Usage:
{debug(["i"|"include"|"e"|"exclude"]):<variables>}Aliases:
debugParameter: one of
i,include,e,excludePayload:
variablesExamples:
# In the following example, the desired output is "Hello" but instead "Bye" is returned: {=(something):Hello/World} {=(parsed):{something(1)}} {if({parsed}==Hello):Hello|Bye} # Bye # We can investigate by adding the DebugBlock at the end of the script: {debug} # This will return a dictionary with all known variable names and their values # at the time of this block's processing. # In this example, the dictionary would look like this (Python) { "something": "Hello/World", "parsed": "Hello/World", } # Now we can see that the definition of parsed is missing a custom delimiter in # order to split the value on the slash / # We can fix this: {=(something):Hello/World} {=(parsed):{something(1):/}} {if({parsed}==Hello):Hello|Bye} # Hello #### # Note how the variables names are split by zero-depth commas and not in a nested block: # (assume these exist) {debug:my_var,another var}Response Attribute:
This block sets the following attribute on the
Responseobject:extra_kwargsextra_kwargs["debug"]:dict[str, str]— A dictionary with all known variables at the time of interpretation (variable names are mapped to their values)
Note
This block only sets the
debugextra_kwargskey as shown above. It is the responsibility of the client to somehow surface this data to the user, if this is desired.
RNG Blocks
- class ya_tagscript.blocks.FiftyFiftyBlock[source]
Bases:
BlockABCThis block has a 50% change of returning the (interpreted) payload, and 50% chance of returning an empty string.
Usage:
{5050:<message>}Aliases:
5050,50,?Parameter:
NonePayload:
message(required)Examples:
I pick {if({5050:.}!=):heads|tails}! # I pick heads! (50% chance)
- class ya_tagscript.blocks.RandomBlock[source]
Bases:
BlockABCThis block picks a random item from a list split by commas (
,) or tildes (~).The separators must be consistent (only commas or only tildes).
Note
The payload is interpreted before splitting at the separator, so this block does not have a “zero-depth” requirement.
An optional seed can be provided as the parameter to always choose the same item when using that seed.
Items can be weighted differently by adding a weight and
|to the item(s). Not all items need to be weighted. If no weight is provided, the item will be handled as if its weight was 1.Usage:
{random([seed]):<list>}Aliases:
random,rand,#Parameter:
seed(optional)Payload:
list(required)Examples:
{random:Carl,Harold,Josh} attempts to pick the lock! # Possible Outputs: # Josh attempts to pick the lock! # Carl attempts to pick the lock! # Harold attempts to pick the lock! {random:5|Cool,3|Lame} # 5 to 3 odds of "Cool" vs "Lame" {random:first,10|second,third,4|fourth} # 10:4:1:1 odds of "second" vs "fourth" vs "first" vs "third" {assign(items):hello~hi~good morning} {assign(seed):123} {random({seed}):{items}} # 5:1:1 odds for "good morning" vs "hello" vs "hi" # but because the is seeded with "123": (Output below line) # --- # good morning
- class ya_tagscript.blocks.RangeBlock[source]
Bases:
BlockABCThis block picks a random number from a range of numbers separated by
-.The number range is inclusive (i.e.
[lowest, highest]), so the bounding numbers can be returned as well. Both bounds can be negative.If the lower bound is larger than the upper bound, the block will return an error message.
Behaviour differs between aliases:
range: Returns integers (bounds are truncated to integers)rangef: Returns floating point numbers
An optional seed can be provided as the parameter to always choose the same item when using that seed.
Usage:
{range([seed]):<lowest>-<highest>}Aliases:
range,rangefParameter:
seed(optional)Payload:
lowest-highest(both are numbers) (required)Examples:
Your lucky number is {range:10-30}! # Your lucky number is 14! {=(height):{rangef:5-7}} I am guessing your height is {height}ft. # I am guessing your height is 5.3ft.
String Blocks
- class ya_tagscript.blocks.CaseBlock[source]
Bases:
BlockABCThis block modifies the case of the provided payload.
Behaviour differs between aliases:
lower: Converts the payload to lowercaseupper: Converts the payload to uppercase
Usage:
{lower:<text>}or{upper:<text>}Aliases:
lower,upperParameter:
NonePayload:
text(required)Examples:
{lower:SCREAMING!} # screaming! {upper:I am talking.} # I AM TALKING.
- class ya_tagscript.blocks.JoinBlock[source]
Bases:
BlockABCThis block replaces spaces in the payload with the provided separator.
If the parameter is missing, the block will be rejected.
To use this block as a pseudo-concatenation block, include the parentheses with no content between them (see examples below).
Usage:
{join(<separator>):<text>}Aliases:
joinParameter:
separator(required; can be empty)Payload:
text(required)Examples:
{join(.):Dot notation is funky} # Dot.notation.is.funky {join():I can masquerade as a concat block} # Icanmasqueradeasaconcatblock
- class ya_tagscript.blocks.PythonBlock[source]
Bases:
BlockABCThis block supports string operations like containment, word matching, and positional indexing in the payload.
Behaviour differs between aliases:
contains: Checks if the parameter matches any word in the payload, split by whitespace.in: Checks if the parameter exists anywhere in the payload.index: Finds the position of the parameter in the payload, split by whitespace. If the parameter is not found, it returns -1.
Usage:
{contains(<string>):<payload>}Aliases:
contains,in,indexParameter:
string(required)Payload:
payload(required)Examples:
{contains(mute):How does it feel to be muted?} # false {contains(muted?):How does it feel to be muted?} # true {in(apple pie):banana pie apple pie and other pie} # true {in(mute):How does it feel to be muted?} # true {in(a):How does it feel to be muted?} # false {index(food.):I love to eat food. everyone does.} # 4 {index(pie):I love to eat food. everyone does.} # -1Changed in version 1.3: This block was moved from
blocks.conditionaltoblocks.strings. Users should import blocks by doingfrom ya_tagscript.blocks import PythonBlockso this change should affect very few users.
- class ya_tagscript.blocks.ReplaceBlock[source]
Bases:
BlockABCThis block replaces all occurrences of a substring in the payload with another substring.
The substring to replace and its replacement are provided as a comma-separated pair in the parameter. If
newis omitted or empty, the substring will be removed.The
oldsubstring is case-sensitive, e.g.Ais not replaced ifoldisa, etc.Usage:
{replace(<old>,<new>):<text>}Aliases:
replaceParameter:
oldORold,new(required;newcan be empty)Payload:
text(required)Examples:
{replace(o,i):welcome to the server} # welcime ti the server {replace(1,6):{args}} # if {args} is 1234567 # 6234567 {replace(, ):Test} # T e s t {replace(an):An amazing Canadian banana} # An amazing Cadi ba
- class ya_tagscript.blocks.SubstringBlock[source]
Bases:
BlockABCThis block extracts a substring from the payload based on the parameter.
The parameter specifies the start and end indices of the substring, separated by a hyphen (
-). The starting index is inclusive and the ending index is exclusive.If only one index is provided, the rest of the payload is returned starting from this index.
This block is 0-indexed. Negative indices are supported.
Note
The indices behave like normal Python slices. That means an index that is too large will return an empty string and an index that is too negative will return the entire string (see examples below).
Usage:
{substring(<start>-<end>):<text>}Aliases:
substring,substrParameter:
<start>OR<start>-<end>(both numbers) (required)Payload:
text(required)Examples:
{substring(1-4):testing} # est {substring(6):hello world} # world {substring(100):hello world} # (an empty string is returned) {substring(-100):hello world} # hello world
- class ya_tagscript.blocks.URLDecodeBlock[source]
Bases:
BlockABCThis block decodes a URL-encoded string back into its original format.
The payload is the URL-encoded string to be decoded.
The parameter determines the decoding style: if the parameter is
+, both%20and+are decoded as a space; otherwise, only%20is decoded as a space. Other character sequences are decoded as normal in either case.Usage:
{urldecode(<parameter>):<text>}Aliases:
urldecodeParameter:
+(optional) (all other values are ignored)Payload:
text(required)Examples:
{urldecode:hello%20world} # hello world {urldecode(+):Hello+there.+General+Kenobi.} # Hello there. General Kenobi. {urldecode(+):this%20is+a%20combined+test} # this is a combined test {urldecode:this+will+keep+the+plus+signs} # this+will+keep+the+plus+signs
- class ya_tagscript.blocks.URLEncodeBlock[source]
Bases:
BlockABCThis block encodes a string into a URL-safe format.
The payload is the string to be encoded.
The parameter determines the encoding style: if the parameter is
+, spaces are encoded as+; otherwise, spaces are encoded as%20.Usage:
{urlencode(<parameter>):<text>}Aliases:
urlencodeParameter:
+(optional) (all other values are ignored)Payload:
text(required)Examples:
{urlencode:covid-19 sucks} # covid-19%20sucks {urlencode(+):im stuck at home writing docs} # im+stuck+at+home+writing+docs # the following tagscript can be used to search up tag blocks # assume {args} = "command block" <https://ya-tagscript.readthedocs.io/en/latest/search.html?q={urlencode(+):{args}}&check_keywords=yes&area=default> # <https://ya-tagscript.readthedocs.io/en/latest/search.html?q=command+block&check_keywords=yes&area=default>
Time Blocks
- class ya_tagscript.blocks.StrfBlock[source]
Bases:
BlockABCThis block formats dates and times using the provided format string.
Behaviour differs between aliases:
unix: Returns the current time as a seconds-resolution integer timestampstrf: Returns the current time (or time given in the parameter) formatted according to the format string in the payload
The payload is the format string to be used with
strftime().See also
- Python’s
datetimedocumentation
Note
The
unixalias does not take any format string payload and always returns the current Unix Epoch timestamp in seconds-resolution (i.e. seconds since 1970-01-01 at 00:00:00 UTC).The parameter can be a timestamp or an ISO 8601 string. Many other common formats are supported as well but no exhaustive list can be provided. When in doubt, try it and see.
If no parameter is provided, the block defaults to the current time.
Usage:
{strf(<parameter>):<format>}Aliases:
strf,unixParameter:
timestampordatetime string(optional)Payload:
format(required forstrf)Examples:
{strf:%Y-%m-%d} # 2000-01-01 {strf({user(timestamp)}):%c} # Sat Jan 1 00:00:00 2000 {strf(1735689600):%A %d, %B %Y} # Wednesday 01, January 2025 {strf(2025-01-01T01:02:00.999):%H:%M %d-%B-%Y} # 01:02 01-January-2025 {unix} # 946684800 # (this is 2000-01-01T00:00:00+00:00)
- class ya_tagscript.blocks.TimedeltaBlock(time_humanize_fn: Callable[[datetime, datetime], str] | None = None)[source]
Bases:
BlockABCThis block calculates the difference between two datetime values and formats it into a human-readable string.
The payload provides the “target” time, i.e. the time for which to calculate the distance from the “origin” time.
The optional parameter provides the “origin” time, i.e. the time to use as a starting point for the calculation. When no parameter is provided, this defaults to the current date and time.
Whether a date & time is provided via the parameter or payload will influence the direction of the calculation (i.e. whether the time difference is considered “in the past” or “in the future”)
The block supports ISO 8601 strings, timestamps, and other common datetime formats. If only a time is provided, it is assumed to be for the current UTC date.
Formats may be mixed between the parameter and the payload.
Usage:
{timedelta(<origin datetime>):<target datetime>}Aliases:
timedelta,tdParameter:
origin datetime(optional)Payload:
target datetime(required)Examples:
# All examples assume the default humanize function is used {timedelta(2025-01-01T00:00:00):30.01.2024} # 11 months and 2 days ago {timedelta:2024-08-31 00:00:00.000000+00:00} # 4 years, 7 months, and 30 days # (if the current UTC time was 2020-01-01T00:00:00) {timedelta(1735689600):946694800} # 24 years, 11 months, and 30 days ago # (1735689600 = Wed, 01 Jan 2025 00:00:00 +0000) # ( 946694800 = Sat, 01 Jan 2000 02:46:40 +0000) {timedelta(19:30):21:00} # 1 hour and 30 minutes- __init__(time_humanize_fn: Callable[[datetime, datetime], str] | None = None) → None[source]
- Parameters:
time_humanize_fn (
Callable[[datetime, datetime], str]|None) –A function that takes two
datetimeobjects and returns astrexpressing the distance between the two.If set to
None(the default), an implementation using the dateutil package and itsrelativedeltais used which returns the three largest nonzero units of time in order. Example outputs may be:1 year
4 months and 43 seconds
9 days, 1 hour, and 8 seconds
Variable Blocks
- class ya_tagscript.blocks.AssignmentBlock[source]
Bases:
BlockABCThis block assigns a value to a variable within the context of the script.
The payload represents the value to be assigned, while the parameter specifies the variable name. The variable can then be referenced elsewhere in the script.
Usage:
{assign(<variable name>):<value>}Aliases:
=,assign,let,varParameter:
variable name(required)Payload:
value(required)Examples:
{assign(prefix):!} The prefix here is `{prefix}`. # The prefix here is `!`. {assign(day):Monday} {if({day}==Wednesday):It's Wednesday my dudes!|The day is {day}.} # The day is Monday.
- class ya_tagscript.blocks.LooseVariableGetterBlock[source]
Bases:
BlockABCThis block attempts to fetch the value of a variable declared in the script. If the variable exists, its value is returned; otherwise, the block is rejected and not interpreted at all.
Note
In contrast to the
StrictVariableGetterBlock, this block checks for the existence of the variable only during processing. The earlier call toLooseVariableGetterBlock.will_accept()always returnsTrue.Usage:
{<variable name>}Aliases: N/A
Parameter:
NonePayload:
NoneExamples:
# Variables can be assigned with the AssignmentBlock # or supplied to the interpreter via the seed_variables kwarg {assign(user_name):Carl} {user_name} # Carl {non_existent_variable} # This block is rejected because the variable doesn't exist (Output below line): # --- # {non_existent_variable}See also
- Retrieving partial substrings with parameters
How to retrieve only parts of a string variable (part of the
StringAdapterdocumentation).
- class ya_tagscript.blocks.StrictVariableGetterBlock[source]
Bases:
BlockABCThis block attempts to fetch the value of a variable declared in the script. If the variable exists, its value is returned; otherwise, the block is rejected and not interpreted at all.
Note
In contrast to the
LooseVariableGetterBlock, this block checks for the existence of the variable during the earlierStrictVariableGetterBlock.will_accept()phase, rejecting the block early if the variable does not exist already.Usage:
{<variable name>}Aliases: N/A
Parameter:
NonePayload:
NoneExamples:
# Variables can be assigned with the AssignmentBlock # or supplied to the interpreter via the seed_variables kwarg {assign(user_name):Carl} {user_name} # Carl {non_existent_variable} # This block is rejected because the variable doesn't exist (Output below line): # --- # {non_existent_variable}See also
- Retrieving partial substrings with parameters
How to retrieve only parts of a string variable (part of the
StringAdapterdocumentation).