Source code for iamai.event
"""iamai event.
Base class for event classes. Adapter developers should implement a subclass of this event class base class.
"""
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, Generic, Optional, Union
from typing_extensions import Self
from pydantic import BaseModel, ConfigDict
from iamai.typing import AdapterT
__all__ = ["Event", "MessageEvent"]
[docs]
class Event(ABC, BaseModel, Generic[AdapterT]):
"""The base class of event classes.
Attributes:
adapter: The adapter object that generated the current event.
type: event type.
__handled__: Indicates whether the event has been handled, used for adapter processing. Warning: Do not change the value of this property manually.
"""
model_config = ConfigDict(extra="allow")
if TYPE_CHECKING:
adapter: AdapterT
else:
adapter: Any
type: Optional[str]
__handled__: bool = False
def __str__(self) -> str:
"""Returns the textual representation of the event.
Returns:
A textual representation of the event.
"""
return f"Event<{self.type}>"
def __repr__(self) -> str:
"""Returns the description of the event.
Returns:
Description of the event.
"""
return self.__str__()
[docs]
class MessageEvent(Event[AdapterT], Generic[AdapterT]):
"""Base class for general message event classes."""
[docs]
@abstractmethod
def get_plain_text(self) -> str:
"""Get the plain text content of the message.
Returns:
The plain text content of the message.
"""
[docs]
@abstractmethod
async def reply(self, message: str) -> Any:
"""Reply message.
Args:
message: The content of the reply message.
Returns:
The response to the reply message action.
"""
[docs]
@abstractmethod
async def is_same_sender(self, other: Self) -> bool:
"""Determine whether itself and another event are the same sender.
Args:
other: another event.
Returns:
Is it the same sender?
"""
[docs]
async def get(
self,
*,
max_try_times: Optional[int] = None,
timeout: Optional[Union[int, float]] = None,
) -> Self:
"""Get the user's reply message.
Equivalent to `get()` of ``Bot``, the condition is that the adapter, event type and sender are the same.
Args:
max_try_times: Maximum number of events.
timeout: timeout period.
Returns:
Message event that the user replies to.
Raises:
GetEventTimeout: Maximum number of events exceeded or timeout.
"""
return await self.adapter.get(
self.is_same_sender,
event_type=type(self),
max_try_times=max_try_times,
timeout=timeout,
)
[docs]
async def ask(
self,
message: str,
max_try_times: Optional[int] = None,
timeout: Optional[Union[int, float]] = None,
) -> Self:
"""Ask for news.
Indicates getting the user's reply after replying to a message.
Equivalent to executing ``get()`` after ``reply()``.
Args:
message: The content of the reply message.
max_try_times: Maximum number of events.
timeout: timeout period.
Returns:
Message event that the user replies to.
"""
await self.reply(message)
return await self.get(max_try_times=max_try_times, timeout=timeout)