Use direct/group API

Closes https://git.autonomic.zone/decentral1se/xbotlib/issues/13.
This commit is contained in:
Luke Murphy 2021-01-13 21:56:45 +01:00
parent 64cd87fb78
commit e3282a89bc
No known key found for this signature in database
GPG Key ID: 5E2EF5A63E3718CC
4 changed files with 49 additions and 67 deletions

View File

@ -1,5 +1,9 @@
# xbotlib x.x.x (UNRELEASED) # xbotlib x.x.x (UNRELEASED)
# xbotlib 0.6.0 (2021-01-13)
- Implement direct/group API ([#13](https://git.autonomic.zone/decentral1se/xbotlib/issues/13))
# xbotlib 0.5.0 (2021-01-13) # xbotlib 0.5.0 (2021-01-13)
- Revert `source` -> `sender` on `SimpleMessage` as it is more clear ([cf93c07294](https://git.autonomic.zone/decentral1se/xbotlib/commit/cf93c07294d72b11d465491680f5befe882db9bf)) - Revert `source` -> `sender` on `SimpleMessage` as it is more clear ([cf93c07294](https://git.autonomic.zone/decentral1se/xbotlib/commit/cf93c07294d72b11d465491680f5befe882db9bf))

View File

@ -40,21 +40,16 @@ Here's the code for the `EchoBot`.
```python ```python
class EchoBot(Bot): class EchoBot(Bot):
"""Gives back what you sent it. def direct(self, message):
self.reply(message.body, to=message.sender)
In group chats, it responds to the following format. def group(self, message):
if "echobot" in message.body:
echobot:foo self.reply(message.body.split(":")[-1], room=message.room)
"""
def react(self, message):
if message.type == "chat":
self.reply(message.body, to=message.sender)
if message.type == "groupchat" and "echobot" in message.body:
_, to_echo = message.body.split(":")
self.reply(to_echo, room=message.room)
``` ```
Read more in the [API reference](#api-reference) for how to write your own bots.
## All examples ## All examples
- **EchoBot**: Sends back what you sent it - **EchoBot**: Sends back what you sent it
@ -64,37 +59,30 @@ See [xbotlib.py](./xbotlib.py) for all example bots.
## API Reference ## API Reference
When writing your own bot, you always sub-classes the `Bot` class provided from When writing your own bot, you always sub-class the `Bot` class provided from
`xbotlib`. All underling functions can be extended. For example, if you want to `xbotlib`. Then if you want to respond to a direct message, you write a
enable more plugins or add different functionality. If something feels awkward [direct](#botdirectmessage) function. If you want to respond to a group chat
then please raise a ticket for that. Seamlessness is still a bitch but we're message, you write a [group](#botgroupmessage) function.
trying anyway.
> Bot.react(message) ### Bot.direct(message)
A function which you define in your bot implementation in order to respond to Respond to direct messages.
chat messages. You can respond to both direct messages and group chat messages
in this function by checking the `message.type` which can be either `chat` or
`groupchat`.
Arguments: Arguments:
- **message**: sent message and metadata (see [message](#message) reference below) - **message**: received message (see [SimpleMessage](#simplemessage) below for available attributes)
> Bot.reply(body, to=None, room=None) ### Bot.group(message)
Send back a response to a direct chat message. Respond to a message in a group chat.
Arguments: Arguments:
- **body**: the message to send - **message**: received message (see [SimpleMessage](#simplemessage) below for available attributes)
- **to**: which user account to reply to (direct chat)
- **room**: which room to reply to (group chat)
> SimpleMessage ### SimpleMessage
A simple message format. This is the type that you work with when your function A simple message interface.
accepts a `message` argument.
Attributes: Attributes:

View File

@ -4,7 +4,7 @@ build-backend = "poetry.masonry.api"
[tool.poetry] [tool.poetry]
name = "xbotlib" name = "xbotlib"
version = "0.5.0" version = "0.6.0"
description = "XMPP bots for humans" description = "XMPP bots for humans"
authors = ["decentral1se <lukewm@riseup.net>"] authors = ["decentral1se <lukewm@riseup.net>"]
maintainers = ["decentral1se <lukewm@riseup.net>"] maintainers = ["decentral1se <lukewm@riseup.net>"]

View File

@ -117,13 +117,13 @@ class Bot(ClientXMPP):
def register_xmpp_event_handlers(self): def register_xmpp_event_handlers(self):
"""Register functions against specific XMPP event handlers.""" """Register functions against specific XMPP event handlers."""
self.add_event_handler("session_start", self.session_start) self.add_event_handler("session_start", self.session_start)
self.add_event_handler("message", self.message) self.add_event_handler("message", self.direct_message)
self.add_event_handler("groupchat_message", self.groupchat_message) self.add_event_handler("groupchat_message", self.group_message)
def message(self, message): def direct_message(self, message):
"""Handle message event.""" """Handle message event."""
if message["type"] in ("chat", "normal"): if message["type"] in ("chat", "normal"):
self.react(SimpleMessage(message)) self.direct(SimpleMessage(message))
def session_start(self, event): def session_start(self, event):
"""Handle session_start event.""" """Handle session_start event."""
@ -136,11 +136,11 @@ class Bot(ClientXMPP):
if room and nick: if room and nick:
self.plugin["xep_0045"].join_muc(room, nick) self.plugin["xep_0045"].join_muc(room, nick)
def groupchat_message(self, message): def group_message(self, message):
"""Handle groupchat_message event.""" """Handle groupchat_message event."""
if message["type"] in ("groupchat", "normal"): if message["type"] in ("groupchat", "normal"):
if message["mucnick"] != self.config["bot"]["nick"]: if message["mucnick"] != self.config["bot"]["nick"]:
self.react(SimpleMessage(message)) self.group(SimpleMessage(message))
def register_xmpp_plugins(self): def register_xmpp_plugins(self):
"""Register XMPP plugins that the bot supports.""" """Register XMPP plugins that the bot supports."""
@ -183,47 +183,37 @@ class Bot(ClientXMPP):
class EchoBot(Bot): class EchoBot(Bot):
"""Gives back what you sent it. """Responds with whatever you send.
Just direct message the bot and see if you get back what you sent. It also Simply direct message the bot and see if you get back what you sent. It
works in group chats but in this case you need to summon the bot using its also works in group chats but in this case you need to summon the bot using
nickname Usually like so. its nickname. Usually like so.
echobot:foo echobot:foo
""" """
def react(self, message): def direct(self, message):
"""Send back what we get.""" """Send back whatever we receive."""
if message.type == "chat": self.reply(message.body, to=message.sender)
self.reply(message.body, to=message.sender)
if message.type == "groupchat" and "echobot" in message.body: def group(self, message):
_, to_echo = message.body.split(":") """Send back whatever receive in group chats."""
self.reply(to_echo, room=message.room) if "echobot" in message.body:
self.reply(message.body.split(":")[-1], room=message.room)
class WhisperBot(Bot): class WhisperBot(Bot):
"""Pseudo-anonymous whispering in group chats. """Anonymous whispering in group chats.
In order to activate this bot you can invite it to your group chat. Once In order to activate this bot you can invite it to your group chat. Once
invited, you can directly message the bot outside of the group chat and invited, you can start a private chat with the bot and tell it you want it
tell it you want it to whisper your message into the group chat. The bot to whisper your message into the group chat. The bot will then do this on
will then do this on your behalf and not reveal your identity. This is nice your behalf and not reveal your identity. This is nice when you want to
when you want to communicate with the group somewhat anonymously. communicate with the group anonymously.
The bot accepts messages in the following form.
whisper:<room>:<message>
So, I might write it like so.
whisper:myroom@muc.foo.com:i love the music of avril lavigne
""" """
def react(self, message): def direct(self, message):
"""Receive direct messages and pass them to group chats.""" """Receive private messages and whisper them into group chats."""
if message.type == "chat" and "whisper" in message.body: self.reply(f"*pssttt...* {message.body}", room=message.room)
_, room, whisper = message.body.split(":")
self.reply(f"*whispers* {whisper}", room=room)