Using MiScript to create custom commands

16 minute read


Mi(ki)Script is Miki's custom command language, specifically written to make easy-to-use custom commands. In this guide, we will show you how to get started with MiScript.

Commands

Commands Description
>createcommand [command name] [script] Used to create a custom command
>removecommand [command name] Used to delete an existing custom command
>getcommand [command name] Used to get the code of an existing custom command
>getcommandstorage Used to see the storage of custom commands

Your first script

say("hello world")

As you may have realized, this command simply makes Miki say"hello world". There's nothing else happening.

Message variables

Sometimes, you may want to include some additional information in your Discord chats. The ability to add text from variables provided by Miki makes this possible.

say("Hello $[author]")

This would return:

Hello Veld

Conditionals

Different responses are also allowed; for example, you can add conditional branches as shown below:

if author = "Veld" then
    say("Hello Veld!")
else
    say("Wait, you're not Veld!")
end

Stop sequences

Since there is a message limit on Discord, using if and else over and over again is not a good idea for bigger commands. Using stop will stop the script and won't execute the rest of the code.

say("This message will be shown!")
stop
say("However, this message will be ignored!")

Embeds

It is also possible to send embeds with MiScript:

say(embed("Probably because you said something weird...")
    .title("$[author.name] ignores you")
    .image("https://media.giphy.com/media/H9jrEhsr1pUMo/giphy.gif"))

This would return:

image

There are more functions like .footer("Text") and .color("red") for the embed builder; check out the API reference for embeds.

Adding your command

So now that you know how to create a script, let's take a look at how to add it to your server!

⚠ Warning: This will only work if you have the MANAGE ROLES permission in the Discord server.

>createcommand "testcommand" (say "$[author]! Long time no see!")

And if everything goes well, you will see this:

image

Removing commands

To remove an existing command, you can use >removecommand [command name]. For example, if you want to remove the command we created above, you would use >removecommand testcommand. If done correctly, you should see the following:

image

The following sections will go in depth on what MiScript can do. This can be overwhelming when you're new to programming.
If you need help, feel free to join our Discord Server and ask for help in the #miscript channel.

Functions

When you want to execute code multiple times, you can create a function.

Creating functions

The following code creates a function in MiScript:

fun greet(name)
    say("Hello $[name]!")
end

Let's go through this script:

Code Description
fun Tell MiScript that we're create a new function.
greet Function name. Use this name to call the function.
(name) Arguments that the function takes.
say("Hello $[name]!") The body of the function. This will be executed when the function is called.
In the body you can use the arguments that were defined.
end End of the function

Now that we defined the function "greet", we can call it:

greet("Veld")

This will return:

Hello Veld

Arrow functions

Sometimes you have to provide a function as an argument to change or filter a value. For example, in an array, you can map every value:

["hello", "miki"].map(fun(e)
    return e.upper()
end)

As you can see, the function takes quite a lot of code to define itself and to return a value. To reduce the amount of code, you can use an arrow function. An array function is a function that directly returns the value of the body:

["hello", "miki"].map(e => e.upper())

Let's go through the arrow function:

Code Description
e The parameter of the function.
For more than one parameter, you can do (param1, param2)
=> Tell MiScript we're creating an arrow function.
e.upper() The body of the function, which is being directly returned.
In this case, .upper() will uppercase every character.

When you execute the code, you'll get: ["HELLO", "MIKI"].

Arrays

Arrays are used to store multiple values in a single variable.

Use cases of an array

Let's say you want to store multiple values in your script.

var user1 = "Veld"
var user2 = "Gerard"
var user3 = "Zephy"

say("Cool dudes: $[user1], $[user2], $[user3]")

You can see how the amount of variables will pile up if we add more users and there is no easy way to get all the users. The solution is to use arrays.

An array starts with [ and ends with ]. So an empty array would be [].
To create an array with a string, you place the string between the brackets: [ "value" ].
To add multiple strings, you add them separated with commas within the brackets: [ "Veld", "Gerard", "Zephy"].

Now that we have an array, we can combine it to a single string with .join():

var users = ["Veld", "Gerard", "Zephy"]

say("Cool dudes: $[users.join(", ")]")

