move callbacks into python class, simplify demobot

This commit is contained in:
saces 2026-02-03 21:20:29 +01:00
parent 260386bcac
commit 05020f126e
4 changed files with 103 additions and 72 deletions

View file

@ -3,7 +3,6 @@ from time import time_ns
import logging
import json
from smal.bot import SMALBot
from _pygomx import lib, ffi
# setup logging, we want timestamps
logging.basicConfig(
@ -18,55 +17,48 @@ logger.setLevel(level=logging.INFO)
DEFAULT_PREFIX = "!"
@ffi.callback("void(char*)")
def on_event(evt):
e = ffi.string(evt)
print("Got an event: ", e)
class DemoBot(SMALBot):
def on_event(self, evt):
print("Got an event: ", e)
@ffi.callback("void(char*)")
def on_message(msg):
m = ffi.string(msg).decode("utf-8")
def on_message(self, msg):
msg = json.loads(m)
if msg["type"] != "m.room.message":
# not a room message
logger.error(f"not a room message: {msg}")
return
if msg["type"] != "m.room.message":
# not a room message
logger.error(f"not a room message: {msg}")
return
if msg["sender"] == "get own id from missing code":
# ignore own messages
# for now just do not send valid commands by yourself
logger.info(f"ignore own message: {msg}")
return
if msg["sender"] == "get own id from missing code":
# ignore own messages
# for now just do not send valid commands by yourself
logger.info(f"ignore own message: {msg}")
return
if "msgtype" in msg["content"].keys() and msg["content"]["msgtype"] != "m.text":
# only react to messages, not emotes
logger.debug(f"ignore unknown message type: {msg}")
return
if "msgtype" in msg["content"].keys() and msg["content"]["msgtype"] != "m.text":
# only react to messages, not emotes
logger.debug(f"ignore unknown message type: {msg}")
return
if msg["content"]["body"] == "!stop":
logger.info(f"stopping the bot")
bot.stop()
return
if msg["content"]["body"] == "!stop":
logger.info(f"stopping the bot")
bot.stop()
return
if msg["content"]["body"].startswith("!echo"):
logger.error(f"reply to this: {msg}")
if msg["content"]["body"].startswith("!echo"):
logger.error(f"reply to this: {msg}")
bot.sendmessage(msg["roomid"], "huhu")
bot.sendmessage(msg["roomid"], "huhu")
return
return
logger.info(f"ignored a message: {msg}")
logger.info(f"ignored a message: {msg}")
def main():
# create and run the bot
global bot
bot = SMALBot(DEFAULT_PREFIX)
bot.SetOnEventHandler(on_event)
bot.SetOnMessageHandler(on_message)
bot = DemoBot(DEFAULT_PREFIX)
bot.run()

View file

@ -15,6 +15,26 @@ class _MXClient:
def __init__(self):
super().__init__()
self._createMXClient()
# ffi_selfhandle = ffi.new_handle(self)
# self._ffi_selfhandle = ffi_selfhandle
self._ffi_selfhandle = ffi.new_handle(self)
# self._ffi_selfhandle = ffi_selfhandle
r = lib.apiv0_set_on_event_handler(
self.client_id, on_event_callback, self._ffi_selfhandle
)
result = ffi.string(r)
lib.FreeCString(r)
if result.startswith(b"ERR:"):
raise APIError(result)
r = lib.apiv0_set_on_message_handler(
self.client_id, on_message_callback, self._ffi_selfhandle
)
result = ffi.string(r)
lib.FreeCString(r)
if result.startswith(b"ERR:"):
raise APIError(result)
def _createMXClient(self):
r = lib.apiv0_createclient_pass(b".mxpass", b".", b"*", b"*", b"*")
@ -27,20 +47,6 @@ class _MXClient:
result_dict = json.loads(result)
self.client_id = result_dict["id"]
def SetOnEventHandler(self, fn):
r = lib.apiv0_set_on_event_handler(self.client_id, fn)
result = ffi.string(r)
lib.FreeCString(r)
if result.startswith(b"ERR:"):
raise APIError(result)
def SetOnMessageHandler(self, fn):
r = lib.apiv0_set_on_message_handler(self.client_id, fn)
result = ffi.string(r)
lib.FreeCString(r)
if result.startswith(b"ERR:"):
raise APIError(result)
def _sync(self):
r = lib.apiv0_startclient(self.client_id)
result = ffi.string(r)
@ -65,3 +71,32 @@ class _MXClient:
# if result.startswith(b"ERR:"):
# raise APIError(result)
print("_sendmessage: ", result)
def process_event(self, evt):
if hasattr(self, "on_event") and callable(self.on_event):
self.on_event(evt)
else:
logger.warn(f"got event but on_event not declared: {evt}")
def process_message(self, msg):
if hasattr(self, "on_message") and callable(self.on_message):
self.on_message(msg)
else:
logger.warn(f"got message but on_message not declared: {msg}")
self._stopsync()
@ffi.callback("void(char*, void*)")
def on_event_callback(evt, pobj):
cli = ffi.from_handle(pobj)
e = ffi.string(evt).decode("utf-8")
evt = json.loads(e)
cli.process_event(evt)
@ffi.callback("void(char*, void*)")
def on_message_callback(msg, pobj):
cli = ffi.from_handle(pobj)
m = ffi.string(msg).decode("utf-8")
msg = json.loads(m)
cli.process_message(msg)