async def add(self, ctx, discord_channel: discord.TextChannel, twitch_user: str, *, msg: str = None): """Sets up notifications for a Twitch user in the specified channel.""" if not ctx.message.author.permissions_in(ctx.message.channel).manage_guild: return await ctx.send("You need the **Manage Server** permission to do this.") username = twitch_user.split('/')[-1] if self.regex.match(username) is None: return await ctx.send("That doesn't look like a valid Twitch user. You can only include underscores, letters, and numbers.") if not discord_channel.permissions_for(ctx.guild.me).send_messages: return await ctx.send("I don't have permission to send messages in the requested channel.") try: await ctx.trigger_typing() s = TWAPI_REQUEST("https://api.twitch.tv/helix/users?login="******"That user does not exist.") else: if self.bot.notifs.get(s.json()['data'][0]['id']) is None: self.bot.notifs[s.json()['data'][0]['id']] = {str(discord_channel.id): {"name": username, "last_stream_id": None, "message": msg or "<https://twitch.tv/{}> is now live on Twitch!".format(username)}} else: self.bot.notifs[s.json()['data'][0]['id']][str(discord_channel.id)] = {"name": username, "last_stream_id": None, "message": msg or "<https://twitch.tv/{}> is now live on Twitch!".format(username)} f = open(os.path.join(os.getcwd(), 'data', 'notifs.json'), 'w') f.write(json.dumps(self.bot.notifs)) f.close() return await ctx.send("You should now receive a message in {} when `{}` goes live.".format(discord_channel.mention, username)) except KeyError as e: return await ctx.send("That Twitch user doesn't exist. Make sure that you're not putting <> around the name, and that you're not @mentioning a Discord user.") except IndexError as e: return await ctx.send("That Twitch user doesn't exist. Make sure that you're not putting <> around the name, and that you're not @mentioning a Discord user.") except: return await ctx.send(traceback.format_exc())
async def remove(self, ctx, discord_channel: discord.TextChannel, twitch_user: str): """Deletes notifications for a Twitch user in the specified channel.""" username = twitch_user if not ctx.message.author.permissions_in( ctx.message.channel).manage_guild: return await ctx.send( "You need the **Manage Server** permission to do this.") if "https://twitch.tv/" in twitch_user: username = twitch_user.strip("https://twitch.tv").strip("/") try: s = TWAPI_REQUEST("https://api.twitch.tv/helix/users?login="******"That user does not exist.") else: del self.bot.notifs[s.json()['data'][0]['id']][ discord_channel.id] if len(self.bot.notifs[s.json()['data'][0]['id']]) == 0: del self.bot.notifs[s.json()['data'][0]['id']] f = open(os.path.join(os.getcwd(), 'data', 'notifs.json'), 'w') f.write(json.dumps(self.bot.notifs)) f.close() except KeyError: await ctx.send( "Either that user doesn't exist or is not set up for that channel. kthx" ) except: await ctx.send(traceback.format_exc()) else: await ctx.send( "You won't get any notifications in {} when `{}` goes live.". format(discord_channel.mention, username))
async def add(self, ctx, discord_channel: discord.TextChannel, twitch_user: str, *, message: str): """Sets up notifications for a Twitch user in the specified channel.""" if not ctx.message.author.permissions_in( ctx.message.channel).manage_guild: return await ctx.send( "You need the **Manage Server** permission to do this.") username = twitch_users if "https://twitch.tv/" in twitch_users: username = twitch_users.strip("https://twitch.tv").strip("/") username = username.strip(" ").split(",") for u in username: if u.startswith("--"): if u.startswith("--game="): game = u.split("=", 1) else: try: await ctx.trigger_typing() s = TWAPI_REQUEST( "https://api.twitch.tv/helix/users?login="******"That user does not exist.") else: if self.bot.notifs.get( s.json()['data'][0]['id']) is None: self.bot.notifs[s.json()['data'][0]['id']] = { discord_channel.id: True } else: self.bot.notifs[s.json()['data'][0]['id']][ discord_channel.id] = True f = open( os.path.join(os.getcwd(), 'data', 'notifs.json'), 'w') f.write(json.dumps(self.bot.notifs)) f.close() guild = await self.bot.db.fetchval( "SELECT * FROM guilds WHERE id = $1;", ctx.guild.id) if guild: await self.bot.db.execute( "UPDATE guilds SET notifmessage = $1 WHERE id = $2;", message, ctx.guild.id) else: await self.bot.db.execute( "INSERT INTO guilds (id, prefix, notifmessage) VALUES ($1, $2);", ctx.guild.id, message) if len(username) == 1: return await ctx.send( "You should now receive a message in {} when `{}` goes live." .format(discord_channel.mention, u)) except: return await ctx.send(traceback.format_exc()) if len(u) > 1: return await ctx.send( "You should now receive a message in {} when those channels go live." .format(discord_channel.mention))
async def watch(self, ctx, *, user): await ctx.trigger_typing() user = user.split('/')[-1] r = TWAPI_REQUEST("https://api.twitch.tv/helix/streams?user_login="******"data"] == []: await ctx.send("That user doesn't exist or is not online.") else: await ctx.send( "**<:twitch:404633403603025921> Live on Twitch**\nhttps://twitch.tv/{}" .format(user))
async def add(self, ctx, discord_channel: discord.TextChannel, twitch_user: str, *, msg: str = None): """Sets up notifications for a Twitch user in the specified channel.""" if not ctx.message.author.permissions_in( ctx.message.channel).manage_guild: return await ctx.send( "You need the **Manage Server** permission to do this.") username = twitch_user if "https://twitch.tv/" in twitch_user: username = twitch_user.strip("https://twitch.tv").strip("/") try: await ctx.trigger_typing() s = TWAPI_REQUEST("https://api.twitch.tv/helix/users?login="******"That user does not exist.") else: if self.bot.notifs.get(s.json()['data'][0]['id']) is None: self.bot.notifs[s.json()['data'][0]['id']] = { str(discord_channel.id): { "last_stream_id": None, "message": msg or "{user} is now live on Twitch!".format(twitch_user) } } else: self.bot.notifs[s.json()['data'][0]['id']][str( discord_channel.id)] = { "last_stream_id": None, "message": msg or "{user} is now live on Twitch!".format(twitch_user) } f = open(os.path.join(os.getcwd(), 'data', 'notifs.json'), 'w') f.write(json.dumps(self.bot.notifs)) f.close() return await ctx.send( "You should now receive a message in {} when `{}` goes live." .format(discord_channel.mention, username)) except KeyError: return await ctx.send( "That Twitch user doesn't exist. Make sure that you're not putting <> around the name, and that you're not @mentioning a Discord user." ) except: return await ctx.send(traceback.format_exc())
async def trending(self, ctx): await ctx.trigger_typing() r = TWAPI_REQUEST("https://api.twitch.tv/kraken/clips/top") if r.status_code != 200: await ctx.send("An error Occurred: {}".format(r.status_code)) elif len(r.json()['clips']) < 1: await ctx.send("No clips found.") return else: clip = choice(r.json()['clips']) await ctx.send("Check out {} playing {}:\n{}".format( clip['broadcaster']['display_name'], clip['game'], clip['url'].split('?')[0]))
async def game(self, ctx, *, name): await ctx.trigger_typing() e = discord.Embed(color=discord.Color(0x6441A4)) r = TWAPI_REQUEST("https://api.twitch.tv/helix/games/?name=" + name) r.raise_for_status() try: r = r.json()["data"][0] except IndexError: return await ctx.send("No results found.") e.description = "[View Streams](https://www.twitch.tv/directory/game/{})".format( r["name"].replace(' ', '%20')) e.title = r["name"] e.set_image(url=r["box_art_url"].format(width=285, height=380)) await ctx.send(embed=e)
async def game(self, ctx, *, game): await ctx.trigger_typing() trending = "" if game.endswith(" --trending"): trending = "&trending=true" r = TWAPI_REQUEST("https://api.twitch.tv/kraken/search/games?" + urlencode({"query": game.strip(' --trending')})) if r.status_code != 200: await ctx.send("An error Occurred: {}-1".format(r.status_code)) return elif len(r.json()['games']) < 1: await ctx.send("No clips found for that game.") return game = r.json()['games'][0]['name'] await asyncio.sleep(1) r = TWAPI_REQUEST("https://api.twitch.tv/kraken/clips/top?" + urlencode({"game": game}) + trending) if r.status_code != 200: await ctx.send("An error Occurred: {}-2".format(r.status_code)) return elif len(r.json()['clips']) < 1: await ctx.send("No clips found for that game.") return clip = choice(r.json()['clips']) await ctx.send("Check out {} playing {}:\n{}".format( clip['broadcaster']['display_name'], clip['game'], clip['url'].split('?')[0]))
async def top(self, ctx, cnt: int = 10): await ctx.trigger_typing() e = discord.Embed(color=discord.Color(0x6441A4), title="<:twitch:404633403603025921> Top Games") r = TWAPI_REQUEST("https://api.twitch.tv/kraken/games/top?limit=10") r.raise_for_status() r = r.json()["top"] place = 1 for game in r: e.add_field(inline=False, name="`{}.` {}".format(place, game["game"]["name"]), value="{} viewers • {} channels".format( game["viewers"], game["channels"])) place += 1 await ctx.send(embed=e)
async def _from(self, ctx, twitch_user: str, *args): twitch_user = twitch_user.split('/')[-1] trending = "" if "--trending" in args: trending = "&trending=true" await ctx.trigger_typing() r = TWAPI_REQUEST("https://api.twitch.tv/kraken/clips/top?channel=" + twitch_user + trending) if r.status_code != 200: await ctx.send("An error Occurred: {}".format(r.status_code)) elif len(r.json()['clips']) < 1: await ctx.send("No clips found for that user.") return else: clip = choice(r.json()['clips']) await ctx.send("Check out {} playing {}:\n{}".format( clip['broadcaster']['display_name'], clip['game'], clip['url'].split('?')[0]))
async def listen(self, ctx, *, url: str): """Listen to the specified Twitch user in the current voice channel.""" url = "https://www.twitch.tv/" + url.split('/')[-1] author = ctx.message.author if author.voice is None: return await ctx.send("You need to be in a voice channel!") voice_channel = author.voice.channel r = DBOTS_REQUEST("/bots/375805687529209857/check?userId=" + str(author.id)) if r.status_code == 200 and not r.json()['voted'] == 1: await ctx.send("<:twitch:404633403603025921> You need to upvote TwitchBot to listen to streams! Upvote here -> <https://discordbots.org/bot/375805687529209857/vote>. If you just upvoted, please allow up to 5 minutes for the upvote to process.") return m = await ctx.send("Please wait... <a:loading:414007832849940482>") try: vc = await voice_channel.connect() except discord.ClientException: session = ctx.message.guild.voice_client await session.disconnect() await asyncio.sleep(2) vc = await voice_channel.connect() try: r = TWAPI_REQUEST("https://api.twitch.tv/helix/streams?user_login="******"twitch.tv/")[1]) if len(r.json()["data"]) < 1: await m.delete() return await ctx.send("<:twitch:404633403603025921> This user doesn't exist or is not currently streaming.") r = r.json()["data"][0] await asyncio.sleep(0.5) r2 = TWAPI_REQUEST("https://api.twitch.tv/helix/users?login="******"twitch.tv/")[1]) if len(r2.json()["data"]) < 1: await m.delete() return await ctx.send("<:twitch:404633403603025921> This user doesn't exist or is not currently streaming.") r2 = r2.json()["data"][0] e = discord.Embed(color=0x6441A4, title="Now playing in {}".format(voice_channel.name), description="**{}**\n{} currently watching".format(r['title'], r['viewer_count'])) e.set_author(name=r2['display_name'], url=url, icon_url=r2['profile_image_url']) e.set_image(url=r['thumbnail_url'].format(width=1920, height=1080)) player = await YTDLSource.from_url(url, loop=self.bot.loop, stream=True) vc.play(player, after=lambda e: log.error("An audio player error occurred: " + e) if e else None) self.bot.vc[ctx.message.guild.id] = e await m.delete() await ctx.send(embed=e) except youtube_dl.DownloadError: await ctx.send("<:twitch:404633403603025921> This user doesn't exist or is not currently streaming.") except: await ctx.send("A fatal exception occurred:\n```\n" + traceback.format_exc() + "\n```")
async def _from(self, ctx, twitch_user: str, *args): twitch_user = twitch_user.split('/')[-1] if self.regex.match(twitch_user) is None: return await ctx.send( "That doesn't look like a valid Twitch user. You can only include underscores, letters, and numbers." ) trending = "" if "--trending" in args: trending = "&trending=true" await ctx.trigger_typing() r = TWAPI_REQUEST("https://api.twitch.tv/kraken/clips/top?channel=" + twitch_user + trending) if r.status_code != 200: await ctx.send("An error Occurred: {}".format(r.status_code)) elif len(r.json()['clips']) < 1: await ctx.send("No clips found for that user.") return else: clip = choice(r.json()['clips']) await ctx.send("Check out {} playing {}:\n{}".format( clip['broadcaster']['display_name'], clip['game'], clip['url'].split('?')[0]))
async def user(self, ctx, *, user): await ctx.trigger_typing() user = user.split('/')[-1] e = discord.Embed(color=discord.Color(0x6441A4)) r = TWAPI_REQUEST("https://api.twitch.tv/helix/streams?user_login="******"data") in [[], None]: await ctx.send( "That user doesn't exist or is not online. Make sure you're only entering the user's name and not anything extra, like `()` or `<>`." ) else: r = r.json()["data"][0] u = TWAPI_REQUEST("https://api.twitch.tv/helix/users?login="******"data"][0] g = TWAPI_REQUEST("https://api.twitch.tv/helix/games?id=" + r["game_id"]) g.raise_for_status() try: g = g.json()["data"][0] except: g = {"id": 0, "name": "Unknown"} e.set_author(icon_url=u["profile_image_url"], name=u["display_name"], url="https://twitch.tv/{}".format(u["login"])) e.title = r["title"] e.description = """ Playing {2} for {0} viewers **[Watch on Twitch](https://twitch.tv/{1})** or type `twitch stream watch {1}`\n Stream Preview: """.format(r["viewer_count"], u["login"], g["name"]) e.set_image( url=r["thumbnail_url"].format(width="1920", height="1080")) await ctx.send(embed=e)
async def user(self, ctx, *, user): await ctx.trigger_typing() user = user.split('/')[-1] e = discord.Embed(color=discord.Color(0x6441A4)) r = TWAPI_REQUEST("https://api.twitch.tv/helix/users?login="******"data"] == [] or r.status_code == 400: await ctx.send( "That user doesn't exist. If you entered the user's full profile url, try redoing the command with just their user name." ) r.raise_for_status() r = r.json()["data"][0] s = TWAPI_REQUEST("https://api.twitch.tv/helix/streams?user_login="******"data"] verified = "" if not r["broadcaster_type"] == "": verified = " <:twitch_verified:409725750116089876>" e.set_author(icon_url=r["profile_image_url"], name=r["display_name"], url="https://twitch.tv/{}".format(r["login"])) e.set_thumbnail(url=r["profile_image_url"]) e.title = r["login"] + verified e.description = r["description"] e.add_field(inline=False, name="Views", value=r["view_count"]) if not s == []: s = s[0] g = TWAPI_REQUEST("https://api.twitch.tv/helix/games?id=" + s["game_id"]) g.raise_for_status() g = g.json()["data"][0] e.add_field( inline=False, name="Currently Live", value= "Playing {} for {} viewers\n\n**[Watch on Twitch](https://twitch.tv/{})**" .format(g["name"], s["viewer_count"], user)) else: e.add_field( inline=False, name="Currently Offline", value="[View Twitch Profile](https://twitch.tv/{})".format( user)) await ctx.send(embed=e)
async def user(self, ctx, *, user): await ctx.trigger_typing() user = user.split('/')[-1] if self.regex.match(user) is None: return await ctx.send( "That doesn't look like a valid Twitch user. You can only include underscores, letters, and numbers." ) e = discord.Embed(color=discord.Color(0x6441A4)) # get user info r = TWAPI_REQUEST("https://api.twitch.tv/helix/users?login="******"data") == [] or r.status_code == 400 or len( r.json()['data']) == 0: return await ctx.send( "That user doesn't exist. If you entered the user's full profile url, try redoing the command with just their user name." ) r.raise_for_status() r = r.json()["data"][0] # get user streaming status s = TWAPI_REQUEST("https://api.twitch.tv/helix/streams?user_login="******"data"] # get user follows ft = TWAPI_REQUEST( "https://api.twitch.tv/helix/users/follows?first=1&to_id=" + r['id']) ft.raise_for_status() # get user following ff = TWAPI_REQUEST( "https://api.twitch.tv/helix/users/follows?first=1&from_id=" + r['id']) ff.raise_for_status() verified = "" if r["broadcaster_type"] == "partner": verified = " <:twitch_verified:409725750116089876>" e.set_author(icon_url=r["profile_image_url"], name=r["display_name"], url="https://twitch.tv/{}".format(r["login"])) e.set_thumbnail(url=r["profile_image_url"]) e.title = r["login"] + verified e.description = r["description"] e.add_field(name="Followers", value="{:,}".format(ft.json()['total'])) e.add_field(name="Following", value="{:,}".format(ff.json()['total'])) e.add_field(inline=False, name="Views", value="{:,}".format(r["view_count"])) if not s == []: s = s[0] g = TWAPI_REQUEST("https://api.twitch.tv/helix/games?id=" + s["game_id"]) g.raise_for_status() try: g = g.json()["data"][0] except: g = {"name": "Unknown"} e.add_field( inline=False, name="Currently Live", value= "**{}**\nPlaying {} for {} viewers\n\n**[Watch on Twitch](https://twitch.tv/{})**" .format(s['title'], g["name"], s["viewer_count"], user)) e.set_image(url=s['thumbnail_url'].format(width=1920, height=1080)) else: e.add_field( inline=False, name="Currently Offline", value="[View Twitch Profile](https://twitch.tv/{})".format( user)) e.set_image(url=r['offline_image_url']) await ctx.send(embed=e)
async def stream(self, ctx, *, user): await ctx.trigger_typing() user = user.split('/')[-1] e = discord.Embed(color=discord.Color(0x6441A4)) r = TWAPI_REQUEST("https://api.twitch.tv/helix/streams?user_login="******"data"] == []: await self.bot.say("That user doesn't exist or is not online.") else: r = r.json()["data"][0] u = TWAPI_REQUEST("https://api.twitch.tv/helix/users?login="******"data"][0] g = TWAPI_REQUEST("https://api.twitch.tv/helix/games?id=" + r["game_id"]) g.raise_for_status() g = g.json()["data"][0] e.set_author(icon_url=u["profile_image_url"], name=u["display_name"], url="https://twitch.tv/{}".format(u["login"])) e.title = r["title"] e.description = """ Playing {2} for {0} viewers **[Watch on Twitch](https://twitch.tv/{1})** or type `twitch watch {1}`\n Stream Preview: """.format(r["viewer_count"], u["login"], g["name"]) e.set_image( url=r["thumbnail_url"].format(width="1920", height="1080")) await ctx.send(embed=e)
async def game(self, ctx, *, name): await ctx.trigger_typing() g = TWAPI_REQUEST("https://api.twitch.tv/helix/games?" + urllib.parse.urlencode({"name": name})) g.raise_for_status() try: g = g.json()['data'][0] except: return await ctx.send("That game could not be found.") game = g['name'] await asyncio.sleep(1) s = TWAPI_REQUEST("https://api.twitch.tv/helix/streams?game_id=" + g['id']) s.raise_for_status() if len(s.json()['data']) < 1: return await ctx.send("Nobody is streaming that game.") stream = choice(s.json()['data']) await asyncio.sleep(1) u = TWAPI_REQUEST("https://api.twitch.tv/helix/users?id=" + stream['user_id']) u.raise_for_status() await ctx.send( "Check out {0} playing {1} for {2} viewers:\nhttps://twitch.tv/{0}" .format(u.json()['data'][0]['display_name'], game, stream['viewer_count']))
async def top(self, ctx): await ctx.trigger_typing() r = TWAPI_REQUEST("https://api.twitch.tv/helix/streams?first=20") r.raise_for_status() stream = choice(r.json()['data']) u = TWAPI_REQUEST("https://api.twitch.tv/helix/users?id=" + stream['user_id']) u.raise_for_status() await asyncio.sleep(1) u = u.json()["data"][0] g = TWAPI_REQUEST("https://api.twitch.tv/helix/games?id=" + stream["game_id"]) g.raise_for_status() await asyncio.sleep(1) g = g.json()["data"][0] return await ctx.send( "Check out {0} playing {1} for {2} viewers:\nhttps://twitch.tv/{0}" .format(u['login'], g['name'], stream['viewer_count']))