Discord.py grabbing twitch URL without an API - python-3.x

I have a discord bot.
What I want it to do is when the bot detects a user is streaming, print the URL of their stream into chat.
I'm having a problem trying to find out how to get the user's twitch channel url...
this is what I have
#client.event
async def on_member_update(before, after):
aname = after.display_name
aactivity = after.activity.type
mactivity = str(after.activities)
role = after.guild.get_role(736271867836498031)
channel = client.get_channel(736269005651836985)
memberinfo = after.activities.streaming.url
print(memberinfo)
if "Streaming name" in mactivity:
await after.add_roles(role)
await channel.send('{} has started streaming!'.format(after.display_name))
print(aname + " is streaming!")
else:
await after.remove_roles(role)
streamchannel = discord.Profile
await channel.send('{} is not streaming!'.format(after.display_name))
print(aname + " is not streaming.")
print('member updated status')
Is there something I'm missing? I don't know how at all to either find the URL of the streamer, or get it from their connect accounts.

Member objects have a Activity attribute. You can check if before.activity or after.activity is an instance of the Streaming class.
If so, the user either stopped or started streaming and we can send a message in channel:
from discord import Streaming
from discord.utils import get
#client.event
async def on_member_update(before, after):
if not before.activity.type == after.activity.type:
return
role = get(after.guild.roles, id=736271867836498031)
channel = get(after.guild.channels, id=736269005651836985)
if isinstance(after.activity, Streaming):
await after.add_roles(role)
await channel.send(f"{before.mention} is streaming on {activity.platform}: {activity.name}.\nJoin here: {activity.url}")
elif isinstance(before.activity, Streaming):
await after.remove_roles(role)
await channel.send(f'{after.mention} is no longer streaming!')
else:
return
Reference: discord.py documentation

Related

D.py/rewrite - Confessions System

