def getTwitchInformation():
    twitchAppId = getConfigInformationAsString("TwitchAPI", "TwitchAppId")
    twitchAppSecret = getConfigInformationAsString("TwitchAPI",
                                                   "TwitchAppSecret")
    broadcasterId = getConfigInformationAsString("TwitchAPI",
                                                 "TwitchBoradcastId")
    twitch = Twitch(twitchAppId, twitchAppSecret)
    twitch.authenticate_app([])
    return twitch.get_channel_information(broadcasterId)
Example #2
0
def start(bot):
    target_scope = [
        AuthScope.ANALYTICS_READ_GAMES, AuthScope.BITS_READ,
        AuthScope.CHANNEL_EDIT_COMMERCIAL, AuthScope.CHANNEL_MANAGE_BROADCAST,
        AuthScope.CHANNEL_MANAGE_POLLS, AuthScope.CHANNEL_MANAGE_PREDICTIONS,
        AuthScope.CHANNEL_MANAGE_REDEMPTIONS, AuthScope.CHANNEL_MODERATE,
        AuthScope.CHANNEL_READ_HYPE_TRAIN, AuthScope.CHANNEL_READ_POLLS,
        AuthScope.CHANNEL_READ_PREDICTIONS, AuthScope.CHANNEL_READ_REDEMPTIONS,
        AuthScope.CHANNEL_READ_SUBSCRIPTIONS, AuthScope.CHANNEL_SUBSCRIPTIONS,
        AuthScope.CHAT_EDIT, AuthScope.CHAT_READ, AuthScope.CLIPS_EDIT,
        AuthScope.MODERATION_READ, AuthScope.USER_EDIT_BROADCAST,
        AuthScope.USER_MANAGE_BLOCKED_USERS, AuthScope.USER_READ_BLOCKED_USERS,
        AuthScope.USER_READ_BROADCAST, AuthScope.USER_READ_FOLLOWS,
        AuthScope.USER_READ_SUBSCRIPTIONS
    ]

    twitch = Twitch(config['client_id'], config['client_secret'])
    twitch.authenticate_app([])
    twitch.set_user_authentication(config['twitch_token'], target_scope,
                                   config['refresh_token'])

    def callback_bits(uuid: UUID, data: dict):
        print(f"Got callback for UUID {str(uuid)}")
        print(data)
        pubsub.bits(bot, data['data'])

    def callback_subscriptions(uuid: UUID, data: dict):
        print(f"Got callback for UUID {str(uuid)}")
        print(data)
        pubsub.subscription(bot, data['data'])

    def callback_points(uuid: UUID, data: dict):
        print(f"Got callback for UUID {str(uuid)}")
        print(data)
        pubsub.points(bot, data['data'])

    user_id = twitch.get_users(logins=['will_am_i_'])['data'][0]['id']

    pubsubs = PubSub(twitch)
    pubsubs.start()

    bits_uuid = pubsubs.listen_bits(user_id, callback_bits)
    subscriptions_uuid = pubsubs.listen_channel_subscriptions(
        user_id, callback_subscriptions)
    points_uuid = pubsubs.listen_channel_points(user_id, callback_points)

    #pubsubs.stop()
Example #3
0
def setup_platform(
    hass: HomeAssistant,
    config: ConfigType,
    add_entities: AddEntitiesCallback,
    discovery_info: DiscoveryInfoType | None = None,
) -> None:
    """Set up the Twitch platform."""
    channels = config[CONF_CHANNELS]
    client_id = config[CONF_CLIENT_ID]
    client_secret = config[CONF_CLIENT_SECRET]
    oauth_token = config.get(CONF_TOKEN)
    client = Twitch(app_id=client_id, app_secret=client_secret)
    client.auto_refresh_auth = False

    try:
        client.authenticate_app(scope=OAUTH_SCOPES)
    except TwitchAuthorizationException:
        _LOGGER.error("INvalid client ID or client secret")
        return

    if oauth_token:
        try:
            client.set_user_authentication(
                token=oauth_token, scope=OAUTH_SCOPES, validate=True
            )
        except MissingScopeException:
            _LOGGER.error("OAuth token is missing required scope")
            return
        except InvalidTokenException:
            _LOGGER.error("OAuth token is invalid")
            return

    channels = client.get_users(logins=channels)

    add_entities(
        [TwitchSensor(channel=channel, client=client) for channel in channels["data"]],
        True,
    )
    'bananaslamjamma', 'gunnardota2', 'monkeys_forever', 'xcaliburye', 'gorgc',
    'purgegamers'
]