This will return:

Cool dudes: Veld, Gerard, Zephy

There are more functions like .join() for arrays; check out the API reference for arrays.

Storage API

When a script is finished all the variables that you've declared will be lost. To save a variable, you can use the storage API.

⚠ Warning: The storage API is not persisted; it's possible that your data will be lost. In the future, this will be improved.

Let's create a command that remembers how many times the command was executed. First, decide a unique key that you'll use in the storage, in this example we'll be using "count".

To store a value in the storage, you can use store.set.

store.set("count", 1)

To retrieve a value from the storage, you can use store.get.
When a key doesn't exist in the storage, the result will be null.

var count = store.get("count")

Example

Let's make a command that counts how many times it was executed.

First, we retrieve the value from the storage because it's possible that the command was executed before. When it doesn't exist, we set the count to 0.

var count = storage.get("count")

if not count then
    count = 0
end

Now we increment the value by 1, store it back to the storage and say the result:

count = count + 1
storage.set("count", count)

say("Count: $[count]")

When executing the command multiple times, you'll see that the counter increases:

image

View storage

To see what data is stored in the storage, you can use the command >getcommandstorage:

image

Limits

To prevent abuse of the storage API, it has a key and value limit. To increase the amount of data, The owner of the Discord Server (where the command is being executed) can donate to get additional keys.

Default Donator
Amount of keys 1 25
Maximum value size 4 KB 4 KB

API Reference

The following section covers what the API can do in MiScript.

Globals

Function Description
args Array with the arguments from the current message.

Message: >command test
Result: ["test"]
message Current message.
See Message for more information.
author Author of the message.
See User for more information.
guild Current guild.
See Guild for more information.
channel Channel where the message was sent.
See Channel for more information.
storage Storage API.
See Storage for more information.
embed() Create a new embed.
See Embed for more information.
say(content) Send a message or embed.

Example: say(embed("Hello world"))

Message

Function Description
id Discord message ID.

Example: message.id
Result: 322845087467962368
content Content of the message.

Example: message.content
Result: "Hello!"

Guild

Function Description
id Discord guild ID.

Example: guild.id
Result: 160067691783127041
members Amount of members in the guild.

Example: guild.members
Result: 1337
icon Icon of the server.

Example: guild.icon
Result: "https://cdn.discordapp.com/icons/..."
owner Owner of the server.
See User for more information.

Channel

Function Description
id Discord channel ID.

Example: channel.id
Result: 160105994217586689
name Name of the channel.

Example: channel.name
Result: "general"
nsfw True if the channel is NSFW.

Example: channel.nsfw
Result: false

User

Function Description
id Discord user ID.

Example: user.id
Result: 160067691783127041
bot True if the user is a bot.

Example: user.bot
Result: false
mention Create a mention to the user.

Example: user.mention
Result: "<@160105994217586689>"
discrim Discriminator of the user.

Example: user.discrim
Result: "6045"
name Name of the user.

Example: user.name
Result: "Miki"

String

Function Description
.length Length of the string.

Example: "miki".length
Result: 4
.upper() Converts a string to uppercase letters.

Example: "miki".upper()
Result: "MIKI"
.lower() Converts a string to lowercase letters.

Example: "MIKI".lower()
Result: "miki"
.has(str) Check if the string contains a substring.

Example: "Hello Miki".has("Miki")
Result: true
.startsWith(str) Check if the string starts with a substring.

Example: "Hello Miki".startsWith("Hello")
Result: true
.endsWith(str) Check if the string ends with a substring.

Example: "Hello Miki".endsWith("Miki")
Result: true
.replace(old, new) Replace every occurence of the old string with the new string.

Example: "Hello Beld".replace("Beld", "Veld")
Result: "Hello Veld"
.trim() Remove every whitespace character at the begin and end of the string.

Example: " Hello Miki ".trim()
Result: "Hello Miki"
.split() Splits the string into an array of substrings using every whitespace character.

Example: "hello world".split()
Result: ["hello", "world"]
.split(seperator) Splits the string into an array of substrings using the given seperator.

Example: "hello-world".split("-")
Result: ["hello", "world"]
.indexOf(str) Get the position of the substring in the string.

