Added mxma module
This commit is contained in:
parent
48d8298828
commit
87998001f5
32
README.md
32
README.md
|
@ -268,6 +268,38 @@ Commands:
|
|||
* !wa [query] - Query wolfram alpha
|
||||
* !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
|
||||
|
||||
* Create a Matrix user
|
||||
|
|
38
bot.py
38
bot.py
|
@ -19,7 +19,7 @@ import datetime
|
|||
from importlib import reload
|
||||
|
||||
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
|
||||
|
@ -106,6 +106,35 @@ class Bot:
|
|||
}
|
||||
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):
|
||||
for cb_object in self.client.event_callbacks:
|
||||
if cb_object.func == callback:
|
||||
|
@ -233,6 +262,12 @@ class Bot:
|
|||
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}')
|
||||
|
||||
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):
|
||||
try:
|
||||
self.logger.info(f'load module: {modulename}')
|
||||
|
@ -361,6 +396,7 @@ class Bot:
|
|||
self.load_settings(self.get_account_data())
|
||||
self.client.add_event_callback(self.message_cb, RoomMessageText)
|
||||
self.client.add_event_callback(self.invite_cb, (InviteEvent,))
|
||||
self.client.add_event_callback(self.memberevent_cb, (RoomMemberEvent,))
|
||||
|
||||
if self.join_on_invite:
|
||||
self.logger.info('Note: Bot will join rooms if invited')
|
||||
|
|
|
@ -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'
|
Loading…
Reference in New Issue