bots-as-digital-infrapunctures/content/bot-example/mastodon-bot.ipynb

442 lines
14 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Mastodon bot Example"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With this Notebook you can make a bot! \n",
"\n",
"This is a space for experimentation, so feel free to use it as a place to test and play around.\n",
"\n",
"The bot will post its messages to the Mastodon instance [botsin.space](https://botsin.space/about), a space dedicated fully to bot users. \n",
"\n",
"Once your bot is running it will write messages here: <https://botsin.space/@infrapunctures>."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"-------------------"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This Mastodon bot example is part of the module *Bots as Digital Infrapunctures* done by Cristina Cochior and Manetta Berends in the proximity of [Varia](https://varia.zone/en/). The module is produced in the context of the course *Data-driven research and digital tools* at the [Department of Media & Culture, Utrecht University](https://www.uu.nl/en/organisation/department-of-media-and-culture-studies) in collaboration with [Dr. Karin van Es](https://www.karinvanes.net) and [Creative Coding Utrecht](https://creativecodingutrecht.nl/)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We now find ourselves in a Jupyter Notebook — an open-source web application that allows you to create and share documents that contain live code, equations, visualizations and narrative text. This notebook gives us the possibility to write comments alongside the code, and to write run code without installing the dependencies on our own computers.\n",
"\n",
"We're going to be using the [Python](https://www.python.org/) programming language for this example.\n",
"\n",
"In order to execute a block of code, click the *Run* button from the toolbox on the top right corner. Up until the section \"Tooting time!\" every block needs to be run in the order they are layed out in.\n",
"\n",
"You can change the code blocks by double clicking the block and you can run them in order to see the effects.\n",
"\n",
"Also, you can see if a code block is being processed by looking at the `[*]` symbol on the left side. If it changed into a number, for example `[1]`, your code block is executed!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Import the Mastodon library"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We start by importing a Python code library that is written for Mastodon. You can find more information about it on its [code respository](https://github.com/halcy/Mastodon.py)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Defaulting to user installation because normal site-packages is not writeable\n",
"Requirement already satisfied: Mastodon.py in /home/mb/.local/lib/python3.7/site-packages (1.5.1)\n",
"Requirement already satisfied: python-magic in /usr/local/lib/python3.7/dist-packages (from Mastodon.py) (0.4.15)\n",
"Requirement already satisfied: requests>=2.4.2 in /home/mb/.local/lib/python3.7/site-packages (from Mastodon.py) (2.25.0)\n",
"Requirement already satisfied: decorator>=4.0.0 in /usr/lib/python3/dist-packages (from Mastodon.py) (4.3.0)\n",
"Requirement already satisfied: pytz in /home/mb/.local/lib/python3.7/site-packages (from Mastodon.py) (2020.1)\n",
"Requirement already satisfied: python-dateutil in /home/mb/.local/lib/python3.7/site-packages (from Mastodon.py) (2.8.1)\n",
"Requirement already satisfied: six in /usr/lib/python3/dist-packages (from Mastodon.py) (1.12.0)\n",
"Requirement already satisfied: blurhash>=1.1.4 in /home/mb/.local/lib/python3.7/site-packages (from Mastodon.py) (1.1.4)\n",
"Requirement already satisfied: chardet<4,>=3.0.2 in /usr/lib/python3/dist-packages (from requests>=2.4.2->Mastodon.py) (3.0.4)\n",
"Requirement already satisfied: idna<3,>=2.5 in /usr/lib/python3/dist-packages (from requests>=2.4.2->Mastodon.py) (2.6)\n",
"Requirement already satisfied: certifi>=2017.4.17 in /usr/lib/python3/dist-packages (from requests>=2.4.2->Mastodon.py) (2018.8.24)\n",
"Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/lib/python3/dist-packages (from requests>=2.4.2->Mastodon.py) (1.24.1)\n"
]
}
],
"source": [
"import sys\n",
"!{sys.executable} -m pip install Mastodon.py"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from mastodon import Mastodon "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Configuring the infrastructure"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With the code below we are choosing which Mastodon instance we want to use."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"instance = 'https://botsin.space'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Starting the bot"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We have saved the user credentials in a file called 'mastodon-bot-usercred.secret' which contains a token code for indentifying our bot and the name of the instance. In the code below we access this secret file in order to get authorisation to post on the bot's behalf."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"mastodon = Mastodon(\n",
" access_token = 'mastodon-bot-usercred.secret',\n",
" api_base_url = instance\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tooting time! \n",
"\n",
"The following code blocks will already allow us to toot! Tooting in Mastodon vernacular means posting. \n",
"\n",
"Each block will toot something else. You can make changes to the variables in order to toot something else."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Oneliner bot"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is the simplest command you need to run to make a toot:\n",
"\n",
"(If it works: it will print a lot of metadata of the toot you just sent out!)<br>\n",
"(Also: you should be able to see your toot here: https://botsin.space/@infrapunctures) "
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The bot just tooted the following: \"testing tooting\", you can see it here: https://botsin.space/@infrapunctures\n"
]
}
],
"source": [
"toot = 'testing tooting'\n",
"mastodon.toot(toot)\n",
"print(f'The bot just tooted the following: \"{ toot }\", you can see it here: https://botsin.space/@infrapunctures')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Every 5 minutes bot"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the code below we tell the bot to go through the list and toot each element every 5 minutes."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The bot just tooted the following: \"Sentence 1\", you can see it here: https://botsin.space/@infrapunctures\n",
"The bot just tooted the following: \"Sentence 2\", you can see it here: https://botsin.space/@infrapunctures\n",
"The bot just tooted the following: \"Sentence 3\", you can see it here: https://botsin.space/@infrapunctures\n",
"The bot just tooted the following: \"Sentence 4\", you can see it here: https://botsin.space/@infrapunctures\n",
"The bot just tooted the following: \"Sentence 5\", you can see it here: https://botsin.space/@infrapunctures\n"
]
}
],
"source": [
"from time import sleep\n",
"\n",
"toots = [\n",
" 'Sentence 1',\n",
" 'Sentence 2',\n",
" 'Sentence 3',\n",
" 'Sentence 4',\n",
" 'Sentence 5'\n",
"]\n",
"\n",
"for toot in toots:\n",
" mastodon.toot(toot)\n",
" print(f'The bot just tooted the following: \"{ toot }\", you can see it here: https://botsin.space/@infrapunctures')\n",
" sleep(300) # 300 seconds = 5 minutes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Sentence generator bot"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's make another bot. \n",
"\n",
"In this block we will generate a sentence from three lists of words and toot it."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The bot just tooted the following: \"Parks likes oranges\", you can see it here: https://botsin.space/@infrapunctures\n"
]
}
],
"source": [
"import random\n",
"\n",
"names = ['Rosa', 'Luxembourg', 'Parks']\n",
"objects = ['oranges', 'mangos', 'lychees']\n",
"actions = ['likes', 'dislikes', 'is indifferent to']\n",
"\n",
"n = random.choice(names)\n",
"o = random.choice(objects)\n",
"a = random.choice(actions)\n",
"\n",
"separator = ' '\n",
"\n",
"toot = n + separator + a + separator + o\n",
"mastodon.toot(toot)\n",
"\n",
"print(f'The bot just tooted the following: \"{ toot }\", you can see it here: https://botsin.space/@infrapunctures')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Workday / Weekend bot"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One more bot!\n",
"\n",
"`date.today()` returns the day of the week as an integer, where Monday is `0` and Sunday is `6`. \n",
"\n",
"The code bellow will make your bot toot the first sentence if it is a work day, and the second sentence if it is the weekend. "
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The bot just tooted the following: \"I would prefer not to.\", you can see it here: https://botsin.space/@infrapunctures\n"
]
}
],
"source": [
"from datetime import date\n",
"\n",
"day = date.today().weekday()\n",
"\n",
"if (day != 5 & day != 6):\n",
" toot = \"When we have no memory or little imagination of an alternative to a life centered on work, there are few incentives to reflect on why we work as we do and what we might wish to do instead.\"\n",
" mastodon.toot(toot)\n",
"else:\n",
" toot = \"I would prefer not to.\"\n",
" mastodon.toot(toot)\n",
" \n",
"print(f'The bot just tooted the following: \"{ toot }\", you can see it here: https://botsin.space/@infrapunctures')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## For further exploration: make your own bot!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you would like to make your own bot from scratch, you can remove the `#` from the code blocks below and save it as a new Notebook. \n",
"\n",
"The `#` turns them into comments instead of executable lines, so they will not run. \n",
"\n",
"These only need to be run once which for this module had been done in preparation. \n",
"\n",
"The code registers the bot as an application and saves the details as a `.secret` plain text file."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# instance = 'URL'\n",
"# username = 'USERNAME'\n",
"# password = 'PASSWORD'"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"# Mastodon.create_app(\n",
"# 'NAMEOFYOURBOT',\n",
"# api_base_url = instance,\n",
"# to_file = 'mastodon-bot.secret'\n",
"# )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# mastodon = Mastodon(\n",
"# client_id = 'mastodon-bot.secret',\n",
"# api_base_url = instance\n",
"# )\n",
"\n",
"# mastodon.log_in(\n",
"# username,\n",
"# password,\n",
"# to_file = 'mastodon-bot-usercred.secret'\n",
"# )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you put this code block in the beginning of your Notebook, you can register your own bot!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}