def direct_message_channel_id(self, user_id):
        # This function will return the direct message channel ID for the given user ID

        try:
            # Query the "api/users/@me/channels" endpoint

            endpoint = "https://discordapp.com/api/users/@me/channels"

            # JSON data with the recipient_id (user_id) is required
            data = json.dumps({'recipient_id': user_id})

            resp = requests.post(url=endpoint, headers=self.headers, data=data)

            if (resp.status_code != 200):
                # The expected response code is 200, anything else would indicate an issue
                get_logger().warning(resp.json(), exc_info=True)
                return (None)

            try:
                return (resp.json()['id'])
            except:
                # User ID is invalid or bot lacks permission
                return (None)

        except Exception as e:
            # Failed to retrieve direct message channel ID
            get_logger().error(e, exc_info=True)
            return (None)
Beispiel #2
0
    def on_get(self, req, resp):
        try:
            # Retrieve the Discord channel ID and the YouTube channel URL from the headers
            disc_guild_id    = req.get_header('discord_guild_id')
            disc_channel_id  = req.get_header('discord-channel-id')
            yt_channel_url      = req.get_header('youtube-channel-url')

            # If either of the two required headers are missing, return bad request
            if(disc_channel_id == None or yt_channel_url == None):
                raise falcon.HTTPBadRequest('Missing Requried Headers', 'Required headers: discord-channel-id and youtube-channel-url')

            # Using the youtube_management class add the subscription to the database
            message = youtube_management().unsubscribe(yt_channel_url, disc_channel_id)

            resp.status = falcon.get_http_status(message['code'])
            resp.content_type = ['application/json']
            resp.body = json.dumps(message)

        except falcon.HTTPBadRequest as e:
            message = {"status":"error", "code":400, "message":e.description}
            resp.status = falcon.get_http_status(message['code'])
            resp.content_type = ['application/json']
            resp.body = json.dumps(message)

        except Exception as e:
            get_logger().error(e, exc_info=True)
Beispiel #3
0
    def on_get(self, req, resp):
        try:
            # Retrieve twitch_username and discrod_channel_id from headers
            twitch_username = req.get_header('twitch-username')
            discord_channel_id = req.get_header('discord-channel-id')
            discord_guild_id = req.get_header('discord-guild-id')

            # If twitch_username or discord_channel_id are not set then raise exception
            if (twitch_username is None or discord_channel_id is None
                    or discord_guild_id is None):
                raise falcon.HTTPBadRequest(
                    'Missing Requried Headers',
                    'Required headers: twitch_username and discord_channel_id')

            # Using twitch_management class attempt to add new notifiaction
            message = twitch_management(twitch_username, discord_guild_id,
                                        discord_channel_id).delete()

            resp.status = falcon.get_http_status(message['code'])
            resp.content_type = ['application/json']
            resp.body = json.dumps(message)

        except falcon.HTTPBadRequest as e:
            message = {
                "status": "error",
                "code": 400,
                "message": e.description
            }
            resp.status = falcon.get_http_status(message['code'])
            resp.content_type = ['application/json']
            resp.body = json.dumps(message)

        except Exception as e:
            get_logger().error(e, exc_info=True)
Beispiel #4
0
    def post_message(self, message, discord_channel_ids):
        # Used to send a message to an array of discord channel IDs
        # This is called for both Twitch and YouTube notifications

        # Convert the message dict into a JSON object
        json_data = json.dumps(message)

        for channel_id in discord_channel_ids:
            try:
                discord_message_url = "https://discordapp.com/api/channels/{}/messages".format(
                    channel_id)
                r = requests.post(discord_message_url,
                                  headers=self.headers,
                                  data=json_data)

                if (r.status_code == 404
                        and r.json()['message'] == "Unknown Channel"):
                    # Discord channel no longer exist, delete notifications associated
                    # with the discord_channel_id
                    notifications().delete_by_discord_channel_id(channel_id)

                if (r.status_code == 403
                        and r.json()['message'] == "Missing Permissions"):
                    # The bot is missing permissions for the discord channel ID
                    discord_management().alert_guild_owner_permissions(
                        channel_id)

            except Exception as e:
                get_logger().error(e, exc_info=True)
