Home

Documentation Status

Attention

This is not affiliated in any way with Botlabs or Carl-bot.

Attention

Really would like to thank readthedocs.org for making this possible, thank you!

This is an unofficial guide to Carl-bot’s tagscript, started by _Leg3ndary#5759, you may view all contributors here.

Note

All of this documentation contains custom tagscript syntax highlighting through tagscript-ansi

{=(L1):{lower:{1}}}
{=(A2+):{replace(|, - ):{args(2+)}}}
{=(error):You must follow the `afk` command with either `on` or `off`.}
{=(on):add}
{=(off):del}
{=(template):c:ar {{L1}} {user(id)}>{if({L1}==on): {if({list(0):{join(,):{A2+}}}!=):{A2+}|{replace(|, - ):{user}} is afk right now, send them a PM or wait for them to return.}}}
{=(sel):{if({contains({L1}):on off}==false):error|{template}}}
{override}{{sel}}

Raffael#1372's AFK Tag

Tip

If you just want a quick refresher on blocks, this tag will contains everything you need to know: ?tse <block>

Note

This documentation is still under development.

Contributing

If you believe something here is incorrect or would like to add something else, submit a pull request on Github.

All help is appreciated! :)

Important

Please include your username#discriminator as well as your id 123456789012345 as you should have some experience with tagscript.

Note

If you do decide to contribute, make sure to check out Credits so you can be added!

A Basic Guide to Contributing

These docs use ReStructuredText or RST, it’s a fairly simple language that you can learn here RST Docs.

You could also take a look at the readthedocs sphinx theme for more info.

Finally tagscript parsing is here, though there’s not much to know.

Note

If you want to easily create tagscript you can do so by doing the following

.. tagscript::

    {=(Tagscript):Can go here}

This will generate the following

{=(Tagscript):Can go here}

Credits

Note

This page isn’t complete

Massive thanks to anyone who’s contributed to tagscript in Carl-bot’s Support Server, I’m working on figuring out why I can’t add you with profile pictures but you will be added.

Limits

There are many limits in tagscript, and some more when you use Carl.

Loops

You will not have access to loops in any way, there are a few exceptions, but in general if you want to loop through values and edit them, that won’t be possible.

Examples of blocks that you can use that have loop-like features:

{replace}
{join}

Tag Recursion

If you’re looking to save data through tag recursion by using tag add sadly this will not work, you’ll get the following message

Failed Loading Image.

Accessing Other Users Data

You will only be able to access 2 different users when using tags, and you must ping at least one of them.

Failed Loading Image.

Creating Tags

There are 2 different ways you can create tags, through the Dashboard or with commands

Failed Loading Image.

After selecting a server, head into the Tags section

Failed Loading Image.

Anatomy of Blocks

When we refer to blocks we mean anything that contains both an opening { and a closing }.

Warning

Carl-bot will always evaluate brackets so because of this behaviour, you may not have { or } in any block.

There is no way to bypass this while writing your code.

Block Names