streamerstate = {}

for user_ids in streamers:
    streamerstate[user_ids] = 0

check_game = operations.check_game
bot = operations.send_telegram_photo
twitch = Twitch(ClientID, ClientSecret)

while True:

    twitch.authenticate_app([])
    for streamername in streamers:
        data = twitch.get_streams(user_login=[streamername])
        if data['data']:
            streamer = data['data'][0]['user_name']
            game_id = data['data'][0]['game_id']
            game_name = data['data'][0]['game_name']
            stream_title = data['data'][0]['title']
            viewers = data['data'][0]['viewer_count']
            check_game(game_id, game_name)
            stream_start_time = datetime.datetime.strptime(
                data['data'][0]['started_at'], '%Y-%m-%dT%H:%M:%SZ')
            time_now = datetime.datetime.utcnow()
            photo_url = f"https://static-cdn.jtvnw.net/previews-ttv/live_user_{streamername}-720x480.jpg"
            uptime = humanize.precisedelta(time_now - stream_start_time,
                                           minimum_unit='seconds')
Example #5
0
class TwitchNotifier(commands.Cog):
    def __init__(self, bot):
        self.bot: 'PixlBot' = bot
        self.config = bot.config['TwitchNotifier']
        self.backend = FileBackend('db')
        self.backend.autocommit = True
        self.bot.logger.info("Twitch notifier plugin ready")
        self.uuids = []
        self.online_uuids = []
        self.sslcontext = ssl.SSLContext()
        self.sslcontext.load_cert_chain(self.config['cert_path'],
                                        self.config['key_path'])
        self._twitch_init_()

    def _twitch_init_(self):
        self.bot.logger.info("Registering with Twitch...")
        self.twitch = Twitch(self.config['id'], self.config['secret'])
        self.twitch.authenticate_app([])
        self.bot.logger.info(
            f"Registering webhook endpoint {self.config['myurl']} ...")
        self.hook = TwitchWebHook(self.config['myurl'],
                                  self.config['id'],
                                  self.config['port'],
                                  ssl_context=self.sslcontext)
        self.hook.authenticate(self.twitch)
        self.bot.logger.info("Clearing all hook subscriptions...")
        self.hook.unsubscribe_all(self.twitch)  # Clear all subs on startup
        self.hook.start()
        self._register_all()

    def _login_to_id(self, name: str) -> Optional[str]:
        """Returns the twitch ID for a given login name, or None if the name couldn't be resolved."""
        try:
            res: dict = self.twitch.get_users(logins=[name])
        except TwitchBackendException as e:
            self.bot.logger.error(f"Backend error fetching user! {e}")
            return None
        if len(res) == 0:
            return None
        else:
            return res['data'][0]['id']

    def _register_all(self):
        """Attempts to register stream_changed callbacks for all configured users."""
        self.bot.logger.info("Registering callbacks for all watched users..")
        users = self.backend.filter(TwitchWatchedUser,
                                    {'twitch_name': {
                                        "$exists": True
                                    }})
        if not users:
            self.bot.logger.info("No users to watch. No callbacks registered.")
        else:
            for u in users:
                self.bot.logger.info(f"Registering: {u['twitch_name']}")
                success, uuid = self.hook.subscribe_stream_changed(
                    u['twitch_id'], self._cb_stream_changed)
                if success and uuid:
                    self.uuids.append(uuid)
                    self.bot.logger.info(
                        f"{success}: registered subscription UUID: {uuid}")
                else:
                    self.bot.logger.error(
                        f"{success}: failed registering subscription: {uuid}")

    def _cb_stream_changed(self, uuid, data):
        """Callback for Twitch webhooks, fires on stream change event"""
        self.bot.logger.debug(f"Callback data for {uuid}: {data}")
        if data["type"] == "offline":
            if uuid in self.online_uuids:
                self.online_uuids.remove(
                    uuid
                )  # Stupid twitch sending the same damn webhook multiple times...
                return
            else:
                self.bot.logger.debug(
                    f"Ignoring duplicate offline callback for {uuid}")
                return
        elif data["type"] == "live":
            if uuid in self.online_uuids:
                self.bot.logger.debug(
                    f"Ignoring duplicate live callback for {uuid}")
                return
            else:
                self.online_uuids.append(uuid)
        else:
            self.bot.logger.error(
                f"Got a callback type we can't handle: {data['type']}")
            return

        if uuid not in self.uuids:
            self.bot.logger.error(
                f"Got a callback for a UUID we're not tracking: {uuid}, my UUIDs: {self.uuids}"
            )
            return

        try:
            item = self.backend.get(TwitchWatchedUser,
                                    {"twitch_id": data["user_id"]})
        except TwitchWatchedUser.DoesNotExist:
            self.bot.logger.error(
                f"Got a callback for a USER we're not tracking: {data['user_id']} -> {data['user_name']}"
            )
            return
        channel: discord.TextChannel = self.bot.get_channel(
            item['notify_channel'])

        width = 640
        height = 360
        url = data['thumbnail_url'].format(width=width, height=height)

        tu = self.twitch.get_users(data['user_id'])['data'][0]
        self.bot.logger.debug(tu)

        embed = discord.Embed(
            title=f"Now streaming {data['game_name']}",
            description=data['title'],
            color=discord.Color.green(),
        )
        embed.set_image(url=url)
        embed.set_thumbnail(url=tu["profile_image_url"])
        embed.set_author(name=item["twitch_name"],
                         url=f"https://twitch.tv/{data['user_name']}")
        embed.add_field(name="Watch live at",
                        value=f"https://twitch.tv/{data['user_name']}")
        self.bot.loop.create_task(
            channel.
            send(  # This isn't an async function, so enqueue it manually
                embed=embed))
        self.bot.logger.info(
            f"Successfully sent online notification for {data['user_id']}")

    @cog_ext.cog_subcommand(
        base="Twitchwatch",
        name="add_notification",
        description="Add a go live notification for Twitch",
        options=[twitch_name, notify_channel, notify_text],
        guild_ids=util.guilds)
    async def add_notification(self, ctx: SlashContext, twitch_name: str,
                               notify_channel: discord.TextChannel,
                               notify_text: str):
        twitch_id = self._login_to_id(twitch_name)
        try:
            self.backend.get(TwitchWatchedUser, {'twitch_name': twitch_name})
        except TwitchWatchedUser.DoesNotExist:
            pass
        except TwitchWatchedUser.MultipleDocumentsReturned:
            self.bot.logger.error(
                "Multiple users returned - database inconsistent???")
            return
        if not twitch_id:
            await ctx.send(embed=mkembed(
                'error',
                f"Unable to get the Twitch ID for the name {twitch_name}"))
            return
        await ctx.defer()  # This bit can take a minute.
        success, uuid = self.hook.subscribe_stream_changed(
            twitch_id, self._cb_stream_changed)
        if success and uuid:
            self.uuids.append(uuid)
            self.bot.logger.info(
                f"{success}: registered subscription UUID: {uuid}")
        else:
            self.bot.logger.error(
                f"{success}: failed registering subscription: {uuid}")
            await ctx.send("Bluh, couldn't register the webhook with twitch :("
                           )
            return
        item = TwitchWatchedUser({
            'twitch_name': twitch_name,
            'twitch_id': twitch_id,
            'discord_name': ctx.author.id,
            'notify_channel': notify_channel.id,
            'notify_text': notify_text,
            'uuid': str(uuid)
        })
        self.bot.logger.debug(f"DB object dump: {item.__dict__}")
        self.backend.save(item)
        await ctx.send(embed=mkembed("done",
                                     f"Notification added for {twitch_name}",
                                     channel=notify_channel.name))

    @cog_ext.cog_subcommand(
        base="Twitchwatch",
        name="del_notification",
        description="Remove a go live notification for Twitch",
        options=[twitch_name],
        guild_ids=util.guilds)
    async def del_notification(self, ctx: SlashContext, twitch_name: str):
        try:
            item = self.backend.get(TwitchWatchedUser,
                                    {'twitch_name': twitch_name})
        except TwitchWatchedUser.DoesNotExist:
            await ctx.send(embed=mkembed(
                "error", f"No notification exists for {twitch_name}"))
            return
        self.hook.unsubscribe(item['uuid'])
        self.bot.logger.info(f"Removing watch {item['uuid']}: {twitch_name}")
        self.backend.delete(item)
        if item['uuid'] in self.uuids:
            self.uuids.remove(item['uuid'])
        await ctx.send(
            embed=mkembed("done", f"Notification for {twitch_name} removed."))
