Added echo module
This commit is contained in:
parent
b2ca334a51
commit
a1b7d0b1ab
|
@ -1,5 +1,14 @@
|
||||||
# Hemppa - generic Matrix bot
|
# Hemppa - generic Matrix bot
|
||||||
|
|
||||||
|
## Module list
|
||||||
|
|
||||||
|
Write !modulename in Matrix room where the bot is to use modules.
|
||||||
|
|
||||||
|
### Echo
|
||||||
|
|
||||||
|
Simple example module that just echoes what user said. Can be used as an
|
||||||
|
example for writing own modules.
|
||||||
|
|
||||||
## First
|
## First
|
||||||
|
|
||||||
* Create a Matrix user
|
* Create a Matrix user
|
||||||
|
|
75
bot.py
75
bot.py
|
@ -1,14 +1,20 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
import glob
|
||||||
|
import traceback
|
||||||
|
import importlib
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
from nio import (AsyncClient, RoomMessageText, RoomMessageUnknown, JoinError, InviteEvent)
|
from nio import (AsyncClient, RoomMessageText, RoomMessageUnknown, JoinError, InviteEvent)
|
||||||
|
|
||||||
|
|
||||||
class Bot:
|
class Bot:
|
||||||
client = None
|
client = None
|
||||||
join_on_invite = False
|
join_on_invite = False
|
||||||
|
modules = dict()
|
||||||
|
|
||||||
async def send_html(self, body, client, room):
|
async def send_text(self, room, body):
|
||||||
msg = {
|
msg = {
|
||||||
"body": body,
|
"body": body,
|
||||||
"msgtype": "m.text"
|
"msgtype": "m.text"
|
||||||
|
@ -16,14 +22,29 @@ class Bot:
|
||||||
await self.client.room_send(self.get_room_id(room), 'm.room.message', msg)
|
await self.client.room_send(self.get_room_id(room), 'm.room.message', msg)
|
||||||
|
|
||||||
def get_room_id(self, room):
|
def get_room_id(self, room):
|
||||||
for roomid in client.rooms:
|
for roomid in self.client.rooms:
|
||||||
if self.client.rooms[roomid].named_room_name() == room.named_room_name():
|
if self.client.rooms[roomid].named_room_name() == room.named_room_name():
|
||||||
return roomid
|
return roomid
|
||||||
print('Cannot find id for room', room.named_room_name(), ' - is the bot on it?')
|
print('Cannot find id for room', room.named_room_name(), ' - is the bot on it?')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def message_cb(self, room, event):
|
async def message_cb(self, room, event):
|
||||||
pass
|
# Figure out the command
|
||||||
|
body = event.body
|
||||||
|
if len(body) == 0:
|
||||||
|
return
|
||||||
|
command = body.split().pop(0)
|
||||||
|
|
||||||
|
# Strip away non-alphanumeric characters, including leading ! for security
|
||||||
|
command = re.sub(r'\W+', '', command)
|
||||||
|
|
||||||
|
moduleobject = self.modules.get(command)
|
||||||
|
|
||||||
|
if "matrix_message" in dir(moduleobject):
|
||||||
|
try:
|
||||||
|
await moduleobject.matrix_message(bot, room, event)
|
||||||
|
except:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
async def unknown_cb(self, room, event):
|
async def unknown_cb(self, room, event):
|
||||||
if event.msgtype != 'm.location':
|
if event.msgtype != 'm.location':
|
||||||
|
@ -40,15 +61,56 @@ class Bot:
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
def load_module(self, modulename):
|
||||||
|
try:
|
||||||
|
module = importlib.import_module('modules.' + modulename)
|
||||||
|
cls = getattr(module, 'MatrixModule')
|
||||||
|
return cls()
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
print('Module ', modulename, ' failed to load!')
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_modules(self):
|
||||||
|
modulefiles = glob.glob('./modules/*.py')
|
||||||
|
|
||||||
|
for modulefile in modulefiles:
|
||||||
|
modulename = os.path.splitext(os.path.basename(modulefile))[0]
|
||||||
|
moduleobject = self.load_module(modulename)
|
||||||
|
if moduleobject:
|
||||||
|
self.modules[modulename] = moduleobject
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self.client = AsyncClient(os.environ['MATRIX_SERVER'], os.environ['MATRIX_USER'])
|
self.client = AsyncClient(os.environ['MATRIX_SERVER'], os.environ['MATRIX_USER'])
|
||||||
self.client.access_token = os.getenv('MATRIX_ACCESS_TOKEN')
|
self.client.access_token = os.getenv('MATRIX_ACCESS_TOKEN')
|
||||||
self.join_on_invite = os.getenv('JOIN_ON_INVITE')
|
self.join_on_invite = os.getenv('JOIN_ON_INVITE')
|
||||||
|
|
||||||
|
self.get_modules()
|
||||||
|
|
||||||
|
print(f'Starting {len(self.modules)} modules..')
|
||||||
|
|
||||||
|
for modulename, moduleobject in self.modules.items():
|
||||||
|
print(modulename + '..')
|
||||||
|
if "matrix_start" in dir(moduleobject):
|
||||||
|
try:
|
||||||
|
moduleobject.matrix_start(bot)
|
||||||
|
except:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
print(f'Stopping {len(self.modules)} modules..')
|
||||||
|
for modulename, moduleobject in self.modules.items():
|
||||||
|
print(modulename + '..')
|
||||||
|
if "matrix_stop" in dir(moduleobject):
|
||||||
|
try:
|
||||||
|
moduleobject.matrix_stop(bot)
|
||||||
|
except:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
if not self.client.access_token:
|
if not self.client.access_token:
|
||||||
await self.client.login(os.environ['MATRIX_PASSWORD'])
|
await self.client.login(os.environ['MATRIX_PASSWORD'])
|
||||||
print("Logged in with password, access token:", client.access_token)
|
print("Logged in with password, access token:", self.client.access_token)
|
||||||
|
|
||||||
await self.client.sync()
|
await self.client.sync()
|
||||||
|
|
||||||
|
@ -66,5 +128,8 @@ class Bot:
|
||||||
|
|
||||||
bot = Bot()
|
bot = Bot()
|
||||||
bot.init()
|
bot.init()
|
||||||
|
try:
|
||||||
asyncio.get_event_loop().run_until_complete(bot.run())
|
asyncio.get_event_loop().run_until_complete(bot.run())
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
bot.stop()
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
class MatrixModule:
|
||||||
|
def matrix_start(self, bot):
|
||||||
|
print("Echo start!")
|
||||||
|
|
||||||
|
def matrix_stop(self, bot):
|
||||||
|
print("Echo stop!")
|
||||||
|
|
||||||
|
async def matrix_message(self, bot, room, event):
|
||||||
|
args = event.body.split()
|
||||||
|
args.pop(0)
|
||||||
|
|
||||||
|
# Echo what they said back
|
||||||
|
await bot.send_text(room, ' '.join(args))
|
||||||
|
|
||||||
|
def help(self):
|
||||||
|
return('Echoes back what user has said')
|
Loading…
Reference in New Issue