discord.py remove user (json) - discord.py

I wish a user has the option to create his account by saving his ID/Removing it from the Json File.
How can I do?
#client.command(pass_context=True, aliases=["Delete", "DELETE", "unregister", "UnRegister", "Unregister", "UNREGISTER", "elimina", "Elimina", "ELIMINA"])
async def delete(ctx):
id = str(ctx.message.author.id)
lmii = get_emoji(ctx.guild, "VittorianoPuntaFerro")
embed = discord.Embed(
color=0x003399
)
if id not in amounts:
#???
embed.set_author(name="Hai rimosso il tuo account!")
await ctx.send(embed=embed, delete_after=10)
_save()
else:
embed.set_author(name="Hai già registrato un account!")
await ctx.send(embed=embed, delete_after=10)

You can store the ID in the JSON and Even remove it. However, I think you are fully new to this. Json dictionary is the same as the python dictionary but the difference is we store that in a file whereas this is stored in the memory.
Follow this:
We create the .json empty file. You can rename it anything and save it into the directory where your script is saved.
Open the Json file and edit it, enter {} and save it.
#We import the json module in the python.
import json
async def delete(ctx):
#OPEN THE JSON FILE
with open('your_file_name.json','r') as f:
#Here we load the dictionary into Amounts Variable, It can be anything
amounts = json.load(f)
id = str(ctx.message.author.id)
lmii = get_emoji(ctx.guild, "VittorianoPuntaFerro")
embed = discord.Embed(
color=0x003399
)
if id not in amounts:
#TO SAVE THE ID IN THE DICTIONARY
amounts[id] = {}
#To remove the ID From the Dictionary, You can use this.
#amounts.pop(id)
embed.set_author(name="Hai rimosso il tuo account!")
await ctx.send(embed=embed, delete_after=10)
#OPEN THE JSON FILE AGAIN FOR WRITING THE DATA
with open('your_file_name.json','w') as f:
#SAVE THE CONTENT
json.dump(amounts,f,indent= 3)
else:
embed.set_author(name="Hai già registrato un account!")
await ctx.send(embed=embed, delete_after=10)
This is the basic thing about how you can open the JSON file and write the data, Rest all the details are based on the python dictionary. You can explore yourself and learn new ways of implementing your structures.

Related

Telegram bot is running, but does not retrieve data from the database

trying to output data from sql to telegram bot. bot is
running(sending message.answer), but after that nothing happens and
shows no error. using pycharm and xampp. it is my first code
import logging
import mysql.connector
from aiogram import Bot, Dispatcher, executor, types
API_TOKEN = 'token'
logging.basicConfig(level=logging.INFO)
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="",
database="php"
)
mycursor = mydb.cursor()
#dp.message_handler(commands=['start'])
async def send_welcome(message: types.Message):
await message.answer("Hi!\nEnter name:")
# works up to this line
#dp.message_handler(content_types=['text'])
async def send_msg(message: types.Message):
mycursor.execute(
"SELECT surname, age, year, city, phone FROM list WHERE name ='{}'".format(message.from_user.id))
# fetching the rows from the cursor object
result = mycursor.fetchone()
for x in result:
await message.answer(x)
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)
Rewrite your code like this
#dp.message_handler(commands=['start'])
async def send_welcome(message: types.Message, state: FSMContext):
await message.answer("Hi!\nEnter name:")
# works up to this line
await state.set_state("get_name")
#dp.message_handler(state="get_name")
async def send_msg(message: types.Message, state: FSMContext):
mycursor.execute(
"SELECT name FROM users WHERE name ='{}'".format(message.from_user.id)) # message.text should be here?
result = mycursor.fetchone()
for x in result:
await message.answer(x)
await state.finish()
You could use FSM to get data from user

Check if a user id is in a list of user ids to allow command access - discord.py

