# Pingbot | # Pingbot | ||||
A Mastodon bot for pinging | |||||
Pingbot monitors a Mastodon account, and will ping one or more other accounts any time | |||||
that account gets a notification. This is useful for monitoring an admin account that | |||||
may not be logged in all the time, or for checking in on an old account after you've | |||||
made a new one. | |||||
## Setup | |||||
**On the account you want to monitor**, open Preferences, then Development, and click | |||||
the New Application button at the upper right. | |||||
You'll need to give your application a name; this can be pretty much anything you want. | |||||
Leave "Application website" blank, and leave "Redirect URI" alone. | |||||
You can leave Scopes alone; all Pingbot does is check your notifications and send you | |||||
DMs. However, if you want to limit Pingbot's access for security, it **must** have | |||||
`read:notifications` and `write:statuses` in order to do its job. | |||||
Click the Submit button at the bottom, and you'll see "Application successfully created", | |||||
as well as your new application in the list below. Click the name you chose (it should be | |||||
blue), and this will bring up a screen that shows you the **client key**, **client secret**, | |||||
and **access token**. | |||||
In Pingbot's directory, copy `sample-config.cfg` to `config.cfg`, and then open it for | |||||
editing. You'll need a separate header in the config file, enclosed by [brackets], for | |||||
each bot you want to run in the same directory. The sample configuration file includes | |||||
a [pingbot] header for you, as well as a [DEFAULT] header for settings that apply to | |||||
every bot in the directory. You should place most of your information under the | |||||
[pingbot] header; the configuration file includes instructions on how to do this. | |||||
(Note that what the Mastodon web interface calls a "Client key", the config file | |||||
calls a `client_id`.) | |||||
In the configuration file, every username you include should *not* have an @ before it | |||||
(e.g. `noelle@elekk.xyz`, not `@noelle@elekk.xyz`). | |||||
Once all your information is in the configuration file, save it, and then run | |||||
`ananas config.cfg` | |||||
in a terminal window and your bot will start up and begin listening! In Linux, you can | |||||
run your bot in the background by adding an & to the end: | |||||
`ananas config.cfg &` | |||||
Or you can use a window manager like `tmux` or `screen`, which will let you keep the | |||||
bot running on a server without you havnig to be logged in. | |||||
## Making configuration changes | |||||
If you want to change Pingbot's settings, you'll need to stop and restart the bot. | |||||
Make sure you stop the bot *before* you make changes; Pingbot saves its configuration | |||||
when it shuts down, and might overwrite your changes. |
class PingBot(PineappleBot): | class PingBot(PineappleBot): | ||||
def start(self): | def start(self): | ||||
self.notifiees = self.config.notify.split(',') | self.notifiees = self.config.notify.split(',') | ||||
self.notifiees = [f"@{notif}" for notif in self.notifiees] | |||||
self.notifiees_str = ", ".join(self.notifiees) | self.notifiees_str = ", ".join(self.notifiees) | ||||
print(f"Now monitoring {self.config.monitor}; pinging {self.notifiees_str}.") | print(f"Now monitoring {self.config.monitor}; pinging {self.notifiees_str}.") | ||||
petitioner = user["acct"] | petitioner = user["acct"] | ||||
if petitioner != self.config.monitor: # Prevent self-replies | if petitioner != self.config.monitor: # Prevent self-replies | ||||
msg = mention["uri"] | msg = mention["uri"] | ||||
if self.config.full_message: | |||||
if self.config.full_message and str(self.config.full_message).lower() == "true": | |||||
msg += f"\n\n{html_strip_tags(mention['content'])}" | msg += f"\n\n{html_strip_tags(mention['content'])}" | ||||
visibility = 'direct' | visibility = 'direct' | ||||
# This is for logging purposes. You may wish to redirect this into a text log. | # This is for logging purposes. You may wish to redirect this into a text log. | ||||
print(f"Received a reply from {petitioner}. Pinging {self.notifiees_str}.") | print(f"Received a reply from {petitioner}. Pinging {self.notifiees_str}.") | ||||
notify_list = " ".join(self.notifiees) | notify_list = " ".join(self.notifiees) | ||||
status = f"{notify_list} {self.monitor} has received a new message from {petitioner}:\n\n{msg}" | |||||
status = f"{notify_list} {self.config.monitor} has received a new message from {petitioner}:\n\n{msg}" | |||||
if len(status) > 450: # don't let the post get too long! | if len(status) > 450: # don't let the post get too long! | ||||
status = status[:450] + " ...(message continues)" | status = status[:450] + " ...(message continues)" | ||||
self.mastodon.status_post(status, visibility=visibility) | self.mastodon.status_post(status, visibility=visibility) |
client_id = | client_id = | ||||
client_secret = | client_secret = | ||||
access_token = | access_token = | ||||
# The full name of the account you're monitoring, WITH the initial @. | |||||
# The full name of the account you're monitoring, without the initial @. | |||||
# This is only for record-keeping and to make sure the bot doesn't | # This is only for record-keeping and to make sure the bot doesn't | ||||
# reply to itself. | # reply to itself. | ||||
monitor = @contact@mastodon.example | |||||
monitor = contact@mastodon.example | |||||
# The full names of each account you want to notify when the monitored | # The full names of each account you want to notify when the monitored | ||||
# account gets a notification, separated by a comma (but no space!), | # account gets a notification, separated by a comma (but no space!), | ||||
# WITH the initial @. | |||||
notify = @admin@mastodon.example,@moderator@mastodon.example | |||||
# without the initial @. | |||||
notify = admin@mastodon.example,moderator@mastodon.example | |||||
# If this is "True", Pingbot will forward the full message to each | |||||
# account above; if it's anything else, Pingbot will just send a link to | |||||
# the original message. | |||||
full_message = True |