Example: "Hello Miki".indexOf("Miki")
Result: 6
.remove(index, length) Remove a range in the string.

Example: "Hello Miki".remove(0, 6)
Result: "Miki"

Number

Function Description
.toFixed(length) Converts the number into a string with the fixed amount of decimals.

Example: (1.23456).toFixed(2)
Result: "1.23"

Array

Function Description
.length Amount of items in the array.

Example: ["hello", "world"].length
Result: 2
.has(item) Check if the array contains the item.

Example: ["hello", "world"].has("hello")
Result: true
.add(item) Add a new item to the array.

Example: ["hello"].add("world")
Result: ["hello", "world"]
.del(item) Removes am item from the array.

Example: ["hello", "world"].del("world")
Result: ["hello"]
.join(seperator) Combine all the values into a single string with a separator.

Example: ["hello", "world"].join(" ")
Result: "hello world"
.map(function) Create a new array and map all the values by calling the function.

Example: ["hello", "world"].map(i => i.upper())
Result: ["HELLO", "WORLD"]
.filter(function) Create a new array and add the values that pass the function filter.

Example: ["hello", "world"].filter(i => i = "hello")
Result: ["hello"]
.take(amount) Create a new array and insert the first X amount of values.

Example: ["hello", "world"].take(1)
Result: ["hello"]
.skip(amount) Create a new array and remove the first X amount of values.

Example: ["hello", "world"].skip(1)
Result: ["world"]
.reverse() Create a new array and reverse the order of the items.

Example: ["hello", "world"].reverse()
Result: ["world", "hello"]
.random() Get a random value from the array.

Example: ["hello", "world"].random()
Result: "hello" or "world"

Object

Function Description
.keys All the keys in the object.

Example: {name: "Miki", discrim: "6045"}.keys
Result: ["name", "discrim"]
.values All the values in the object.

Example: {name: "Miki", discrim: "6045"}.values
Result: ["Miki", "6045"]
.has(key) True if the key exists in the object.

Example: {name: "Miki", discrim: "6045"}.has("name")
Result: true
.del(key) Removes the key from the object.

Example: {name: "Miki", discrim: "6045"}.del("name")
Result: {discrim: "6045"}

Range

Function Description
.from Start position of the range.

Example: (1..10).from
Result: 1
.to End position of the range.

Example: (1..10).to
Result: 10
.toArray() Create an array with every number in the range.

Example: (1..10).toArray()
Result: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
.random() Get a random number from the range.

Example: (1..10).random()
Result: A number between 1 and 10
.map(function) Create a new array and map every number in the range.

Example: (1..10).map(i => i.upper())
Result: ["HELLO", "WORLD"]

Function

Function Description
.name Get the function name.

Example: (fun test() end).name
Result: "test"

Embed

Function Description
.title(value) Sets the title of the embed.

Example: embed().title("New title")
.image(url) Sets the image of the embed.

Example: embed().image("https://media.giphy.com/media/H9jrEhsr1pUMo/giphy.gif")
.color(value) Sets the color of the embed.
The value can either be a hex color (#FFFFFF) or a HTML color (red).

Example: embed().color("red")
.author(name, image, url) Sets the author of the embed. The image and url parameters are optional.

Example: embed().author("Miki")
.footer(content, url) Sets the footer content of the embed. The url parameter is optional.

Example: embed().footer("Miki")
.field(title, content) Adds a new field to the embed.

Example: embed().field("Title", "Content")
.inlineField(tile, content) Adds a new inline field to the embed.

Example: embed().inlineField("Title", "Content")

Storage

Function Description
.keys All the keys in the storage.

Example: storage.keys
Result: ["name"]
.set(key, value) Changes the value in the storage.

Example: storage.set("name", "Miki")
.get(key) Gets the value from the storage.

Example: storage.get("name")
Result: "Miki"
.del(key) Remove the value from the storage.

Example: storage.del("name")
.clear() Clears the storage.

Example: storage.clear()




Zephy, Gerard, xRappy, Veld

Sat Feb 22 2020

Don't have Miki yet?

Invite Miki!Get support