Ejemplo n.º 1
0
    def on_usernotice(self, chatconn, event):
        tags = {
            tag["key"]: tag["value"] if tag["value"] is not None else ""
            for tag in event.tags
        }

        if event.target != self.channel:
            return

        id = tags["user-id"]
        login = tags["login"]
        name = tags["display-name"]

        with DBManager.create_session_scope(
                expire_on_commit=False) as db_session:
            source = User.from_basics(db_session, UserBasics(id, login, name))
            if event.arguments and len(event.arguments) > 0:
                msg = event.arguments[0]
            else:
                msg = None  # e.g. user didn't type an extra message to share with the streamer

            with new_message_processing_scope(self):
                HandlerManager.trigger("on_usernotice",
                                       source=source,
                                       message=msg,
                                       tags=tags)

                if msg is not None:
                    self.parse_message(msg, source, event, tags)
Ejemplo n.º 2
0
 def bulk_get_user_basics_by_login(self, logins):
     bulk_user_data = self.bulk_get_user_data_by_login(logins)
     return [
         UserBasics(user_data["id"], user_data["login"],
                    user_data["display_name"])
         if user_data is not None else None for user_data in bulk_user_data
     ]
Ejemplo n.º 3
0
 def fetch_user_basics_from_authorization(self,
                                          authorization) -> UserBasics:
     """Fetch the UserBasics for the user identified by the given authorization object.
     `authorization` can be a UserAccessTokenManager or a tuple (ClientCredentials, UserAccessToken)."""
     user_data = self._fetch_user_data_from_authorization(authorization)
     return UserBasics(user_data["id"], user_data["login"],
                       user_data["display_name"])
Ejemplo n.º 4
0
 def bulk_get_user_basics_by_id(
         self, user_ids: List[str]) -> List[Optional[UserBasics]]:
     bulk_user_data = self.bulk_get_user_data_by_id(user_ids)
     return [
         UserBasics(user_data["id"], user_data["login"],
                    user_data["display_name"])
         if user_data is not None else None for user_data in bulk_user_data
     ]
Ejemplo n.º 5
0
    def on_pubmsg(self, chatconn, event):
        tags = {
            tag["key"]: tag["value"] if tag["value"] is not None else ""
            for tag in event.tags
        }

        id = tags["user-id"]
        login = event.source.user
        name = tags["display-name"]

        if event.source.user == self.nickname:
            return False

        if self.streamer == "forsen":
            if "zonothene" in login:
                self._ban(login)
                return True

            raw_m = event.arguments[0].lower()
            if raw_m.startswith("!lastseen forsen"):
                if len(raw_m) > len("!lastseen forsen2"):
                    if raw_m[16] == " ":
                        return True
                else:
                    return True

            if raw_m.startswith("!lastseen @forsen"):
                if len(raw_m) > len("!lastseen @forsen2"):
                    if raw_m[17] == " ":
                        return True
                else:
                    return True

        if self.streamer == "nymn":
            if "hades_k" in login:
                self.timeout_login(login, 3600, reason="Bad username")
                return True

            if "hades_b" in login:
                self.timeout_login(login, 3600, reason="Bad username")
                return True

        with DBManager.create_session_scope(
                expire_on_commit=False) as db_session:
            source = User.from_basics(db_session, UserBasics(id, login, name))

            with new_message_processing_scope(self):
                res = HandlerManager.trigger("on_pubmsg",
                                             source=source,
                                             message=event.arguments[0],
                                             tags=tags)
                if res is False:
                    return False

                self.parse_message(event.arguments[0],
                                   source,
                                   event,
                                   tags=tags)
Ejemplo n.º 6
0
    def on_whisper(self, chatconn, event):
        tags = {tag["key"]: tag["value"] if tag["value"] is not None else "" for tag in event.tags}

        id = tags["user-id"]
        login = event.source.user
        name = tags["display-name"]

        with DBManager.create_session_scope(expire_on_commit=False) as db_session:
            source = User.from_basics(db_session, UserBasics(id, login, name))
            self.parse_message(event.arguments[0], source, event, tags, whisper=True)