Beispiel #5
0
    def manage_databse_subscription(self, mode, yt_channel_id, yt_display_name, discord_channel_id, discord_guild_id = None):
        # This function will add(INSERT) or delete(DELETE) subscriptions to/from the database.

        try:
            if(mode == "subscribe"):
                # Insert notification information
                values = [yt_channel_id, discord_guild_id, discord_channel_id]
                sql = "INSERT INTO `youtube_notifications` VALUES (NULL, %s, %s, %s)"
                res = self.data_handler.insert(sql, values)

                # If the channel ID is new/unique to the database, insert the id
                #  and display name into `youtube_channels`
                channel_res = self.data_handler.select("SELECT * FROM `youtube_channels` WHERE `yt_channel_id` =  %s", [yt_channel_id])

                if(len(channel_res) == 0):
                    self.data_handler.insert("INSERT INTO `youtube_channels` VALUES (NULL, %s, %s)", [yt_channel_id, yt_display_name])


            elif(mode == "unsubscribe"):
                values = [yt_channel_id, discord_channel_id]
                sql = "DELETE FROM `youtube_notifications` WHERE `yt_channel_id` = %s AND `discord_channel_id` = %s"
                res = self.data_handler.delete(sql, values)

            else:
                # "subscribe" and "unsubscribe" are hardcoded so this should never happen
                print("ERROR: Unknown mode in manage_databse_subscription")
                return(False)

            return(True)

        except Exception as e:
            get_logger().error(e, exc_info=True)
            return(False)
Beispiel #6
0
    def manage_webhook_subscription(self, mode, yt_channel_id):
        # This function subscribe/unsubscribe to/from notifications for the youtube
        # channel id given with the YouTube appspot API

        try:
            # Google/YouTube utilizes appspot to send webhook based notifications
            url = "https://pubsubhubbub.appspot.com/subscribe"

            # callback, topic, verify, and mode must be sent as a "form"
            payload = self.get_form_data(mode, yt_channel_id)

            # Currently, no headers are required.
            headers= {}

            # NOTE:  Figure out a better solution
            # timeout =1.xx is 100% a hack. Falcon only supports a single simultaneous
            # connection, the pubsubhubbub attemtps to reach /youtube/callback, however,
            # this current API request is blocking Falcon from responding.
            # Setting timeout to 1 sec will "ensure" that the payload POST data is sent,
            # and that the pubsubhubbub is able to reach the callback.
            response = requests.post(url, headers=headers, data = payload, timeout=1.0000000001)

            return(True)

        except requests.exceptions.ReadTimeout:
            # NOTE: See above
            return(True)
        except Exception as e:
            get_logger().error(e, exc_info=True)
            return(False)
Beispiel #7
0
    def select(self, sql, input, values_only=False):
        try:
            conn = self.get_connection()

            with conn.cursor() as cursor:
                cursor.execute(sql, input)

            return (cursor.fetchall())

        except Exception as e:
            get_logger().error(e, exc_info=True)
            return (None)
Beispiel #8
0
    def on_post(self, req, resp, twitch_user_id):

        try:
            data = json.loads(req.bounded_stream.read().decode())

            if 'display_name' in data['data'][0]:
                twitch_display_name = data['data'][0]['display_name']
                twitch_management(twitch_display_name, 0,
                                  0).update_user(twitch_user_id,
                                                 twitch_display_name)

        except Exception as e:
            get_logger().error(e, exc_info=True)
