Ok, so I'm having an issue with my bot. I know what it is, but I don't know what the string to fix it is.
Basically I have it set to store config and prefixes and such in a json but the help command which is loading one of my commands multiple times.
I've checked the help command and i don't think that's it. Because after redoing my setprefix command (which is being displayed multiple times) it added yet another one on so now it's even worse.
Here is my storage system that I believe to be causing the issue.
with open("./config/config.json", "r") as configjsonFile:
configData = json.load(configjsonFile)
login_token = configData["discordtoken"]
with open("./config/prefixes.json") as f:
prefixes = json.load(f)
default_prefix = "-"
def prefix(client, message):
id = message.guild.id
return prefixes.get(id, default_prefix)
client = commands.Bot(command_prefix=prefix)
client.remove_command('help')
#client.command(name="setprefix", aliases=["Prefix", "prefix"])
#commands.has_permissions(administrator=True)
async def setprefix(ctx, new_prefix):
"""Change the server prefix for the bot.
Alt : Prefix, prefix
Usage : prefix <custom prefix>"""
prefixes[ctx.message.guild.id] = new_prefix
with open("./config/prefixes.json", "w") as f:
json.dump(prefixes, f, indent=4)
embed = discord.Embed(color=0x4a3d9a, timestamp=ctx.message.created_at)
embed.set_author(name=f"{client.user.name}", icon_url=client.user.avatar_url)
embed.add_field(name="Success", value=f"Successfully changed prefix changed to `{new_prefix}`")
embed.set_thumbnail(url=client.user.avatar_url)
embed.set_footer(text="NewHorizon Development | https://newhorizon-development.netlify.app", icon_url=client.user.avatar_url)
await ctx.message.delete()
await ctx.send(embed=embed, delete_after=4)
and here is my custom help command just in case I'm wrong about what is causing the issue.
#commands.command(name="help", aliases=["Help", "H", "h"])
#commands.has_permissions(add_reactions=True, embed_links=True)
async def help(self, ctx, *cog):
"""Gets all cogs and commands.
Alt : h, H, Help
Usage : [h]elp <cog or command>"""
try:
if not cog:
"""Cog listing. What more?"""
embed = discord.Embed(title='Cog Listing and Uncatergorized Commands',
description='Use `help <cog>` to find out more about them!\n(BTW, the Cog Name Must Be in Title Case, Just Like this Sentence.)')
cogs_desc = ''
for x in self.client.cogs:
cogs_desc += ('{} - {}'.format(x, self.client.cogs[x].__doc__) + '\n')
embed.add_field(name='Cogs', value=cogs_desc[0:len(cogs_desc) - 1], inline=False)
cmds_desc = ''
for y in self.client.walk_commands():
if not y.cog_name and not y.hidden:
cmds_desc += ('{} - {}'.format(y.name, y.help) + '\n')
embed.add_field(name='Uncatergorized Commands', value=cmds_desc[0:len(cmds_desc) - 1], inline=False)
await ctx.message.add_reaction(emoji='✉')
await ctx.message.author.send('', embed=embed)
else:
"""Helps me remind you if you pass too many args."""
if len(cog) > 1:
embed = discord.Embed(title='Error!', description='That is way too many cogs!', color=discord.Color.red())
await ctx.message.author.send('', embed=embed)
else:
"""Command listing within a cog."""
found = False
for x in self.client.cogs:
for y in cog:
if x == y:
embed = discord.Embed(title=cog[0] + ' Command Listing', description=self.client.cogs[cog[0]].__doc__)
for c in self.client.get_cog(y).get_commands():
if not c.hidden:
embed.add_field(name=c.name, value=c.help, inline=False)
found = True
if not found:
"""Reminds you if that cog doesn't exist."""
embed = discord.Embed(title='Error!', description='How do you even use "' + cog[0] + '"?', color=discord.Color.red())
else:
await ctx.message.add_reaction(emoji='✉')
await ctx.message.author.send('', embed=embed)
except:
await ctx.send("Excuse me, I can't send embeds.")
I am using the rewrite branch if it helps. And my setprefix command IS NOT in a cog, unlike the rest of my commands. Thus why they appear a slight bit different.
Now I'm ASSUMING my issue is that the json are not closing, which I need to know how to make them close, but if that's not the issue, I would very much appreciate someone helping me figure out what's going wrong.
Related
I want to add a same check before all my commands in discord.py. I have to do it in each and every command. Is there a way that i can add that check only once for all commands??.
Example:
#commands.command(name="ping")
async def _ping(self,ctx):
db = firebase.database()
isEnabled = db.child('Disabled').child(str(ctx.guild.id)).child(ctx.command).get()
if isEnabled.val() is None:
lat = round((self.bot.latency)*1000)
if lat < 150:
em = discord.Embed(title=":ping_pong: | Pong!",description=f":green_circle: Current Latency : `{lat}`ms",color=discord.Color.green())
elif lat >= 150:
em = discord.Embed(title=":ping_pong: | Pong!",description=f":yellow_circle: Current Latency : `{lat}`ms",color=discord.Color.from_rgb(255,255,0))
else:
em = discord.Embed(title=":ping_pong: | Pong!",description=f":red_circle: Current Latency : `{lat}`ms",color=discord.Color.red())
await ctx.send(embed=em)
else:
em = discord.Embed(description="This command is disabled in your server. Ask admin to enable it",color=discord.Color.random())
await ctx.send(embed=em)
Here i check if the command is disabled or not first, as i have to do this same thing in each command is there another way to do so, apart from what i am doing??
Pls help me.
Yes you can use bot.check decorator that will apply to all your commands
Example:
#bot.check
async def globally_block_dms(ctx):
return ctx.guild is not None # no dms
You can check if the command is disabled by using ctx.guild and ctx.guild.id
I'm trying to make a multiple-choice trivia background task. I'm trying to await client.wait_for_message only for either the correct answer or the incorrect choices. I'm checking message.content but I'm missing something because no matter what anyone types, it says "incorrect answer" UNLESS it's the correct answer. If someone types something other than the incorrect answer or correct answer then I want it to ignore their text.
async def trivia_loop():
await client.wait_until_ready()
channel = client.get_channel("123456778999533")
triviamonies = random.randint(1250, 2550)
while not client.is_closed:
await client.send_message(channel, '**Category**: {}\n**Difficulty**: {}\n\n{}\n\n**Potential Answers:**\n{}'.format(category, formatdiff, formatquestion, '\n'.join(tup)))
winner = ''
def check(m):
return m.content.lower() == formatanswer.lower() and m.content.lower() != incorrectanswer1 or incorrectanswer2 or incorrectanswer3
while winner == '':
answerid = await client.wait_for_message(timeout=420, channel=channel, check=check)
if answerid is None:
winner = 1
await client.delete_message(questionsend)
await client.send_message(channel, 'No one answered correctly! The answer was {}'.format(formatanswer))
await asyncio.sleep(840)
elif get_triviaguessesTaken(answerid.author) < 1 and answerid.content.lower() == formatanswer.lower():
winner = 1
await client.delete_message(questionsend)
await client.send_message(channel, '**{}** is correct!\n{} earns **${:,}** !'.format(formatanswer, answerid.author.mention, triviamonies))
add_dollars(answerid.author, triviamonies)
add_trivias(answerid.author, 1)
await asyncio.sleep(900)
elif get_triviaguessesTaken(answerid.author) < 1 and answerid.content.lower() == incorrectanswer1 or incorrectanswer2 or incorrectanswer3:
await client.send_message(channel, '**{}** that is incorrect! Please try again on the next trivia question'.format(answerid.author.mention))
add_triviaguessesTaken(answerid.author, 1)
elif get_triviaguessesTaken(answerid.author) > 0 and answerid.content.lower() == incorrectanswer1 or incorrectanswer2 or incorrectanswer3:
await client.send_message(channel, '{} you have already tried to guess this trivia question. Try again on the next one!'.format(answerid.author.mention))
Discord.py Version:
From the looks of your code, you're still using the async version of d.py (v0.16.12), and you haven't moved to the more up-to-date and stable rewrite version of d.py.
I can highly recommend running pip install --upgrade discord.py for the most recent stable version. Make sure you do this and rewrite your code sooner rather than later, as it'll be less of a pain when you have less code to work with.
Wait_for() usage in rewrite:
The docs use an example in an on_message event, but I'll make an example here to suit your case with a command instead, so you have both ways available to you and can mix-and-match:
#bot.command(aliases=["trivia"])
async def starttrivia(ctx):
answers = ["paris", "london", "oslo"]
await ctx.send(f"What's the capital of France?\n\n*Potential answers:*\n{', '.join(answers)}")
correct = False
def check(m):
for a in answers:
if a in m.content.lower():
return True
while not correct:
try:
reply = await bot.wait_for("message", check=check, timeout=30)
if "paris" in reply.content.lower():
await ctx.send(f"Correct! {reply.author.mention} got the right answer!")
correct = True
else:
await ctx.send("Incorrect, try again!")
except asyncio.TimeoutError: # exception thrown when no reply is sent in time
await ctx.send("Nobody guessed for 30 seconds! The answer was: Paris")
break
I have a development setup (Laptop, Django, Dialogflow, Ngrok) When I test my chatbot all is well.
I have a production setup (Ubuntu server hosted by Digital Ocean, Django, Dialogflow, Nginx, gunicorn) When I test dialog flow has troube matching intents. i.e i have to repeat the same sentence a few times until it matches the intent.
Any ideas why this might be?
I have tried pointing dialogflow fullfillment to my development environment and hit it from the production environment however i still have to repeat myself to get a matched intent.
I have tried pointing dialogflow to the production environment and hitting it from the development server and all works as it should.
conversation tested on production server:
Hello Chris from Cemlyn group! What can I do for you? Something map related perhaps?
return a map
Sorry, I dont understand what you want.
return a map
Sorry, I dont understand what you want.
return a map
Chris what map do you want to return?
1
Sorry, I dont understand what you want.
1
Sorry, I dont understand what you want.
1
OK just to confirm, you want me to return 1 for you Chris
return a map
Chris what map do you want to return?
1
Sorry, I dont understand what you want.
1
Sorry, I dont understand what you want.
1
OK just to confirm, you want me to return 1 for you Chris
Conversation tested from development setup:
Hello Chris from Cemlyn group! What can I do for you? Something map related perhaps?
return a map
Chris what map do you want to return?
1
OK just to confirm, you want me to return 1 for you Chris
the webhook looks like this:
def webhook(request):
# build a request object
req = json.loads(request.body)
#s = Session.objects.get(pk='')
#print(s)
# get action from json
action = req.get('queryResult').get('action')
params = req.get('queryResult').get('parameters')
print('session hitting webhook - '*3)
print(request.session.session_key)
for key, value in request.session.items():
print('{} => {}'.format(key, value))
print(req)
if action == 'issue_a_map':
if 'Maps' in params:
if params['Maps']:
mapid = int((params['Maps'][0]))
group = (params['ValleyGroups'][0])
if mapid == 99:
fulfillmentText = {'fulfillmentText': 'issue the next map for ' + group + ' from webhook.'}
else:
fulfillmentText = {'fulfillmentText': 'issue a map from webhook.'}
elif action == 'return_a_map':
print('return a map - '*4)
if 'Maps' in params:
if params['Maps']:
mapid = int(params['Maps'])
map = CongMap.objects.get(map_no=mapid)
if map.issued:
retuner = params['username']
return_map_form(request, mapid, retuner )
fulfillmentText = {'fulfillmentText': 'OK I will return map ' + str(mapid) + ' for you ' +params['username']}
else:
#reply = prepresponse('name please','admin','welcome_event')
fulfillmentText = {'fulfillmentText': 'Hmmm there is a problem, that map isnt issued currently. A map has to be issued before it can be returned.'}
ffr=fulfillment_response()
fftext= ffr.fulfillment_text(fulfillmentText)
params = {'problem': str(map.map_title) +' map hasnt been issued however we are trying to return it.'}
fue = ffr.followup_event_input('ProblemEvent', params)
ffm = None
ocx = None
reply = ffr.main_response(fftext, ffm, ocx, fue)
return JsonResponse(reply, safe=False)
else:
fulfillmentText = {'fulfillmentText': 'Sorry I need to know the map no or name.'}
else:
fulfillmentText = {'fulfillmentText': 'Sorry I need to know the map no or name.'}
elif action == 'help_problem':
fulfillmentText = {'fulfillmentText': 'OK ' +params['username'] +', I will send him an email asking him to help.'}
send_mail('Territory Problem', '{}. Please can you help {} with this problem'.format(params['problem'], params['username']), 'territorybot#chivers.io', ['tain259#gmail.com'])
else:
fulfillmentText = {'fulfillmentText': 'Sorry, I dont understand what you want.'}
# return response
return JsonResponse(fulfillmentText, safe=False)
I am struggling to click over an element. I am not able to click on the contact element from the attach icon in whatsapp chat. i am using url= "web.whatsapp.com".
Also is there any other option of doing the task?
I get "NoSuchElementException" error when i run the below code. Please help me to select it correctly.
try:
chat_button = driver.find_element_by_xpath("//a[#id = 'action-button']").click()
time.sleep(2)
element_presence(By.XPATH,'//*[#id="main"]/footer/div[1]/div[2]/div/div[2]',30)
msg_box=driver.find_element(By.XPATH , '//*[#id="main"]/footer/div[1]/div[2]/div/div[2]')
msg_box.send_keys(message + Keys.ENTER)
time.sleep(2)
attach_icon = driver.find_element_by_xpath("//div[#title = 'Attach']").click()
# issue starts from here...
contact_icon = driver.find_element_by_xpath("//svg[#id = 'contact-Layer_1']")
contact_icon.click()
time.sleep(2)
search_contact = driver.find_element_by_xpath("//input[#title = 'search']")
search_contact.click()
search_contact.send_keys("pravin tcs")
driver.find_element_by_xpath("//div[#class = '_1kfc8_2uQfJ']").click()
driver.find_element_by_xpath("//span[#data-icon = 'send-light']").click()
except Exception as e:
print("Invalid phone no :"+str(phone_no))
I'm still learning python and programming and i've got myself into a problem that i can't solve. I want to make a command that would make a bot send an image that its name corresponds to number what user wrote (e.g. user wrote "!image_nr 22" and bot sends 22.jpg). I've only made code that sends random image from folder but I cant get into chosen. Here's my latest code for this problem:
elif message.content.startswith("!obrazeknr"): #missing an argument or something, idk what to make here
obrazDirectoryChc = "C:/Users/Lewando54/Downloads/Localisation/English/" + liczba + ".jpg"
await client.send_file(message.channel, obrazDirectoryChc, content=obrazName[1])
You could try inside this elif statement:
msg = message.content[12:] #skips the command word and the '!' and the " "
msg = msg.split() #split the message into an array at the spaces.
#msg = ["!image_nr","22"]
if msg[0] == "!image_nr" and msg[1].isnumeric():
obrazDirectoryChc = "C:/Users/Lewando54/Downloads/Localisation/English/" +
liczba + ".jpg"
await client.send_file(message.channel, obrazDirectoryChc,
content=obrazName[int(msg[1]])
now it should send the user requested photo.
e.g. !obrazeknr image_nr 22
Hope this helps. Sorry for the long wait; I just saw this today.
Might be a better idea, for next time, posting on https://programming.stackoverflow.com could give you more help.
It works. I've slightly modified it and it works. Thx for idea :D
elif message.content.startswith('!obrazeknr'):
msg1 = message.content #skips the command word and the '!' and the " "
msg1 = msg1.split() #split the message into an array at the spaces.
#msg = ["!obrazeknr","22"]
if msg1[0] == "!obrazeknr" and msg1[1].isnumeric() == True:
await client.send_file(message.channel, "C:/Users/Lewando54/Downloads/Localisation/English/" + str(int(msg1[1])) + ".jpg")