Open OddBloke opened 5 years ago
This is a feature that I've already starting playing around with implementing locally. I have the beginnings of something that works for Mastodon.
(I'm currently not running any Twitter bots, so I won't be able to build out the Twitter-specific part of the change.)
OK, I'm putting this down for now, so I'm going to checkpoint my thinking (a) so I can pick it up more easily when I come back to it, and (b) so that anyone else who cares can comment on it.
My initial (very WIP) implementation adds a handle_mentions
method to Bot
. This iterates over each service calling service.get_mentions()
, which generates a set of parameters for each mention. Those parameters are passed to self.handle_mention
by handle_mentions
. The expectation is that a bot implementer will (a) implement handle_mention
, and (b) call self.handle_mentions()
in their main
implementation to trigger the handling.
handle_mention
takes three parameters:
reply_callback
is the function to call if you want to reply to the mention. Because we only want replies to mentions to go to the service from which the mention originated, we can't use self.post
, and passing a callback in keeps the implementation of handle_mention
service-agnostic. (An alternative I'm considering: keep a mapping of mention_id
-> service
somewhere so that we can just use self.post
with the appropriate in_reply_to_id
and have it route that only to the appropriate service.)status
contains the text of the mention. This turns out to be more complex than you might expect, because Mastodon's API only gives you the rendered-to-HTML content of a status. Initially, I implemented this as two parameters (status
, status_content_type
) so that I could just pass the Mastodon API content through, but I decided that this was pretty hostile to bot developers who would almost all have to implement some HTML parsing just to make their bots work with Mastodon. Instead, we use a simple html.parser.HTMLParser
subclass to just pull out all the text parts of the status. (I'm thinking that storing the original HTML as an attribute that people can use if they need the full HTML would make this usable both for the "trying to build a quick bot" use case and the "I need the full HTML because I'm fancy" use case.)recipients
contains a list of people mentioned in the message. This is important to pass through separately for Mastodon, because the text of the status
doesn't carry enough information to correctly mention users on other instances (for example, with this status, the status text is @PromoBot @Odd_Bloke Test
, which doesn't distinguish between @Odd_Bloke@wrestle.town
and @Odd_Bloke@mastodon.social
; even with the HTML, you'd have to do some complex parsing to get there).(I currently haven't done anything to handle only fetching mentions since the last time the bot ran.)
Thanks, this looks good!
I don't have time to think about this in detail at the moment, but I think it might be useful to have a class which encapsulates a status update and handles the HTML issue, as well as stuff like message length and attachments when posting tweets/toots.
I would like to be able to extend my bots to be able to handle the mentions they receive, including an easy interface to reply to them.
(Specifically, I'd like people to be able to give the start of a wrestling promo and have @PromoBot reply back with one generated using Markov chains.)