getRole "yagpdb"
and getRole "yAgPdB"
would have same responses even if server has both of these roles, so using IDs is better.editChannelName
channel "newName"channel
can be either ID, "name" or even nil
if triggered in that channel name change is intended to happen. "newName"
has to be of type string. For example >{{editChannelName nil (print "YAG - " (randInt 1000))}}
editChannelTopic
channel "newTopic"channel
can be either ID, "name" or nil
if triggered in that channel where name change is intended to happen. "newTopic"
has to be of type string. For example >{{editChannelTopic nil "YAG is cool"}}
getChannel
channelchannel
argument which can be either its ID, name or nil
for triggering channel, and is of type *templates.CtxChannel. For example > {{(getChannel nil).Name}}
returns the name of the channel command was triggered in.getChannelOrThread
channelgetPinCount
channelnil
for triggering channel. Can be called 2 times for regular and 4 for premium servers.getThread
channeldbBottomEntries
pattern amount nSkipamount (max 100)
top entries of keys determined by the pattern
from the database, sorted by the value in a ascending order.dbCount
(userID|pattern|query)userID
is given, counts entries for that userID; if pattern
, only those keys are counted that match the given pattern; and if query
is provided, it should be an sdict with the following keys:userID
- only counts entries with that userID, defaults to counting entries with any userID.pattern
- only counts dbEntry keys with names matching the pattern given, defaults to counting entries with any name.dbDel
userID keydbDelByID
userID IDdbDelMultiple
query amount skipamount (max 100)
entries from the database matching the criteria provided. query
should be an sdict with the following options:userID
- only deletes entries with the dbEntry field .UserID provided, defaults to deleting entries with any ID.pattern
- only deletes entry keys with a name matching the pattern given.reverse
- if true, starts deleting entries with the lowest values first; otherwise starts deleting entries with the highest values first. Default is false
.dbGet
userID key dbGetPattern
userID pattern amount nSkipamount (max 100)
entries from the database in ascending order.dbGetPatternReverse
userID pattern amount nSkipamount (max 100)
entries from the database in descending order.dbIncr
userID key incrBy incrBy .
Also returns the entry's current, increased value.dbRank
query userID keyquery
specifies the set of entries that should be considered, and should be a sdict with the following options:userID
- only includes entries with that user ID, defaults to including entries with any user IDpattern
- only includes database's key
entries with names matching the pattern given, defaults to counting entries with any namereverse
- if true, entries with lower value have higher rank; otherwise entries with higher value have higher rank. Default is false
.dbSet
userID key valuekey
for the specific userID
to the specified value
. userID
can be any number of type int64.
Values are stored either as of type float64 (for numbers, oct or hex) or as varying type in bytes (for slices, maps, strings etc) depending on input argument.dbSetExpire
userID key value ttldbSet
but with an expiration ttl
which is an int and represents seconds.dbTopEntries
pattern amount nSkipamount (max 100)
top entries of keys determined by the pattern
from the database, sorted by the value in a descending order.(_)
matches any single character; a percent sign (%)
matches any sequence of zero or more characters.{{$v := .User.ID}} {{dbSet 0 "userid" (str $v)}} {{$fromDB := toInt (dbGet 0 "user_id").Value}}
dict
key values are also retrieved as int64, so to use them for indexing one has to e.g. index $x (toInt64 0)
execCC
calls are limited to 1 / CC for non-premium users and 10 / CC for premium users.cancelScheduledUniqueCC
ccID keyscheduleUniqueCC
execCC
ccID channel delay dataccID.
With delay 0 the max recursion depth is 2 (using .StackDepth
shows the current depth). execCC
is rate-limited strictly at max 10 delayed custom commands executed per channel per minute, if you go over that it will be simply thrown away. Argument channel
can be nil
, channel's ID or name. Thedelay
argument is execution delay of another CC is in seconds. The data
argument is content that you pass to the other executed custom command. To retrieve that data
you use .ExecData
. This example is important > execCC example also next snippet which shows you same thing run using the same custom command > Snippets.scheduleUniqueCC
ccID channel delay key dataexecCC
except there can only be 1 scheduled cc execution per server per key, if key already exists then it is overwritten with the new data and delay (as above, in seconds).add
x y z ...toFloat
on the first argument to force floating point math.){{add 5 4 3 2 -1}}
sums all these numbers and returns 13
.bitwiseAnd
x y{{bitwiseAnd 12 25}}
returns 8
, that in binary 00001100 AND 00011001 is 00001000.bitwiseAndNot
x y{{bitwiseAndNot 7 12}}
returns 3
, that is 0111 AND NOT 1100 is 11.bitwiseNot
x{{bitwiseNot 7}}
returns -8
. that in binary 0111 to 1000bitwiseOr
x y z...{{bitwiseOr 12 25}}
returns 29
, that in binary 00001100 OR 00011001 is 00011101.bitwiseXor
x y{{bitwiseXor 12 25}}
returns 21
, that in binary 00001100 OR 00011001 is 00010101.bitwiseLeftShift
x y{{range seq 0 3}} {{bitwiseLeftShift 212 .}} {{end}}
returns 212 424 848
bitwiseRightShift
x y{{range seq 0 3}} {{bitwiseRightShift 212 .}} {{end}}
returns 212 106 53
.cbrt
{{cbrt 64}}
returns 4
.div
x y z ...add
or mult
, detects first number's type first. {{div 11 3}}
returns 3
whereas {{div 11.1 3}}
returns 3.6999999999999997
fdiv
x y z ...log
x base{{ log "123" 2 }}
will return 6.94251450533924
.mathConst
"arg""arg"
has to be a case-insensitive string from math constants list. For example {{mathConst "sqrtphi"}}
would return 1.272019649514069
.max
x ymin
x ymod
x ymod 17 3
returns 2
of type float64.mult
x y z ...add
or div
, detects first number's type. {{mult 3.14 2}}
returns 6.28
pow
x y{{ pow 2 3 }}
returns 8
.randInt
(stop, or start stop){{$d := randInt 10}}
Stores random int into variable $d
(a random number from 0-9).{{div (round (mult 12.3456 100)) 100}}
returns 12.35
{{div (roundFloor (mult 12.3456 100)) 100}}
returns 12.34getTargetPermissionsIn
memberID channelIDeditNickname
"newNick"hasPermissions
arggetMember
mention/userID{{(getMember .User.ID).JoinedAt}}
is the same as {{.Member.JoinedAt}}
onlineCount
targetHasPermissions
memberID argmentionEveryone
@everyone
.mentionHere
@here
.mentionRoleID roleID
mentionRoleName
"rolename"<@{{.User.ID}}>
Outputs a mention to the user that called the command and is the same as {{.User.Mention}}
<@&##########>
Mentions the role with ID ######## (listroles command gives roleIDs). This is usable for example with {{sendMessageNoEscape nil "Welcome to role <@&11111111...>"}}
. Mentioning that role has to be enabled server- side in Discord.addMessageReactions
channel messageID emojis...addReactions
or addResponseReactions
, but can be used on any messages using its ID. channel
can be either nil
, channel's ID or its name. Example in section's Snippets.addReactions
"👍" "👎" ...emojiName:emojiID
).addResponseReactions
"👍" "👎" ...emojiName:emojiID
).complexMessage
"content" args "embed" args "file" args "filename" args complexMessage
creates a so-called bundle of different message fields for sendMessage...
functions to send them out all together. Its arguments need to be preceded by predefined keys "content"
for regular text, "embed"
for embed arguments created by cembed
or sdict
, "file"
for printing out content as a file with default name attachment_YYYY-MM-DD_HH-MM-SS.txt
(max size 100 000 characters ca 100kB). "filename"
lets you define custom file name if "file"
is used with max length of 64 characters, extension name remains txt
. Example in this section's Snippets.complexMessageEdit
"content" args "embed" argseditMessage
function - either if complexMessage
is involved or works even with regular message. Has two parameters "content"
and "embed"
to edit regular text part or embed part. If "embed"
is set to nil
, it deletes whole embed. Example in this section's Snippets.deleteAllMessageReactions
channel messageID (emojis...)channel
can be ID, "name" or nil
. emojis
argument is optional and works like it's described for the function deleteMessageReaction
.deleteMessage
channel messageID (delay)messageID
from channel
. Channel can be either nil
, channel's ID or its name. (delay)
is optional and like following two delete functions, it defaults to 10 seconds, max being 1 day or 86400 seconds. Example in section's Snippets.deleteMessageReaction
channel messageID userID emojis...channel
can be ID, "name" or nil
.
emojis
argument can be up to 10 emojis, syntax is emojiName
for Unicode/Discord's default emojis and emojiName:emojiID
for custom emotes.
Example: {{deleteMessageReaction nil (index .Args 1) .User.ID "👍" "👎"}}
will delete current user's reactions with thumbsUp/Down emotes from current running channel's message which ID is given to command as first argument (index .Args 1)
.
Also usable with Reaction trigger.deleteResponse
(delay)delay
argument (max 86400 seconds = 1 day). Defaults to 10 seconds.deleteTrigger
(delay)delay
argument (max 86400 seconds = 1 day). Defaults to 10 seconds.editMessage
channel messageID newMessageContentnil
, channel's ID or "name". Light example in section's Snippets.editMessageNoEscape
channel messageID newMessageContentsendMessageNoEscape
. getMessage
channel messageIDpinMessage
channel messageIDchannel
can be either its ID, name or nil for triggering channel. Can be called 5 times.sendDM
"message here"sendMessage
channel messagemessage (string or embed)
in channel
, channel can be either nil
, the channel ID or the channel's "name".sendMessageNoEscape
channel messagemessage (string or embed)
in channel
, channel can be either nil
, the channel ID or the channel "name". Doesn't escape mentions (e.g. role mentions or @here/@everyone).sendMessageNoEscapeRetID
channel messagesendMessageNoEscape
, but also returns messageID to assigned variable for later use.sendMessageRetID
channel messagesendMessage
, but also returns messageID to assigned variable for later use. Example in section's Snippets.nil
and gets messageID to variable $x
. Also adds reactions to this message. After 5 seconds, deletes that message. >{{$x := sendMessageRetID nil "Hello there!"}} {{addMessageReactions nil $x "👍" "👎"}} {{deleteMessage nil $x 5}}
sleep
and slightly also editMessage
functions. >
{{$x := sendMessageRetID nil "Hello"}} {{sleep 3}} {{editMessage nil $x "There"}} {{sleep 3}} {{sendMessage nil "We all know, that"}} {{sleep 3}} YAGPDB rules!
complexMessage
with sendMessage
. {{sendMessage nil (complexMessage "content" "Who rules?" "embed" (cembed "description" "YAGPDB of course!" "color" 0x89aa00) "file" "Here we print something nice - you all are doing awesome!")}}
complexMessageEdit
with editMessage
.
{{$mID := sendMessageRetID nil (complexMessage "content" "You know what is..." "embed" (cembed "title" "FUN!?" "color" 0xaa8900))}} {{sleep 3}} {{editMessage nil $mID (complexMessageEdit "embed" (cembed "title" "YAGPDB!" "color" 0x89aa00) "content" "Yes, it's always working with...")}}{{sleep 3}}{{editMessage nil $mID (complexMessageEdit "embed" nil "content" "Embed deleted, goodbye YAG!")}}{{deleteMessage nil $mID 3}}
adjective
cembed
"list of embed values"createTicket
author topiccslice, sdict
dict
key1 value1 key2 value2 ...sdict
. dict
also has helper methods .Del, .Get, .HasKey and .Set and they function the same way as sdict
ones discussed here.exec
"command" "args" "args" "args" ...exec
will return raw data of type embed, so you can use embed fields for better formatting - e.g. {{$resp := exec "whois"}} {{$resp.Title}} Joined at > {{(index $resp.Fields 4).Value}}
will return the title (username#discriminator) and "Joined at" field's value from whois
command.
NB! This will not work for commands with paginated embed returns, like un/nn
commands!exec "command" arguments
- this means you format it the same way as you would type the command regularly, just without the prefix, e.g. if you want to clear 2 messages and avoiding the pinned message > {{exec "clear 2 -nopin"}}
, where "command"
part is whole "clear 2 -nopin"
. If you change that number inside CC somewhere then you have to use arguments
part of exec formatting > {{$x := 2}} {{exec "clear" $x "-nopin"}}
Here "clear"
is the "command"
and it is followed by arguments
, one variable $x
and one string "-nopin"
. Last example is the same as {{exec (joinStr " " "clear" $x "-nopin")}}
(also notice the space in joinStr
separator). execAdmin
"command" "args" "args" "args" ...exec
but effectively runs the command as the bot user (YAGPDB). This has essentially the same effect as if a user with the same permissions and roles as YAGPDB ran the command: for example, if YAGPDB had ban members permission but the user which ran the command did not, {{exec "ban" 12345}}
would error due to insufficient permissions but {{execAdmin "ban" 12345}}
would succeed.execTemplate
"template" datahasPrefix
string prefixhasPrefix
tests whether the given string
begins with prefix
and returns bool. Example > {{hasPrefix "YAGPDB" "YAG"}}
returns true
.hasSuffix
string suffixstring
ends with suffix
and returns bool.{{hasSuffix "YAGPDB" "YAG"}}
returns false
.humanizeThousands
argarg
can be int or string, has to be a whole number, e.g. {{humanizeThousands "1234567890"}}
will return 1,234,567,890
.in
list value{{ in (cslice "YAGPDB" "is cool") "yagpdb" }}
returns false
.index
arg ...keys{{index .Args 1}}
returns first argument after trigger which is always at position 0. index X 0 1
is equivalent to calling index (index X 0) 1
inFold
list valuein
, but is case-insensitive. {{inFold (cslice "YAGPDB" "is cool") "yagpdb"}}
returns true
.kindOf
value (flag)flag
part is a bool and if set as true (false is optional) returns the value where given value
points to. Example: {{kindOf cembed false}} {{kindOf cembed true}}
will return ptr
and struct
.len
arg{{ len (cslice 1 2 3) }}
3
.noun
parseArgs
required_args error_message ...carg
.Get
and .IsSet
.
carg "type" "name"
is required by parseArgs
and it defines the type of argument for parseArgs
. sendTemplate
channel templateName data{{define "logsTemplate"}}This text will output on different channel, you can also use functions like {{currentTime}}. {{.TemplateArgs}} would be additional data sent out. {{end}}
{{sendTemplate "logs" "logsTemplate" "YAG rules!"}}.
Template definitions are discussed here.addRoleID
roleIDlistroles
command for a list of roles).addRoleName
roleNamelistroles
command for a list of roles).getRole
rolegiveRoleID
userID roleIDgiveRoleName
userID "roleName"hasRoleID
roleIDhasRoleName
"rolename"removeRoleID
roleID (delay)Delay
is optional argument in seconds.removeRoleName
roleName (delay)Delay
is optional argument in seconds.roleAbove
role1 role2roleAbove
compares two role objects e.g. getRole
return and givestrue/false
value is role1
positioned higher than role2
or not.setRoles
userID roles{{setRoles .User.ID cslice}}
would clear the roles of the triggering user.takeRoleID
userID roleID (delay)Delay
is optional argument in seconds.takeRoleName
userID "roleName" (delay)Delay
is optional argument in seconds.targetHasRoleID
userID roleIDtargetHasRoleName
userID "roleName"joinStr
"separator" "str1" (arg1)(arg2) "str2" ..."separator"
, example:{{joinStr "" "1" "2" "3"}}
returns 123
. Also if functions have string, []string or easily convertible return, they can be used inside joinStr
e.g. {{joinStr "" "Let's calculate " (add (mult 13 3) 1 2) ", was returned at " (currentTime.Format "15:04") "."}}
lower
"string"print, printf, println
printf
cheat sheet here.
printf
is usable for example to determine the type of the value > {{printf "%T" currentTime}}
outputs currentTime
functions output value type of time.Time
. In many cases, printf
is a great alternative to joinStr
for concatenate strings.reFind
"regex" "string"{{reFind "AG" "YAGPDB is cool!"}}
returns AG
(regex pattern is case sensitive).reFindAll
"regex" "string" (count)count
determines how many matches are made. Example: {{reFindAll "a*" "abaabaccadaaae" 4}}
would return [a aa a ].
reFindAllSubmatches
"regex" "string" (count){{reFindAllSubmatches "(?i)y([a-z]+)g" "youngish YAGPDB"}}
returns [[young oun] [YAG A]]
(regex pattern here is case insensitive). Optional count
works the same way as for reFindAll
. So example above with count
set to 1 would return [[young oun]].
reQuoteMeta
"string"reQuoteMeta
returns a string that escapes all regular expression metacharacters inside the argument text; the returned string is a regular expression matching the literal text. Example in package documentation.reReplace
"regex" "string1" "string2"{{reReplace "I am" "I am cool!" "YAGPDB is"}}
returns YAGPDB is cool!
(regex pattern here is case sensitive).reSplit
"regex" "string" (count)reSplit
slices string
into substrings separated by the regex
expression and returns a slice of the substrings between those expression matches. The optional count
determines the number of substrings to return. If count
is negative number the function returns all substrings, if 0 then none. If count
is bigger than 0 it returns at most n substrings, the last substring being the unsplit remainder.{{ $x := reSplit "a" "yagpdb has a lot of fame" 5}}
{{$x}} {{index $x 3}}
would return [y gpdb h s lot of f me]
and lot of f.
slice
arg integer (integer2)arg
after cutting/slicing off integer (numeric) value of symbols (actually starting the string's index from integer through integer2) - e.g. {{slice "Fox runs" 2}}
outputs x runs
. When using also integer2 - e.g. {{slice "Fox runs" 1 7}}
, it outputs ox run
. For slicing whole arguments, let's say words, see example in section's Snippets. slice
function is not the same as basic dynamically-sized slice data type discussed in this reference doc. Also it's custom, not having 3-indices as the default one from text/template package.split
"string" "sepr""string"
to substrings separated by "sepr"
arg and returns new slice of the substrings between given separator e.g. {{split "YAG, is cool!" ","}}
returns [YAG is cool!]
slice where YAG
is at index
position 0 and is cool!
at index
position 1. Example also in section's Snippets.title
"string"trimSpace
"string"upper
"string"urlescape
"string"urlquery
which is covered here.\
, which gives the remaining characters special meaning - let's call them metacharacters. The most common escape sequence you will encounter is \n
, which means "newline". {{reFind "\\d+" (toString 42)}}
versus {{reFind `\d+` (toString 42)}}
{{$args:= (joinStr " " (slice .CmdArgs 1))}}
Saves all the arguments except the first one to a variable $args
. split
function. >
{{$x := "Hello, World, YAGPDB, here!"}} {{range $k, $v := (split $x ", ")}}Word {{$k}}: __{{$v}}__ {{end}}
reFindAll
. >
Before regex: {{$msg := "1 YAGPDB and over 100000 servers conquered."}} {{$re2 := reFindAll "[0-9]+" $msg}} {{$msg}}
After regex matches: {{println "Only" (index $re2 0) "YAGPDB and already" (index $re2 1) "servers captured."}}
currentTime
formatTime
Time ("layout arg")Time
shows it needs to be of type time.Time, also with extra layout if second argument is given - e.g. {{formatTime currentUserCreated "3:04PM"}}
would output 11:22AM
if that would have been when user was created. Layout argument is covered here.humanizeDurationHours
{{humanizeDurationHours 9000000000000000000}}
returns 285 years 20 weeks 6 days and 16 hours
. More in Snippets.humanizeDurationMinutes
humanizeDurationHours
, this time duration is returned in minutes - e.g. {{humanizeDurationMinutes 3500000000000}}
would return 58 minutes
.humanizeDurationSeconds
{{humanizeDurationSeconds 3500000000000}}
would return 58 minutes and 20 seconds
.humanizeTimeSinceDays
{{humanizeTimeSinceDays currentUserCreated}}.
loadLocation
"location"{{currentTime.In (loadLocation "Asia/Kathmandu")}}
would return current time in Nepal.
location
is of type string and has to be in ZONEINFO syntax.newDate
year month day hour minute second (timezone){{humanizeDurationHours ((newDate 2059 1 2 12 34 56).Sub currentTime)}}
will give you how much time till year 2059 January 2nd 12:34:56. More examples in Snippets. timezone
is an optional argument of type string which uses golang's LoadLocation function and ZONEINFO syntax. For example: {{newDate 2020 4 20 12 34 56 "Atlantic/Reykjavik"}}
would return that time in GMT+0.snowflakeToTime
snowflake{{snowflakeToTime .BotUser.ID}}
returns 2016-07-17 15:17:19 +0000 UTC
for YAGPDB.weekNumber
timetime
of type time.Time. {{weekNumber currentTime}}
would return the week number of current time.{{print "<t:" currentTime.Unix ":F>"}}
for "Long Date/Time" formatting.humanizeDurationHours
and also how to parse a timestamp, output will be like whois
command shows user's join server age.
{{humanizeDurationHours (currentTime.Sub .Member.JoinedAt.Parse)}}
newDate
to get Epoch times.
{{$unixEpoch := newDate 1970 1 1 0 0 0}} in seconds > {{$unixEpoch.Unix}}
{{$discordEpoch := newDate 2015 1 1 0 0 0}} in seconds > {{$discordEpoch.Unix}}
json
valuevalue
through MarshalJSON (more here) and returns it as type string. For example {{json .TimeHour}}
outputs type string; before this .TimeHour
was of type time.Duration. Basically it's good to use if multistep type conversion is needed (toString (toInt value) )
and certain parts of cembed
need this for example.structToSdict
struct{{$x := cembed "title" "Something rules!" "color" 0x89aa00}} {{$x.Title}} {{$x = structToSdict $x}} {{- $x.Set "Title" "No, YAGPDB rules!!!" -}} {{$x.Title}} {{$x}}
will return No, YAGPDB rules!!! and whole sdict-mapped cembed.toByte
"arg"{{toByte "YAG€"}}
would output [89 65 71 226 130 172]
. toString
is capable of converting that slice back to string.toDuration
s, m, h, d, w, mo, y
,without a modifier string will be converted to minutes. Usage:(toDuration x)
. Example in section's Snippets. toFloat
(toFloat x)
. Function will return 0, if type can't be converted to float64.toInt
(toInt x)
. Function will return 0, if type can't be converted to int.toInt64
(toInt64 x)
. Function will return 0, if type can't be converted to int64.toRune
"arg"{{toRune "YAG€"}}
would output [89 65 71 8364]
. These two functions - the one above, are good for further analysis of Unicode strings. toString
is capable of converting that slice back to string.toString
str
. Converts some other types into a string. Usage: (toString x)
.toDuration
, outputs 12 hours from current time in UTC.
{{(currentTime.Add (toDuration (mult 12 .TimeHour))).Format "15:04"}}
is the same as{{(currentTime.Add (toDuration "12h")).Format "15:04"}}
or{{(currentTime.Add (toDuration 43200000000000)).Format "15:04"}}
printf "%c"
. For example, printf "%c" 99
would result in the string c
as 99
is the Unicode code point for c
.printf
is briefly covered later on in the next section, further documentation can be found here. Cheat sheet here.currentUserAgeHuman
3 days 2 hours
).currentUserAgeMinutes
currentUserCreated
pastNicknames
userID offsetpastUsernames
.pastUsernames
userID offsetoffset
number in that list.{{range pastUsernames .User.ID 0}}
{{.Name}} - {{.Time.Format "Jan _2 2006"}}
{{end}}
userArg
mention/userID{{(userArg .User.ID).Mention}}
mentions triggering user. Explained more in this section's snippets. Previous limit of 5 to this functions is no longer there.{{(userArg .Guild.OwnerID).String}}
this template's action-structure returns Guild/Server owner's username and discriminator as of type string. First, userArg
function is given .Guild.OwnerID
as argument (what it does, explained in templates section). The parentheses surrounding them make userArg
function return .User
as .User object which is handled further by .String
method (ref..User.String
), giving a result like > YAGPDB#8760
.