An invalid syntax within an discord.py event - discord.py

import discord
from discord.ext.commands import Bot
from discord.ext import commands+
from discord.utils import get
import time
bot = commands.Bot(command_prefix='r.', description="prefix")
#bot.event
async def on_message_delete(message):
if(message.author != bot.user):
else:
deleted = message.content
channel = bot.get_channel(657899187957923852)
await channel.send(time + '"' + deleted + '"')
in the line 12 else: is invalid syntax ( unknown, line 12)pylint(syntax-error) I am trying to make it when a message that is not the bot will send to another channel that the channel id is equal to 657899187957923852.
with the imports i dont know what i have used and the ones that are necessary for this one command (edited)

You need to have some code in the block under the if statement.
#bot.event
async def on_message_delete(message):
if(message.author != bot.user):
return
else:
deleted = message.content
channel = bot.get_channel(657899187957923852)
await channel.send(time + '"' + deleted + '"')

Related

Wait for time, then DM with bot, with multiple users at once

I have a discord bot I am working on for practice that reminds the users with a dm after a certain amount of time. My issue is that I am using time.sleep() to handle the delay. This stops other users from setting up reminders because it is waiting for the previous time.sleep() to end. I want to have multiple requests for a reminder happen simultaneously, rather than wait for each request to end before the next one starts. Below is my code. My discord tokens are hosted in a seprate .env file.
# bot 2
import os
import discord
import time
from dotenv import load_dotenv
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN2')
client = discord.Client()
#client.event
async def on_ready():
print(
f'{client.user} has connected to Discord!')
#client.event
async def on_message(message):
if message.author == client.user:
return
remind_me = 'You will be reminded '
if 'remindme!' in message.content.lower():
if message.content[-1] == 'h' or \
message.content[-1] == 's' or\
message.content[-1] == 'm':
response = remind_me + '\'' + message.content[10:-3] + '\' in' + message.content[-3::]
await message.channel.send(response)
else:
await message.channel.send('I don\'t understand.')
if message.content[-1] == 'h':
time.sleep(3600 * int(message.content[-2]))
await message.author.send('Reminder! \n' + message.content[10:-3])
if message.content[-1] == 's':
time.sleep(int(message.content[-2]))
await message.author.send('Reminder! \n' + message.content[10:-3])
if message.content[-1] == 'm':
time.sleep(int(message.content[-2])*60)
await message.author.send('Reminder! \n' + message.content[10:-3])
client.run(TOKEN)
I know I can clean up the if statements, so dont worry about that.
Use asyncio.sleep instead of time.sleep.
import asyncio
[...]
if message.content[-1] == 'h':
asyncio.sleep(3600 * int(message.content[-2]))
await message.author.send('Reminder! \n' + message.content[10:-3])
[...]

I'm having a problem with my modmail bot code that was written my discord.py

So, I'm making a modmail bot for my discord server. But when I run, the bot can connect but when I send a test messange in the bot DM, I receive this error: AttributeError: 'NoneType' object has no attribute 'send'.
I'm using python 3.9.1 on Arch Linux. Here is my code:
import discord
from discord.ext.commands import Bot
from discord.ext import commands
import asyncio
client = commands.Bot(command_prefix="!")
#client.event
async def on_ready():
await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name='for moderation mail'))
print("Thunderbird is ready")
#client.event
async def on_message(message):
empty_array = []
modmail_channel = discord.utils.get(client.get_all_channels(), name="modmail-box")
if message.author == client.user:
return
if str(message.channel.type) == "private":
if message.attachments != empty_array:
files = message.attachments
await modmail_channel.send("<#" + message.author.id + ">: ")
for file in files:
await modmail_channel.send(file.url)
else:
await modmail_channel.send("<#" + str(message.author.id) + ">: " + message.content)
elif str(message.channel) == "modmail" and message.content.startswith("<"):
member_object = message.mentions[0]
if message.attachments != empty_array:
files = message.attachments
await member_object.send("**[MOD]** " + "**" + message.author.display_name + "**: ")
for file in files:
await member_object.send(file.url)
else:
index = message.content.index(" ")
string = message.content
mod_message = string[index:]
await member_object.send("**[MOD]** " + "**" + message.author.display_name + "**: " + mod_message)
client.run('No leaking here')
I am assuming that the error is on this line:
await member_object.send("**[MOD]** " + "**" + message.author.display_name + "**: ")
and member_object is coming from this block:
elif str(message.channel) == "modmail" and message.content.startswith("<"):
member_object = message.mentions[0]
if message.attachments != empty_array:
files = message.attachments
await member_object.send("**[MOD]** " + "**" + message.author.display_name + "**: ")
for file in files:
await member_object.send(file.url)
You are defining member_object as the first element in the message.mentions array, however your error of NoneType has no attribute suggests that there are no elements in that array and so member_object is actually equal to None not an instance of a class which has a send method.
You need to check your input to that function and ensure that when your code reaches that block it actually has the attributes that you are expecting

