You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.4 KiB
86 lines
2.4 KiB
import logging
|
|
import os
|
|
|
|
import slixmpp
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class XmppBot(slixmpp.ClientXMPP):
|
|
def __init__(self, jid, password, rooms="", on_message=None):
|
|
super().__init__(jid, password)
|
|
self.nickname = jid.split("@")[0]
|
|
self.rooms = rooms
|
|
self.on_message = on_message
|
|
self.register_plugin("xep_0045")
|
|
self.register_plugin("xep_0066")
|
|
self.add_event_handler("session_start", self.start)
|
|
self.add_event_handler("message", self.handle_message)
|
|
|
|
async def start(self, event):
|
|
self.send_presence()
|
|
await self.get_roster()
|
|
if self.rooms:
|
|
for room in self.rooms.split(","):
|
|
room = room.strip()
|
|
if room:
|
|
self["xep_0045"].join_muc(room, self.nickname)
|
|
|
|
async def handle_message(self, msg):
|
|
sender = msg["from"]
|
|
body_preview = msg["body"][:100]
|
|
logger.info("<< [%s] %s: %s", msg["type"], sender, body_preview)
|
|
|
|
if msg["type"] == "groupchat":
|
|
if msg["mucnick"] == self.nickname:
|
|
return
|
|
|
|
body = msg["body"].strip()
|
|
if not body:
|
|
return
|
|
|
|
mention = f"@{self.nickname}"
|
|
mention2 = f"{self.nickname}:"
|
|
if not (body.startswith(mention) or body.startswith(mention2)):
|
|
return
|
|
|
|
for prefix in (mention, mention2):
|
|
if body.startswith(prefix):
|
|
body = body[len(prefix):].strip()
|
|
break
|
|
else:
|
|
if msg["type"] not in ("chat", "normal"):
|
|
return
|
|
body = msg["body"].strip()
|
|
|
|
if not body:
|
|
return
|
|
|
|
if msg["oob"]["url"]:
|
|
msg.reply("message received").send()
|
|
return
|
|
|
|
if self.on_message:
|
|
await self.on_message(body, msg["type"], str(sender), msg)
|
|
else:
|
|
msg.reply(f"echo-{body}").send()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s [%(levelname)s] %(message)s",
|
|
)
|
|
|
|
jid = os.getenv("XMPP_USERNAME")
|
|
password = os.getenv("XMPP_PASSWORD")
|
|
if not jid or not password:
|
|
logger.error("XMPP_USERNAME and XMPP_PASSWORD must be set in .env")
|
|
exit(1)
|
|
|
|
bot = XmppBot(jid, password, rooms=os.getenv("XMPP_ROOMS", ""))
|
|
bot.connect()
|
|
bot.loop.run_forever()
|
|
|