Example #6
0
class DiscordTwitchWebhook():
    def __init__(self, twitch_appid, twitch_secret, callback_url):
        self.discord_username = "******"
        self.twitch = Twitch(twitch_appid, twitch_secret)
        self.callback_url = callback_url
        self.hook = TwitchWebHook(callback_url, twitch_appid, 8080)
        self.authenticated = False
        self.subscriptions = []

    def authenticate(self):
        self.authenticated = False
        try:
            self.twitch.authenticate_app([])
            self.hook.authenticate(self.twitch)
        except TwitchAuthorizationException:
            print("Twitch authentication failed")
        except RuntimeError:
            print("Webhook must be https")
        else:
            self.authenticated = True
        return self.authenticated

    def subscribe_user(self, user: DiscordTwitchCallback):
        if not self.authenticated:
            raise Exception
        #TODO handle more exceptions

        user_data = self.twitch.get_users(logins=[user.username])
        user.data = user_data['data'][0]
        user.id = user.data['id']
        if user not in self.subscriptions:
            ret, user.uuid = self.hook.subscribe_stream_changed(
                user.id, self.callback_stream_changed)
            if ret:
                self.subscriptions.append(user)
            else:
                print(f"Failed to subscribe to {user.username}")

    def unsubscribe_user(self, user: DiscordTwitchCallback):
        #TODO
        return

    def start(self):
        self.hook.start()

    def stop(self):
        self.hook.unsubscribe_all(self.twitch)
        self.hook.stop()

    def callback_stream_changed(self, uuid, twdata):
        print('Callback for UUID ' + str(uuid), twdata)
        user = next((user for user in self.subscriptions if user.uuid == uuid),
                    None)
        if user == None:
            print("Callback failed")
            return
        if twdata['type'] == 'live':
            emb = self.create_embed(twdata)
            user.run_callback(emb)

    def create_embed(self, twdata):
        return Embed(title=f"{twdata['user_name']}",
                     description=f"{twdata['user_name']} is streaming {twdata['game_name']}! Get in here!",
                     color=6570404,
                     url=f"https://twitch.tv/{twdata['user_name']}") \
                    .set_image(url=twdata['thumbnail_url'].format(width="1280", height="720"))
