Skip to content

Commit

Permalink
Ticket 1501, adding role-based notify
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Philion committed Dec 5, 2024
1 parent 0171f72 commit 1251da5
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 5 deletions.
18 changes: 18 additions & 0 deletions docs/devlog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Netbot Development Log

## 2024-12-05

Working on ticket #1501: When notifying a ticket assigned to a group, notify the matching Discord role

Technical details: when notifying a ticket, if that ticket is assigned to a team (not an individual), convert the team name into a role.

Notifying that because notify relies deeply on how Discord functions, it's tough to test.

The solution is a little hacky, but it works: The only difference between @-ing a user and roles is:

<@ID>

vs

<@&ID>

When the role lookup hits, it simply prepends '&' to the numerical ID before passing to the formatting code. That wraps the ID in '<@' and '>' and everything works out.

## 2024-11-26

Starting work on ticket #1203, `/ticket parent`.
Expand Down
18 changes: 17 additions & 1 deletion netbot/netbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ async def synchronize_ticket(self, ticket, thread:discord.Thread) -> bool:
del self.ticket_locks[ticket.id]
log.debug(f"UNLOCK thread - id: {ticket.id}, thread: {thread}")

def get_channel_by_name(self, channel_name: str):

def get_channel_by_name(self, channel_name: str) -> discord.TextChannel:
for channel in self.get_all_channels():
if isinstance(channel, discord.TextChannel) and channel_name == channel.name:
return channel
Expand All @@ -244,6 +245,14 @@ def get_channel_by_name(self, channel_name: str):
return None


def get_role_by_name(self, role_name: str) -> discord.Role:
# Noting: "guild" maps to discord server, and the API is designed to run on many "Discord servers" concurrently
for guild in self.guilds:
for role in guild.roles:
if role_name == role.name:
return role


async def on_application_command_error(self, context: discord.ApplicationContext,
exception: discord.DiscordException):
"""Bot-level error handler"""
Expand Down Expand Up @@ -422,6 +431,13 @@ def extract_ids_from_ticket(self, ticket: Ticket) -> set[int]:
discord_ids.add(user.discord_id.id)
else:
log.info(f"No Discord ID for {named}")
elif self.redmine.user_mgr.is_team(named.name):
# a team, look up role it.
team = self.get_role_by_name(named.name)
if team:
discord_ids.add(f"&{team.id}")
else:
log.warning(f"Team name {named} has no matching Discord role.")
else:
log.info(f"ERROR: user ID {named} not found")

Expand Down
15 changes: 11 additions & 4 deletions redmine/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,12 @@ def find_discord_user(self, discord_user_id:str) -> User:
return None


def is_user_or_group(self, name:str) -> bool:
return name in self.users or name in self.teams
#def is_user_or_group(self, name:str) -> bool:
# return name in self.users or name in self.teams


def is_team(self, name:str) -> bool:
return name in self.teams


def get_teams(self) -> list[Team]:
Expand Down Expand Up @@ -283,8 +287,11 @@ def find_discord_user(self, discord_user_id:str) -> User:
# just a proxy
return self.cache.find_discord_user(discord_user_id)

def is_user_or_group(self, term:str):
return self.cache.is_user_or_group(term)
#def is_user_or_group(self, term:str):
# return self.cache.is_user_or_group(term)

def is_team(self, name:str):
return self.cache.is_team(name)

def get(self, user_id:int):
"""get a user by ID, directly from redmine"""
Expand Down

0 comments on commit 1251da5

Please sign in to comment.