Beispiel #9
0
    def event(self, data):
        # This function is called when Twitch sends a webhook callback

        event = data["event"]

        try:
            # store/check event["id"]; Twitch creates a unique ID for each event
            #  Sometimes the same event can be delivered multiple times. This prevents
            #  the event from being processed multiple times.
            sql = "SELECT `event_id` FROM `twitch_event_ids` WHERE `event_id` = %s"
            res = data_handler().select(sql, [event["id"]])

            if (len(res) != 0):
                # Event has already been published
                return

            # New event, add to the database
            sql = "INSERT INTO `twitch_event_ids` (`event_id`) VALUES (%s)"
            data_handler().insert(sql, [event["id"]])

            if (event["type"] == "live"):
                # Channel is now live

                # Update live status in database
                sql = "UPDATE `twitch_channels` SET `streaming` = 1 WHERE `twitch_user_id` =  %s"
                data_handler().update(sql, [event['broadcaster_user_id']])

                # Format thumbnail URL
                twitch_thumbnail_url = "https://static-cdn.jtvnw.net/previews-ttv/live_user_" + event[
                    "broadcaster_user_name"] + "-640x360.jpg"

                # Prepare and Send discord message
                discord_post_obj = discord_post()
                message = discord_post_obj.prepare_twitch_message(
                    event["broadcaster_user_name"], twitch_thumbnail_url)
                discord_channel_ids = data_handler().select(
                    'SELECT DISTINCT `discord_channel_id` FROM `twitch_notifications` WHERE `twitch_user_id`=%s',
                    [event["broadcaster_user_id"]])
                discord_channel_ids = list(
                    map(lambda x: x['discord_channel_id'],
                        discord_channel_ids))  # FLatten results into a list
                discord_post_obj.post_message(message, discord_channel_ids)

            elif (event["type"] == "offline"):

                # Set streaming status to false
                sql = "UPDATE `twitch_channels` SET `streaming` = 0 WHERE `twitch_user_id` = %s"
                data_handler().update(sql, [event['broadcaster_user_id']])

        except Exception as e:
            get_logger().error(e, exc_info=True)
Beispiel #10
0
    def delete(self, sql, input):

        try:
            conn = self.get_connection()

            with conn.cursor() as cursor:
                cursor.execute(sql, input)

            conn.commit()
            conn.close()

            return (True)
        except Exception as e:
            get_logger().error(e, exc_info=True)
            return (False)
Beispiel #11
0
    def defined_update(self, key, input):

        try:
            conn = self.get_connection()

            with conn.cursor() as cursor:
                cursor.execute(self.defined_queries[key], input)

            conn.commit()
            conn.close()

            return (True)

        except Exception as e:
            get_logger().error(e, exc_info=True)
            return (False)
    def find_parent_guild(self, discord_channel_id):
        # This function will return the parent guild ID of a given discord_channel_id
        # Typically, this relationship will be stored in the local database, however,
        # in the event that it is not found, a request will be made to the Discord API.
        try:
            # Search database for relationship
            # This relationship will be in either 'twitch_notifications' or 'youtube_notifications'
            # This query uses the 'UNION ALL' operator to combine the discord guild ID's from both tables.
            sql = (
                "SELECT `discord_guild_id` FROM `twitch_notifications` WHERE `discord_channel_id` = %s "
                "UNION ALL SELECT `discord_guild_id` FROM `youtube_notifications` WHERE `discord_channel_id` = %s LIMIT 1"
            )

            # Fetch the discord_guild_id
            discord_guild_id = self.db.select(
                sql, [discord_channel_id, discord_channel_id])

            # Determine if a discord_guild_id was found in the database
            # Expected format: [{'discord_guild_id'}].
            # If the value does not exist, the exception will trigger.
            try:
                return (discord_guild_id[0]['discord_guild_id'])
            except:
                # Discord Guild ID was not found in the databse
                discord_guild_id = None

            # Query the Discord API
            endpoint = "https://discordapp.com/api/channels/" + str(
                discord_channel_id)
            resp = requests.get(url=endpoint, headers=self.headers)

            if (resp.status_code != 200):
                # The expected response code is 200, anything else would indicate an issue
                get_logger().warning(resp.json(), exc_info=True)
                return (None)

            try:
                # Attempt to retreive the guild_id from the response
                return (resp.json()['guild_id'])
            except:
                # Either invalid channel ID or bot lacks access (should be caught in prior if statement)
                return (None)

        except Exception as e:
            # An exception occured while attempting to lookup the parent guild ID
            get_logger().error(e, exc_info=True)
            return (None)
Beispiel #13
0
    def on_put(self, req, resp):

        try:
            yt_management = youtube_management()
            yt_management.update_display_names()
            yt_management.update_webhook_subs()

            resp.status = falcon.get_http_status(200)
            resp.content_type = ['application/json']
            resp.body = json.dumps({"status": "success", "code": 200})

        except Exception as e:
            get_logger().error(e, exc_info=True)

            resp.status = falcon.get_http_status(400)
            resp.content_type = ['application/json']
            resp.body = json.dumps({"status": "error", "code": 400})
