summaryrefslogtreecommitdiffstats
path: root/main.py
blob: e40a82f9d7b4e10911e1f158534dc03db4eee15a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import logging

from slixmpp import ClientXMPP

from config import Config


class RetiredMucBot(ClientXMPP):
    def __init__(self, jid, password, nick, config):
        ClientXMPP.__init__(self, jid, password)
        self.use_message_ids = True
        self.use_ssl = True

        # passthrough the config obj
        self.config = config

        self.rooms = None
        self.nick = nick
        self.messages = self.config.get("messages")

        # feature config
        self.functions = self.config.get("features")

        # session start disconnect events
        self.add_event_handler("session_start", self.start_session)
        self.add_event_handler("disconnected", self.reconnect_session)

        # register receive handler for both groupchat and normal message events
        self.add_event_handler("message", self.message)

    def reconnect_session(self, event):
        """
        method to handle disconnects / session drops
        """
        self.connect()

    def start_session(self, event):
        """
        session start
        """
        self.send_presence()
        self.join_rooms()

    def join_rooms(self):
        """
        method to join configured rooms and register their response handlers
        """
        self.rooms = self.config.get("rooms")

        if self.rooms is not None:
            for room in self.rooms:
                self.add_event_handler(f"muc::{room}::got_online", self.notify_user)
                self.plugin["xep_0045"].join_muc(room, self.nick, wait=True)

    def message(self, msg):
        """
        method to handle incoming chat, normal messages
        :param msg: incoming msg object
        """

        # do not process our own messages
        ourself = self.plugin["xep_0045"].get_our_jid_in_room(msg.get_mucroom())
        if msg["from"] == ourself:
            return

        # ever other messages will be answered statically
        if msg["type"] in ("normal", "chat"):
            self.send_message(
                mto=msg["from"],
                mbody=self.messages["direct_msg"].format(nick=self.nick),
                mtype=msg["type"],
            )

    def notify_user(self, presence):
        """
        method to compose the redirect action
        :param presence: incoming user presence object
        """
        user_nick = presence["muc"]["nick"]

        # catch empty user_nicks slixmpp does that for some reason
        if user_nick == "":
            return

        # handle all incoming user presences, this may cause duplicates
        if user_nick != self.nick:
            new_room = self.rooms[presence.get_from().bare]
            self.send_message(
                mto=presence.get_from().bare,
                mbody=self.messages["grp_msg"].format(user_nick=user_nick, new_room=new_room),
                mtype="groupchat",
            )

            if self.functions["direct_invite"]:
                jid = presence["muc"].get_jid().bare
                self.invite_user(jid, new_room)

    def invite_user(self, jid, room):
        """
        method to invite the user to the new room
        :param jid: jid to invite
        :param room: room to which the jid should be invited
        """
        self.plugin["xep_0045"].invite(
            room=jid,
            jid=room,
            reason="redirection due to retirement",
        )


if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG)

    # init config obj
    config = Config()

    # config
    login = config.get("login", default=None)

    # init the bot and register used slixmpp plugins
    xmpp = RetiredMucBot(login["jid"], login["password"], login["nick"], config)
    xmpp.register_plugin("xep_0030")  # Service Discovery
    xmpp.register_plugin("xep_0045")  # Multi-User Chat
    xmpp.register_plugin("xep_0085")  # Chat State Notifications
    xmpp.register_plugin("xep_0092")  # Software Version
    xmpp.register_plugin("xep_0199")  # XMPP Ping
    xmpp.register_plugin("xep_0249")  # Direct MUC Invite

    # connect and start receiving stanzas
    xmpp.connect()
    xmpp.process()