Skip to content

Working with Callbacks

Astariul edited this page May 25, 2019 · 5 revisions

Callbacks allow you to do 2 things :

  1. Updating the content of the next page, to display dynamic information.
  2. Choose a path between several pages.

Let's see them in details.


Callback's signature

When declaring your own callback, always use the following signature :

async def callback_name(link, member, prev_input):

where :

Name Type Description
link Link Current link being displayed to user.
member Discord.Member This is the member using the help system.
prev_input list of Discord.Message List of messages previously inputted by the user. If user didn't input anything, this list is empty.

Note : your callback should be asynchronous.

Update the content of the next page

Let's say you want to display to the user its Discord ID. You can do that with a callback, which will update the next page to display to change the message and put the Discord ID. Example :

async def display_id(link, member, prev_input):
    link.page().msg = "Your ID is : {}".format(member.id)

In this example, we took the current link, get the page that will next be displayed by this link with the page() method, and update the msg of this page.

Choose a path between several pages

Let's say you give your user the possibility to create a guild, with a unique name. When creating the guild, either the name is taken and an error should be displayed to user, or a success message should be displayed if the name was free. Let's see how to do with an example.

First, when declaring your pages, you should link both pages (success & failure) to the one with the callback :

page_register = Page('Registering...')
page_fail = Page('Fail')
page_success = Page('Success')

page_register.link([page_fail, page_success], callbacks=check_register)

Now, your callback is called when we are on the link between page_register and page_fail / page_success. You need to adapt which page will be displayed depending on your database call :

async def check_register(link, member, prev_input):
    # Call database
    is_already_registered = ...

    if is_already_registered:
        link.path = 0
    else:
        link.path = 1

Here, depending on the outcome, we update the path to be taken by the link. If the name is already registered, we will display the first page of the list : page_fail. If not, we will display the second page of the list : page_success.

Retrieving the user's input

The help system record the user's input when this is needed by a link (MsgLink).

Let's make a simple callback that display the previous user's input, but reversed :

async def reversed(link, member, prev_input):
    last_message = prev_input[-1].content
    link.page().msg = last_message[::-1]

prev_input is the list of all previous inputs by the user.


Important note : In the Repl.it example, several inputs are recorded before a callback is used. It's completely possible to do it, but be careful ! If your user come back to previous page and enter again a message, this will be recorded as a new input ! So instead of having 2 messages, you will have 3 ! To avoid that, just don't build a parent link between the 2 inputs. So you are sure that the last 2 inputs are the one you want.