Example #7
0
# basic twitch API authentication, this will yield a app token but not a user token
auth_scope = [
    AuthScope.BITS_READ, AuthScope.USER_EDIT, AuthScope.WHISPERS_READ,
    AuthScope.CHANNEL_READ_SUBSCRIPTIONS, AuthScope.CHANNEL_READ_STREAM_KEY,
    AuthScope.ANALYTICS_READ_EXTENSION, AuthScope.ANALYTICS_READ_GAMES,
    AuthScope.CHANNEL_EDIT_COMMERCIAL, AuthScope.CHANNEL_READ_HYPE_TRAIN,
    AuthScope.CHANNEL_MANAGE_BROADCAST, AuthScope.CHANNEL_READ_REDEMPTIONS,
    AuthScope.CLIPS_EDIT, AuthScope.USER_EDIT_BROADCAST,
    AuthScope.USER_READ_BROADCAST, AuthScope.USER_READ_EMAIL,
    AuthScope.USER_EDIT_FOLLOWS, AuthScope.CHANNEL_MODERATE,
    AuthScope.CHAT_EDIT, AuthScope.CHAT_READ, AuthScope.WHISPERS_READ,
    AuthScope.WHISPERS_EDIT, AuthScope.MODERATION_READ,
    AuthScope.CHANNEL_SUBSCRIPTIONS
]
twitch = Twitch(APP_ID, APP_SECRET)
twitch.authenticate_app(auth_scope)
# since we want user information, we require a OAuth token, lets get one
# you dont need to generate a fresh user token every time, you can also refresh a old one or get one using a different online service
# for refreshing look here: https://github.com/Teekeks/pyTwitchAPI#user-authentication
# please note that you have to add http://localhost:17563 as a OAuth redirect URL for your app, see the above link for more information
# auth = UserAuthenticator(
#     twitch, auth_scope)
# token, refresh_token = auth.authenticate()  # this will open a webpage
# print(token, refresh_token)
# setting the user authentication so any api call will also use it
twitch.set_user_authentication(TOKEN, auth_scope, REFRESH_TOKEN)
# setting up the Webhook itself
sslContext = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS)
hook = TwitchWebHook(PUBLIC_ADDR, APP_ID, PORT, ssl_context=sslContext)
# this will use the highest authentication set, which is the user authentication.
hook.authenticate(twitch)
Example #8
0
class Streamer:

    global TWITCH_APP_ID
    global TWITCH_SECRET
    global StreamerName
    global StreamerID
    isID = False

    def __init__(self, TWITCH_APP_ID, TWITCH_SECRET, User, isID = False):

        self.reader = codecs.getreader('utf-8')
        self.TWITCH_APP_ID = TWITCH_APP_ID
        self.TWITCH_SECRET = TWITCH_SECRET
        self.twitch = Twitch(self.TWITCH_APP_ID, self.TWITCH_SECRET)

        self.StreamerName = User
        self.isID = isID
        self.LOCK = False

        if not self.isID:
            self.StreamerID = self.getUserID()




    def getUserID(self):

        if self.isID: return self.StreamerName

        self.twitch.authenticate_app([])
        data = self.twitch.get_users(logins=[self.StreamerName])
        return data['data'][0]['id']


    def isStreaming(self):

        data = self.twitch.get_streams(user_id=self.StreamerID)
        if len(data['data']) != 0:
            if data['data'][0]['type'] == 'live':
                return True
        return False

    def getStreamLink(self): return 'https://www.twitch.tv/' + str(self.StreamerName.lower())

    def lock(self): self.LOCK = True

    def unlock(self): self.LOCK = False

    def lockStatus(self): return self.LOCK

    def getGame(self):

        if self.isStreaming():
            data = self.twitch.get_streams(user_id=self.StreamerID)
            game = data['data'][0]['game_name']
            return game
        return False

    def getViewers(self):

        if self.isStreaming():
            data = self.twitch.get_streams(user_id=self.StreamerID)
            viewers = data['data'][0]['viewer_count']
            return viewers
        return False

    def getTitle(self):

        if self.isStreaming():
            data = self.twitch.get_streams(user_id=self.StreamerID)
            title = data['data'][0]['title']
            return  title
        return False

    def getThumbnail(self):

        if self.isStreaming():
            data = self.twitch.get_streams(user_id=self.StreamerID)
            thumbnail = data['data'][0]['thumbnail_url']
            thumbnail = thumbnail.format(width='1920', height='1080')
            return thumbnail
        return False

    def getProfilePicture(self):

        data = self.twitch.get_users(logins=self.StreamerName)
        picture = data['data'][0]['profile_image_url']
        return picture

    def getStreamerName(self):
        return self.StreamerName