Ejemplo n.º 7
0
 def on_message(self, message):
     msg = json.loads(message)
     if msg["type"].lower() == "pong":
         self.sent_ping = False
         return
     elif msg["type"].lower() == "reconnect":
         self.reset()
         return
     elif msg["type"].lower() == "message":
         if msg["data"][
                 "topic"] == "channel-bits-events-v2." + self.bot.streamer_user_id:
             messageR = json.loads(msg["data"]["message"])
             user_id_of_cheer = str(messageR["data"]["user_id"])
             bits_cheered = str(messageR["data"]["bits_used"])
             with DBManager.create_session_scope() as db_session:
                 user = User.find_by_id(db_session, user_id_of_cheer)
                 if user is not None:
                     HandlerManager.trigger("on_cheer",
                                            True,
                                            user=user,
                                            bits_cheered=bits_cheered)
             return
         try:
             message_message = json.loads(msg["data"]["message"])
             if message_message["type"] == "reward-redeemed":
                 userDict = message_message["data"]["redemption"]["user"]
                 HandlerManager.trigger(
                     "on_redeem",
                     redeemer=UserBasics(userDict["id"], userDict["login"],
                                         userDict["display_name"]),
                     redeemed_id=message_message["data"]["redemption"]
                     ["reward"]["id"],
                     user_input=message_message["data"]["redemption"].get(
                         "user_input", ""),
                 )
         except Exception as e:
             log.error(e)
     elif msg["type"].lower() == "response":
         if not msg["error"]:
             return
     log.warning(msg)
Ejemplo n.º 8
0
    def on_pubmsg(self, chatconn, event):
        tags = {
            tag["key"]: tag["value"] if tag["value"] is not None else ""
            for tag in event.tags
        }

        id = tags["user-id"]
        login = event.source.user
        name = tags["display-name"]

        if event.source.user == self.nickname:
            return False

        with DBManager.create_session_scope(
                expire_on_commit=False) as db_session:
            source = User.from_basics(db_session, UserBasics(id, login, name))
            res = HandlerManager.trigger("on_pubmsg",
                                         source=source,
                                         message=event.arguments[0])
            if res is False:
                return False

            self.parse_message(event.arguments[0], source, event, tags=tags)
Ejemplo n.º 9
0
 def get_user_basics_by_login(self, login):
     user_data = self._get_user_data_by_login(login)
     if user_data is None:
         return None
     return UserBasics(user_data["id"], user_data["login"],
                       user_data["display_name"])
Ejemplo n.º 10
0
    def on_usernotice(self, source, tags, **rest):
        if "msg-id" not in tags:
            return

        if tags["msg-id"] == "resub":
            num_months = -1
            substreak_count = 0
            if "msg-param-months" in tags:
                num_months = int(tags["msg-param-months"])
            if "msg-param-cumulative-months" in tags:
                num_months = int(tags["msg-param-cumulative-months"])
            if "msg-param-streak-months" in tags:
                substreak_count = int(tags["msg-param-streak-months"])
            if "msg-param-should-share-streak" in tags:
                should_share = bool(tags["msg-param-should-share-streak"])
                if not should_share:
                    substreak_count = 0

            if "msg-param-sub-plan" not in tags:
                log.debug(
                    f"subalert msg-id is resub, but missing msg-param-sub-plan: {tags}"
                )
                return

            # log.debug('msg-id resub tags: {}'.format(tags))

            # TODO: Should we check room id with streamer ID here? Maybe that's for pajbot2 instead
            self.on_resub(source, num_months, tags["msg-param-sub-plan"], None,
                          substreak_count)
            HandlerManager.trigger("on_user_resub",
                                   user=source,
                                   num_months=num_months)
        elif tags["msg-id"] == "subgift":
            num_months = 0
            substreak_count = 0
            if "msg-param-months" in tags:
                num_months = int(tags["msg-param-months"])
            if "msg-param-cumulative-months" in tags:
                num_months = int(tags["msg-param-cumulative-months"])
            if "msg-param-streak-months" in tags:
                substreak_count = int(tags["msg-param-streak-months"])
            if "msg-param-should-share-streak" in tags:
                should_share = bool(tags["msg-param-should-share-streak"])
                if not should_share:
                    substreak_count = 0

            if "display-name" not in tags:
                log.debug(
                    f"subalert msg-id is subgift, but missing display-name: {tags}"
                )
                return

            with DBManager.create_session_scope() as db_session:
                receiver_id = tags["msg-param-recipient-id"]
                receiver_login = tags["msg-param-recipient-user-name"]
                receiver_name = tags["msg-param-recipient-display-name"]
                receiver = User.from_basics(
                    db_session,
                    UserBasics(receiver_id, receiver_login, receiver_name))

                if num_months > 1:
                    # Resub
                    self.on_resub(receiver, num_months,
                                  tags["msg-param-sub-plan"],
                                  tags["display-name"], substreak_count)
                    HandlerManager.trigger("on_user_resub",
                                           user=receiver,
                                           num_months=num_months)
                else:
                    # New sub
                    self.on_new_sub(receiver, tags["msg-param-sub-plan"],
                                    tags["display-name"])
                    HandlerManager.trigger("on_user_sub", user=receiver)
        elif tags["msg-id"] == "sub":
            if "msg-param-sub-plan" not in tags:
                log.debug(
                    f"subalert msg-id is sub, but missing msg-param-sub-plan: {tags}"
                )
                return

            self.on_new_sub(source, tags["msg-param-sub-plan"])
            HandlerManager.trigger("on_user_sub", user=source)
        elif tags["msg-id"] == "giftpaidupgrade":
            self.on_gift_upgrade(source)
        elif tags["msg-id"] == "extendsub":
            self.on_extend_sub(source)
        else:
            log.debug(f"Unhandled msg-id: {tags['msg-id']} - tags: {tags}")
