commit 7f1b87272362307f5921919c170f371ee9472406 Author: William Kray Date: Sat Jun 18 10:40:20 2022 -0700 initial commit, super basic bot that just tracks last message sent in the current room. lots of comments for what to do next. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c6e98d5 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# kickbot + +a maubot plugin that tracks the last message timestamp of a user across all rooms in a space, and kicks them from the +space and all rooms after a period of inactivity. diff --git a/base-config.yaml b/base-config.yaml new file mode 100644 index 0000000..bff02cc --- /dev/null +++ b/base-config.yaml @@ -0,0 +1,16 @@ +# list of users who should never be kicked. +# important to add room admins or service/bot accounts. +exclusion_list: + - '@user1:server.tld' + - '@user2:server.tld' + +# list of rooms or spaces to police. +# if a space is listed here, all rooms within the space +# will be monitored, but users will only be able to be kicked +# from rooms where the bot has the power to do so! +# NOTE: this bot does not support crawling a space for subspaces! +# if your community is broken into sub-spaces, please add each sub-space +# to this list. +room_list: + - '!sOmEsPeCiAlRoOm:server.tld' + - '!sOmEoThErRoOm12:server.tld' diff --git a/kickbot/__init__.py b/kickbot/__init__.py new file mode 100644 index 0000000..96de584 --- /dev/null +++ b/kickbot/__init__.py @@ -0,0 +1 @@ +from .bot import KickBot diff --git a/kickbot/bot.py b/kickbot/bot.py new file mode 100644 index 0000000..ea711f9 --- /dev/null +++ b/kickbot/bot.py @@ -0,0 +1,63 @@ +# kickbot - a maubot plugin to track user activity and remove inactive users from rooms/spaces. + +from typing import Awaitable, Type, Optional, Tuple +import json +import time + +from mautrix.client import Client +from mautrix.types import (Event, StateEvent, EventID, UserID, FileInfo, EventType, + MediaMessageEventContent, ReactionEvent, RedactionEvent) +from mautrix.util.config import BaseProxyConfig, ConfigUpdateHelper +from maubot import Plugin, MessageEvent +from maubot.handlers import command, event + +# database table related things +from .db import upgrade_table + + + +class Config(BaseProxyConfig): + def do_update(self, helper: ConfigUpdateHelper) -> None: + helper.copy("exclusion_list") + + +class KickBot(Plugin): + # database table related things +# kickbot_t: Type[KickBot] +# version: Type[Version] + + async def start(self) -> None: + await super().start() + self.config.load_and_update() + + @event.on(EventType.ROOM_MESSAGE) + async def update_user_timestamp(self, evt: MessageEvent) -> None: + excluded = evt.sender in self.config["exclusion_list"] + q = """ + REPLACE INTO user_events(mxid, last_message_timestamp, ignore_inactivity) + VALUES ($1, $2, $3) + """ + await self.database.execute(q, evt.sender, evt.timestamp, int(excluded)) + self.log.info("record added") + + #need a command to load/reload full space-member list to user_events table, + #if not already in the table set last_message value to 0 + + #need a command to return a list of users who are in the space member-list, + #but have a last_message value greater than 30 and 60 days AND ignore_activity + #value is set to 0 + # + #memberlist = await self.client.get_joined_members(space_room_id) + #self.log.info(memberlist.keys()) + #current_time = int(time.time() * 1000) # get current timestamp to match matrix datestamp formatting + #30_days_ago = (current_time - 2592000000) # not useful now but will be when we compare timestamps + #60_days_ago = (current_time - 5184000000) # not useful now but will be when we compare timestamps + + + @classmethod + def get_db_upgrade_table(cls) -> None: + return upgrade_table + + @classmethod + def get_config_class(cls) -> Type[BaseProxyConfig]: + return Config diff --git a/kickbot/db.py b/kickbot/db.py new file mode 100644 index 0000000..8283634 --- /dev/null +++ b/kickbot/db.py @@ -0,0 +1,19 @@ +from __future__ import annotations + +from mautrix.util.async_db import UpgradeTable, Connection + +upgrade_table = UpgradeTable() + +@upgrade_table.register(description="Table initialization") +async def upgrade_v1(conn: Connection) -> None: + await conn.execute( + """CREATE TABLE user_events ( + mxid TEXT PRIMARY KEY, + last_message_timestamp BIGINT NOT NULL + )""" + ) + +@upgrade_table.register(description="Include ignore_inactivity column") +async def upgrade_v2(conn: Connection) -> None: + await conn.execute("ALTER TABLE user_events ADD COLUMN ignore_inactivity INT DEFAULT O") + diff --git a/maubot.yaml b/maubot.yaml new file mode 100644 index 0000000..8178cf0 --- /dev/null +++ b/maubot.yaml @@ -0,0 +1,10 @@ +maubot: 0.1.0 +id: org.jobmachine.kickbot +version: 0.0.1 +modules: + - kickbot +main_class: KickBot +extra_files: + - base-config.yaml +database: true +database_type: asyncpg