basic wordlist message redaction
add file and image redaction update readme, version bump
This commit is contained in:
@@ -80,6 +80,18 @@ easy (or possible) to find. this subcommand (`!community roomid`) can be used to
|
||||
points to. with no argument passed, it will return the current room's ID, or you can pass it an alias (e.g. `!community
|
||||
roomid #whatisthisroom:myserver.tld`).
|
||||
|
||||
## message redaction
|
||||
|
||||
the bot can be configured to redact messages automatically to protect your users. set `censor` to either `true`,
|
||||
`false`, or a list of room IDs to enable censorship in.
|
||||
|
||||
set `censor_files` to have the bot immediately redact file uploads in the censored rooms. define trigger words in
|
||||
`censor_wordlist` to flag messages for automatic redaction.
|
||||
|
||||
please keep in mind that wordlist-based censorship is problematic and may redact false positives. writing a matching
|
||||
algorithm that is perfect is impossible. consider configuring your community such that censorship need only be applied
|
||||
in a limited subset of rooms.
|
||||
|
||||
# installation
|
||||
|
||||
install this like any other maubot plugin: zip the contents of this repo into a file and upload via the web interface,
|
||||
|
||||
@@ -62,3 +62,19 @@ notification_room:
|
||||
# message to send to the notification room when someone joins one of the above rooms:
|
||||
join_notification_message: |
|
||||
User <code>{user}</code> has joined <code>{room}</code>.
|
||||
|
||||
# whether to censor files/messages
|
||||
# can be boolean (true/false) for all-or-nothing behavior,
|
||||
# or pass a list of room IDs to only censor certain rooms. this may be helpful
|
||||
# if certain rooms are publicly facing while others are more trustworthy.
|
||||
# this bot, bot admins and bot moderators are immune to censorship.
|
||||
censor: false
|
||||
|
||||
# whether to redact file and image uploads. this will apply to all rooms defined
|
||||
# in the censor variable (either boolean or a list of room IDs).
|
||||
censor_files: true
|
||||
|
||||
# what words should trigger message redaction if censorship is enabled?
|
||||
censor_wordlist:
|
||||
- 'effword'
|
||||
- 'essword'
|
||||
|
||||
+41
-1
@@ -8,7 +8,7 @@ import re
|
||||
from mautrix.client import Client, InternalEventType, MembershipEventDispatcher, SyncStream
|
||||
from mautrix.types import (Event, StateEvent, EventID, UserID, FileInfo, EventType,
|
||||
MediaMessageEventContent, ReactionEvent, RedactionEvent, RoomID,
|
||||
RoomAlias, PowerLevelStateEventContent)
|
||||
RoomAlias, PowerLevelStateEventContent, MessageType)
|
||||
from mautrix.errors import MNotFound
|
||||
from mautrix.util.config import BaseProxyConfig, ConfigUpdateHelper
|
||||
from maubot import Plugin, MessageEvent
|
||||
@@ -34,6 +34,9 @@ class Config(BaseProxyConfig):
|
||||
helper.copy("join_notification_message")
|
||||
helper.copy_dict("greeting_rooms")
|
||||
helper.copy_dict("greetings")
|
||||
helper.copy("censor")
|
||||
helper.copy("censor_wordlist")
|
||||
helper.copy("censor_files")
|
||||
|
||||
|
||||
class CommunityBot(Plugin):
|
||||
@@ -111,6 +114,32 @@ class CommunityBot(Plugin):
|
||||
report["ignored"] = [ row["mxid"] for row in ignored_results ] or ["none"]
|
||||
|
||||
return report
|
||||
|
||||
def flag_message(self, msg):
|
||||
if msg.content.msgtype in [MessageType.FILE, MessageType.IMAGE]:
|
||||
return self.config['censor_files']
|
||||
|
||||
for w in self.config['censor_wordlist']:
|
||||
try:
|
||||
if bool(re.search(w, msg.content.body, re.IGNORECASE)):
|
||||
self.log.debug(f"DEBUG message flagged for censorship")
|
||||
return True
|
||||
else:
|
||||
pass
|
||||
except Exception as e:
|
||||
self.log.error(f"Could not parse message for flagging: {e}")
|
||||
|
||||
def censor_room(self, msg):
|
||||
if isinstance(self.config['censor'], bool):
|
||||
self.log.debug(f"DEBUG message will be redacted because censoring is enabled")
|
||||
return self.config['censor']
|
||||
elif isinstance(self.config['censor'], list):
|
||||
if msg.room_id in self.config['censor']:
|
||||
self.log.debug(f"DEBUG message will be redacted because censoring is enabled for THIS room")
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
@event.on(InternalEventType.JOIN)
|
||||
async def newjoin(self, evt:StateEvent) -> None:
|
||||
@@ -141,6 +170,17 @@ class CommunityBot(Plugin):
|
||||
|
||||
@event.on(EventType.ROOM_MESSAGE)
|
||||
async def update_message_timestamp(self, evt: MessageEvent) -> None:
|
||||
if self.flag_message(evt):
|
||||
# do we need to redact?
|
||||
if evt.sender not in self.config['admins'] and \
|
||||
evt.sender not in self.config['moderators'] and \
|
||||
evt.sender != self.client.mxid and \
|
||||
self.censor_room(evt):
|
||||
try:
|
||||
await self.client.redact(evt.room_id, evt.event_id, reason="message flagged")
|
||||
except Exception as e:
|
||||
self.log.error(f"Flagged message could not be redacted: {e}")
|
||||
|
||||
if not self.config["track_messages"]:
|
||||
pass
|
||||
else:
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
maubot: 0.1.0
|
||||
id: org.jobmachine.communitybot
|
||||
version: 0.1.6
|
||||
version: 0.1.7
|
||||
license: MIT
|
||||
modules:
|
||||
- community
|
||||
|
||||
Reference in New Issue
Block a user