Welcome plugin added. Refactored funguy.py a bit.
This commit is contained in:
@@ -90,6 +90,22 @@ class FunguyBot:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Error loading plugin {plugin_name}: {e}") # Logging error if plugin loading fails
|
logging.error(f"Error loading plugin {plugin_name}: {e}") # Logging error if plugin loading fails
|
||||||
|
|
||||||
|
def setup_plugins(self):
|
||||||
|
"""
|
||||||
|
Method to call setup(bot) on any plugin that defines it.
|
||||||
|
|
||||||
|
This must be called AFTER self.bot is created (i.e. inside run()), so
|
||||||
|
that plugins which register custom event listeners (e.g. on_custom_event
|
||||||
|
for RoomMemberEvent) receive a valid bot instance.
|
||||||
|
"""
|
||||||
|
for plugin_name, plugin_module in self.PLUGINS.items():
|
||||||
|
if hasattr(plugin_module, "setup") and callable(plugin_module.setup):
|
||||||
|
try:
|
||||||
|
plugin_module.setup(self.bot)
|
||||||
|
logging.info(f"Setup called for plugin: {plugin_name}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error during setup of plugin {plugin_name}: {e}")
|
||||||
|
|
||||||
def reload_plugins(self):
|
def reload_plugins(self):
|
||||||
"""
|
"""
|
||||||
Method to reload all plugins.
|
Method to reload all plugins.
|
||||||
@@ -100,6 +116,9 @@ class FunguyBot:
|
|||||||
if plugin_name.startswith(self.PLUGINS_DIR + "."):
|
if plugin_name.startswith(self.PLUGINS_DIR + "."):
|
||||||
del sys.modules[plugin_name] # Deleting plugin module from system modules
|
del sys.modules[plugin_name] # Deleting plugin module from system modules
|
||||||
self.load_plugins() # Reloading plugins
|
self.load_plugins() # Reloading plugins
|
||||||
|
# Re-run setup for any plugin that needs it (bot already exists at this point)
|
||||||
|
if self.bot is not None:
|
||||||
|
self.setup_plugins()
|
||||||
|
|
||||||
def load_config(self):
|
def load_config(self):
|
||||||
"""
|
"""
|
||||||
@@ -223,6 +242,11 @@ class FunguyBot:
|
|||||||
creds = botlib.Creds(MATRIX_URL, MATRIX_USER, MATRIX_PASS) # Creating credentials object
|
creds = botlib.Creds(MATRIX_URL, MATRIX_USER, MATRIX_PASS) # Creating credentials object
|
||||||
self.bot = botlib.Bot(creds, self.config) # Creating bot instance
|
self.bot = botlib.Bot(creds, self.config) # Creating bot instance
|
||||||
|
|
||||||
|
# Call setup() on any plugin that defines it, now that self.bot exists.
|
||||||
|
# This is what registers custom event listeners such as the join-event
|
||||||
|
# listener in the welcome plugin.
|
||||||
|
self.setup_plugins()
|
||||||
|
|
||||||
# Defining listener for message events
|
# Defining listener for message events
|
||||||
@self.bot.listener.on_message_event
|
@self.bot.listener.on_message_event
|
||||||
async def wrapper_handle_commands(room, message):
|
async def wrapper_handle_commands(room, message):
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
"""
|
||||||
|
Plugin for welcoming new users to the room.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Automatically greets users when they join the target room.
|
||||||
|
* !welcome command – manually trigger the welcome message for yourself.
|
||||||
|
|
||||||
|
Restricted to room: !NXdVjDXPxXowPkrJJY:matrix.org
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import simplematrixbotlib as botlib
|
||||||
|
import nio
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Configuration
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ALLOWED_ROOM_ID = "!NXdVjDXPxXowPkrJJY:matrix.org"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Internal helpers
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def _build_welcome_message(display_name: str) -> str:
|
||||||
|
"""Return the Markdown welcome message for a given display name."""
|
||||||
|
return (
|
||||||
|
f"Welcome to the room, **{display_name}**! 🎉\n\n"
|
||||||
|
"We're glad to have you here in "
|
||||||
|
"**Self‑hosting | Security | Sysadmin | Homelab | Programming**!\n\n"
|
||||||
|
"To help us get to know you better:\n"
|
||||||
|
"• 🔧 **What do you self‑host?** Got any cool services running?\n"
|
||||||
|
"• 🔐 **Are you into cybersecurity?** What areas interest you most?\n"
|
||||||
|
"• 💻 **What programming languages do you use?**\n"
|
||||||
|
"• 🏠 **Tell us about your homelab setup!**\n\n"
|
||||||
|
"Feel free to introduce yourself and jump into the conversation! 🍄"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Plugin setup - called by funguy.py's run() after the bot object is created
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
"""
|
||||||
|
Register the member-join listener.
|
||||||
|
|
||||||
|
funguy.py must call plugin_module.setup(self.bot) for each loaded plugin
|
||||||
|
(after self.bot is created) for this listener to fire. See the note in
|
||||||
|
funguy.py's run() method.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@bot.listener.on_custom_event(nio.RoomMemberEvent)
|
||||||
|
async def _on_member_event(room, event):
|
||||||
|
logging.debug(
|
||||||
|
"RoomMemberEvent received: room=%s, sender=%s, membership=%s",
|
||||||
|
room.room_id, event.sender, event.membership,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Only the configured room
|
||||||
|
if room.room_id != ALLOWED_ROOM_ID:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Only on actual join (not invite / leave / ban)
|
||||||
|
if event.membership != "join":
|
||||||
|
return
|
||||||
|
|
||||||
|
# Ignore the bot itself
|
||||||
|
if event.sender == bot.async_client.user_id:
|
||||||
|
logging.debug("Ignoring bot's own join event")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Derive a friendly display name from the Matrix ID (@name:server → name)
|
||||||
|
display_name = event.sender.split(":")[0].lstrip("@")
|
||||||
|
|
||||||
|
logging.info(
|
||||||
|
"User %s joined room %s – sending welcome", event.sender, room.room_id
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
await bot.api.send_markdown_message(
|
||||||
|
room.room_id, _build_welcome_message(display_name)
|
||||||
|
)
|
||||||
|
logging.info("Welcome message sent successfully to %s", display_name)
|
||||||
|
except Exception as exc:
|
||||||
|
logging.error("Failed to send welcome message: %s", exc)
|
||||||
|
|
||||||
|
logging.info("Join listener registered for room %s", ALLOWED_ROOM_ID)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Plugin entry point - called by FunguyBot for every message event
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
async def handle_command(room, message, bot, prefix, config):
|
||||||
|
"""Handle the !welcome command."""
|
||||||
|
|
||||||
|
match = botlib.MessageMatch(room, message, bot, prefix)
|
||||||
|
|
||||||
|
if not (
|
||||||
|
match.is_not_from_this_bot()
|
||||||
|
and match.prefix()
|
||||||
|
and match.command("welcome")
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
if room.room_id != ALLOWED_ROOM_ID:
|
||||||
|
await bot.api.send_text_message(
|
||||||
|
room.room_id,
|
||||||
|
"The !welcome command only works in the designated room.",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
sender = str(message.sender)
|
||||||
|
display_name = sender.split(":")[0].lstrip("@")
|
||||||
|
|
||||||
|
await bot.api.send_markdown_message(
|
||||||
|
room.room_id, _build_welcome_message(display_name)
|
||||||
|
)
|
||||||
|
logging.info("Sent manual !welcome to %s", sender)
|
||||||
Reference in New Issue
Block a user