I have been making a Discord bot for one of my servers, and one of it's functions is to prevent curse words. I want it to toggle the censor mode when you type in a command. However, instead of switching the variable to 1 and back again, it just stays on 0, even though I get the "Bad words will now not work" output.
#client.event
async def on_message(message):
swareCensor: int = 0
if message.content == 'f! censor':
if swareCensor == 0:
await message.channel.send('Bad words will now not work')
swareCensor += 1
else:
await message.channel.send('The bad word filter is now off')
swareCensor *= 0
if swareCensor == 1:
if 'fuck' in message.content:
await message.delete()
await message.channel.send('Sware has been detected')
It wouldn't be ideal for swears to be censored all the time, especially if I want it on multiple servers
I would first of all strongly recommend using the actual command method instead of saying if message == "!command" in an onMessage event.
swearFilter = False
#client.command()
async def sensor(ctx):
swearFilter = not swearFilter
await ctx.send(f"Swear filter is now set to {swearFilter}")
#client.event()
async def on_message(message):
if swearFilter:
if "fuck" in message.content:
await message.delete()
await message.channel.send("Swear detected!")
Related
I created a discord bot which can control a "word game". In this game, bot reads every message and then it adds their last letter into "harfkontrol" list. Then he checks every messages first letter and checks if their message starts with the last letter of previous word. It works. But problem is, it works on every channel. It must work in only one channel. What should I do? (I know get_channel() method, but I want it understand which channel it must read & delete messages, without my help.)
Code:
import discord
import os
TOKEN = os.environ['TOKEN']
client = discord.Client()
kullanilan_sozcukler=[]
harfkontrol = ["a"]
komutlar=["bilgi!koyunu", "liste!koyunu", "sayı!koyunu", "komutlar!koyunu"]
komutmetin = "Komutlar:\n**bilgi!koyunu:** Botun ne yaptığı ve kim tarafından yapıldığı hakkında bilgi almak için.\n**liste!koyunu:** Bot kanala eklendikten sonra yazılan kelimelerin listesi.\n**sayı!koyunu:** Yukarıdaki komutun gösterdiği listedeki kelime sayısı."
def son_harf(kelime):
list(kelime)
return kelime[-1]
def ilk_harf(kelime):
list(kelime)
return kelime[0]
def kontrol(kelime):
list(kelime)
if harfkontrol[-1] == kelime[0]:
return True
else:
return False
#client.event
async def on_ready():
print("{0.user}".format(client), "çalıştırıldı.")
#client.event
async def on_message(message):
msg = message.content
if message.author == client.user:
return
if msg.startswith("bilgi!koyunu"):
await message.channel.send('**Kelime Oyunu,** "Kelime Oyunu" kanalınızı yöneten bir bottur. Bot, eklendiği andan itibaren kelime oyununun kurallarına uygun oynanmasını sağlar.\n\nYapıcı:AjanSmith#4747')
if msg.startswith("liste!koyunu"):
sozcuk_listesi = ", ".join(kullanilan_sozcukler)
await message.channel.send(f"Kullanılan sözcükler: {sozcuk_listesi}")
if msg.startswith("sayı!koyunu"):
uzunluk = len(kullanilan_sozcukler)
await message.channel.send(f"Şimdiye kadar {uzunluk} farklı kelime kullanıldı.")
if msg.startswith("komutlar!koyunu"):
await message.channel.send(komutmetin)
if msg in komutlar:
return
else:
if len(list(msg)) == 1:
await message.delete()
await message.channel.send("Lütfen bir kelime giriniz.")
elif msg in kullanilan_sozcukler:
await message.delete()
await message.channel.send(f"{msg} sözcüğü daha önce kullanıldı. Lütfen başka bir sözcük giriniz.")
elif ilk_harf(msg) != harfkontrol[-1]:
await message.delete()
await message.channel.send(f"Lütfen '{harfkontrol[-1]}' ile başlayan bir kelime giriniz.")
else:
harfkontrol.append(son_harf((msg)))
kullanilan_sozcukler.append(msg)
client.run(TOKEN)
In on_message you can get the ID of the channel the message was posted in using message.channel.id. You can then compare this to the ID of the desired channel to post messages in, returning from on_message if these do not match.
Therefore, in order to solve your issue, you could simply change
if message.author == client.user:
return
to
if message.author == client.user or message.channel.id == CHANNEL_ID_HERE:
return
Replacing CHANNEL_ID_HERE with the ID of your channel (as an integer). You can find this ID by activating Developer Mode in the advanced tab of Discord settings, then right-clicking on the channel and selecting "Copy ID".
Wow... Hello, I'm back here after two days. (Thank you to the person who helped me last time..)
First of all, this code works in the direction I want.
However, there is a problem.
This bot's command is "!공지". However, this bot sends me a message because the code works no matter what chat I write... I want to make it work only when I write "!공지"
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith("!공지"):
await message.channel.purge(limit=1)
i = (message.author.guild_permissions.send_messages)
if i is True:
notice = message.content[4:]
channel = client.get_channel(927233433489526904)
embed = discord.Embed(title="*브리핑*", description="\n――――――――――――――――――――――――――――\n\n{}\n\n――――――――――――――――――――――――――――".format(notice), color=0x00ff00)
embed.set_footer(text="-C0de")
embed.set_thumbnail(url="https://i.imgur.com/UDJYlV3.png")
await channel.send (embed=embed)
if i is False:
await message.channel.send("{}, 당신은 관리자가 아닙니다".format(message.author.mention))
If you want the code to exit if the user's message doesn't start with "!공지" then add
if message.content.startswith("!공지"):
await message.channel.purge(limit=1)
else:
return
This will exit the function if the message does not start with those characters.
The problem lies in this:
i = (message.author.guild_permissions.send_messages)
if i is True:
Since anyone who writes something has that permission, i will always be true.
I guess what you want to do is to indent those two lines, so it is inside the if-block that checks the command.
Try moving your i = (message.author.guild_permissions.send_messages) line to the same indentation as the if conditional, while also initializing your i before the if-else statement:
i = False
if message.content.startswith("!공지"):
await message.channel.purge(limit=1)
i = (message.author.guild_permissions.send_messages) # set only in condition.
else:
i = False
When inserted in code:
#client.event
async def on_message(message):
if message.author == client.user:
return
i = False # initialize i
if message.content.startswith("!공지"):
await message.channel.purge(limit=1)
i = (message.author.guild_permissions.send_messages) # set only in condition.
else:
i = False
if i is True:
notice = message.content[4:]
channel = client.get_channel(927233433489526904)
embed = discord.Embed(title="*브리핑*", description="\n――――――――――――――――――――――――――――\n\n{}\n\n――――――――――――――――――――――――――――".format(notice), color=0x00ff00)
embed.set_footer(text="-C0de")
embed.set_thumbnail(url="https://i.imgur.com/UDJYlV3.png")
await channel.send (embed=embed)
if i is False:
await message.channel.send("{}, 당신은 관리자가 아닙니다".format(message.author.mention))
This should let your code properly branch based on the command
I am a beginner in python and i am to trying to code a discord game bot in which you have to choose your paths.
I want that the user first run !adv command and then can press 'c' to continue but my code is not able to do so.
I am not getting any error but after running the !adv command ,i am not able to run the 'c' command to further do something.
client = discord.Client()
#client.event
async def on_ready():
general_channel = client.get_channel(864471185907908608)
await general_channel.send('Hey!')
#client.event
async def on_message(message):
count = 0
msg = message.content.lower()
general_channel = client.get_channel(864471185907908608)
if count == 0:
if msg == '!adv':
await general_channel.send('Hello '+ message.author.name +'. \nWelcome to the Lands of The Supreme Lord , The Godfather.\nYou woke up in the marketplace with crowd bustling everywhere.\nYou have many questions.\nWhat led you to this place and whats your destiny?\nYou are set to write your own path here.\nPress c to continue.')
count += 1
async def on_message(message):
msg = message.content.lower()
if count == 1:
if msg == 'c':
await general_channel.send('\nYou see a vase shop and an weaponsmith ahead.\nDecide who you want to talk.\nType v or w')
Please include the code for the solution as well because it is easy to understand with code.
Thanks in advance
You cannot really have more than one on_message (though you're not registering the second one as an event). To wait for a user response you should use client.wait_for:
#client.event
async def on_message(message):
def check(m): # simple check to wait for the correct user
return m.author == message.author and m.channel == message.channel
count = 0
msg = message.content.lower()
general_channel = client.get_channel(864471185907908608)
if count == 0:
if msg == '!adv':
await general_channel.send('Hello '+ message.author.name +'. \nWelcome to the Lands of The Supreme Lord , The Godfather.\nYou woke up in the marketplace with crowd bustling everywhere.\nYou have many questions.\nWhat led you to this place and whats your destiny?\nYou are set to write your own path here.\nPress c to continue.')
# Waiting for the response
resp = await client.wait_for("message", check=check)
if resp.content.lower() == "c":
# continue the story
await general_channel.send('\nYou see a vase shop and an weaponsmith ahead.\nDecide who you want to talk.\nType v or w')
resp2 = await client.wait_for("message", check=check)
if resp2.content.lower() in ["v", "w"]:
# continue the story
...
count += 1
You might wanna use some return statements to not have such deep indentation.
So I'm making this weird kinda discord bot. It displays a set of obstacles, and adds a corresponding key that you need to press to a string. It adds a 'w' for every '...', and an 's' for every '***'. In Discord, the player has to type the correct string in to pass the level. So it all works and displays properly. The call function is '!go', and that displays the level. But it fails me before I can type in the string. I want to know, why is it automatically activating? My message.content function is outside that loop. I think it is because I type '!go' and it doesn't reset my message. Here is the code:
#client.event
async def on_message(message):
global correct_answerS
correct_answerS = ""
obstacleList = []
for i in range (0, 24):
randNum = random.randint(1,2)
if randNum == 1:
obstacleList.append('...')
correct_answerS += 'w'
if randNum == 2:
obstacleList.append('***')
correct_answerS += 's'
if message.content == ('!practice'):
sky = str("```css\n A ... ... *** ...```")
skyembed = discord.Embed(title="!============================!")
skyembed.add_field(name='When you see three dots, it is a w. When you see 3 asteriks, it is an s.', value = sky)
await message.channel.send(embed=skyembed)
if message.content == ('wwsw'):
await message.channel.send("Success.")
if message.content == ('!go'):
randlev = (str("```css\n A "))
for i in range(0, 24):
randlev += (str(obstacleList[i]) + " ")
randlev += "```"
randlevembed = discord.Embed(title="!===============================================!")
randlevembed.add_field(name='Good luck!', value = randlev)
await message.channel.send(embed=randlevembed)
print(correct_answerS)
if message.content == (correct_answerS):
await message.channel.send("Success!")
else:
await message.channel.send("Fail.")
#client.event
async def on_ready():
print("Ready")
print(client.user.id)
print('--------------------------')
await client.change_presence(activity=discord.Game(name='up and away'))
client.run(Token)
There is no error message, just as soon as I type '!go', it displays the level and then continually says 'Fail.' until I stop it.
I don't know what to do, any help is just that, helpful. Thanks.
The bot is stuck in a loop where it's sending a message, and then processing that message, which causes it to send another message, etc. You can add a check to the beginning of on_message to force it to ignore bot-generated messages:
#client.event
async def on_message(message):
if message.author.bot:
return
...
I have been asking lots of questions lately about discord.py and this is one of them.
Sometimes there are those times when some people spam your discord server but kicking or banning them seems too harsh. I had the idea for a silence command which would delete every new message on a channel for a given amount of time.
My code so far is:
#BSL.command(pass_context = True)
async def silence(ctx, lenghth = None):
if ctx.message.author.server_permissions.administrator or ctx.message.author.id == ownerID:
global silentMode
global silentChannel
silentChannel = ctx.message.channel
silentMode = True
lenghth = int(lenghth)
if lenghth != '':
await asyncio.sleep(lenghth)
silentMode = False
else:
await asyncio.sleep(10)
silentMode = False
else:
await BSL.send_message(ctx.message.channel, 'Sorry, you do not have the permissions to do that #{}!'.format(ctx.message.author))
The code in my on_message section is:
if silentMode == True:
await BSL.delete_message(message)
if message.content.startswith('bsl;'):
await BSL.process_commands(message)
All the variables used are pre-defined at the top of the bot.
My problem is that the bot deletes all new messages in all channels which it has access to. I tried putting if silentChannel == ctx.message.channel in the on_message section but this made the command stop working completely.
Any suggestions as to why this is happening are much appreciated.
Something like
silent_channels = set()
#BSL.event
async def on_message(message):
if message.channel in silent_channels:
if not message.author.server_permissions.administrator and message.author.id != ownerID:
await BSL.delete_message(message)
return
await BSL.process_commands(message)
#BSL.command(pass_context=True)
async def silent(ctx, length=0): # Corrected spelling of length
if ctx.message.author.server_permissions.administrator or ctx.message.author.id == ownerID:
silent_channels.add(ctx.message.channel)
await BSL.say('Going silent.')
if length:
length = int(length)
await asyncio.sleep(length)
if ctx.message.channel not in silent_channels: # Woken manually
return
silent_channels.discard(ctx.message.channel)
await BSL.say('Waking up.')
#BSL.command(pass_context=True)
async def wake(ctx):
silent_channels.discard(ctx.message.channel)
Should work (I haven't tested it, testing bots is a pain). Searching through sets is fast, so doing it for every message shouldn't be a real burden on your resources.