Block names are what’s inside the curly brackets, these will always be the first thing after { and is mandatory for every block.

Note

An exception is made for variables in which you can literally define variables to be “blank” {=():}, if you don’t understand this, don’t worry, it’s not important right now.

Some examples include:

{user}
{command}
{let}

The name of the block will determine how the parameters and payload are evaluated.

Parameters and Payloads

Parameters

Parameters will be defined straight after the block name {block(PARAMETERS)}, parameters will usually let us alter the payload depending on what we put in it.

{user(PARAMETERS)}
{command(PARAMETERS)}
{let(PARAMETERS)}

Warning

You also may not have any ( or ) in parameters.

Payloads

Payloads will also be defined after the command name using a :, unless parameters were added, in that case, it will go straight after parameters instead. Payloads are the text that we want to alter/use.

{user(PARAMETERS):PAYLOAD}
{command:PAYLOAD}

Note

Payloads may contain :

Note

When working with conditional blocks such as if, or, or and, you may not be able to use vertical pipes |, as it can break the else condition.

Note

Remember that payloads and parameters can be optional, meaning all of these are possible with the right blocks.

{block(PARAMETERS)}
{block:PAYLOAD}
{block(PARAMETERS):PAYLOAD}

Examples

The blocks' parameter in this case is "avatar"
{user(avatar)}

The blocks' payload in this case is "lock server"
{command:lock server}

The blocks' parameter here is "tagscript", while the payload is "cool"
{let(tagscript):cool}

Important

It’s strongly advised that you familiarize yourself with basic anatomy to avoid common errors, this will also later be essential to understand more advanced concepts such as blanks and switches.

Default Variables

Defualt variables are variables that every tag will have defined.

Unix

{unix}

Returns the current unix time

Often used in conjunction with strf and timedelta blocks

Note

To use this outside of tags, add this to the top of your code {=(unix):{strf:%s}}

Warning

This is exclusive to tags.

Uses

{uses}

Returns how many times your tag was used

Warning

This is exclusive to tags.

Warning

This increments even if the tag fails to output/work, the only way to reset this is to delete and re-import the tag.

Mention

{mention}

Mentions the user who used the tag

Note

This is the same as {user(mention)}

Args/Message

Important

This is probably the most used and important block in tagscript, it’s what allows you to access what users put after an invocation.

In addition you will often need to parse this block, so it would be wise to check out Parsing.

{args}
{message}

What is after a tag invocation:

?foo bar baz

{args} will output bar baz

Note

If used in a trigger, this block will also contain the trigger invocation.

Digit Shorthands

{1}
{2}
{3} etc.

The main difference between args and message is how message has digit shorthands.

{args(1)} is equivalent to {1}
{args(2)} is equvalent to {2}

However digit shorthands are based upon the message variable, meaning if you change it, by redefining it, digit shorthands will now be based on that instead.

Note

If you don’t understand digit shorthands, don’t worry! They aren’t really used and it’s much more common to see people use {args(1)} over {1}!

Discord Objects

Discord related default variables

User/Target

{user}
{target}

{user(name)}
{target(avatar)}

One of the most used blocks is the target block, it allows you to access other users data.

user is the user who invoked the tag, while target is the first user that was pinged in the commands arguments. If no one is pinged, target is equivalent to user.

Note

It’s common to check if someone was pinged in the command, to do this you compare user against target

{if({user(id)}=={target(id)}):You need to ping someone|You pinged {target}}

Parameters/Properties

Parameters can be specified within parenthesis after the block name: {user(PARAMETER)} or {user(PARAMETER)}. When used without a parameter ({user} or {target}), the block will output the nickname of the user/target.

Parameter

Output

avatar

A link to the user’s avatar

icon

Same as avatar

id

The user’s ID

mention

@’s/Mentions the user

created_at

Date and time that the account was created in the form of yyyy-mm-dd HH:MM:SS

joined_at

Date and time that the user joined this server in the form of yyyy-mm-dd HH:MM:SS

color

The user’s hexadecimal role color with the leading # included

name

The user’s discord username

proper

The user’s username + discriminator/tag, example _Leg3ndary#5759

roleids

A list of every role (id) the user has from lowest to highest separated by a space

position

The user’s position in the role hierarchy, starts with 0 for @everyone and increases by 1 for each role in the server

Server

{server}

{server(roles)}

Contains details about the server

Parameters

Parameters can be specified within parenthesis after the block name: {server(PARAMETER)}. When used without a parameter ({server}), the block will output the server’s name.

Warning

Some of these are deprecated.

Parameter

Output

icon

A link to the server’s icon

id

The server’s ID

owner

The username + discriminator of the server owner

random

The username + discriminator of a random member

members

The number of members in the server

roles

The number of roles in the server

channels

The number of channels in the server

created_at

When the server was created in the format yyyy-mm-dd HH:MM:SS

[BROKEN] humans

The number of humans in the server. Currently returns the same as members.

[DEPRECATED] randomonline

The username + discriminator of a random online member

[DEPRECATED] randomoffline

The username + discriminator of a random offline member

[DEPRECATED] bots

The number of bots in the server

Channel

{channel}

{channel(topic)}

Contains details about the channel

Parameters

Parameters can be specified within parenthesis after the block name: {channel(PARAMETER)}. When used without a parameter ({channel}), the block will output the channel’s name.

Parameter

Output

id

The channel’s ID

topic

The channel’s topic

slowmode

The channel’s slowmode delay in seconds

position

The channel’s position, in the order of which channels were created, 0 being the first

mention

Clickable link to the channel

Meta

Meta blocks are blocks that will change a tags overall behaviour, this includes changing where it replies, deleting the invocation, and interacting with users.

Delete

{delete}
{del}

Deletes the message which invoked the commmand

Silent

{silent}
{silence}

Silences any command block outputs

Override

{override}

Overrides any permissions needed to run a command

Danger

Use this with caution.

Warning

This still respects hierarchy, for example if you’re trying to add a role to yourself, using carl, or someone who has a higher role then you. This will not work.

Direct Message

{dm}

This will instead send the output to a users direct messages (DMS)

Note

This won’t ever be able to send anything to another users dms. The bot will only dm you if you use a tag with this block in it.

Redirect

{redirect:channel_id}

Redirect will redirect the output to whatever channel id you provide

Warning

The user must have the send_messages permission for this to work, or you can add an override block

Require/Blacklist

Important

You can use technically use the role/channel name though it is heavily discouraged, if that name ever changes, the tag will cease to work properly, while using ids will stay the same forever.

{require(Optional Error Message):Required Roles, Channels}
{blacklist(Optional Error Message):Blacklisted Roles, Channels}

{require(You aren't a moderator, or you aren't using this in the right channel):209797471608635392,465563733981265921}
{blacklist(Muted users aren't allowed to use this command, if you aren't muted, use #bot-commands):469237398279159818,456625369974308866}

Require is the easiest way to require a user to have a role, or use it in a specific channel.

Blacklist is also an easy way for blacklisting certain channels and or roles from using tags.

Require Blocks: Separate the channels or roles by a , with no spaces inbetween, and as long as they have one of the roles, and one of the channels (If you have both) they will be able to use the tag.

Blacklist Blocks: Also separate the channels or roles by a , with no spaces inbetween, if they have any of the roles or are using it in any of the channels, the tag will output your error message

Parameters

{require(ERROR MESSAGE):209797471608635392}

{blacklist(ERROR MESSAGE):469237398279159818}

Note

This is optional, you can simply do {require:209797471608635392} or {blacklist:469237398279159818}

The error message that will output when the user doesn’t have one of the roles or isn’t using it in a channel listed.

The error message that will output when the user is using the tag when they have a role or are using it in a blacklisted channel.

Warning

If you do choose to omit the parameter for either blacklist or require, carl will react with a ⚠️ emoji instead, to avoid this simply make the error message a space like so

{require( ):209797471608635392} or {blacklist( ):469237398279159818}

Warning

This is exclusive to tags

Payload

{require(You aren't a moderator!):ID LIST}

{require(You can't use this command here!):ID LIST}

A list of role or channel ids separated by , with no spaces inbetween.

As long as the user using the tag has one of the role ids, and one of the channel ids (If you have both) they will be able to use the tag.

Important

When using blacklist, you can blacklist the server id to automatically break the tag if you want, this is most often used when you want to prevent an embed from posting

React(u)

{react: :turtle: :robot:}
{reactu: :turtle: :robot:}

React blocks will react to what carl outputs, while reactu blocks will react to the tags invocation.

Attention

In tags you’re limited to 1 reaction without premium, and 5 with premium

In triggers you’re limited to 3 reactions without premium, and 5 with premium *I believe

Payload

{react:EMOJI LIST}
{reactu:EMOJI LIST}

The emoji list should be separated by spaces, for custom discord emojis, send a \ in front of it and send it to a channel, use what you then see.

Commands

Caution

Want to stop a command block from conditionally running? Remember to use blanks!

{c:Command}
{cmd:role add _Leg3ndary Red}
{command:ban Carl-bot Useless bot}

Command blocks execute Carl’s commands, it’s what allows you to add roles, change nicknames, etc.

Note

Every server is limited to a maximum of one command block, an exception is made for premium servers who are allowed up to three.

Payload

{c:COMMAND YOU WANT TO RUN}

Tip

If you want to create an alias for an existing command, it’s as simple as creating a tag with the alias as it’s name and adding a command block with args

{c:COMMAND NAME {args}}

{c:mute {args}}

{c:ban {args}}

Warning

Tags aren’t able to run reactionrole commands nor can they run tag commands, eg tag add, or rr add

Control

Control blocks “control” what happens based on the condition we give it

Consider the following:

If I, am hungry, I will eat, if not, I will drink some water.

To convert this into tagscript we first create an if statement

{if}

Now we create our condition

{if(I==hungry)}

Now we add the payload or what will happen

{if(I==hungry):Eat}

Finally we add the else

{if(I==hungry):Eat|Drink}

Note

This just pseudo code! If you run this, it will always say Drink Water as I is not the same as hungry!

Boolean Operators (Parameters)

{if(CONDITION):true|false}

{if(carl==carl):true|false} -> true

{if(carl!=carl):true|false} -> false

{if(5>1):true|false} -> true

{if(5<1):true|false} -> false

This is how we determine what to do, in this case we just print out true or false

If the left side is exactly the same as the right side, space and case sensitive

If the left side is different from the right side, space and case sensitive

Greater than or equal too

Lesser than or equal too

Greater than

Lesser Than

Tip

An extremely common question, is how we check if a user was pinged!

We can easily check this by comparing the user id, to target id

{if({user(id)}=={target(id)}):You need to ping someone!|You pinged {target}}

Then/Else (Payload)

{if({user(id)}==235148962103951360):THEN|ELSE}

{if({uses}>10):This command has been used more then 10 times|This command has only been used {uses} times!}

{and({target}==Carl-bot|{target(id)}!=235148962103951360):How dare you impersonate me!}

The payload for conditional blocks can either be a then without an else, or both, you separate these with a pipe |.

If

{if(CONDITION):THEN|ELSE}

The simplest of conditional blocks, checks a singular condition.

Any/Or

{any(CONDITION|CONDITION|CONDITION):THEN|ELSE}

If you want to check if any condition out of whatever you provide are true, you can use an any block, just separate every condition with a |.

All/And

{and(CONDITION|CONDITION|CONDITION):THEN|ELSE}

Nearly identical to the any block, this block just checks if every condition you provide is true.

Break/Shortcircuit

{break(CONDITION):THEN}

When used, if the condition given is true, the tags text output will only be whatever you put as the payload.

Danger

This will not prevent command blocks from running or the embed from the embed builder from sending.

Data Storage/Variables

Note

Tags cannot store data between invocations through regular means, you have other options though! See here.

{=(VARIABLE NAME):VARIABLE CONTENT}

{=(tag_name):afk}
{tag_name} -> afk

{let(new nick):Default User}
{new nick} -> Default User

{var(formulaEQ):5+6(x-1)}
{formulaEQ} -> 5+6(x-1)

{assign(userGoal):1,000,000 Members!}
{userGoal} -> 1,000,000 Members!

An extremely important block, the variable block allows you to save data per command invocation and use/alter it.

To define a variable, you just need to give it a name, and content, which may be empty.

After that, to call it, all you have to do is put brackets around the variables name.

Warning

You cannot name variables, names of existing blocks, for example, you cannot name a variable user, as that already exists (See Discord.rst)

Parsing

Parsing is an extremely important part of tagscript, and there are a few ways in which you can parse text.

Note

Parsing can be done with basically anything, though you shouldn’t try to parse datetimes using methods below, that’s what strf blocks are for.

Variable Parsing

{=(test_var):Carl-bot is the best bot! His favorite food is subway!}

{test_var} -> Calling the variable
{Variable Name(Elements):Delimiter}

{test_var(1)} -> Calling the first "word" (Basically setting the delimiter to a space)
The above would return Carl-bot

{test_var(1):!} -> Calling the first part of the variable up to the first "!"
The above would return Carl-bot is the best bot

One big function of variables is the ability to parse them, you can specify any number of elements and can also change the delimiter.

Note

This also works with {args} and {message}.

Elements

{=(test_var):Carl-bot is the best bot! His favorite food is subway!}

{test_var(ELEMENT)}

{test_var(4)} -> Calling the fourth element
The above would return best

{test_var(0)} {test_var(-2)} -> Calling the last element and the third last element.
The above would return subway! food

{test_var(+3)} | {test_var(7+)} -> Calling everything up to the third element and everything from the seventh onward
The above would return Carl-bot is the | favorite food is subway!

Elements are how you control how many elements you return.

Delimiters

{=(test_var):Carl-bot is the best bot! His favorite food is subway!}

{test_var(ELEMENT):DELIMITER}

{test_var(2):!} -> Calling the second argument when test_var is split by ! instead of spaces
The above would return His favorite food is subway!

When a delimiter isn’t specified, tagscript automatically assumes you mean a space, or basically {args(5)} is the same as {args(5): }.

Delimiters on their own don’t do anything, you need to specify an element for this to change anything.

Note

This is most often used to get certain parts of variables, an example being a urls domain name.

Knowing that urls are formatted like so: https://readthedocs.org/dashboard/ We can first parse everything after the // and then everything before the first /.

{=(url):https://readthedocs.org/dashboard/}
{=(url):{url(2)://}}
{=(url):{url(1):/}}
{url}

Warning

Just to reiterate {test_var:DELIMITER} won’t do anything

List & Cycle

{list(INDEX):elem,elem2,elem3,elem4}
{list(INDEX):elem~elem2~elem3~elem4}

{cycle(INDEX):elem,elem2,elem3,elem4}
{cycle(INDEX):elem~elem2~elem3~elem4}

List blocks will return the element at whatever index you specify. If you specify an index that’s out of bounds, the block will return nothing.

Cycle blocks will work the same, however when specifying an index that’s out of bounds, the block will cycle back.

When separating elements you may use , or ~, however if you have both, the tilde will take precedence.

Index

{list(-1):elem~elem2~elem3~elem4} -> elem4
{list(1):elem~elem2~elem3~elem4} -> elem2

{cycle(5):elem~elem2~elem3~elem4} -> elem2
{cycle(-6):elem~elem2~elem3~elem4} -> elem3

You may parse this similarily to regular parsing, however you may only parse one element at a time.

You also may use negative numbers to go backward.

Attention

Indexes start at 0, meaning the first element will have index 0, the second, 1 etc. etc.

Index

{index(ELEMENT):elem~elem2~elem3~elem4}

Index is quite straightforward, it will simply index the element and return its position.

Element

{index(elem2):elem~elem2~elem3~elem4} -> 1

{index(elem5):elem~elem2~elem3~elem4} -> -1

Note that this block will always return the first found instance regardless of how many times it’s found in the string, in addition if the element isn’t found, the block will return -1.

Attention

Indexes start at 0, meaning the first element will have index 0, the second, 1 etc. etc.

Membership Testing (In & Contains)

{in(STRING):TEXT}

{contains(ELEMENT):LIST}

These blocks test if a list or piece of text has a string or element in it.

In is the more powerful of the two, it will check if the string is in the text regardless of where it is while contains must have spaces around the given text.

This will return a bool value of true or false.

{in(cool):Carl-bot is cool!} -> true
{contains(cool):Carl-bot is cool!} -> false

{in(efg):abcdefghijklmnop} -> true
{contains(efg):abcdefghijklmnop} -> false

{in(Carl):Carl bot} -> true
{in(carl):Carl bot} -> true
{contains(Carl):Carl bot} -> true
{contains(carl):Carl bot} -> false

Attention

Everything in tagscript is case-sensitive, this includes contains and in blocks, you can use the lower or upper block to null this though.

Embed

{embed(EMBED PARAMETER):VALUE}

{embed(title):Embed Title}
{embed(timestamp):now}

Embed blocks are quite simple, they simply change the value in the embed sent via the embed builder.

Attention

You MUST have a value in the embed builder, anywhere, if the embed builder is empty, the tag will not send the embed.

EMBED PARAMETER

Output

title

Sets the embed title

url

Sets the embed url for the title

description

Sets the embeds description

color

Sets the embeds hex color, must include #

timestamp

Sets the embeds timestamp, the only possible payload for this is now.

Manipulation

Ordinal Abbreviation

{ord:INT}

{ord:1} returns 1st
{ord:22} returns 22nd
{ord:37} returns 3th
{ord:456} returns 456th

The ordinal abbreviation block returns exactly what you’d expect it to, the ordinal abbreviation of the number.

Note

If you don’t supply a number or the number has commas/decimals, this block will return <ord error>.

Case Blocks

{lower:Whoozard is a Wizard} -> whoozard is a wizard
{upper:carl-bot best bot} -> CARL-BOT BEST BOT

Case blocks also do exactly what’d you’d expect them too, they either upper or lower what you want, this is often used to make inputs case insensitive.

Text Replacement

{join(STRING):TEXT}
{replace(FIRST STRING,SECOND STRING):TEXT}
{urlencode(SPACE ENCODING):URL}

{join(_):Carl-bot is cool} -> Carl-bot_is_cool
{replace(, ):Carl-bot is cool} -> C a r l - b o t   i s   c o o l
{replace(l-bot,w-bot):Carl-bot is cool} -> Carw-bot is cool
{urlencode:Hey there, how are you?} -> Hey%20there%2C%20how%20are%20you%3F
{urlencode(+):Hey there, how are you?} -> Hey+there%2C+how+are+you%3F

Text replacement blocks also do what you would expect them too.

Join will join the strings spaces with whatever string you provide it with, this means it’s the equivalent of {replace( ,STRING):TEXT}.

Replace is similar to join but you separate what you want to replace and what it will be replaced with, with a comma. This can be used to space variables {replace(, ):TEXT}.

Urlencode will encode any text (Usually URLs obviously) into percent form. The only possible value for SPACE ENCODING is +.

Note

Since you must separate what you want to replace with comma, you aren’t able to replace commas.

Math

{m:EQUATION}

{math:9+10} -> 19
{calc:365-5} -> 360
{+:14/7} -> 2
{m:12*10} -> 120

The math block also works as you’d expect it to, the block itself only takes a payload which will be calculated in the correct order of operations.

Basic Functions and Operators

Function/Operator

Explanation

x+y

Addition

x-y

Subtraction

x*y

Multiplication

x/y

Division

x%y

Modulo

x^y

Exponent

abs(x)

Absolute value

round(x)

Rounds to the nearest whole number

trunc(x)

Truncation

Advanced Functions, Operators and Vars

Function/Operator/Var

Explanation

sin(x)

Sine (radians)

cos(x)

Cosine (radians)

tan(x)

Tangent (radians)

exp(x)

Eulers number to the x power

sgn()

Returns the sign of a number, 1 positive, -1 negative, 0 0

log(x)

Logarithm

ln(x)

Natural Logarithm

log2(x)

Logarithm with base 2

pi/PI

Will be replaced with pi

e/E

Will be replaced with Euler’s number

Warning

When calculating long equations carl will occasionally hiccup and just output the entire equation, there’s nothing you can do about this.

Try it for yourself

Random Number Generators

Random

{random(OPTIONAL SEED):List,of,elements}
{rand(OPTIONAL SEED):List~of~elements}
{#(OPTIONAL SEED):4|Weighted,2|list,of,3|elements}

Random blocks just pick a random choice out of a list you provide, you can also provide optional seeds and weight elements to prevent repetition.

Optional Seeding

Seed values are completely optional, however when you use a certain seed value with the same list of elements, the same element will always be chosen.

You can think of this to almost be a key that works almost like a cycle block.

Weighting

{#:4|Carl,2|bot} == {#:Carl,Carl,Carl,Carl,bot,bot}

{#:4|Lose,Win}

Weighting is just a simple way to add more elements without typing as much, keep in mind you don’t need to provide weighting for every value, the last example shows an example of having a 1 in 5 chance of winning.

Range

{range(OPTIONAL SEED):LOWER-HIGHER}
{rangef(OPTIONAL SEED):LOWER-HIGHER}

{range:1-100}
{rangef:0-1}

Range blocks generate random numbers between the 2 numbers given (inclusive) while rangef blocks generate random numbers with a single decimal (also inclusive).

Seeds may also be provided and work exactly the same as random blocks.

5050 Blocks

{5050:OPTION}
{50:OPTION}
{?:OPTION}

Has a 5050 chance of choosing said option, or nothing at all.

Time

STRF

{strf(OPTIONAL DATETIME OR UNIX):STRF FORMAT CODE}

December 31st 1999 was a {strf(1999-12-31 23.59.59):%A} -> December 31st 1999 was a Friday
The current time is {strf:%-I:%M %p} -> The current time is followed by whatever the current 12h clock is for UTC, eg 2:19 AM
Your account was created on {strf({user(created_at)}: %x} -> Your account was created on 2015/12/24 (For Carl)

When dealing with time we often want it to be outputted in different ways, strf does exactly that.

You can either supply a datetime or unix value, if none are supplied, the engine assumes you want the current time.

Note

For a full list of STRF codes, check here

Note

Some useful codes

%Y-%m-%d %H:%M:%S & the short version %F %T are the DateTime format in strf codes, which can be useful for timedelta blocks.

{strf:%FT%T}.000Z is the strf code for the ISO 8601 format, which is used when setting the timestamp in an embed's JSON. Useful if you're creating embeds manually.

Timedelta

{td(OPTIONAL DATETIME OR UNIX):DATETIME}

{td:2020-01-01 00.00.00} as of 2019-11-25 would output 1 month, 5 days and 21 hours, or the time until Midnight New Years Day

{td({m:trunc({unix}-3600)}):{strf:%Y-%m-%d %H.%M.%S}} -> 1 hour because we're just subtracting 3600 seconds or 1 hour from the current time.

Timedelta blocks will output a readable time until said datetime will be reached.

Blanks

Blanks are how we conditionally run blocks, this is due to tagscript running all blocks first, and not checking wether they should actually be run (Conditional Statements).

Danger

Probably the hardest concept you’ll ever have to learn in tagscript, most people give up here.

If you think you can explain blanks feel free to add a dropdown with your explanation on it.

Switches

Switches are basically a way you can change a variable to something you’ve set before based on keywords.

Danger

If you have anything that looks relatively similar to this, you’re doing it wrong. Keep reading for more info on why

{=(test_var):{if(keyword=={args}):something}}
{=(test_var):{if(keyword2=={args}):Tagscript|{test_var}}}
{=(test_var):{if(keyword3=={args}):Tagscript|{test_var}}}
{=(test_var):{if(keyword4=={args}):Tagscript|{test_var}}}

USERNAME#DISCRIMINATOR

MAKE SURE TO ADD THIS TO THE index.rst FILE, LOOK FOR toctree AND CustomTags/TEMPLATE

TAG NAME

ADD A DESCRIPTION

Tag Import

Raffael#1372

Original AFK COMMAND

Made an “afk” tag. When it’s set to on it will inform anyone that mentions you that you are afk. Setting it to off will turn it off. If you type a message after on it will be set as your away message, but if you leave it blank the tag will use the default away message.

Tag Import

Back 4 Blood Card Lookup

A Back 4 Blood card lookup command. Will display the card that best matches the provided search term alphabetically. Displays an error message if the provided search term does not match a card’s name or a substring of that name.

For when you can’t recall the specifics of a card, or want to discuss it within a Discord server without having to type out the card’s description or stats.

I will attempt to keep the card images updated as future patches occur. These card images are current as of 2021-10-16.

This custom command is not affiliated with or endorsed by Back 4 Blood, Warner Bros. and it’s divisions, or Turtle Rock Studios. I do not own these images, I am using them under the constraints of Fair Use as established in the Copyright Act of 1976, for nonprofit educational purposes.

The image below shows the command invocation for example purposes. This invocation will be deleted upon execution in the linked version of this tag.

Tag Import

_Leg3ndary#5759

Shell Cloud Command

Working this out took a lot of time, however I’m proud to show the tagscript community the first tag that can save data through the bot, you don’t have to do any setting up. (Other then importing of course)

You might recall Raffael made a tag where you would setup a role and then guess the number, you also might remember a user named Squidtoon made an api that did similar things however he removed his project from repl where it was hosted…

What?

You can use this tag to do something similar to the cbsays tag where you can post a shell with text on it, you can also view other users posts or the latest post!

Why? This is just the general idea of using an api and python to interact through embed images, for those of you who don’t know what an API is, its an “application program interface”, you send a request to a site which then can give you something back, thats basically what I did. You send a request to a repl, the program will then save it to another further external cloud db known as mongodb (There are problems with saving data through repl which is why this part is needed).

Usage:

?shell add <Word>
Your word must be less then or 10 characters
?shell show <Index>
View already posted words, must be a number eg. view the 7th word added with the add command
USE 0 OR LATEST TO VIEW LATEST POST
?shell cache
Shows the Cache which you can use to view words with the show command

⚠️ Warning. ⚠️

People are naturally stupid. In short people will be able to use words that shouldn’t be used. For this reason I highly recommend this tag be marked nsfw.

Tag does not use any commands.

Tag Import

Suspicion Command

Check for alts using a system of checks with each being given their own weight, in addition see other info about the user to manually determine if a user is “sus”.

{=(ud.seconds.points):3} {=(README):Users account age is under 24 hours old, usually an alt MAKE THIS THE BIGGEST NUMBER}
{=(ud.minutes.points):2} {=(README):Users account age is 1-30 days old, could be an alt would recommend keeping an eye on the user}
{=(ud.hours.points):1} {=(README):Users account age is 1-12 months old, again could be an alt but not likely}
{=(ud.days.points):0} {=(README):Users account age is 1+ years old, most likely not an alt but could be one}
{=(ujd.seconds.points):2} {=(README):Users account age in server is under 24 hours old, new memberMAKE THIS THE BIGGEST NUMBER}
{=(ujd.minutes.points):1} {=(README):Users account age in server is 1-30 days old, not a new member but not really an old member}
{=(ujd.hours.points):0} {=(README):Users account age in server is 1-12 months old, would be considered seasoned or at least an old member}
{=(ujd.days.points):0} {=(README):Users account age in the server is 1+ years old, old member}
{=(ua.default.points):3} {=(README):Is the users avatar a default one? Most alts don't change pfps which is a dead giveaway}
{=(ua.nitro.points):-1} {=(README):Does the user have a .gif avatar? Not many people have nitro for an alt(s) Negative number here because user has nitro}
{=(un.points):1} {=(README): Has the user changed his/her nickname? Alts don't usually change their nickname, Disable this with "0" if needed}

Tag Import

Asty’#8926

The Best Embed Maker Command

Have you ever dreamt of creating an Embed Message with images, a footer, a custom side color… easily with just a command?

As you may already know, Carl-bot has the embed command that limits you to only a title, a description and a side color, and the cembed command that requires you to know about what JSON even is (which is not the majority, let’s face it), and is a pain to use on a regular basis (or even once to be honest).

This is why out of frustration and as a huge QoL (Quality of Life) improvement for you all, I built this buildembed custom command (be for short), which is very easy and convenient to use, while being powerful!

Features

  • Each field name has Substring Matching, meaning you can for example type t for title, desc for description, c or col for color and it will still recognize it!

  • You can specify any field in the order of your choice! Unlike other embed commands, if you want to specify a footer, then a thumbnail, then a title, you can!

  • For the color field, you can specify either a color name, a hexadecimal code (like #eeaaee), or even self for your own color.

  • Custom-made blocks to use in some fields, such as user {avatar} and server {icon} in image fields, {server} and {channel} in text fields, and {channel(mention)} in the Description field.

  • Even if you don’t have Nitro, ability to use custom emojis from other servers, by using <emoji (literally) followed by the emoji ID and >.

Usage

!be fieldName:Content|fieldName:Content|fieldName:Content...

Available Fields and Colors

Tag Import

Niloc#0421