Tutorial by: DereWah


In this tutorial we'll see how to create a Telegram Bot from scratch completely in Skript. I'll teach you the basics on how to make the bot interact with your minecraft server, and at the end you'll have a fully functional Telegram Bot hosted on your minecraft server.

REQUIREMENTS

Initial setup

Creating a Bot on Telegram

Let's get started! First of all, we need to create a Telegram bot. To do so, head on Telegram and search for the username @BotFather
This is an official Telegram bot, and is used to create other bots.
BotFather will guide you through creation of a new bot, and in the end you'll obtain a Bot Token.

In the image, the token is the long string of random characters. You should keep that secret, as anyone with a bot's token can access it.

Authorizing the Bot on Skript

As said above, in order to actually use the bot, we need to login it to it using the token.
Telegram doesn't know that we are the owners of the bot, and only trusts who knows the token.
Therefore, we need to log in to the bot with the following code:

telegram login to bot "USERNAME" with token "TOKEN"

where token is, well, the token, and the username is the @ username your bot has (without the @) . You can see it by opening the bot's information on Telegram.

You should put this effect in a custom Skript command (with an admin permission) or on an on load event, if your server often goes offline.

command /authorizebot:
    permission: *
    trigger:
        telegram login to bot "SkriptItaly_bot" with token "TOKEN"
        send message "Logged in to the bot!"

on load: #other way, in an on load event
    telegram login to bot "SkriptItaly_bot" with token "TOKEN"

To check if everything worked properly, check the console. If you don't see any errors, your bot is now being controlled by Skript!
Right now the bot doesn't do anything, so let's make it alive!

Responding to Messages

One of the first and easiest behaviours to implement are responses. Note that right now we are coding the bot only to interact on telegram, and even though it's entirely coded and hosted on minecraft it has no relation to that. If you're a beginner, you should follow this tutorial from here to understand everything, and then we'll switch to a bot that works with both.

Listen for Messages

When we send a message to the bot, it receives an update. An update can be any interaction with the bot, and holds all the required information for us to work with it. There are different update types, but we'll begin with a message update. In your code, to listen for message updates, simply write

on telegram message: #(1)
    if "%event-telegram bot%" is "USERNAME": #(2)
        #do stuff

(1) is the event, and is fired whenever the the running bot receives a message (or also photos, anything).
If you're writing a bot that interacts with groups, note that bots don't receive by default all the messages from groups, but just commands. If you want to enable message updates also from groups, check this post
(2) If you are runnning multiple bots on the same server, you should know that the "on telegram message" event listens and fires when any running bot receives a message. Because of that, you should filter out other messages directed to other bots that may be running on the server (especially if you're making skripts that you will publish to the public). By adding this check, you'll make sure that the message is directed to your current bot with the username USERNAME. As you can see we're reusing the same variable "USERNAME", and in order to make everything easier (in case you'll change the bot username in the future), let's add it as an option. Edit the skript as below, by adding in the top the Options part.

Options:
    username: USERNAME #constant

command /authorizebot:
    permission: *
    trigger:
        telegram login to bot "{@username}" with token "TOKEN"
        send message "Logged in to the bot!"

on telegram message: #1
    if "%event-telegram bot%" is "{@username}": #2
        #do stuff

Options are basically Skript constants, wherever you write {@username} it will be replaced by Skript with whatever value you put in the Options. In this case your bot username. From now on I'll refer to usernames with the option value.

Now that we have listened for messages, let's make our bot responsive!

Send Messages

In the telegram event on telegram message, add this line after the bot username check:

send telegram message "This message was sent from telegram!" to sender of event-telegram message

Let's analyze the code: the first part is the content of the message. You'll see it appear on telegram when you run the bot and send any message.
The second part is the target. It tells the bot who to send the message to. Instead of sender of event-telegram message, you can type any of these types:

Now that you've added the effect above, if you reload and authorize the skript, you'll have a bot that instantly replies to your messages!

Let's use this first simple Skript to make a bot that welcomes any new user. A user, when starts the bot for the first time, sends automatically a /start command. We can make sure that the text of the message sent was "/start" and reply them with a warm welcome to the bot!

Options:
    username: USERNAME #constant

command /authorizebot:
    permission: *
    trigger:
        telegram login to bot "{@username}" with token "TOKEN"
        send message "Logged in to the bot!"

on telegram message: #1
    if "%event-telegram bot%" is "{@username}": #2
        if text of event-telegram message is "/start":
            send telegram message "Welcome to @{@username}!%nl%This bot has been entirely coded in Skript, following a tutorial on github! Here is a list of commands:%nl%%nl%/list%nl%/admin" to chat of event-telegram message #note that I have changed from (sender of) to (chat of)

Possible issues / bugs