discord.py not finding commands within a class

If I use .join in discord with the code below, I get the following error:
Ignoring exception in command None:
discord.ext.commands.errors.CommandNotFound: Command "join" is not found
I'm not sure how to fix this (this is turning into being part of a music bot). Here is the relevant code:
import discord
import discord.voice_client
from discord import utils
from discord.ext import commands
from discord.utils import *
import discord.utils
import lavalink
bot = commands.Bot(command_prefix= ".", intents=intents)
class MusicCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.bot.music = lavalink.Client(self.bot.user.id)
self.bot.music.add_node('localhost', 7000, 'testing', 'na' , 'music-node')
self.bot.add_listener(self.bot.music.voice_update_handler, 'on-socket-response')
self.bot.music.add_event_hook(self.track_hook)
#commands.command(name= 'Join')
async def join(self, ctx):
print("join command worked")
member = utils.find(lambda m: m.id == ctx.author.id, ctx.guild.members)
if member is not None and member.voice is not None:
vc = member.voice.channel
player = self.bot.music.player_manager.create(ctx.guild.id, endpoint= str(ctx.guild.region))
if not player.is_connected:
player.store('channel', ctx.channel.id)
await self.connect_to(ctx.guild.id, str(vc.id))
#commands.command(name= "Play")
async def play(self, ctx, *, query):
try:
player = self.bot.music.player_manager.get(ctx.guild.id)
query = f'ytsearch: {query}'
results = await player.node.get_tracks(query)
tracks = results['tracks'][0:10]
i = 0
query_result = ''
for track in tracks:
i = i + 1
query_result = query_result + f'{i}) {track["info"]["title"]} - {track["info"]["url"]}\n'
show_songs = discord.Embed(
title= None,
description= None,
colour= discord.Colour.blue()
)
show_songs.description = query_result
await ctx.channel.send(embed= show_songs)
def check(m):
return m.author.id == ctx.author.id
response = await self.bot.wait_for('message', check=check)
track = tracks[int(response.conetent)-1]
player.add(requester = ctx.author.id, track = track)
if not player.is_playing:
await player.play()
except Exception as error:
print(error)
async def track_hook(self, event):
if isinstance(event, lavalink.events.QueueEndEvent):
guild_id = int(event.player.guild.id)
await self.connect_to(guild_id, None)
async def connect_to(self, guild_id: int, channel_id: str):
ws = self.bot._connection._get_websocket(guild_id)
await ws.voice_state(str(guild_id), channel_id)
def setup(bot):
bot.add_cog(MusicCog(bot))
I've tried changing #commands.command to #bot.command, which didn't end up working, and I'm almost certain the indentation is correct throughout the code, so at this point, I'm not sure how to fix it. Any help would be appreciated!
By default, commands are case sensitive so you'd have to type .Join or .Play in order to invoke your them.
If you want your commands to be case insensitive, simply type :
bot = commands.Bot(command_prefix='.', intents=intents, case_insensitive=True)
PS : the name argument in the commands.command() decorator refers to what needs to be typed after your prefix to invoke the function.

Call function outside of #client.event (discord.py)

