add a wrapper for message callbacks
This commit is contained in:
parent
66cbd31f82
commit
139b9e138b
4 changed files with 52 additions and 10 deletions
|
@ -3,3 +3,9 @@
|
|||
A package implementing a reusable class to make matrix bots
|
||||
|
||||
This is inventing the wheel once again, but who care? It's fun :)
|
||||
|
||||
## TODO:
|
||||
|
||||
- Use more of nio features and less custom hacks (like, use callback for the
|
||||
invite policy stuff, and nio.Room is way better than my custom type)
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
"""
|
||||
The Client class.
|
||||
Connect to the matrix server and handle interactions with the server.
|
||||
|
@ -9,6 +10,8 @@ import nio
|
|||
from aiopath import AsyncPath
|
||||
from typing import (
|
||||
Any,
|
||||
Awaitable,
|
||||
Callable,
|
||||
Optional,
|
||||
NoReturn,
|
||||
Union
|
||||
|
@ -32,6 +35,8 @@ class Client(Aobject):
|
|||
Connect to the matrix server and handle interactions with the
|
||||
server.
|
||||
|
||||
user: the user id of the client (exp: @bot:matrix.org)
|
||||
|
||||
/!\ The client is initialized asyncronously: `client = await Client(...)`
|
||||
"""
|
||||
|
||||
|
@ -43,6 +48,7 @@ class Client(Aobject):
|
|||
__sync_token_queue: asyncio.Queue[str]
|
||||
__invite_queue: asyncio.Queue[tuple[RoomId, nio.responses.InviteInfo]]
|
||||
__invite_policy: InvitePolicy
|
||||
user: str
|
||||
|
||||
async def __init__(
|
||||
self,
|
||||
|
@ -81,6 +87,7 @@ class Client(Aobject):
|
|||
if isinstance(resp, nio.responses.LoginError):
|
||||
raise RuntimeError(f"Fail to connect: {resp.message}")
|
||||
log.info("logged in")
|
||||
self.user_id = self.__client.user_id
|
||||
|
||||
async def resolve_room(
|
||||
self,
|
||||
|
@ -283,6 +290,18 @@ class Client(Aobject):
|
|||
for room_id in invites:
|
||||
await self.__invite_queue.put((room_id, invites[room_id]))
|
||||
|
||||
def add_message_callback(
|
||||
self,
|
||||
callback: Callable[[Client, nio.rooms.Room, nio.events.room_events.RoomMessageText], Awaitable[None]]
|
||||
):
|
||||
"""
|
||||
Add a callback called when a message is received.
|
||||
The callback is an async function that take the client, the room and the event message in arg.
|
||||
"""
|
||||
async def new_callback(room: nio.rooms.Room, msg: nio.events.room_events.RoomMessageText):
|
||||
await callback(self, room, msg)
|
||||
self.__client.add_event_callback(new_callback, nio.RoomMessageText)
|
||||
|
||||
async def run(
|
||||
self,
|
||||
sync_timeout:int=30
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
from __future__ import annotations
|
||||
"""
|
||||
Utilities for the bot.
|
||||
"""
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from dataclasses import (
|
||||
dataclass,
|
||||
field
|
||||
)
|
||||
if TYPE_CHECKING:
|
||||
from .client import Client
|
||||
|
||||
RoomAlias = str
|
||||
RoomId = str
|
||||
|
@ -17,3 +21,18 @@ class Room:
|
|||
id: RoomId
|
||||
aliases: set[RoomAlias] = field(default_factory=set)
|
||||
|
||||
def ignore_client_message(
|
||||
callback: Callable[[Client, nio.rooms.Room, nio.events.room_events.RoomMessageText], Awaitable[None]]
|
||||
)->Callable[[Client, nio.rooms.Room, nio.events.room_events.RoomMessageText], Awaitable[None]]:
|
||||
"""
|
||||
Decorator for message callback.
|
||||
The decorated callback will ignore message sent by the client.
|
||||
"""
|
||||
async def new_callback(
|
||||
client: Client,
|
||||
room: nio.rooms.Room,
|
||||
message: nio.events.room_events.RoomMessageText
|
||||
):
|
||||
if client.user_id != message.sender:
|
||||
await callback(client, room, message)
|
||||
return new_callback
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
Not really tests, because I don't know how to testt without a whole matrix server.
|
||||
Not really tests, because I don't know how to test without a whole matrix server.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
|
@ -12,10 +12,15 @@ from matrix_bot.invite_policy import (
|
|||
DeclineAll,
|
||||
WhiteList
|
||||
)
|
||||
from matrix_bot.utils import ignore_client_message
|
||||
from getpass import getpass
|
||||
|
||||
logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.DEBUG)
|
||||
|
||||
@ignore_client_message
|
||||
async def callback(client, room, event):
|
||||
await client.send_message(room.room_id, "Hello!")
|
||||
|
||||
async def main():
|
||||
load_dotenv()
|
||||
client = await Client(
|
||||
|
@ -23,25 +28,18 @@ async def main():
|
|||
os.environ["HOMESERVER"],
|
||||
os.environ["PASSWD"],
|
||||
)
|
||||
client.add_message_callback(callback)
|
||||
withelisted_room_names = os.environ["ROOMS"].split(",")
|
||||
whitelist_policy = await WhiteList(client, withelisted_room_names)
|
||||
room_name = withelisted_room_names[0]
|
||||
client.set_invite_policy(whitelist_policy)
|
||||
await client.send_message(room_name, "Beware of Greeks bearing gifts")
|
||||
await asyncio.sleep(5)
|
||||
await asyncio.sleep(1)
|
||||
await client.send_formated_message(
|
||||
room_name,
|
||||
"<b><font color='red'>Beware of Greeks bearing gifts</font></b>",
|
||||
"Beware of Greeks bearing gifts"
|
||||
)
|
||||
await asyncio.sleep(5)
|
||||
await client.send_firework_message(room_name, "fire")
|
||||
await asyncio.sleep(5)
|
||||
await client.send_confetti_message(room_name, "confetti")
|
||||
await asyncio.sleep(5)
|
||||
await client.send_snow_message(room_name, "snow")
|
||||
await asyncio.sleep(5)
|
||||
await client.send_space_invader_message(room_name, "space")
|
||||
await client.run()
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue