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".
Related
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content == 'Hey Sloime':
if message.author.id == xxx:
await message.channel.send('Yes master?')
elif message.author.id == xxx:
await message.channel.send('Tell me brother')
else:
await message.channel.send('TF u want?')
else:
return
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content == 'Can I have my Dis ID?':
await message.channel.send(message.author.id)
else:
await message.channel.send('Do I look like I can answer that?')
return
client.run(os.environ['TOKEN'])
It's my first time ever coding in Python, I have experience coding in c, c++, java and sql. My problem is that after I enter the second event on this bot I want to wait for a message corresponding to the first event, but it keeps looping on the second event, I apologize in advance if this is very simple.
Something like this?
#client.event
async def on_message(message):
if message.content == 'i want cheese':
await message.channel.send('how much?')
msg = await client.wait_for('message')
await message.channel.send(f'ok, you want {msg.content} cheese')
# you can do a check like this also
msg = await client.wait_for('message', check=lambda msg: msg.author.id == xxx)
wait_for('message') waits for a message to happen
https://i.stack.imgur.com/VAgTp.png
it aint see my message. There is just empty message
I upload my bot to discord and copy the token, but there ni message just empty
import discord
import random
TOKEN = "token is here"
intents = discord.Intents(messages=True, guilds=True)
client = discord.Client(intents=intents)
#client.event
async def on_ready():
print("We have logged in as {0.user}".format(client))
#client.event
async def on_message(message):
username = str(message.author).split('#')[0]
user_message = str(message.content)
channel = str(message.channel.name)
print(f"{username}: {user_message} ({channel})")
if message.author == client.user:
return
if message.channel.name == "discord-bot-tutorial":
if user_message.lower() == "hello":
await message.channel.send(f"Hello {username}!")
return
elif user_message.lower() == "bye":
await message.channel.send(f"See you next time!{username}!")
elif user_message.lower() == "!random":
response = f"This is your random number: {random.randrange(100000)}"
await message.channel.send(response)
return
if user_message.lower() == "!anywhere":
await message.channel.send(f"This can be anywhere")
client.run(TOKEN)
The most probable cause of this could be that the Message Content Intent is turned off. Without it Discord will not send you content of the messages.
You can enable it on Discord Developer Portal under "Bot" tab.
You will also need to add this intent in your code like this:
intents = discord.Intents.message_content
client = discord.Client(intents=intents)
The problem that I am facing is that my discord bot does not respond or read the messages that I am writing in the chat.
The out put of the code down bellow is the users name and nothing else.
import discord
import random
TOKEN ='example'
client = discord.Client(intents=discord.Intents.default())
#client.event
async def on_ready():
print('We have logged in as{0.user}'.format(client))
#client.event
async def on_message(message):
username = str(message.author).split('#')[0]
user_message = (message.content)
channel = str(message.channel.name)
print(f'{username}: {user_message} ({channel})')
if message.author == client.user:
return
if message.channel.name == 'example':
if user_message.lower() == 'Hello':
await message.channel.send(f'Hello {username}')
elif user_message.lower() == 'bye':
await message.channel.send(f'Hello {username}')
elif user_message.lower() == '!random':
response = f'This is your number: {random.randrange(1000000)}'
await message.channel.send(response)
client.run(TOKEN)
The .lower() method only searches for lower case letters in a string, hence the name, so typing "Hello" into the chat will not trigger the command, as "Hello" has a capital "H". To fix your code you can either:
Change your code to
if user_message.lower() == 'hello':
await message.channel.send(f'Hello {username}')
Notice you can still keep the capital H for hello in
await message.channel.send(f'Hello {username}')
Or, you could compare 2 values like this:
string = 'Hello'
if user_message == string:
#the rest of your code goes here
Your full code should be:
import discord
import random
TOKEN ='exemple'
client = discord.Client(intents=discord.Intents.default())
#client.event
async def on_ready():
print('We have logged in as{0.user}'.format(client))
#client.event
async def on_message(message):
username = str(message.author).split('#')[0]
user_message = (message.content)
channel = str(message.channel.name)
print(f'{username}: {user_message} ({channel})')
if message.author == client.user:
return
if message.channel.name == 'example':
string = 'Hello'
if user_message.casefold() == string:
await message.channel.send(f'Hello {username}')
elif user_message.lower() == 'bye':
await message.channel.send(f'Hello {username}')
return
elif user_message.lower() == '!random':
response = f'This is your number: {random.randrange(1000000)}'
await message.channel.send(response)
return
client.run(TOKEN)
Intents.default() doesn't include the Message Content intent, which is now required. Without the intent, message.content will be empty.
More information in the docs:
https://discordpy.readthedocs.io/en/stable/intents.html#privileged-intents
Your bot can't read the content of the messages sent in a guild because it is missing the message_content intent.
You gave your bot only the default intents, which doesn't include the message_content one.
client = discord.Client(intents=discord.Intents.default())
Here is how you fix it:
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)
In case your bot isn't still able to read the content of the guild messages, you need also to turn on the message content intent in the Discord Developer Portal:
Select your app
Go to the "Bot" tab
Turn the "message content intent" on
Now your bot should be able to read the content of the messages sent in guilds.
I've got a function to set up the server when the bot joins, but i'm talking with my friends at the same time and it is getting errors because i only want the bot to read messages from dm
async def on_guild_join(guild):
print("Bot added to server: " + guild.name)
gid = str(guild.id)
server = Server()
server.name = guild.name
server.discordId = guild.id
server.ownerId = guild.id
server.welcome_message = None
server.lang = "en"
# here goes another tons of values
if guild.id in db['guilds']:
pass
else:
servers_dic = db['guilds']
servers_dic[gid] = server.toJSON()
print(server.toJSON())
db['guilds'] = servers_dic
await guild.owner.send(f"Hi! Thanks for adding me to your server, {guild.name}! To start using me, we'll have to set up a few things. Do you want to do it now or later?\n\n(n/l)")
msg = await bot.wait_for('message', check=lambda message: message.author == guild.owner)
if msg.content.lower() in ['n', 'now']:
server = deencoder(db['guilds'][gid])
if isinstance(server, Server):
print("Class created successfully!")
print(server)
is there any way to do that?
You can simply use the isinstance function and check for a discord.DMChannel
def check(message):
return message.author == guild.owner and isinstance(message.channel, discord.DMChannel)
msg = await bot.wait_for('message', check=check)
# or if you still want to use lambda expressions
msg = await bot.wait_for('message', check=lambda message: message.author == guild.owner and isinstance(message.channel, discord.DMChannel))
You could add the #commands.dm_only() decorator for the command to only work in a DM channel:
import discord
from discord.ext import commands
#bot.command()
#commands.dm_only()
async def something(ctx):
#do something
Or you could change your check to check if the message was sent in a DM channel:
msg = await bot.wait_for('message', check=lambda message: message.author == guild.owner and isinstance(message.channel, discord.DMChannel))
so right now I'm trying to create a type of application bot and right now the check I used for the bot doesn't allow the user to move onto the next question. There is no traceback so it's something with the check I defined.
#commands.command()
#commands.has_role("Realm OP")
async def block(self, ctx, user: discord.User):
DMchannel = await ctx.author.create_dm()
channel = ctx.message.channel
author = ctx.message.author
mentions = [role.mention for role in ctx.message.author.roles if role.mentionable]
channel2 = str(channel.name)
channel = channel2.split('-')
if len(channel2) == 2: # #real-emoji
realm, emoji = channel
else: # #realm-name-emoji
realm, emoji = channel[0], channel[-1]
realmName = realm.replace("-" , " ")
realmName1 = realmName.lower()
rolelist = []
print(realmName1)
a = solve(realmName1)
print(a)
realmName2 = str(a) + " OP"
print(realmName2)
check_role = discord.utils.get(ctx.guild.roles, name= realmName2)
if check_role not in ctx.author.roles:
return await ctx.send('You do not own this channel')
else:
await ctx.send("You own this channel!")
def check(m):
return m.channel == channel and m.author != self.bot.user
await DMchannel.send("Please fill out the questions in order to block the user!")
await DMchannel.send("User's Gamertag: (If you don't know, try using the >search command to see if they have any previous records!) ")
blocka1 = await self.bot.wait_for('message', check=check)
await DMchannel.send("Reason for block:")
blocka2 = await self.bot.wait_for('message', check=check)
Right now the bot doesn't do anything after the user responds to the first question and there is no traceback.
Any help or suggestions would help greatly!
Your check isn't returning anything. It's supposed to return either True or False. This means your wait_for will never end (as the check never returns True), so it will never ask the next question.
def check(m):
return m.channel == channel and m.author != self.bot.user
EDIT:
Your channel is the ctx.channel, while your bot waits for answers in DM. Assuming you answer your bot in DM as well, this means your check will never pass, as m.channel never equals channel.
def check(m):
return m.guild is None and m.author == ctx.author
This checks if a message was sent in DM (Guild is None), and if it was a DM by the original author.