Invite user after confirmation is received

This commit is contained in:
Panoramic 2024-06-11 22:53:11 +03:00
parent a304f0a34d
commit 3b1ca97bb7
Signed by: Panoramic
GPG Key ID: 29FEDD73E66D32F1
6 changed files with 59 additions and 24 deletions

View File

@ -34,11 +34,13 @@ storage:
# Vetting options # Vetting options
vetting: vetting:
# The main space, where new recruits will be invited to
main_space_id: "!xxx:xxx"
# Internal room id for the main vetting room # Internal room id for the main vetting room
# Commands will be run here # Commands will be run here
room_id: "!xxx:xxx" vetting_room_id: "!xxx:xxx"
# A space which will house all the vetting rooms # A sub-space which will house all the vetting rooms
space_id: "!xxx:xxx" vetting_space_id: "!xxx:xxx"
# Voting time in seconds # Voting time in seconds
voting_time: 172800 voting_time: 172800
# Requirements for getting accepted # Requirements for getting accepted

View File

@ -6,6 +6,7 @@ from nio import (
JoinError, JoinError,
MatrixRoom, MatrixRoom,
MegolmEvent, MegolmEvent,
ReactionEvent,
RoomGetEventError, RoomGetEventError,
RoomMessageText, RoomMessageText,
UnknownEvent, UnknownEvent,
@ -187,25 +188,41 @@ class Callbacks:
# red_x_and_lock_emoji, # red_x_and_lock_emoji,
# ) # )
async def reaction(self, room: MatrixRoom, event: ReactionEvent):
"""Callback when a reaction event is received.
Args:
room (MatrixRoom): The room the reaction was sent in.
event (ReactionEvent): The event itself.
"""
# Ignore own events
if event.sender == self.client.user_id:
return
if room.room_id == self.config.vetting_room_id:
if event.key == "confirm":
# Check which user the reaction is for (if any)
self.store.cursor.execute(
"SELECT mxid FROM vetting WHERE decision_event_id = ?",
(event.reacts_to,),
)
row = self.store.cursor.fetchone()
if row is None:
return
# Invite the user
logger.info("Inviting new user (%s) to the Federation.", row[0])
await self.client.room_invite(self.config.main_space_id, row[0])
async def unknown(self, room: MatrixRoom, event: UnknownEvent) -> None: async def unknown(self, room: MatrixRoom, event: UnknownEvent) -> None:
"""Callback for when an event with a type that is unknown to matrix-nio is received. """Callback for when an event with a type that is unknown to matrix-nio is received.
Currently this is used for reaction events, which are not yet part of a released
matrix spec (and are thus unknown to nio).
Args: Args:
room: The room the reaction was sent in. room: The room the reaction was sent in.
event: The event itself. event: The event itself.
""" """
if event.type == "m.reaction":
# Get the ID of the event this was a reaction to
relation_dict = event.source.get("content", {}).get("m.relates_to", {})
reacted_to = relation_dict.get("event_id")
if reacted_to and relation_dict.get("rel_type") == "m.annotation":
await self._reaction(room, event, reacted_to)
return
logger.debug( logger.debug(
f"Got unknown event with type to {event.type} from {event.sender} in {room.room_id}." f"Got unknown event with type to {event.type} from {event.sender} in {room.room_id}."
) )

View File

@ -107,13 +107,23 @@ class Config:
self.command_prefix = self._get_cfg(["command_prefix"], default="!c") + " " self.command_prefix = self._get_cfg(["command_prefix"], default="!c") + " "
# Vetting setup # Vetting setup
self.vetting_room_id = self._get_cfg(["vetting", "room_id"], required=True) self.main_space_id = self._get_cfg(["vetting", "main_space_id"], required=True)
if not re.match("!.*:.*", self.vetting_room_id): if not re.match("!.*:.*", self.main_space_id):
raise ConfigError("vetting.room_id must be in the form !xxx:domain") raise ConfigError("vetting.main_space_id must be in the form !xxx:domain")
self.vetting_space_id = self._get_cfg(["vetting", "space_id"], required=True) self.vetting_room_id = self._get_cfg(
["vetting", "vetting_room_id"], required=True
)
if not re.match("!.*:.*", self.vetting_room_id):
raise ConfigError("vetting.vetting_room_id must be in the form !xxx:domain")
self.vetting_space_id = self._get_cfg(
["vetting", "vetting_space_id"], required=True
)
if not re.match("!.*:.*", self.vetting_space_id): if not re.match("!.*:.*", self.vetting_space_id):
raise ConfigError("vetting.space_id must be in the form !xxx:domain") raise ConfigError(
"vetting.vetting_space_id must be in the form !xxx:domain"
)
self.voting_time = int(self._get_cfg(["vetting", "voting_time"], required=True)) self.voting_time = int(self._get_cfg(["vetting", "voting_time"], required=True))

View File

@ -12,6 +12,7 @@ from nio import (
LocalProtocolError, LocalProtocolError,
LoginError, LoginError,
MegolmEvent, MegolmEvent,
ReactionEvent,
RoomMessageText, RoomMessageText,
UnknownEvent, UnknownEvent,
) )
@ -68,6 +69,7 @@ async def main():
callbacks.invite_event_filtered_callback, (InviteMemberEvent,) callbacks.invite_event_filtered_callback, (InviteMemberEvent,)
) )
client.add_event_callback(callbacks.decryption_failure, (MegolmEvent,)) client.add_event_callback(callbacks.decryption_failure, (MegolmEvent,))
client.add_event_callback(callbacks.reaction, (ReactionEvent,))
client.add_event_callback(callbacks.unknown, (UnknownEvent,)) client.add_event_callback(callbacks.unknown, (UnknownEvent,))
# Keep trying to reconnect on failure (with some time in-between) # Keep trying to reconnect on failure (with some time in-between)

View File

@ -112,7 +112,8 @@ class Storage:
vetting_create_time INT(12), vetting_create_time INT(12),
voting_start_time INT(12), voting_start_time INT(12),
poll_event_id VARCHAR(255), poll_event_id VARCHAR(255),
vote_ended BOOLEAN NOT NULL DEFAULT FALSE vote_ended BOOLEAN NOT NULL DEFAULT FALSE,
decision_event_id VARCHAR(255)
) )
""" """
) )

View File

@ -175,7 +175,10 @@ class Timer:
) )
# Finally - update database # Finally - update database
# self.store.cursor.execute( self.store.cursor.execute(
# "UPDATE vetting SET vote_ended = 1 WHERE mxid = ?", "UPDATE vetting SET vote_ended = 1, decision_event_id = ? WHERE mxid = ?",
# (mxid,), (
# ) decision_resp.event_id,
mxid,
),
)