Example #9
0
class Twitch(commands.Cog):
    """Get live updates for your favourite twitch streamers
    """
    def __init__(self, disclient, twitch_id, twitch_sec):
        self.disclient = disclient
        self.disclient.loop.create_task(self.get_online_streams())
        self.twitch = Twitchy(
            twitch_id,
            twitch_sec,
        )
        self.twitch.authenticate_app([])
        self.time_format = '%Y-%m-%d %H:%M:%S'

    async def get_online_streams(self):
        await self.disclient.wait_until_ready()
        print('Looking for live Twitch streams!')
        while not self.disclient.is_closed():
            try:
                # print("checking twitch")
                check = get_all_twitch_channels_to_check(3)
                if not check:
                    await asyncio.sleep(60)
                    continue
                if len(check) > 100:
                    # need to split list into lengths of 100 in future
                    # get_streams only takes 100 inputs at a time
                    check = check[:99]
                ids = [str(x) for x in check.keys()]
                b = self.twitch.get_streams(user_id=ids)
                for stream in b["data"]:
                    c = self.twitch.get_users(user_ids=stream["user_id"])
                    linkend = c['data'][0]['login']
                    link = f"https://www.twitch.tv/{linkend}"
                    username = stream['user_name']
                    desc = stream['title']
                    msg = f"`{username}` is live! {link}"
                    image_url = f"""{stream['thumbnail_url'].format(
                                     width=852, height=480)}?{str(datetime.datetime.now().timestamp())}"""
                    embed = discord.Embed(title=msg,
                                          description=desc,
                                          color=discord.Color.purple())
                    embed.set_image(url=image_url)
                    embed.add_field(name='Playing', value=stream['game_name'])
                    check_time = datetime.datetime.strptime(
                        stream['started_at'], '%Y-%m-%dT%H:%M:%SZ')
                    check_time.strftime(self.time_format)
                    if check[int(stream['user_id'])] != check_time:
                        update_twitch_last_live(stream['user_id'], check_time)
                    else:
                        continue
                    channels = get_channels_following_twitch_stream(
                        stream['user_id'])
                    if not channels:
                        await asyncio.sleep(60)
                        continue
                    for chan in channels:
                        channel = self.disclient.get_channel(int(chan))
                        # set ping roles up in the future
                        # gid = channel.guild.id
                        # rol = self.disclient.get_guild(gid).roles
                        # tr = discord.utils.get(rol, name="twitch")
                        await channel.send(
                            embed=embed
                        )  # content=tr.mention, for when roles are assigned
            except Exception as e:
                print(e)
            # delay 60 seconds before checking again
            await asyncio.sleep(60)

    @commands.command(
        aliases=['followstream', 'follow_stream', 'followtwitch'])
    @commands.guild_only()
    @commands.has_permissions(administrator=True)
    async def follow_twitch(self, ctx, stream):
        """Follows a twitch stream in this channel! Live updates will be posted here.
        .follow_twitch <username or link>"""
        channel = ctx.channel.id
        if "twitch.tv" in stream:
            stream = stream.split("/")[-1].lower()
        else:
            stream = stream.lower()
        user = self.twitch.get_users(logins=stream)
        print(user)
        if not user:
            await ctx.send(
                embed=error_embed(f"Failed to find Twitch user {stream}!"))
            return
        for d in user["data"]:
            ayed = str(d["id"])
            add_channel(channel)
            add_twitch_channel_to_db(ayed)
            followed = follow_twitch_channel_db(channel, ayed)
            if followed:
                display_name = d['display_name']
                profile_image = d['profile_image_url']
                link = f"https://www.twitch.tv/{d['login']}"
                msg = f'This channel will now receive updates on when {display_name} goes live at {link}'
                embed = discord.Embed(
                    title=f'Successfully Followed {display_name}!',
                    description=msg,
                    color=discord.Color.purple())
                embed.set_thumbnail(url=profile_image)
                await ctx.send(embed=embed)
            else:
                await ctx.send(embed=error_embed(
                    f"Failed to follow {stream} in this channel!"))

    @commands.command(
        aliases=['unfollowstream', 'unfollow_stream', 'unfollowtwitch'])
    @commands.guild_only()
    @commands.has_permissions(administrator=True)
    async def unfollow_twitch(self, ctx, stream):
        """Unfollows a twitch stream followed in this channel.
        .unfollow_twitch <username or link>"""
        channel = ctx.channel.id
        if "twitch.tv" in stream:
            stream = stream.split("/")[-1].lower()
        else:
            stream = stream.lower()
        user = self.twitch.get_users(logins=stream)
        if not user:
            await ctx.send(
                embed=error_embed(f"Failed to find Twitch user {stream}!"))
            return
        for d in user["data"]:
            ayed = str(d["id"])
            unfollowed = unfollow_twitch_channel_db(channel, ayed)
            if unfollowed:
                await ctx.send(embed=success_embed(
                    f"Unfollowed {stream} in this channel!"))
            else:
                await ctx.send(embed=error_embed(
                    f"Failed to unfollow {stream} in this channel!"))

    @commands.command(name='twitch', aliases=['twitchs', 'twitches'])
    @commands.guild_only()
    async def twitches(self, ctx):
        """Returns a list of all twitch users followed in this server!"""
        guild = ctx.guild
        chans = get_all_twitch_followed_in_guild()
        chan_dict = {}
        for pair in chans:
            if pair[0] not in chan_dict:
                chan_dict.update({pair[0]: [pair[-1]]})
            else:
                chan_dict[pair[0]].append(pair[-1])
        msg = ''
        for channel in guild.channels:
            if channel.id in chan_dict:
                for twitch in chan_dict[channel.id]:
                    twitch_str = str(twitch)
                    twitch = self.twitch.get_users(user_ids=[twitch_str])
                    twitch = twitch['data'][0]['login']
                    spacing = 39 - len(channel.name + twitch)
                    chan_str = f"`#{channel.name}{' ' * spacing}{twitch}`\n"
                    msg = msg + chan_str
        if msg == '':
            await ctx.send(
                embed=error_embed('No Twitch streams followed in this server!')
            )
        else:
            add_to_start = f"`Channel Name{' ' * 17}Twitch User`\n"
            msg = add_to_start + msg
            embed = discord.Embed(
                title=f'Twitch Streams Followed in {guild.name}!',
                description=msg,
                color=discord.Color.purple())
            await ctx.send(embed=embed)