LabCleaningBot: parse reactions

This commit is contained in:
lemoer 2024-12-27 01:59:48 +01:00
parent d7b22f3bc5
commit fb994d1a5e
2 changed files with 87 additions and 3 deletions

81
main.py
View File

@ -156,7 +156,7 @@ class SignalAPI:
async for websocket in websockets.connect(f"{ws_url}/v1/receive/{self.number}"): async for websocket in websockets.connect(f"{ws_url}/v1/receive/{self.number}"):
yield websocket yield websocket
async def receive_messages(self, websocket) -> Result[Message, str]: async def receive_message(self, websocket) -> Result[Message, str]:
return parse_response(Message, await websocket.recv()) return parse_response(Message, await websocket.recv())
def send_message(self, message: SendMessageSimple) -> Result[SendMessageResponse, str]: def send_message(self, message: SendMessageSimple) -> Result[SendMessageResponse, str]:
@ -224,12 +224,87 @@ class LabCleaningBot:
async for websocket in self.api.websocket_connect_receive(): async for websocket in self.api.websocket_connect_receive():
try: try:
while True: while True:
message = await self.api.receive_messages(websocket) message_result = await self.api.receive_message(websocket)
print(message)
if is_err(message_result):
print(message_result.unwrap_err())
continue
else:
message = message_result.unwrap()
self.message_received(message, session)
except websockets.exceptions.ConnectionClosed: except websockets.exceptions.ConnectionClosed:
print("Websockets connection closed. Reestablishing connection.") print("Websockets connection closed. Reestablishing connection.")
def message_received(self, message: Message, session: Session):
envelope = message.envelope
match envelope:
# Normal direct message (no edits, no reactions)
case EnvelopeData(dataMessage=DataMessage(message=message, groupInfo=None), sourceNumber=sourceNumber):
print(message, "direct", sourceNumber)
# Normal group message (no edits, no reactions)
case EnvelopeData(dataMessage=DataMessage(message=message, groupInfo=GroupInfo(groupId=group_id)), sourceNumber=sourceNumber):
print(message, group_id)
# Reaction in direct messages
case EnvelopeData(
dataMessage=ReactionMessage(
reaction=Reaction(
emoji=emoji,
isRemove=isRemove,
targetSentTimestamp=targetSentTimestamp
),
groupInfo=None,
timestamp=timestamp
),
sourceNumber=sourceNumber):
reactionTimestamp = signal_timestamp_to_datetime(timestamp)
requestTimestamp = signal_timestamp_to_datetime(targetSentTimestamp)
maybe_request = get_participation_request_by_timestamp(session, requestTimestamp)
if is_err(maybe_request):
print("No participation request found for timestamp %s." % requestTimestamp)
return
request = maybe_request.unwrap()
response_msg = ""
if emoji == "👍" and not isRemove:
accept_result = request.try_accept(now=reactionTimestamp)
match accept_result:
case Ok(AcceptInTime()):
response_msg = "You accepted the request."
case Ok(AcceptAfterRejectAllowed()):
response_msg = "You accepted the request after rejecting it."
case Err(AcceptAfterRejectExpired()):
response_msg = "You cannot accept the request after rejecting it after 5 minutes."
case Err(AlreadyAccepted()):
response_msg = "You already accepted the request."
case Err(AcceptAfterTimeout()):
response_msg = "You cannot accept the request after the timeout."
else:
reject_result = request.try_reject(now=reactionTimestamp)
match reject_result:
case Ok(RejectInTime()):
response_msg = "You rejected the request."
case Ok(RejectAfterAccept()):
response_msg = "You rejected the request after accepting it."
case Err(AlreadyRejected()):
response_msg = "You already rejected the request."
case Err(RejectAfterTimeout()):
response_msg = "You cannot reject the request after the timeout."
self.api.send_message(
SendMessageSimple(message=response_msg, recipients=[sourceNumber]))
print(emoji, "direct", sourceNumber, isRemove)
async def sync_members_and_tasks(self, session: Session): async def sync_members_and_tasks(self, session: Session):
unfulfillable_tasks = [] unfulfillable_tasks = []

View File

@ -69,6 +69,15 @@ def get_user_by_name(session: Session, name: str, only_active: bool = True) -> R
else: else:
return Ok(user) return Ok(user)
def get_participation_request_by_timestamp(session: Session, timestamp: datetime.datetime) -> Result["ParticipationRequest", None]:
Q = select(ParticipationRequest).where(ParticipationRequest.requested_at == timestamp)
request = session.exec(Q).first()
if request is None:
return Err(None)
else:
return Ok(request)
class Task(SQLModel, table=True): class Task(SQLModel, table=True):
id: int = Field(primary_key=True) id: int = Field(primary_key=True)
name: str name: str