im fairly new to python and have been writing a discord bot for a server with me and a few friends as practice. I've added a few commands that could be pretty disruptive if all users had access to them at all times and have been trying to add a method to enable and disable access to them without using discord roles but a python list instead. I added a command that i can use to to add their user id to a list, but when the user tries to use the command they receive a permission error.
the code below is the problematic code from a cog
modlist = []
def ListCheck():
async def IsInList(ctx):
member = ctx.message.author.id
return member in modlist
return commands.check(IsInList)
#commands.command()
async def AddUser(self, ctx, *, question):
modlist.append(question)
#commands.command()
async def ViewModList(self, ctx):
await ctx.send('User ids that have access:')
for i in range(0, len(modlist)):
await ctx.send(modlist[i])
#commands.command()
async def ClearModList(self, ctx):
modlist.clear()
await ctx.send('Modlist cleared')
#commands.command()
#ListCheck()
async def PermTest(self, ctx):
await ctx.send('user is in modlist')
Any help would be hugely appreciated
One way you could do it would be to use commands.check(). The function in the code below checks if the message author, ctx.author, is in the given list, modList. If the author is in this list when the command 'test' is invoked, then the bot will send "You are a mod!", otherwise it will raise a check error.
modList = [394506589350002688, 697725862128386048] # just some ids as examples
def check_Mod(ctx):
if ctx.author.id in modList:
return ctx.author.id in modList
#commands.command()
#commands.check(check_Mod)
async def test(ctx):
await ctx.send("You are a mod!")
The above working is shown in the image below:
To answer is there is a way to add user ids to the list via a command?, you may either use a json or text file. In this case, I will use a text file since it's simpler, and also because my json isn't as fluent as others.
Here's an example of how your text file may look like:
394506589350002688
697725862128386048
First you need to read the file and check whether the author's id is in the file. We will be changing the check_Mod function for this. If you want to know more about reading through a text file, or feel that you may need a more efficient way, you may have a look at this: How to search for a string in text files?
def check_Mod(ctx):
with open('Mod.txt') as f: # do change the 'Mod.txt' to the name that suits you. Ensure that this file is in the same directory as your code!
if str(ctx.author.id) in f.read(): # this is reading the text file and checking if there's a matching string
return ctx.author.id
Now for writing the author id into your text file.
#commands.command()
#commands.check(check_Mod)
async def add_Mod(ctx, user:discord.Member=None):
if user == None:
await ctx.send("Please provide a user to add as a Mod!")
return
# First we'll make some functions for cleaner, more readable code #
def is_Mod(user_id):
## This function will check if the given id is already in the file. True if in file, False if not ##
with open('Mod.txt', 'r') as f:
if str(user_id) in f.read():
return True
else:
return False
def add_Mod(user_id):
## This function will add the given user id into the given text file, Mod.txt ##
with open('Mod.txt', 'a') as f: # 'a' is used for appending, since we don't want to overwrite all the ids already in the file
f.write(f"{str(user_id)}\n")
f.close()
# Now we put those functions to use #
if is_Mod(user.id) == True:
await ctx.send(f"The user {user} is already a Mod!")
else:
add_Mod(user.id)
await ctx.send(f"{user} added as a Mod!")
The above should work as seen in the image below.
p.s. If you have any other questions, please post them as a new question, thank you!

How do i create a numbered report system?