Beispiel #14
0
    def on_get(self, req, resp):
        # Return a list of recent event entries.

        try:
            # Get level and limit variables from the headers
            # If the 'level' header is not provided, set it to 0
            if req.get_header('min-log-level') is None:
                level = 0
            else:
                # Will raise exception if cannot convert to int
                level = int(req.get_header('min-log-level'))

            # Create a soft limit of 100 events, this will prevent an excessive amount
            # of entries being returned. Also if limit is not provided, set it to 100
            if req.get_header('limit') is None:
                limit = 100
            else:
                # Get int value of limit, if limit is greater than 100: set to 100
                # Will raise exception if cannot convert to int
                limit = int(req.get_header('limit'))
                if limit > 100:
                    limit = 100

            # Retrieve the requested entries from the database
            events = data_handler().select("SELECT * FROM `logging` WHERE `level` >= %s ORDER BY `id` DESC LIMIT %s", [level, limit])

            resp.status = falcon.HTTP_200
            resp.content_type = ['application/json']
            # default=str resloves an issue with datetime.datetime not being
            #    JSON serializable
            resp.body = json.dumps(events, default=str)

        except (TypeError, ValueError) as e:
            # Intended to capture value/type errors with header value int casting
            get_logger().warning(e, exc_info=True)

            resp.status = falcon.HTTP_400
            resp.content_type = ['application/json']
            resp.body = json.dumps({"status":"error", "code":400, "message":"Ensure that header values 'min-log-level' and 'limit' are integers."})

        except Exception as e:
            get_logger().error(e, exc_info=True)

            resp.status = falcon.HTTP_400
            resp.content_type = ['application/json']
            resp.body = json.dumps({"status":"error", "code":400, "message":"Failed to retrieve entries."})
    def insert_auth_token(self, data, code):

        try:
            db_obj = data_handler()

            input = [
                None, None, code, data['access_token'], data['refresh_token'],
                data['scope'], data['token_type']
            ]
            sql = "INSERT INTO `discord_auth` VALUES (%s,%s,%s,%s,%s,%s,%s)"

            db_insert = db_obj.insert(sql, input)

            return (db_insert)

        except Exception as e:
            get_logger().error(e, exc_info=True)
            return (False)
Beispiel #16
0
    def on_post(self, req, resp):
        try:
            # Read data from POST
            data = req.bounded_stream.read().decode('UTF-8')

            # Parse the data using BeautifulSoup and XML parser
            bs_data = BeautifulSoup(data,"xml")

            # Select out the relavent data
            # video_url    = bs_data.feed.entry.link['href']
            channel_id   = bs_data.feed.entry.findAll('yt:channelId')[0].contents[0]
            video_id     = bs_data.feed.entry.findAll('yt:videoId')[0].contents[0]
            video_author = bs_data.feed.entry.author.findAll('name')[0].contents[0]
            video_title  = bs_data.feed.entry.title.contents[0]

            youtube_notification().post_notification(channel_id, video_id, video_author, video_title)

        except Exception as e:
            get_logger().error(e, exc_info=True)
Beispiel #17
0
    def on_post(self, req, resp, twitch_user_id=None):

        try:
            # Load the JSON data
            data = json.loads(req.bounded_stream.read().decode())

            # Check if the request is a challenge
            if "challenge" in data:
                # Respond to the challenge
                resp.status = falcon.HTTP_200
                resp.body = data["challenge"]

                # This request is not an actually notification, stop processing
                return

            if "event" in data:
                # Call the twitch_handler event function
                twitch_handler().event(data)

        except Exception as e:
            get_logger().error(e, exc_info=True)
