Tutorial: Moo Cow
in this tutorial, we will build a simple bot that replies with a random length mooo when mentioned. We will be going through all the steps for it.
Creating an account
In order to use mechanical_bull, we need an account on a server supporting the Moo Client Registration Flow. This can be accomplished through using bovine as a server.
To build this tutorial, I registered the account moocow@mymath.rocks and then ran
$ python -m mechanical_bull.add_user --accept moocow mymath.rocks
Please add did:key:z6MkekwC6R9bj9ErToB7AiZJfyCSDhaZe1UxhDbCqJrhqpS5 to the access list of your ActivityPub actor
We furthermore should update the actor profile to include a name, a summary, and a profile picture.
The handler
We create a file moocow_handler.py and add the following to it:
import bovine
import random
async def handle(client: bovine.BovineClient, data: dict, min_o=4, max_o=20):
if data.get("type") != "Create":
return
obj = data.get("object")
if not isinstance(obj, dict):
return
tags = obj.get("tag")
if not isinstance(tags, list):
if isinstance(tags, dict):
tags = [tags]
else:
return
This so far ensures that the activitiy, we receive is a new post and that it contains tags. Tags are what is used to encode mentions. We will now iterate over the tags and see if our actor is mentioned.
actor_id = client.information["id"]
def mentions_me(entry):
return entry["type"] == "Mention" and entry["href"] == actor_id
if not any(mentions_me(x) for x in tags):
return
So we are now in the position of wanting to reply, for this we build a note and send it via
mention = await client.object_factory.mention_for_actor_uri(obj["attributedTo"])
note = client.object_factory.note(
content="m" + "o" * random.randint(min_o, max_o),
to={obj["attributedTo"]},
tag=[mention.build()],
in_reply_to=obj["id"]
).as_public().build()
await client.send_to_outbox(client.activity_factory.create(note).build())
This means we are done. By putting this file into the directory the config.toml file is inand editing it to say:
[moocow]
private_key = "z3u2Yxcowsarethebestcowsarethebestcowsarethebest"
host = "mymath.rocks"
[moocow.handlers]
"mechanical_bull.actions.accept_follow_request" = false
"moocow_handle" = { min_o = 5, max_o = 25 }
we are done. After restarting the mechanical bull process, we should be able to contact the new bot.