Hello so i am trying to create a report system where when a report is created it is report #0001 when a new one is it is report #0002 here is my code so far.
#commands.command()
async def report(self, ctx, member : discord.Member, reason=None):
await ctx.send(f'{member} has been reported!')
channel = discord.utils.get(ctx.guild.text_channels, name='reports')
embed = discord.Embed(name=f'Report incoming! #0001 ')
embed.add_field(name='Member', value=f'{member}', inline=False)
embed.add_field(name='Member who reported them', value=f'{ctx.author}', inline=False)
embed.add_field(name='Reason', value=f'{reason}', inline=False)
embed.add_field(name='Channel', value=f'{ctx.channel}', inline=False)
await channel.send(content=None, embed=embed)
Does anyone know how if so please respond to this thanks!
If you sure that there will be no internet problem or some other problems that will prevent the boat from running, you can simply do
count = 0
#commands.command()
async def report(self, ctx, member : discord.Member, reason=None):
count += 1
#the rest of the command
Then you can change the embed name like this
embed = discord.Embed(name=f'Report incoming! #{count}')
But if you are not completely sure that the bot will have not any problem,
you can save the numbers in a file like txt, json or yaml. I'd prefer txt in that case because you just need to save one line of text. So you can do this:
with open('counts.txt', 'r+') as file:
number = file.read()
if number == '':
file.write('0')
#commands.command()
async def report(self, ctx, member : discord.Member, reason=None):
with open('counts.txt', 'w+') as file:
count = file.read()
file.write(int(count)+1)
embed = discord.Embed(name=f'Report incoming! #{count}')
Well, you have to store the report count somewhere, preferably a proper database. For this example you can use a json file, however, keep in mind that a json file as a database is fundamentally flawed due to its lack of atomic writes which can result in data corruption and loss.
import json
#commands.command()
async def report(self, ctx, member: discord.Member, reason=None):
# Get currect report number
with open('reports.json', 'r', encoding='utf-8') as counts:
data = json.load(counts)
counter = data['count']
await ctx.send(f'{member} has been reported!')
data = {"count": counter + 1} # Add 1 everytime a report is invoked
with open('reports.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
channel = discord.utils.get(ctx.guild.text_channels, name='reports')
embed = discord.Embed(title=f'Report incoming! #{counter} ')
embed.add_field(name='Member', value=f'{member}', inline=False)
embed.add_field(name='Member who reported them', value=f'{ctx.author}', inline=False)
embed.add_field(name='Reason', value=f'{reason}', inline=False)
embed.add_field(name='Channel', value=f'{ctx.channel}', inline=False)
await channel.send(content=None, embed=embed)
reports.json
{
"count": 0
}

Copy a discord user's avatar and nickname to bot

I am trying to make a joke bot that basically "steals" his nickname and avatar but I've had no success
#tasks.loop(minutes=.01)
async def avatar(*, member: discord.Member = None):
member = client.get_user(id=<id>)
userAvatar = discord.Member.avatar_url
bot.user.edit(avatar=userAvatar)
That's the code that I have done, You have to create 2 folders Avatars/Steal_av
and then what this code does is that it gets the user's avatar and stores it in Stolen.png then sets it as his avatar/PFP, but you have to get his password and put it in a config file, without the password it doesn't work.
If you still need me to tell you how to do the steal nickname tell me but I thought you won't want it since I told you that it doesn't work unless you have his password.
#Imports
import requests
from PIL import Image
with open('Avatars/Steal_av/Stolen.png', 'wb') as f:
r = requests.get(user.avatar_url, stream=True)
for block in r.iter_content(1024):
if not block:
break
f.write(block)
Image.open('Avatars/Steal_av/Stolen.png').convert('RGB')
with open('Avatars/Steal_av/Stolen.png', 'rb') as f:
await client.user.edit(password=password, avatar=f.read())

Python Youtube ffmpeg Session Has Been Invalidated

I get the following error while I'm playing YouTube audio with my bot
[tls # 0000024ef8c4d480] Error in the pull function.
[matroska,webm # 0000024ef8c4a400] Read error
[tls # 0000024ef8c4d480] The specified session has been invalidated for some reason.
Last message repeated 1 times
It seems like YouTube links expire? I don't really know but I need to fix this issue. This is my code:
class YTDLSource(discord.PCMVolumeTransformer):
def __init__(self, source, *, data, requester):
super().__init__(source)
self.requester = requester
self.title = data['title']
self.description = data['description']
self.uploader = data['uploader']
self.duration = data['duration']
self.web_url = data['webpage_url']
self.thumbnail = data['thumbnail']
def __getitem__(self, item: str):
return self.__getattribute__(item)
#classmethod
async def create_source(cls, ctx, player, search: str, *, loop, download=True):
async with ctx.typing():
loop = loop or asyncio.get_event_loop()
to_run = partial(ytdl.extract_info, url=search, download=download)
raw_data = await loop.run_in_executor(None, to_run)
if 'entries' in raw_data:
# take first item from a playlist
if len(raw_data['entries']) == 1:
data = raw_data['entries'][0]
else:
data = raw_data['entries']
#loops entries to grab each video_url
total_duration = 0
try:
for i in data:
webpage = i['webpage_url']
title = i['title']
description = i['description']
uploader = i['uploader']
duration = i['duration']
thumbnail = i['thumbnail']
total_duration += duration
if download:
source = ytdl.prepare_filename(i)
source = cls(discord.FFmpegPCMAudio(source), data=i, requester=ctx.author)
else:
source = {'webpage_url': webpage, 'requester': ctx.author, 'title': title, 'uploader': uploader, 'description': description, 'duration': duration, 'thumbnail': thumbnail}
player.queue.append(source)
except Exception as e:
print(e)
return
embed=discord.Embed(title="Playlist", description="Queued", color=0x30a4fb, timestamp=datetime.now(timezone.utc))
embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url)
embed.set_thumbnail(url=data[0]['thumbnail'])
embed.add_field(name=raw_data['title'], value=f"{len(data)} videos queued.", inline=True)
embed.set_footer(text=raw_data["uploader"] + ' - ' + '{0[0]}m {0[1]}s'.format(divmod(total_duration, 60)))
await ctx.send(embed=embed)
return
embed=discord.Embed(title="Playlist", description="Queued", color=0x30a4fb, timestamp=datetime.now(timezone.utc))
embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url)
embed.set_thumbnail(url=data['thumbnail'])
embed.add_field(name=data['title'], value=(data["description"][:72] + (data["description"][72:] and '...')), inline=True)
embed.set_footer(text=data["uploader"] + ' - ' + '{0[0]}m {0[1]}s'.format(divmod(data["duration"], 60)))
await ctx.send(embed=embed)
if download:
source = ytdl.prepare_filename(data)
else:
source = {'webpage_url': data['webpage_url'], 'requester': ctx.author, 'title': data['title'], 'uploader': data['uploader'], 'description': data['description'], 'duration': data['duration'], 'thumbnail': data['thumbnail']}
player.queue.append(source)
return
source = cls(discord.FFmpegPCMAudio(source), data=data, requester=ctx.author)
player.queue.append(source)
#classmethod
async def regather_stream(cls, data, *, loop):
loop = loop or asyncio.get_event_loop()
requester = data['requester']
to_run = partial(ytdl.extract_info, url=data['webpage_url'], download=True)
data = await loop.run_in_executor(None, to_run)
return(cls(discord.FFmpegPCMAudio(data['url']), data=data, requester=requester))
I'm using the rewrite branch of discord.py for the bot.
I'm not sure if I need to provide more details? Please let me know, I really need to get this fixed...
In fact it isn't really a problem with your code (and many people complain of this error).
This is just a possible issue when streaming a video. If you absolutely want to stream it, you have to accept this as a potential issue. Note how (almost) every music bots set limitations for the video/music you want to listen to.
If you need to ensure you do not get this issue, you have to fully download the music. (Which will also make the bot loading longer before playing).
Would you be able to post all your code? i may have a solution for you if i was able to see the whole code.
the solution i would recomend is to download the soong and then delete it after.
You could set your download to true and then add this in your player_loop
try:
# We are no longer playing this song...so, lets delete it!
with YoutubeDL(ytdlopts) as ydl:
info = ydl.extract_info(source.web_url, download=False)
filename = ydl.prepare_filename(info)
try:
if os.path.exists(filename):
os.remove(filename)
else:
pass
except Exception as E:
print(E)
await self.np.delete()
except discord.HTTPException:
pass
bit botched but could be cleaned up, this was the best solution i have found for me.

Resources