Beispiel #18
0
    def on_post(self, req, resp):
        # Create a new log entry, this function will manually trigger the
        # 'db_insert_log' and 'discord_post_log' functions.
        try:
            # Create an event_log object, this provides access to DB and Discord functions
            log = event_log()

            # Expects data to be in JSON format in POST data
            data = json.loads(req.bounded_stream.read().decode('UTF-8'))

            # Insert a log entry into the database.
            db_status = log.db_insert_log(
                            data['log_level'],
                            data['log_pathname'],
                            data['log_class_name'],
                            data['log_function_name'],
                            data['log_exc_info'],
                            data['log_message']
                    )

            # If inserting the log into the database resulted in an error db_status = (false)
            if not db_status:
                raise

            # Send message to Discord, note: level must meet DISCORD_MIN_TO_LOG
            message = str(data['log_level']) + " | " + str(data['log_pathname']) + " | " + str(data['log_class_name']) + " | " + str(data['log_function_name']) + " | " + str(data['log_exc_info']) + " | " + str(data['log_message'])
            log.discord_post_log(int(data['log_level']), message)

            # Inserting entry was successful, return http_200 success
            resp.status = falcon.HTTP_200
            resp.content_type = ['application/json']
            resp.body = json.dumps({"status":"success", "code":200, "message":"Event logged to the database."})

        except Exception as e:
            get_logger().error(e, exc_info=True)

            # Inserting the entry failed, return http_400
            resp.status = falcon.HTTP_400
            resp.content_type = ['application/json']
            resp.body = json.dumps({"status":"error", "code":400, "message":"Failed to log event to the database"})
Beispiel #19
0
    def on_delete(self, req, resp):
        # Used to delete notifications associated with either a discord_channel_id
        # or a discord_guild_id
        try:
            # Check if discord-channel-id or discord-guild-id is in the headers, else HTTPBadRequest
            if req.get_header('discord-channel-id') is not None:
                notifications().delete_by_discord_channel_id(
                    req.get_header('discord-channel-id'))

            elif req.get_header('discord-guild-id') is not None:
                notifications().delete_by_discord_guild_id(
                    req.get_header('discord-guild-id'))

            else:
                raise falcon.HTTPBadRequest(
                    'Missing Requried Headers',
                    'Required header(s): discord-channel-id or discord-guild-id'
                )

            resp.status = falcon.get_http_status(200)
            resp.content_type = ['application/json']
            resp.body = json.dumps({"status": "success", "code": 200})

        except falcon.HTTPBadRequest as e:
            message = {
                "status": "error",
                "code": 400,
                "message": e.description
            }
            resp.status = falcon.get_http_status(message['code'])
            resp.content_type = ['application/json']
            resp.body = json.dumps(message)

        except Exception as e:
            get_logger().error(e, exc_info=True)

            message = {"status": "error", "code": 400, "message": 'API ERROR'}
            resp.status = falcon.get_http_status(message['code'])
            resp.content_type = ['application/json']
            resp.body = json.dumps(message)
    def send_direct_message(self, user_id, message):
        # Sends direct message to the given user_id

        try:
            # Get the direct message channel ID
            direct_message_channel = self.direct_message_channel_id(user_id)

            endpoint = "https://discordapp.com/api/channels/" + str(
                direct_message_channel) + "/messages"
            data = json.dumps({'content': message})

            resp = requests.post(url=endpoint, headers=self.headers, data=data)

            if (resp.status_code != 200):
                # Expected status_code is 200
                get_logger().error(resp.json(), exc_info=True)
                return (False)

            return (True)
        except Exception as e:
            get_logger().error(e, exc_info=True)
            return (False)
Beispiel #21
0
    def unsubscribe(self, yt_channel_url, discord_channel_id):
        # Use the youtube_channel_id class to determine the YouTube channel ID
        # for the given URL.

        # Convert the yt_channel_url into a YouTube channel ID.
        yt_channel_id = youtube_channel_id().get_yt_channel_id(yt_channel_url)

        # If the youtube_channel_id is unable to parse the URL, return the error.
        if yt_channel_id is None:
            return({"status":"error", "code":400, "message":"Error unable to parse the URL!"})

        # Remove the yt_channel and discord_channel_id combination from the database
        database_status = self.manage_databse_subscription("unsubscribe", yt_channel_id, None, discord_channel_id, None)

        # Ignore unsubscribing from the YouTube webhook, the lease will automatically expire,
        # and unsubscribing could create unintended results

        if database_status == False:
            get_logger().error("Error removing notification from the database!", exc_info=True)
            return({"status":"error", "code":503, "message":"Error removing notification from the database!"})
        else:
            return({"status":"success", "code":200, "message":"Notification successfully removed!"})