I'm making a discord bot to play a game, using direct and open message commands to register player actions.
The message event handler is here. When getting a message to start the game, it'll start doing various things to get the game running.
import discord
import random
import datetime
client = discord.Client()
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
if message.author == client.user:
return
if "!ww start" == message.content.lower() and not(discord.ChannelType == "private"):
# Do stuff
night(message)
if "!ww save " in message.content.lower() and discord.ChannelType == "private":
save(message)
if "!ww kill " in message.content.lower() and discord.ChannelType == "private":
kill(message)
if "!ww vote " in message.content.lower() and discord.ChannelType == "private":
vote(message)
if "!ww view " in message.content.lower() and discord.ChannelType == "private":
view(message)
if "!ww remove" == message.content.lower():
remove(message)
if ("!ww add" == message.content.lower()):
add(message)
if (message.content == '!ww count'):
count(message)
if discord.ChannelType == "private":
night(message)
day(message)
'''
One example of a function I want to call is here, like others it makes use of the message and channel. This is in line with the above block of code.
'''
async def night(message):
with open("GameData.txt", mode="r", encoding="utf-8") as my_file:
gameData = my_file.read().replace('\n', '')
if gameData[-1] != " ":
gameData = gameData + " "
gameData = list(gameData.split(", "))
if gameData[4] != "Night":
return
for i in range(len(gameData)):
if gameData[i] == ".":
return
# Read who was killed
channel = client.get_channel(int(gameData[1]))
if gameData[2] == gameData[0]:
await channel.send("Someone was saved in the night")
else:
killed = gameData[2]
await channel.send(killed + " was killed in the night")
remove(message)
await message.channel.send("It is now day, the game will continue when you all make your decision")
nightClean()
client.run("No")
Eventually there is a loop between two functions that call each other once run. They will only run when other inputs have been made through additional message inputs handled in other functions.
Currently I'm getting an error saying: RuntimeWarning: "coroutine 'day' was never awaited day(message)" as with another function.
How can I work around this?
Thanks!
To create a command use:
#client.command()
async def command_name(ctx, commands args like user to ban etc):
Do stuff
And this is a command. Don't use the on_message function.

Bot keeps executing random parts of loop

Im trying to make a bot that sends a message whenever it detects page status changes, but after 3-5 seconds it randomly sends "server is online" even tho nothing changed in the page.
import os
import discord
from dotenv import load_dotenv
import time
import requests
def check(r):
if "online" in r.text:
return True
else:
return False
online = False
load_dotenv()
TOKEN = "#hidden"
GUILD = #hidden
client = discord.Client()
#client.event
async def on_ready():
for guild in client.guilds:
if guild.name == GUILD:
break
print(
f'{client.user} is connected to the following guild:\n'
f'{guild.name}(id: {guild.id})')
channel = client.get_channel(#hidden)
last_status = check(requests.get("#page"))
while True:
if check(requests.get("#page")) == last_status:
continue
else:
if check(requests.get(#page")):
await channel.send("server is online")
last_status = check(requests.get("#page"))
else:
await channel.send("Server is offline")
last_status = check(requests.get("#page"))
client.run(TOKEN)
It's probably because you have multiple runing instance of on_readyfunction.
Discord API often send (especially during this period of overload due to the pandemic) a instruction of reconnect.
When discord.py recieve this instruction, it reconnect and call on_ready again, without killing the other.
The solution is to use asyncio.ensure_future and client.wait_until_ready to be sure there is only one instance
code:
import os
import discord
from dotenv import load_dotenv
import time
import requests
import asyncio
def check(r):
if "online" in r.text:
return True
else:
return False
online = False
load_dotenv()
TOKEN = "#hidden"
GUILD = #hidden
client = discord.Client()
async def routine():
await client.wait_until_ready()
channel = client.get_channel(#hidden)
last_status = check(requests.get("#page"))
while True:
if check(requests.get("#page")) == last_status:
continue
else:
if check(requests.get(#page")):
await channel.send("server is online")
last_status = check(requests.get("#page"))
else:
await channel.send("Server is offline")
last_status = check(requests.get("#page"))
#client.event
async def on_ready():
for guild in client.guilds:
if guild.name == GUILD:
break
print(
f'{client.user} is connected to the following guild:\n'
f'{guild.name}(id: {guild.id})')
asyncio.ensure_future(routine())
client.run(TOKEN)

Resources