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

View File

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

View File

@ -117,13 +117,13 @@ class Bot(ClientXMPP):
def register_xmpp_event_handlers(self):
"""Register functions against specific XMPP event handlers."""
self.add_event_handler("session_start", self.session_start)
self.add_event_handler("message", self.message)
self.add_event_handler("groupchat_message", self.groupchat_message)
self.add_event_handler("message", self.direct_message)
self.add_event_handler("groupchat_message", self.group_message)
def message(self, message):
def direct_message(self, message):
"""Handle message event."""
if message["type"] in ("chat", "normal"):
self.react(SimpleMessage(message))
self.direct(SimpleMessage(message))
def session_start(self, event):
"""Handle session_start event."""
@ -136,11 +136,11 @@ class Bot(ClientXMPP):
if room and nick:
self.plugin["xep_0045"].join_muc(room, nick)
def groupchat_message(self, message):
def group_message(self, message):
"""Handle groupchat_message event."""
if message["type"] in ("groupchat", "normal"):
if message["mucnick"] != self.config["bot"]["nick"]:
self.react(SimpleMessage(message))
self.group(SimpleMessage(message))
def register_xmpp_plugins(self):
"""Register XMPP plugins that the bot supports."""
@ -183,47 +183,37 @@ class Bot(ClientXMPP):
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
works in group chats but in this case you need to summon the bot using its
nickname Usually like so.
Simply direct message the bot and see if you get back what you sent. It
also works in group chats but in this case you need to summon the bot using
its nickname. Usually like so.
echobot:foo
"""
def react(self, message):
"""Send back what we get."""
if message.type == "chat":
self.reply(message.body, to=message.sender)
def direct(self, message):
"""Send back whatever we receive."""
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)
def group(self, message):
"""Send back whatever receive in group chats."""
if "echobot" in message.body:
self.reply(message.body.split(":")[-1], room=message.room)
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
invited, you can directly message the bot outside of the group chat and
tell it you want it to whisper your message into the group chat. The bot
will then do this on your behalf and not reveal your identity. This is nice
when you want to communicate with the group somewhat 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
invited, you can start a private chat with the bot and tell it you want it
to whisper your message into the group chat. The bot will then do this on
your behalf and not reveal your identity. This is nice when you want to
communicate with the group anonymously.
"""
def react(self, message):
"""Receive direct messages and pass them to group chats."""
if message.type == "chat" and "whisper" in message.body:
_, room, whisper = message.body.split(":")
self.reply(f"*whispers* {whisper}", room=room)
def direct(self, message):
"""Receive private messages and whisper them into group chats."""
self.reply(f"*pssttt...* {message.body}", room=message.room)