コード例 #1
0
ファイル: icq.py プロジェクト: viert/knowledgehub
class ICQBot(AbstractBot):

    NETWORK_NAME = "icq"
    NETWORK_BASE_URL = "https://api.icq.net/bot/v1"

    def __init__(self):
        super(ICQBot, self).__init__()
        self.bot = Bot(token=self.token, api_url_base=self.base_url)

    def send_message(self, where: str, what: str):
        self.bot.send_text(where, what)

    def start(self):
        self.poller.start()
        event_id = None
        try:
            while True:
                try:
                    response = self.bot.events_get(last_event_id=event_id)
                except Exception as e:
                    ctx.log.error("error receiving icq events: %s", e)
                    continue
                response = response.json()

                if "events" not in response:
                    ctx.log.error("no events field in response")
                    continue
                for event in response["events"]:
                    event_id = event["eventId"]
                    self.process_event(event)

        except KeyboardInterrupt:
            ctx.log.info("SIGINT received, about to quit")
            self.poller.stopped = True

    def _new_user_message(self, event):
        base_url = ctx.cfg.get("base_uri", "http://localhost:8000/")
        link = f"{base_url}#/profile"
        text = "Hey there, I'm a KnowledgeHub bot. You may have forgotten to " \
               "fill in your ICQ id on your profile page. Or may have misspelled it. " \
               "A typo or something, a common thing, no worries. Well, you have two options " \
               "of fixing that. The first one is broken and the second one is to fill in " \
               "your ICQ id on profile page: {link} properly and run /start once again. " \
               "I'll be waiting right here. Not going anywhere. Honestly."
        self.send_message(event["payload"]["chat"]["chatId"], text.format(link=link))

    def _new_user_confirmed_message(self, event):
        text = "Hey there, I'm a KnowledgeHub bot. Looks, like you " \
               "did it all right, I have found your account and connected " \
               "it to this chat. Here's where your notifications will go to. " \
               "If you're fed up, this chat can be muted. Or just type /stop " \
               "and the nightmare is over. But remember that I'll forget you " \
               "in that case. Forever. Well, at least until you type /start once again."
        self.send_message(event["payload"]["chat"]["chatId"], text)

    @staticmethod
    def search_for_commands(text: str) -> List[str]:
        return CMD_MATCH.findall(text)

    def process_event(self, event):
        if event["type"] != "newMessage":
            ctx.log.debug("unknown event type '%s', skipping %s", event["type"], event)
            return

        commands = self.search_for_commands(event["payload"]["text"])
        for cmd in commands:
            method_name = f"cmd_{cmd}"
            if hasattr(self, method_name):
                method = getattr(self, method_name)
                method(event)

    def cmd_start(self, event):
        chat_dsc = event["payload"]["chat"]
        ctx.log.debug("running command 'start' by request from %s", chat_dsc)

        if chat_dsc["type"] != "private":
            self.send_message(chat_dsc["chatId"], "Hey there! Unfortunately I'm not capable of working in groups. "
                                              "Please add me privately")
            return

        chat = Chat.find_one({"chat_id": chat_dsc["chatId"], "network_type": "icq"})
        if chat is None:
            user = User.find_by_icq_id(event["payload"]["from"]["userId"])
            if user is None:
                return self._new_user_message(event)

            chat = Chat({
                "chat_id": chat_dsc["chatId"],
                "user_id": user._id,
                "network_type": "icq"
            })
            chat.save()
            return self._new_user_confirmed_message(event)

    def cmd_ping(self, event):
        ctx.log.debug("running command 'ping' by request from %s", event["payload"]["chat"])
        chat = Chat.find_one({"chat_id": event["payload"]["chat"]["chatId"]})
        if chat is None:
            return
        self.send_message(chat.chat_id, "pong")

    def cmd_stop(self, event):
        ctx.log.debug("running command 'stop' by request from %s", event["payload"]["chat"])
        chat = Chat.find_one({"chat_id": event["payload"]["chat"]["chatId"]})
        if chat is not None:
            chat.destroy()