diff --git a/base-config.yaml b/base-config.yaml index b7631ed..07fedc5 100644 --- a/base-config.yaml +++ b/base-config.yaml @@ -2,32 +2,29 @@ # DO NOT CHANGE THIS UNLESS YOU KNOW WHAT YOU ARE DOING command_prefix: report -# Whether or not the bot should pay attention to only specific state/territory designators -# This bot will include the designator in the pushed notificaion if this is disabled, -# or if the allowed_locations contains multiple strings -allowed_locations_enabled: false -allowed_locations: - - arizona - - california - -# Which accounts should be paid attention to on a state/territory-by-state/territory basis. -# If the state/territory is not in allowed_senders, then the bot will allow all senders -# Otherwise only listed senders -allowed_senders: +# Which regions the bot should pay attention to +# Additionally, optionally whitelist specific accounts for each region +allowed_regions: foo: - "@reports:fiftyfiftyonerarizona.org" bar: - "@reports:example.org" - "@reports:example.com" + buzz: + aaa: -# Where and how the plugin will send the data to -server_url: "https://ntfy.sh" -server_topic: "changeMe" +# Bot-specific configurations per region +region_configs: + arizona: + # Where and how the plugin will send the data to + server_url: "https://ntfy.sh" + server_topic: "changeme" -# If the plugin should use a username and password to send notifications -server_use_authentication: false -server_username: "foo" -server_password: "bar" + # If the plugin should use a username and password to send notifications + server_use_authentication: true + server_username: "no" + server_password: "way" -# If this bot should send a reaction to the message if the notification was successful +# If this bot should send a reaction to the message +# if the notification was successful send_reaction: true \ No newline at end of file diff --git a/consumerntfy.py b/consumerntfy.py index e54a1e5..822d18d 100644 --- a/consumerntfy.py +++ b/consumerntfy.py @@ -11,15 +11,8 @@ import aiohttp class Config(BaseProxyConfig): def do_update(self, helper: ConfigUpdateHelper) -> None: helper.copy("command_prefix") - helper.copy("allowed_locations_enabled") - helper.copy("allowed_locations") - helper.copy("allowed_senders") - helper.copy("server_url") - helper.copy("server_topic") - helper.copy("command_prefix") - helper.copy("server_use_authentication") - helper.copy("server_username") - helper.copy("server_password") + helper.copy("allowed_regions") + helper.copy("region_configs") helper.copy("send_reaction") class ConsumerNTFY(Plugin): @@ -36,51 +29,79 @@ class ConsumerNTFY(Plugin): def get_command_name(self) -> str: return self.config["command_prefix"] + # Checks if a sender if allowed to send for a particular region + def validateSender(self, region: str, sender: str): + # Check that config value exists + if not self.config["allowed_regions"]: return False + # Check that region is allowed + if not self.config["allowed_regions"][region]: return False + # All senders allowed for this region + if len(self.config["allowed_regions"][region]) == 0: return True + # Check that sender is allowed for region + if not sender in self.config["allowed_regions"][region]: return False + return True + + # Does the necesary config checks for the given event + # Returns list of regions to process (strings) + # Currently just the specified region and "__global__" + def validateReport(self, evt: MessageEvent, message: str): + # Split command (minus !command_name) into tokens + tokens = message.split() + region = tokens[0].lower() + + # Each command must have a state/territory designation and a message + if len(tokens) < 2: return None + + self.log.debug(region) + + # This is a list of regions to process for this specific message + # This is only used to consider __global__ + regions_to_process = [] + if (self.validateSender("__global__", evt.sender)): + regions_to_process.append("__global__") + if (self.validateSender(region, evt.sender)): + regions_to_process.append(region) + + return regions_to_process + # What gets called when !command_name message is sent @command.new(name=get_command_name, help="Report Something") @command.argument("message", pass_raw=True) async def report(self, evt: MessageEvent, message: str) -> None: - # Split command (minus !command_name) into tokens - tokens = message.split() - st_desig = tokens[0].lower() - - # Each command must have a state/territory designation and a message - if len(tokens) < 2: return - - # Check locations whitelist - if self.config["allowed_locations_enabled"]: - if not tokens[0].lower() in self.config["allowed_locations"]: - return - - # Check allowed senders - allowed_senders = self.config["allowed_senders"] - - print(evt.sender) - - if st_desig in self.config["allowed_senders"]: - print(f"Allowed senders for {st_desig}: {self.config['allowed_senders'].get(st_desig, [])}") - if not evt.sender in self.config['allowed_senders'].get(st_desig, []): - return - - # Sending notification to NTFY - - url = self.config["server_url"] + "/" + self.config["server_topic"] - body = ' '.join(tokens[1:]) - if len(self.config["allowed_locations"]) != 1: - body = tokens[0] + ": " + body - - # Consider authentication - authentication = None - if self.config["server_use_authentication"]: - authentication = aiohttp.BasicAuth(self.config["server_username"], self.config["server_password"]) - - # Send notification - for trash in range(3): # Try to send 3 times - async with self.http.post(url, data=body, auth=authentication) as response: - if response.status == 200: - await evt.react("👍") - return + # If all have passed + ntfy_posts_passed = None + # Iterate through each endpoint that the message should be pushed to + # (if any) + for region in self.validateReport(evt, message): + # Detect no regions in reaction + if ntfy_posts_passed is None: ntfy_posts_passed = True + + # Grab region-specific conrfig + region_config = self.config["region_configs"][region] + + # Create notification text + split_message = message.split() + text = "[" + split_message[0] + "] " + ' '.join(message.split()[1:]) + + # Build URL + url = region_config["server_url"] + "/" + region_config["server_topic"] + + # Consider authentication + authentication = None + if region_config["server_use_authentication"]: + authentication = aiohttp.BasicAuth(region_config["server_username"], region_config["server_password"]) + + # Send notification + async with self.http.post(url, data=text, auth=authentication) as response: + if not response.status == 200: + ntfy_posts_passed = False + # Send reaction based on successful or failedPOSTs + if self.config["send_reaction"]: + if ntfy_posts_passed is True: + await evt.react("👍") + elif ntfy_posts_passed is False: + await evt.react("👎") # That's all, folks \ No newline at end of file diff --git a/maubot.yaml b/maubot.yaml index daf2dfb..899e4fe 100644 --- a/maubot.yaml +++ b/maubot.yaml @@ -1,6 +1,6 @@ maubot: 0.1.0 id: org.fiftyfiftyonearizona.reports.consumerntfy -version: 1.0.0 +version: 1.1.0 license: MIT modules: - consumerntfy