Ejemplo n.º 11
0
    def authorized():
        try:
            resp = twitch.authorized_response()
        except OAuthException as e:
            log.error(e)
            log.exception("An exception was caught while authorizing")
            next_url = get_next_url(request, "state")
            return redirect(next_url)
        except Exception as e:
            log.error(e)
            log.exception("Unhandled exception while authorizing")
            return render_template("login_error.html")

        if resp is None:
            if "error" in request.args and "error_description" in request.args:
                log.warning(f"Access denied: reason={request.args['error']}, error={request.args['error_description']}")
            next_url = get_next_url(request, "state")
            return redirect(next_url)
        elif type(resp) is OAuthException:
            log.warning(resp.message)
            log.warning(resp.data)
            log.warning(resp.type)
            next_url = get_next_url(request, "state")
            return redirect(next_url)

        session["twitch_token"] = (resp["access_token"],)
        session["twitch_token_expire"] = time.time() + resp["expires_in"] * 0.75

        me_api_response = twitch.get("users")
        if len(me_api_response.data["data"]) < 1:
            return render_template("login_error.html")

        with DBManager.create_session_scope(expire_on_commit=False) as db_session:
            me = User.from_basics(
                db_session,
                UserBasics(
                    me_api_response.data["data"][0]["id"],
                    me_api_response.data["data"][0]["login"],
                    me_api_response.data["data"][0]["display_name"],
                ),
            )
            session["user"] = me.jsonify()

        # bot login
        if me.login == app.bot_config["main"]["nickname"].lower():
            redis = RedisManager.get()
            token_json = UserAccessToken.from_api_response(resp).jsonify()
            redis.set(f"authentication:user-access-token:{me.id}", json.dumps(token_json))
            log.info("Successfully updated bot token in redis")

        # streamer login
        if me.login == app.bot_config["main"]["streamer"].lower():
            # there's a good chance the streamer will later log in using the normal login button.
            # we only update their access token if the returned scope containes the special scopes requested
            # in /streamer_login

            # We use < to say "if the granted scope is a proper subset of the required scopes", this can be case
            # for example when the bot is running in its own channel and you use /bot_login,
            # then the granted scopes will be a superset of the scopes needed for the streamer.
            # By doing this, both the streamer and bot token will be set if you complete /bot_login with the bot
            # account, and if the bot is running in its own channel.
            if set(resp["scope"]) < set(streamer_scopes):
                log.info("Streamer logged in but not all scopes present, will not update streamer token")
            else:
                redis = RedisManager.get()
                token_json = UserAccessToken.from_api_response(resp).jsonify()
                redis.set(f"authentication:user-access-token:{me.id}", json.dumps(token_json))
                log.info("Successfully updated streamer token in redis")

        next_url = get_next_url(request, "state")
        return redirect(next_url)
Ejemplo n.º 12
0
 def get_user_basics_by_id(self, user_id: str) -> Optional[UserBasics]:
     user_data = self._get_user_data_by_id(user_id)
     if user_data is None:
         return None
     return UserBasics(user_data["id"], user_data["login"],
                       user_data["display_name"])