Beispiel #22
0
    def get_override_value(self, platform, discord_guild_id):
        # This function will select the proper SQL statement based on the given
        #  platform value, expected platform values: ['twitch', 'youtube']
        # Returns override value if exist else returns None.

        try:
            platform = str(platform).lower()

            sql = "SELECT `override` FROM `notification_limit_overrides` WHERE `platform` = %s AND `discord_guild_id` = %s"

            res = self.db.select(sql, [platform, discord_guild_id])

            return (int(res[0]['override']))

        except (TypeError, IndexError) as e:
            # Expected exception if the override value does not exist
            return (None)

        except Exception as e:
            # Unexpected exception, log event
            get_logger().error(e, exc_info=True)
            return (None)
Beispiel #23
0
    def subscribe(self, yt_channel_url, discord_guild_id, discord_channel_id):
        # Use the youtube_channel_id class to determine the YouTube channel ID
        # for the given URL.

        try:
            # Check if the discord_guild_id has reached the notification limit
            if(notification_limit().youtube_limit_reached(discord_guild_id)):
                # The limit has been reached
                return({"status":"error", "code":403, "message":"Notification limit has been reached!"})

            # Convert the yt_channel_url into a YouTube channel ID.
            yt_channel_id = youtube_channel_id().get_yt_channel_id(yt_channel_url)

            # If the youtube_channel_id is unable to parse the URL, return the error.
            if yt_channel_id is None:
                return({"status":"error", "code":400, "message":"Error unable to parse the URL!"})

            # Check if the yt_channel_id and discord_channel_id combination are unqiue.
            if(self.check_if_exist(yt_channel_id, discord_channel_id)):
                # The subscription to the YouTube channel in the Discord channel already exist.
                return({"status":"error", "code":400, "message":"Notification already exist!"})

            # Add notifcation to local databse
            yt_display_name = self.get_display_name(yt_channel_id)
            database_status = self.manage_databse_subscription("subscribe", yt_channel_id, yt_display_name, discord_channel_id, discord_guild_id)

            # Check if the local database insertion
            if database_status is False:
                # Error with the database
                get_logger().error("Error inserting subscription", exc_info=True)
                return({"status":"error", "code":503, "message":"Error internal database failure!"})

            # Subscribe to the webhook for the given channel
            subscribe_status = self.manage_webhook_subscription("subscribe", yt_channel_id)

            # Check if the YouTube API subscription was successful
            if subscribe_status is False:
                # Error with YouTube API (pubsubhubbub)
                get_logger().error("Error YouTube webhook subscription failed", exc_info=True)

            return({"status":"success", "code":200, "message":"Notification successfully added!"})

        except Exception as e:
            get_logger().error(e, exc_info=True)
            return({"status":"error", "code":503, "message":"Error internal system failure!"})
    def get_guild_data(self, discord_guild_id=None, discord_channel_id=None):
        # Fetches the guild object, this function can perform a lookup based on either the
        # guild ID or a channel ID.
        # https://discord.com/developers/docs/resources/guild#guild-object-guild-structure

        try:
            if discord_guild_id is None and discord_channel_id is None:
                # Neither value provided
                get_logger().warning(
                    "Neither discord_guild_id nor discord_channel_id provided",
                    exc_info=True)
                return (None)

            if discord_guild_id is None:
                # Use the find_parent_guild function to lookup the guild ID
                discord_guild_id = self.find_parent_guild(discord_channel_id)

                if discord_guild_id is None:
                    # Failed to find Guild ID
                    return (None)

            # Use the Discord API to retrieve the Guild Owners user ID
            endpoint = "https://discordapp.com/api/guilds/" + str(
                discord_guild_id)
            resp = requests.get(url=endpoint, headers=self.headers)

            if (resp.status_code != 200):
                # The expected response code is 200, anything else would indicate an issue
                get_logger().warning(resp.json(), exc_info=True)
                return (None)

            try:
                # Attempt to parse the response into a dict and return it
                return (resp.json())
            except:
                # Either invalid guild_id or bot lacks access to guild
                return (None)

        except Exception as e:
            # Error retrieving guild owner_id
            get_logger().error(e, exc_info=True)
            return (None)
    def alert_guild_owner_permissions(self, discord_channel_id):
        # This is used to notify a guild owner that the bot is missing the permissions
        # required to send a notification.

        try:
            # Create an event warning of the issue
            get_logger().warning(str("Missing permissions in " +
                                     str(discord_channel_id)),
                                 exc_info=True)

            # Retreive the guild data object, this contains the owner_id and guild name
            guild_data = self.get_guild_data(
                discord_channel_id=discord_channel_id)

            # Set the message
            message = "I've encountered an error in guild: `" + str(
                guild_data['name']
            ) + "`! \n Please ensure that I'm able to read messages, send messages, and embed links in the channels you want me to operate in."

            # Send the message
            status = self.send_direct_message(guild_data['owner_id'], message)

            if status is False:
                # Failed to contact the guild owner
                # NOTE: determine if a notification should be removed
                get_logger().error(
                    "Failed to contact guild owner for channel_id: " +
                    str(discord_channel_id),
                    exc_info=True)

            return (status)

        except Exception as e:
            # Failed to notify the guild owner
            get_logger().error(e, exc_info=True)
            return (False)
