No description
Find a file
2023-05-22 16:14:53 +02:00
examples Extend the advanced example to be a complete command-line Mastodon client for local posts 2023-04-03 20:55:26 +02:00
mastobot Rename data_types.py to models.py and add docstrings 2023-05-22 16:14:53 +02:00
tests Rename data_types.py to models.py and add docstrings 2023-05-22 16:14:53 +02:00
.gitignore Initial commit 2020-07-19 23:13:08 +08:00
.gitlab-ci.yml Add CI job for running automated tests 2023-03-29 20:58:58 +02:00
CHANGELOG.md Rename data_types.py to models.py and add docstrings 2023-05-22 16:14:53 +02:00
HACKING.md Rewrite HACKING.md to be more general and apply to the new version of mastobot 2023-03-29 20:48:52 +02:00
LICENSE Add 0BSD license 2020-07-19 23:15:26 +08:00
poetry.lock Add CI job for running automated tests 2023-03-29 20:58:58 +02:00
pyproject.toml Rename package to matzobot and make it publishing ready 2023-05-12 21:21:51 +02:00
README.md Update the README with a section on using register_decorator 2023-03-29 20:21:44 +02:00

Babka Mastobot

This is a fork of the Mastobot library. The goal of this fork is to improve the internal structure of this library to be more functional while at the same time relying on predicate functions (a function returning a bool) for the most generic possible decorator generators, while also providing easy support for the way people used mastobot using text and regex patterns.

Examples

from mastobot import Bot

bot = Bot(
    instance_url="https://mastodon.instance",
    access_token="your_access_token"
)

@bot.on_mention_text("hi")
def respond_to_hi(event):
    status = event.get_latest_status()
    name = status.account.username

    return f"Hey, {name}!"

bot.run()

You should be able to migrate from Mastobot to this library in the simplest cases by just appending _text or _regex to on_mention and on_home_update and it will behave predictably.

Predicate functions and the generic on

The reason you need to add _text or _regex to your decorators if you want to pass in the old text patterns, is that on_mention and on_home_update now expect a predicate function as it's argument instead of a string:


@bot.on_mention(lambda event: event.notification.account.username == "CSDUMMI")
def on_mention_from_csdummi(event):
    return "Hi, CSDUMMI"

This function will only be called if an account with the username CSDUMMI is mentioning the bot.

As you can see, predicate functions can be rather more powerful than simple strings as they can consider additional information about an event occuring or even have side-effects (i.e. reading a database, checking an ACL).

Both on_mention and on_home_update now expect a predicate function as their only argument.

But there is more: if you want to create a callback that should be triggered on any event that the bot receives, you can use the .on function.

from urllib.parse import urlparse

def predicate(event):
    status = event.get_latest_status()

    if status is None:
        return False

    domain = urlparse(status.url).netloc
    return domain == "mastodon.instance"

@bot.on(predicate):
def on_local(event):
    return "Hello"

Here the on_local function is called for every event that has a status from the instance mastodon.instance.

(See examples/simple.py for a complete example).

Reusing predicates with register_decorator

Sometimes you have a predicate that in some form you want to reuse across multiple callback functions. For this purpose we have register_decorator.


def on_command(command, event):
    status = event.get_latest_status()
    if status and type(event) is NotificationEvent):
        return command in status.text
    else:
        return False


bot.register_decorator(on_command)

@bot.on_command("/help")
def help(event):
    return "How can I help you?"

@bot.on_command("/greet")
def greet(event):
    return f"Hello, {event.get_latest_status().account.display_name}"

In this example a generic on_command decorator is created that receives a string and whenever this specific string is found in a notification, it will call etiher help or greet.

The predicate supplied to register_decorator can accept both keyword and positional arguments, although the last positional argument always has to be the event that is being checked.

(See examples/advanced.py for a complete example).

Using Types

mastobot.data_types and mastobot.events contain the Pydantic Model definitions used to parse Mastodon.py dictionaries. You can either look at these modules themselves or use help to get the documentation on specific types.

I'll illustrate here the general use of these modules.

Events

mastobot.events.EventTypes is a Union f the four main events supported by Mastodon.py:

  • UpdateEvents occur when a new post appears on the home timeline of a user.
  • NotificationEvents occur when a new notification to the bot occurs. (This is the only event type received by functions decorated with on_mention)
  • DeleteEvents may occur when a status was deleted.
  • ConverstaionEvents may occur when a status in a direct message was added.

When an event is received, it is first parsed as a generic Event and later converted to the specific event that it represented using Event.to_event.

The functions decorators provided by this library expect to decorator a function taking one of the above specific EventTypes and returning either a Reply (from mastobot.data_types) or a str, which is then posted as a reply to the status causing the given event.

Every specific event has a function called get_latest_status that returns the Status object causing this event. (Except for the DeleteEvent, which returns None).