Before we go ahead, I'd like to address some possible issues you might encounter while getting to this part of the tutorial.
1: The console gets spammed with loads of "ERROR [409]" saying multiple instances are running the bot!
This is because you might have authorized the bot multiple times, and the addon Skelegram didn't see that there was another one running and created it. Note that the addon, by default, will not authorize to a bot if it knows that it's already being ran by another skript (you will get a message saying it in the console if you, for example, do /authorizebot multiple times), but, especially with frequent skript reloads or server reloads, it might bug. An easy fix is to add the following command:

command /clearsessions:
    permission: *
    trigger:
        send message "Clearing all bot sessions... This may take up to 50 seconds, so be patient and wait for the Completed messages before continuing using Skelegram skripts."
        clear all telegram sessions
        send message "Completed. If you have more issues, check in the console for errors or fully restart the server."

The command may take up to 50 seconds to complete, as the TG API is quite slow at stopping sessions, so you'll have to wait. If the console still is getting spammed, restart (fully, NO RELOAD) the server. This will 100% stop any running bot (well, you're stopping the server so...) and fix everything.

2: Long error about webhooks -> You are using an invalid token. Double check your token, make sure the string is only "TOKEN" with pasted only the token. It should look something like this:"5846270037:AAEvs7a8p9obmGRUKbu8S3AsVZiFnuhChyY" (don't worry, this token is invalid ;) )

Now that we've addressed some possible issues, let's continue with the bot! In the message, the bot now says "Here is a list of commands:%nl%%nl%/list%nl%/admin"!
Let's create our commands! Those can be created exactly just like the /start command. Make another condition and see if the text of the message is "/list"

Sending Messages as Replies

on telegram message: #1
    if "%event-telegram bot%" is "{@username}": #2
        if text of event-telegram message is "/start":
            send telegram message "Welcome to @{@username}!%nl%This bot has been entirely coded in Skript, following a tutorial on github! Here is a list of commands:%nl%%nl%/list%nl%/admin" to chat of event-telegram message #note that I have changed from (sender of) to (chat of)
        else if text of event-telegram message is "list": #new command check
                #do stuff

In our new do stuff, we want to send to the user a list of all the online players. This could be a cool feature for players that want to see if their best friend (or worst enemy) are online on the server, without having to boot up minecraft.

To do so, well send them a new message, containing the list of all players. To send them the message, however, we'll use a different effect.

reply to telegram message event-telegram message with "There are currently %size of all players% players online:%nl%%nl%%all players%"

We're using "reply". This will send the message automatically in the chat where the command was sent, and it will displayed as a reply. (like in telegram, when you send a message in reply to another). In the text of the message we add size of all players, which is a way to get the amount of online players, and then the list containing all the players. It will be displayed with commas, and will send "DereWah, Dere_X, Notch" (example)

This is the final skript as of right now:

Options:
    username: USERNAME #constant

command /authorizebot:
    permission: *
    trigger:
        telegram login to bot "{@username}" with token "TOKEN"
        send message "Logged in to the bot!"

on telegram message: #1
    if "%event-telegram bot%" is "{@username}": #2
        if text of event-telegram message is "/start":
            send telegram message "Welcome to @{@username}!%nl%This bot has been entirely coded in Skript, following a tutorial on github! Here is a list of commands:%nl%%nl%/list%nl%/admin" to chat of event-telegram message #note that I have changed from (sender of) to (chat of)
        else if text of event-telegram message is "list": #new command check
            if size of all players > 0: #check if there are any players
                reply to telegram message event-telegram message with "There are currently %size of all players% players online:%nl%%nl%%all players%" #send full list and size of list
            else:
                reply to telegram message event-telegram message with "There are no players online ): please join!" #send pity message saying the server is empty.

Sending Messages with buttons

Let's now code the /admin command. We want this command to send the user a message with a link button. The button, when clicked, will send the user to the admin's telegram account, so that they can be contacted.

For this, we'll use functions. If you don't know how functions work, check out this tutorial: https://skripthub.net/tutorials/9 and then come back.

function adminMessage() :: telegram message:
    set {_mess} to a new telegram message with text "Click on the button below to contact an admin!"
    set {_button} to a new inline button with text "ADMIN" with url "https://t.me/DereWah" #you can change the URL with yours. it must be VALID, or you'll receive errors.
    #continue reading

So first of all, we created an empty message, with just some text. If we send simply the message {_mess}, it will not have any keyboard. Each message can have a keyboard, and a keyboard is basically a list of buttons. So, in order to add a button to a message, we'll have to first add it to a keyboard, that will then be associated to the button.

button1,button2,button3 -> keyboard -> message

    set {_kb} to a new inline keyboard with buttons {_button} #you can add more buttons, all of them will be set on the first row
    set 2nd row of keyboard {_kb} to {_button} and {_button2} # If you wish, you can add multiple buttons on multiple rows, by specifying it.

Finally, we must add the keyboard to the message!

    set inline keyboard of {_mess} to {_kb} #add the keyboard

If we send now the message, it will display buttons. Let's return it in our function and send it:

Options:
    username: USERNAME #constant

command /authorizebot:
    permission: *
    trigger:
        telegram login to bot "{@username}" with token "TOKEN"
        send message "Logged in to the bot!"

on telegram message: #1
    if "%event-telegram bot%" is "{@username}": #2
        if text of event-telegram message is "/start":
            send telegram message "Welcome to @{@username}!%nl%This bot has been entirely coded in Skript, following a tutorial on github! Here is a list of commands:%nl%%nl%/list%nl%/admin" to chat of event-telegram message #note that I have changed from (sender of) to (chat of)
        else if text of event-telegram message is "/list": #new command check
            if size of all players > 0: #check if there are any players
                reply to telegram message event-telegram message with "There are currently %size of all players% players online:%nl%%nl%%all players%" #send full list and size of list
            else:
                reply to telegram message event-telegram message with "There are no players online ): please join!" #send pity message saying the server is empty.
        else if text of event-telegram message is "/admin":
            reply to telegram message event-telegram message with adminMessage()

function adminMessage() :: telegram message:
    set {_mess} to a new telegram message with text "Click on the button below to contact an admin!"
    set {_button} to a new inline button with text "ADMIN" with url "https://t.me/DereWah" #you can change the URL with yours. it must be VALID, or you'll receive errors.
    set {_kb} to a new inline keyboard with buttons {_button} #you can add more buttons, all of them will be set on the first row
    set inline keyboard of {_mess} to {_kb} #add the keyboard
    return {_mess}

React to Button clicks

We've seen how to open links on a button press, but we can actually program custom bot behaviour to our buttons. In fact, you can create a button and instead of an URL add a "callback data", which is a message or a code that is sent to the bot upon button press. We can then listen to those presses and for specific codes to understand which button has been pressed and what to do with it.
Let's make a menu with pages! First, create functions for each page of a menu.

function mainPage() :: telegram message:
    set {_b1} to a new inline button with text "page1" with callback data "page1"
    set {_b2} to a new inline button with text "page" with calllback data "page2"
    set {_kb} to a new inline keyboard with button {_b1}
    set 2nd row of keyboard {_kb} to {_b2}
    set {_mess} to a new telegram message with text "This is the main menu!%nl%%nl%Click on buttons below to switch between pages."
    set inline keyboard of {_mess} to {_kb}
    return {_mess}

function firstPage() :: telegram message:
    set {_b1} to a new inline button with text "BACK" with callback data "back"
    set {_kb} to a new inline keyboard with button {_b1}
    set {_mess} to a new telegram message with text "This is the 1st page! You can click on the button below to go back to the main menu."
    set inline keyboard of {_mess} to {_kb}
    return {_mess}

function secondPage() :: telegram message:
    set {_b1} to a new inline button with text "BACK" with callback data "back"
    set {_kb} to a new inline keyboard with button {_b1}
    set {_mess} to a new telegram message with text "This is the 2nd page! You can click on the button below to go back to the main menu."
    set inline keyboard of {_mess} to {_kb}
    return {_mess}

As you can see in the functions, where we created buttons we added a "callback data". This callback data is basically the message that the bot will receive upon presses.

on callback query "back": #Specify that this should be fired ONLY when the button pressed has the word "back" in its callback data.
    if "%event-telegram bot%" is "{@username}" #always check that it is YOUR bot.
        edit telegram message event-telegram message to mainPage()

on callback query "page1:
    if "%event-telegram bot%" is "{@username}" #always check that it is YOUR bot.
        edit telegram message event-telegram message to firstPage() 

on callback query "page2:
    if "%event-telegram bot%" is "{@username}" #always check that it is YOUR bot.
        edit telegram message event-telegram message to secondPage()

If you want, you can add any behaviour inside of those events. You can even make stuff happen in minecraft, such as a "kill-switch" button that stops the server through a button press. Anything. With this example, we're creating a menu that changes its appearance upon button presses and lets us explore pages in it. You can create as many pages as you want by just making functions.

Conclusion

With Skelegram it is possible to create fully functional Telegram Bots. The main purpose of this should be to link Minecraft and Telegram, but you also make stuff that isn't related to the server, and use it as a host.

As a finaly tip, I have created a Skript called TeleLink. TeleLink manages linking minecraft users to their telegram accounts for you. If you think about it, Skript doesn't know what Telegram account a player has. To get it, TeleLink lets the player go through a pairing process (that requires sending a code to make sure it's the actual user of the account) and stores such information in the database. As a Skript developer, you can use functions to get a user's TG account from their MC, if they have linked one on the server. To learn more, check out the Skript: https://www.spigotmc.org/resources/telelink-link-minecraft-accounts-to-telegram-with-skript.109675/


Did you find DereWah's tutorial helpful?


You must be logged in to comment

  • Aug. 11, 2023, 1:09 a.m. - steveshat  

    Why would you make a telegram bot on a minecraft server...

    |