Bovine
The source for bovine can be on codeberg. As bovine is meant as a general purpose Fediverse library, the actual source code for we are running is included in the docker files.
Furthermore, our bovine setup includes an automated actor called MooCow that replies to every post that mentions them with moo.
You can install the Fediverse pasture via
Start bovine via
Access Data
Property | Value |
---|---|
MooCow handle | moocow@bovine |
Your user handle | vanilla@bovine |
secret | z3u2Yxcowsarethebestcowsarethebestcowsarethebest |
Note
Due to bovine’s architecture, actor URIs are not stable, but generated
randomly on each container build. The same goes for the public / private
key. It unfortunately, seems to be necessary to purge databases of some
other Fediverse applications in order for them to recognize the bovine
actors. This can be achieved via rm -rf volumes
.
bovine repl
By running
one can drop into a python REPL to interact as the user vanilla
.
Messaging moocow
In order to message moocow, we will first look her up using webfinger. Then build a note that mentions her, finally send it to her then check our inbox.
>>> from bovine.clients import lookup_uri_with_webfinger
>>> remote, _ = await lookup_uri_with_webfinger(session=client.session, uri="acct:moocow@bovine", domain="http://bovine")
>>> mention = (await object_factory.mention_for_actor_uri(remote)).build()
>>> note = object_factory.note(to={remote}, tag=[mention], content="moo").build()
>>> await client.send_to_outbox(activity_factory.create(note).build())
>>> await client.inbox().__anext__()
The result is
{
"@context": "about:bovine",
"actor": {
"id": "http://bovine/endpoints/tJSD4he3EVY3epL5P6R0gV-JfWTXP0MSsgecw_hgLp8",
"inbox": "http://bovine/endpoints/MRZi0ilmfD7ZdD6Nxfte2XBrcVPyCFFMe6U7RuOnQMg",
"name": "moocow",
"outbox": "http://bovine/endpoints/eI-EJJIQFvOyNSkUGJcbKk7C_QFVsAoGiZIGqm5UyBE",
"preferredUsername": "moocow",
"publicKey": "http://bovine/endpoints/tJSD4he3EVY3epL5P6R0gV-JfWTXP0MSsgecw_hgLp8#serverKey",
"type": "Person",
},
"cc": ["http://bovine/endpoints/_l28Gx9jXnHHeMgua7_LiHRgHf6169GARwTGug6ZKYY"],
"id": "http://bovine/objects/226e81b5-9266-41d4-889b-eb4c23fab6ef",
"object": {
"attributedTo": "http://bovine/endpoints/tJSD4he3EVY3epL5P6R0gV-JfWTXP0MSsgecw_hgLp8",
"cc": ["http://bovine/endpoints/_l28Gx9jXnHHeMgua7_LiHRgHf6169GARwTGug6ZKYY"],
"content": "mooooo",
"id": "http://bovine/objects/f3ad7979-03a3-43b3-bfdf-37f2a92313be",
"inReplyTo": "http://bovine/objects/1d092228-b508-4779-98a0-998d48c289e8",
"likes": "http://bovine/objects/f3ad7979-03a3-43b3-bfdf-37f2a92313be/likes",
"replies": "http://bovine/objects/f3ad7979-03a3-43b3-bfdf-37f2a92313be/replies",
"shares": "http://bovine/objects/f3ad7979-03a3-43b3-bfdf-37f2a92313be/shares",
"tag": [{"href": "http://bovine/endpoints/ITx52m5Cb4gxLfEzLRwVTtX25kd8NMVGM3EsWwn6gOo", "name": "vanilla@bovine", "type": "Mention"}],
"to": ["http://bovine/endpoints/ITx52m5Cb4gxLfEzLRwVTtX25kd8NMVGM3EsWwn6gOo", "as:Public"],
"type": "Note",
},
"to": ["http://bovine/endpoints/ITx52m5Cb4gxLfEzLRwVTtX25kd8NMVGM3EsWwn6gOo", "as:Public"],
"type": "Create",
}
Inbox
To view the inbox, run
Replying
Assuming, you declared first_post
as in the previous section, you
can now compose a reply via
>>> mention = (await object_factory.mention_for_actor_uri(first_post["actor"]["id"])).build()
>>> reply = object_factory.reply(first_post["object"], content="I'm replying to you", tag=[mention]).build()
>>> await client.send_to_outbox(activity_factory.create(reply).build())
What is available here is described in the documentation for