I made a confessions system but there’s some things that are wrong with it. How would I make it so when users want to type, they don’t have to put in *confess and they can just type whatever they want without needing to use a command? And how do I make a mod logs channel to log the deleted confessions with the author name, etc.?
import discord
from discord.ext import commands
class Confess(commands.Cog):
def __init__(self, client: discord.ext.commands.Bot):
self.client = client
#commands.command()
async def confess(self, ctx: commands.Context, *, message: str):
channel = self.client.get_channel(806649868314869760)
await ctx.message.delete()
embed = discord.Embed(title="Success", description=f"I've received your confession and sent it to the <#806649874379964487> channel!")
embed.set_footer(text="Confessions")
await ctx.send(embed=embed, delete_after=10)
channel = self.client.get_channel(806649874379964487)
embed = discord.Embed(title="Confession", description=f"{message}")
embed.set_footer(text="All confessions are anonymous.")
await channel.send(embed=embed)
def setup(client):
client.add_cog(Confess(client))
For the first question
If you want to use a "command" without actually using a command you could make an on_message event, check the id of the channel (like a confessions channel) and if it matches then do the thing
Example:
#commands.Cog.listener()
async def on_message(message):
if message.channel.id == some_channel_id_here:
channel = self.client.get_channel(806649868314869760)
await message.delete()
embed = discord.Embed(title="Success", description=f"I've received your confession and sent it to the <#806649874379964487> channel!")
embed.set_footer(text="Confessions")
await message.channel.send(embed=embed, delete_after=10)
channel = self.client.get_channel(806649874379964487)
embed = discord.Embed(title="Confession", description=f"{message}")
embed.set_footer(text="All confessions are anonymous.")
await channel.send(embed=embed)
For the second question
You can use get_channel again to get the log channel and post in there. (If you mean't on how to check if someone deleted a message/confession, use on_message_delete)
Example:
#commands.command()
async def confess(self, ctx: commands.Context, *, message: str):
channel = self.client.get_channel(806649868314869760)
log_channel = self.client.get_channel(log_channel_id)
await ctx.message.delete()
embed = discord.Embed(title="Success", description=f"I've received your confession and sent it to the <#806649874379964487> channel!")
embed.set_footer(text="Confessions")
await ctx.send(embed=embed, delete_after=10)
channel = self.client.get_channel(806649874379964487)
embed = discord.Embed(title="Confession", description=f"{message}")
embed.set_footer(text="All confessions are anonymous.")
await channel.send(embed=embed)
await logchannel.send("User confessed something!")

Delete discord invites if someone post it in a channel

I want that the bot remove invites from channel if someone send one in all channels
Im using discord.py 1.6.0 and wrote it so but nothing happens.
rules = xxx
links = xxx
teamroom = xxx
# regex
DISCORD_INVITE = r'discord(?:\.com|app\.com|\.gg)[\/invite\/]?(?:[a-zA-Z0-9\-]{2,32})'
class Mod(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.links_allowed = (rules, teamroom, links)
self.url_regex = DISCORD_INVITE
#commands.Cog.listener()
async def on_message(self, message):
if search(self.url_regex, message.content):
await message.delete()
await message.channel.send("You cant send invites.", delete_after=10)
def setup(bot):
bot.add_cog(Mod(bot))
Might be late but try this:
import re
discordInviteFilter = re.compile("(...)?(?:https?://)?discord(?:(?:app)?\.com/invite|\.gg)/?[a-zA-Z0-9]+/?")
async def on_message(message):
if discordInviteFilter.match(message.content):
await message.delete()
await message.channel.send('no invites NOPPERS')
await client.process_commands(message)
You can check if the link posted starts with https://discord.gg and delete the message if the condition is met.
async def on_message(self, message):
if message.content.startswith("https://discord.gg"):
await message.delete()
await message.channel.send("You cannot send invites.")
You can check if the message has discord.gg in it I think having even if the message doesn't have HTTPS it still works with discord.gg if you add HTTPS:// then users will bypass by just using discord.gg only Hope you got your answer

Print the list of members in a voice channel

i'm coding a discord bot and I need a function that kick all members in my channel. I wrote this code:
#client.command()
async def separaci(ctx):
canale = ctx.message.author.voice.channel
utenti = canale.members #This return an empty list
for utente in utenti:
await utente.edit(voice_channel = None)
I don't know why canale.members return an empty list. Can you help me? Thanks you :)
Try this:
#client.command()
async def separaci(ctx):
if ctx.author.voice: # if the author is connected to a voice channel
canale = ctx.message.author.voice.channel
utenti = canale.members #This return an empty list
for utente in utenti:
await utente.edit(voice_channel = None)
await ctx.send("Kicked all the members from the voice channel!")
else:
await ctx.send("You need to be in a voice channel!")
return
NOTE:
You need to be in a voice channel while using this command.
Make sure the bot has the permission to disconnect the members present in the voice channel.
Make sure you have the members intent enabled in your developer portal.
You have to enable member intents, also make sure to enable them in the developer portal
intents = discord.Intents.default()
intents.members = True
client = commands.Bot(command_prefix='', intents=intents)
#client.command()
async def separaci(ctx):
channel = ctx.author.voice.channel
members = channel.members
A Primer Gateway to Intents

Simple bot command is not working in discord.py

I want to know in which text channels admin want to enable my bot functions. But in this case my code is not working.
The main idea was when admin typing !enable in text-chat, bot reacts to it and add text-chat id, guild id(ctx.channel.id) to the list, then bot responds in chat with bot has been enabled.
code where this command is not working:
channel = []
#bot.command()
async def enable(ctx):
global channel
print("Debug")
await ctx.send('Restriction bot has been enabled for this text channel.')
channel.append(ctx.channel.id)
full bot code:
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
#bot.event
async def on_ready():
print(f'We have logged in as {bot.user.name}.')
channel = []
#bot.command()
async def enable(ctx):
global channel
print("Debug")
await ctx.send('Restriction bot has been enabled for this text channel.')
channel.append(ctx.channel.id)
#bot.event
async def on_message(ctx):
if ctx.author == bot.user:
return
#if ctx.channel.id != [for channnels in channel]:
# return
if ctx.attachments[0].height:
await ctx.author.send('Your media file is restricted!')
await ctx.delete()
The channel variable is initialized in your program so each time you will restart your bot, it will be emptied. One way you can solve your problem is by storing them in a file. The easiest way to do it would be to use the json library. You'll need to create a channels.json file.
The code :
from json import loads, dumps
def get_data():
with open('channels.json', 'r') as file:
return loads(file.read())
def set_data(chan):
with open('channels.json', 'w') as file:
file.write(dumps(chan, indent=2))
#bot.command()
async def enable(ctx):
channels = get_data()
channels.append(ctx.channel.id)
set_data(channels)
await ctx.send('Restriction bot has been enabled for this text channel.')
The channels.json file :
[]

Python how to forward messages from server

Hello i have a old discord server which we don't using now. and we created a new server and moved all members there but still some members r there in old server. So is there a option to forward all messages from server A to server B to specific channel.
Update:
I mean like when ever server A gets a message it should be sended to server B to a specific channel. bot is in both server so with that i can forward all incoming message exactly.
Bot Code
token = "xxxxxxxxxxxxx"
prefix = "!"
import discord
from discord.ext import commands
from discord.ext.commands import Bot
bot = commands.Bot(command_prefix=prefix)
bot.remove_command("help")
#bot.event
async def on_ready():
print('\nLogged in as')
print("Bot Name: " + bot.user.name)
print("Bot User ID: " + bot.user.id)
old_server = bot.get_server('xxxxxxxxxxxxx')
new_channel = bot.get_channel('xxxxxxxxxxxxx')
#bot.event
async def on_message(message):
message.content = message.content.lower()
if message.server == old_server:
await bot.send_message(new_channel, message.content)
await bot.process_commands(message)
bot.run(token)
You can use the on_message event to check when messages are sent to the old server and have the bot post the message to the new server.
Below is example code where the bot will check when the old server gets a message, then posts the same message to a specified channel on the new server.
from discord.ext import commands
client = commands.Bot(command_prefix='!')
#client.event
async def on_message(message):
old_server = client.get_server('old_server_id')
new_channel = client.get_channel('new_channel_id')
if message.server == old_server:
await client.send_message(new_channel, message.content + ' - ' + message.author.nick)
client.run('token')

Resources