Beispiel #26
0
        from wsgiref import simple_server

        # If API_PORT is set as a system variable use it, else use 8445
        if(os.getenv('API_PORT') == None):
            port = 8445
        else:
            port = int(os.getenv('API_PORT'))

        # create a simple_server object to serve the API
        self.httpd = simple_server.make_server('0.0.0.0', port, self.app)
        self.httpd.serve_forever()

    def get_app(self):
        # Getter function for the falcon API object.
        return(self.app)


try:
    if __name__ == '__main__':
        # If the main.py is executed directly, the API will launch in "test" mode
        get_logger().info('API starting in test mode', exc_info=True)
        public_facing_api().start()

    else:
        # Guincorn will look for the variable "app"
        get_logger().info('API starting via Guincorn: ' + str(os.getpid()), exc_info=True)
        app = public_facing_api().get_app()

except Exception as e:
    get_logger().critical(e, exc_info=True)
Beispiel #27
0
    def on_get(self, req, resp):

        try:
            # Check if discord-channel-id is in headers, if not return HTTPBadRequest
            discord_channel_id = req.get_header('discord-channel-id')
            if discord_channel_id is None:
                raise falcon.HTTPBadRequest(
                    'Missing Requried Headers',
                    'Required header(s): discord-channel-id')

            # Get the parent guild of the discord_channel_id
            discord_guild_id = discord_management().find_parent_guild(
                discord_channel_id)

            # Create object for notifications class, get notification data for twitch and youtube
            # If no notifications are found, type None will be returned
            notifications_obj = notifications()

            # Create object for notification limit class, get notification limit and number of
            # notifications registered for each platform
            notification_limit_obj = notification_limit()

            # Create dict with notification data
            data = {
                discord_channel_id: {
                    'twitch':
                    notifications_obj.get_twitch_notifications(
                        discord_channel_id),
                    'youtube':
                    notifications_obj.get_youtube_notifications(
                        discord_channel_id),
                    'limits': {
                        'twitch': {
                            'limit':
                            notification_limit_obj.get_twitch_limit(
                                discord_guild_id),
                            'used':
                            notification_limit_obj.
                            get_twitch_notification_count(discord_guild_id)
                        },
                        'youtube': {
                            'limit':
                            notification_limit_obj.get_youtube_limit(
                                discord_guild_id),
                            'used':
                            notification_limit_obj.
                            get_youtube_notification_count(discord_guild_id)
                        }
                    }
                }
            }

            # Set http status to 200, set content_type to JSON, and convert the data dict into JSON
            resp.status = falcon.get_http_status(200)
            resp.content_type = ['application/json']
            resp.body = json.dumps(data)

        except falcon.HTTPBadRequest as e:
            message = {
                "status": "error",
                "code": 400,
                "message": e.description
            }
            resp.status = falcon.get_http_status(message['code'])
            resp.content_type = ['application/json']
            resp.body = json.dumps(message)

        except Exception as e:
            get_logger().error(e, exc_info=True)

            message = {"status": "error", "code": 400, "message": 'API ERROR'}
            resp.status = falcon.get_http_status(message['code'])
            resp.content_type = ['application/json']
            resp.body = json.dumps(message)