Added mxma module

This commit is contained in:
Ville Ranki 2020-03-29 23:50:33 +03:00
parent 48d8298828
commit 87998001f5
3 changed files with 96 additions and 1 deletions

View File

@ -268,6 +268,38 @@ Commands:
* !wa [query] - Query wolfram alpha * !wa [query] - Query wolfram alpha
* !wa appid [appid] - Set appid (must be done as bot owner) * !wa appid [appid] - Set appid (must be done as bot owner)
### Matrix Messaging API
This is a simple API to ask bot to send messages in Matrix using JSON file from external service.
You'll need an API endpoint (webserver) that contains a message queue. It must respond with following JSON to a HTTP GET request:
```json
{
"messages":[
{
"to": "@example:matrix.org",
"title": "Room Title",
"message": "Hello from Hemppa"
},
{
"to": "@another:matrix.user",
"title": "Room 2 Title",
"message": "Second message"
}
]
}
```
Normally you want to clear the messages when the endpoint is GETted or the messages will repeat
every time bot updates itself.
These messages are sent to given Matrix users in private message with given room title.
Messages are sent "best effort" - if sending fails, it will be logged to bot output log.
Then just:
* !mxma add http://url.to.the/endpoint.json
## Bot setup ## Bot setup
* Create a Matrix user * Create a Matrix user

38
bot.py
View File

@ -19,7 +19,7 @@ import datetime
from importlib import reload from importlib import reload
import requests import requests
from nio import AsyncClient, InviteEvent, JoinError, RoomMessageText, MatrixRoom, LoginError from nio import AsyncClient, InviteEvent, JoinError, RoomMessageText, MatrixRoom, LoginError, RoomMemberEvent, RoomVisibility, RoomPreset, RoomCreateError
# Couple of custom exceptions # Couple of custom exceptions
@ -106,6 +106,35 @@ class Bot:
} }
await self.client.room_send(room.room_id, 'm.room.message', msg) await self.client.room_send(room.room_id, 'm.room.message', msg)
async def send_msg(self, mxid, roomname, message):
# Sends private message to user. Returns true on success.
# Find if we already have a common room with user:
msg_room = None
for croomid in self.client.rooms:
roomobj = self.client.rooms[croomid]
if len(roomobj.users) == 2:
for user in roomobj.users:
if user == mxid:
msg_room = roomobj
# Nope, let's create one
if not msg_room:
msg_room = await self.client.room_create(visibility=RoomVisibility.private,
name=roomname,
is_direct=True,
preset=RoomPreset.private_chat,
invite={mxid},
)
if not msg_room or (type(msg_room) is RoomCreateError):
self.logger.error(f'Unable to create room when trying to message {mxid}')
return False
# Send message to the room
await self.send_text(msg_room, message)
return True
def remove_callback(self, callback): def remove_callback(self, callback):
for cb_object in self.client.event_callbacks: for cb_object in self.client.event_callbacks:
if cb_object.func == callback: if cb_object.func == callback:
@ -233,6 +262,12 @@ class Bot:
else: else:
self.logger.warning(f'Received invite event, but not joining as sender is not owner or bot not configured to join on invite. {event}') self.logger.warning(f'Received invite event, but not joining as sender is not owner or bot not configured to join on invite. {event}')
async def memberevent_cb(self, room, event):
# Automatically leaves rooms where bot is alone.
if room.member_count == 1 and event.membership=='leave':
self.logger.info(f"membership event in {room.display_name} ({room.room_id}) with {room.member_count} members by '{event.sender}' - leaving room as i don't want to be left alone!")
await self.client.room_leave(room.room_id)
def load_module(self, modulename): def load_module(self, modulename):
try: try:
self.logger.info(f'load module: {modulename}') self.logger.info(f'load module: {modulename}')
@ -361,6 +396,7 @@ class Bot:
self.load_settings(self.get_account_data()) self.load_settings(self.get_account_data())
self.client.add_event_callback(self.message_cb, RoomMessageText) self.client.add_event_callback(self.message_cb, RoomMessageText)
self.client.add_event_callback(self.invite_cb, (InviteEvent,)) self.client.add_event_callback(self.invite_cb, (InviteEvent,))
self.client.add_event_callback(self.memberevent_cb, (RoomMemberEvent,))
if self.join_on_invite: if self.join_on_invite:
self.logger.info('Note: Bot will join rooms if invited') self.logger.info('Note: Bot will join rooms if invited')

27
modules/mxma.py Normal file
View File

@ -0,0 +1,27 @@
from modules.common.module import BotModule
import requests, json
import traceback
from modules.common.pollingservice import PollingService
class MatrixModule(PollingService):
def __init__(self, name):
super().__init__(name)
self.service_name = 'MXMA'
self.poll_interval_min = 5
self.poll_interval_random = 2
async def poll_implementation(self, bot, account, roomid, send_messages):
try:
response = requests.get(url=account, timeout=5)
if response.status_code == 200:
if 'messages' in response.json():
messages = response.json()['messages']
for message in messages:
success = await bot.send_msg(message['to'], message['title'], message['message'])
except Exception:
self.logger.error('Polling MXMA failed:')
traceback.print_exc(file=sys.stderr)
def help(self):
return 'Matrix messaging API'