I am making a Discord bot with Python.
I would like to add a feature in where, there is a channel called "chatbot", and any text typed there would be replied to by Cleverbot
I am currently trying with the cleverbotfree library, but it doesn't work and I can't find good documentation on it. My problem is that I am trying to run this async command:
#CleverbotAsync.connect
async def async_chat(bot, message, user_input, bot_prompt):
"""Example code using cleverbotfree async API with decorator."""
reply = await bot.single_exchange(user_input)
await message.channel.send(f'{0}'.format(reply))
await bot.close()
However, I can't do this in on_message, because it needs to be run in this snippet of code:
if chnl == 'chatbot':
#whatever running that command
So, I'm not sure how do it.
And yes, I have looked into and tried Selenuim, but it appears that whenever I click the accept button, nothing loads. (This must be a way for Cleverbot to make people actually pay for their API, which I can't do).
Here is my full code(I know it's not the best):
import discord
from discord import channel
from discord.flags import MessageFlags
from webserver import keep_alive
import os
from discord.ext import commands
import youtube_dl
import time
import asyncio
from cleverbotfree import CleverbotAsync
from cleverbotfree import Cleverbot
requests = []
def send(message,user_input,bot_prompt):
asyncio.run(async_chat(message,user_input,'Cleverbot:'))
client = commands.Bot(command_prefix="!")
#client.command()
async def request(ctx, request: str,member: discord.Member):
requests.append('{0}: {1}'.format(member,request))
await ctx.send(f'Thanks {member.metion} for the request, my dev will (hopefully) get right to work!')
#client.command(description="See what my dev is working on")
async def workingon(ctx):
ctx.send("My Dev is currently working on adding a feature in where, in a channel called 'chatbot', it will respond like a human.(though he has spent hours on it, it still doesn't work)")
#client.event
async def on_ready():
#confirming login
print('Logged on as {0.user}'.format(client))
#client.event
async def on_member_join(member):
print(f'Greetings {member}, welcome to server')
#CleverbotAsync.connect
async def async_chat(bot, message, user_input, bot_prompt):
"""Example code using cleverbotfree async api with decorator."""
reply = await bot.single_exchange(user_input)
await message.channel.send(f'{0}'.format(reply))
await bot.close()
#client.event
async def on_message(message):
#getting variables
usrnm = str(message.author).split('#')[0]
msg = str(message.content)
chnl = str(message.channel.name)
if usrnm != str(client.user).split('#')[0] and msg.lower() == 'hello bot':
await message.channel.send(f'Hello {usrnm}, how do you do?')
return
if str(msg).split(' ')[0].lower() == 'im':
print(str(msg).split(' ')[0].lower())
await message.channel.send(f'Hi, {msg}, im a dad!')
if msg.lower() == '!newfeatures':
await message.channel.send(f'{message.author.mention}, The newest feature added to the bot is that if a new member joins, it will greet them')
if msg.lower() == '!help':
await message.channel.send(f'{message.author.mention}, Type !help for help. \n\n - Typing "Hello Bot" will make the bot answer\n - typing "im" before anything will make the bot answer\n - Typing !newfeatures will tell you the newest feature added to the bot.')
if chnl == 'chatbot':
send(message,str(message.content),'Cleverbot:')
#muting system
keep_alive()
TOKEN = os.environ.get("DISCORD_BOT_SECRET")
client.run(TOKEN)
Any help would be appreciated!
Related
So I was used to use this bot about one year ago, now I wanted to launch it again but after discord.py 2.0 update it seems doesn't work propery
import discord
from keep_alive import keep_alive
class MyClient(discord.Client):
async def on_ready(self):
print('bot is online now', self.user)
async def on_message(self, message):
word_list = ['ffs','gdsgds']
if message.author == self.user:
return
messageContent = message.content
if len(messageContent) > 0:
for word in word_list:
if word in messageContent:
await message.delete()
await message.channel.send('Do not say that!')
# keep_alive()
client = discord.Client(intents=discord.Intents.default())
client.run('OTkxfsa9WC5G34')
from flask import Flask
from threading import Thread
app = Flask('')
#app.route('/')
def home():
return 'dont forget uptime robot monitor'
def run():
app.run(host='0.0.0.0',port=8000)
def keep_alive():
t = Thread(target=run)
t.start()
I tried to fix it by my own by changing this line
client = discord.Client(intents=discord.Intents.default())
It has to be some trivial syntax mistake, but I cannot locate it
Edit1: so i turned on intents in bot developer portal and made my code to looks like this but still seems something doesn't work
import discord
from keep_alive import keep_alive
class MyClient(discord.Client):
async def on_ready(self):
print('bot is online now', self.user)
async def on_message(self, message):
word_list = ['fdsfds','fsa']
if message.author == self.user:
return
messageContent = message.content
if len(messageContent) > 0:
for word in word_list:
if word in messageContent:
await message.delete()
await message.channel.send('Do not say that!')
# keep_alive()
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents = intents)
client.run('OTkxMDcxMTUx')
If it would be a syntax mistake you'd get a syntax error. The real issue is that you didn't enable the message_content intent, so you can't read the content of messages. Intents.default() doesn't include privileged intents.
intents = discord.Intents.default()
intents.message_content = True
Don't forget to enable it on your bot's developer portal as well.
Also all of that keep alive & flask stuff hints that you're abusing an online host to run a bot on. This brings loads of issues along with it that you can't fix so you should really consider moving away from that. There's posts on a daily basis of people with problems caused by this.
Your code should be:
import discord
from discord.ext import commands # you need to import this to be able to use commands and events
from keep_alive import keep_alive
client = commands.Bot(intents=discord.Intents.default())
#bot.event
async def on_ready(): # you don't need self in here
print('bot is online now', client.user) # you can just use client.user
#bot.event
async def on_message(message): # again, you do not need self
word_list = ['ffs','gdsgds']
if message.author == client.user: # you can use client.user here too
return
messageContent = message.content
if len(messageContent) > 0:
for word in word_list:
if word in messageContent:
await message.delete()
await message.channel.send('Do not say that!')
keep_alive()
client.run('OTkxfsa9WC5G34') #if this is your real token/you have been using this token since you made the bot, you should definitely generate a new one
To help you, I added some comments to help show you what I have changed and why. As one of the comments in the code says, you should regenerate your bot token at the Discord Developer Portal.
For more info about migrating to 2.0, read the Discord.Py docs
I've never coded before so I'm pretty new and I'm trying python on replit, I've searched a lot and this is what I did so far but it isn't working. (ignore the reverse part)
import os
import discord
from keep_alive import keep_alive
client = discord.Client(intents=discord.Intents.default())
#client.event
async def on_ready():
print("I'm in")
print(client.user)
#client.event
async def on_message(message):
if message.content.startswith("!reverse"):
await message.channel.send(message.content[::-1])
my_secret = os.environ['DISCORD_BOT_SECRET']
client.run(my_secret)
keep_alive()
my_secret = os.environ['DISCORD_BOT_SECRET']
client.run(my_secret)
async def on_message(message):
echo = message.content.split(" ", 1)[1]
if message.content.startswith("!say"):
await message.channel.send(echo)
I want the bot to be like this:
me:!say blah blah blah
bot: blah blah blah
thanks to anyone that answers
There's a lot of problems here
Intents.default() doesn't include the message contents intent, so you won't be able to read messages. For more info on intents and how to enable them, read the docs: https://discordpy.readthedocs.io/en/stable/intents.html
You've got two on_message functions, which doesn't work. You can't have multiple functions with the same name. Combine them into one instead.
Never put any code underneath client.run() - it'll never get executed.
You've got two client.run()'s. Why?
The on_message at the bottom is missing the #client.event decorator, so even if you wouldn't have 2 of them it still wouldn't be invoked.
Why don't you use a Bot with commands instead of manually parsing everything in on_message? https://discordpy.readthedocs.io/en/stable/ext/commands/index.html
Replit isn't made to run bots on and will cause you a lot of trouble. Consider hosting it on an actual VPS (or during the development phase - just locally).
Ok, there's some other changes to make first.
You're not using commands, and are instead looking for messages(technically nothing wrong with that, but it can cause unnecessary issues)
I'll modify the code, and hopefully, it works.
import os
import discord
from keep_alive import keep_alive
client= commands.Bot(command_prefix='!', intents=discord.Intents.default())
#client.event
async def on_ready():
print("I'm in")
print(client.user)
#client.command()
async def reverse(ctx,*,message):
await ctx.message.delete()
await ctx.channel.send(message[::-1])
my_secret = os.environ['DISCORD_BOT_SECRET']
client.run(my_secret)
keep_alive()
my_secret = os.environ['DISCORD_BOT_SECRET']
client.run(my_secret)
#client.command()
async def say(ctx, *, message):
await ctx.message.delete()
await ctx.channel.send(message)
So, I'm using replit.com to make the bot, and the bot comes online just fine. I type in $hello and expect to get a response saying "Commander". I do that, but the bot doesn't reply back. I based this script off a video on Youtube. I'm guessing it could be something to do with my code, or the discord bot permissions. Any help/ advice would be appreciated, thanks.
import discord
import os
import time
client = discord.Client()
#client.event
async def on_ready():
print('We have broken into american server farms as {0.user}'.format(client))
time.sleep(1)
print("Accessing private data...")
time.sleep(2)
print("Installing malware...")
time.sleep(2)
print("Extracting stolen files...")
time.sleep(2)
print("Finishing up..")
time.sleep(1)
print("All objectives completed, State Messenger Bot is now online.")
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('$hello'):
await message.channel.send('Commander')
client.run(os.getenv('TOKEN'))
I am not sure I fully understand the question but I will try to answer it
import discord
client = commands.Bot(command_prefix = '$')
#client.event
async def on_ready():
print("we have powered on, I an alive.")
#client.command()
async def hello(ctx):
await ctx.send('Commander')
client.run('TOKEN')
What the last part does is wait until someone says $hello and then replies Commander. The prefix has been defined at the start so you do not need to define a prefix for every command. In async def hello(ctx): you can change hello to be the name of your command
I am trying to create a python script that would mute the users of a specific voice channel when executed. Till now I am able to mute everyone by typing the command in the discord text channel, but I would like to mute everyone when another python script tells the bot to. Below is my attempt to do that.
bot.py is the python discord bot:
import discord
from discord.ext import commands
from time import sleep
client = commands.Bot(command_prefix="./")
#client.event
async def on_ready():
print("Bot is online. ")
#client.command()
async def play_music_test():
channel = await client.get_channel(voice_channel_number)
voice = await channel.connect()
await voice.play(
discord.FFmpegPCMAudio(executable="C:/Users/USER/ffmpeg/bin/ffmpeg.exe",
source="C:/Users/USER/Desktop/song.mp3"))
client.run(TOKEN)
abc.py is the other python script trying to call a function:
from bot import play_music_test
import asyncio
print("")
asyncio.run(play_music_test())
I ran the bot.py first and then tried to execute the abc.py next, bot came online but when executing abc.py, it didn't print or do anything at all. I just started to learn discord.py so if this is a silly question, forgive me.
Instead of running the python file you can import it, or making it a cog
heres an example:
importing: bot.py
import discord
from discord.ext import commands
from time import sleep
from abc import *
client = commands.Bot(command_prefix="./")
#client.event
async def on_ready():
print("Bot is online. ")
#client.command(name = "play_music", aliases = ["you can asign aliases like this", "multiple ones too"])
async def play_music_test(ctx, channel): # If the python file doesn't know what channel is, it can be asigned when calling the function in discord, think of it like sys.argv or argparse
if channel == None: channel = ctx.channel # This sets the current channel you are in if none was provided when executing it in discord
# channel = await client.get_channel(channel) now you don't need this line
voice = await channel.connect()
await voice.play(
discord.FFmpegPCMAudio(executable="C:/Users/USER/ffmpeg/bin/ffmpeg.exe",
source="C:/Users/USER/Desktop/song.mp3"))
client.run(TOKEN)
importing: abc.py
remove asyncio.run(play_music_test())
use it in discord instead! ex. play_music_test #general
Making it a cog: bot.py
import discord
from discord.ext import commands
from time import sleep
import os
client = commands.Bot(command_prefix="./")
#client.event
async def on_ready():
print("Bot is online. ")
for filename in os.listdir("./"):
if filename == "bot.py": continue
else: client.load_extension(f"cogs.{filename[:-3]}")
client.run(TOKEN)
Making it a cog: abc.py
from bot import play_music_test
import asyncio
class Mycog(commands.Cog):
def __init__(self, client):
self.client = client
#client.command(name = "play_music", aliases = ["you can asign aliases like this",
"multiple ones too"])
async def play_music_test(ctx, channel): # If the python file doesn't know what
channel is, it can be asigned when calling the function in discord, think of it like sys.argv or argparse
if channel == None: channel = ctx.channel # This sets the current channel you are in if none was provided when executing it in discord
# channel = await client.get_channel(channel) now you don't need this line
voice = await channel.connect()
await voice.play(
discord.FFmpegPCMAudio(executable="C:/Users/USER/ffmpeg/bin/ffmpeg.exe",
source="C:/Users/USER/Desktop/song.mp3"))
def setup(client):
client.add_cog(Mycog(client))
This anwser is not the best but hope this helps!
i'm not sure, if i really understand, what you try to do, but to open a script from another script, i use subprocess.Popen()
but i think, in your case it fits more, to change the way you try to solve your problem. maybe you should take a look into the on_message event and use message.content
?
You can importing your client variable (from bot import play_music_test, client) and then client.loop.create_task(play_music_test())
(Although I do not understand why you would do such a thing)
I am looking for a way to allow a user to move him or her self and another user to a different voice channel. I already got the command to work for the author of the message, but I am having trouble finding out a way to move another user in the same message. The idea is that the user would be able to type "n!negotiate [Other User]" and it would move the author and the other user to the Negotiation channel.
I would love some help with how I might be able to do this. The code is provided below excluding the tokens and ids.
Code:
import discord
from discord.ext.commands import Bot
from discord.ext import commands
import asyncio
import time
Client = discord.Client() #Initialise Client
client = commands.Bot(command_prefix = "n!") #Initialise client bot and prefix
#client.event
async def on_ready():
print("Logged in as:")
print(client.user.name)
print("ID:")
print(client.user.id)
print("Ready to use!")
#client.event
async def on_message(check): #Bot verification command.
if check.author == client.user:
return
elif check.content.startswith("n!check"):
await client.send_message(check.channel, "Nations Bot is online and well!")
async def on_message(negotiation): #Negotiate command. Allows users to move themselves and other users to the Negotiation voice channel.
if negotiation.author == client.user:
return
elif negotiation.content.startswith("n!negotiate"):
author = negotiation.author
voice_channel = client.get_channel('CHANNELID')
await client.move_member(author, voice_channel)
client.run("TOKEN")
You should use discord.ext.commands. You're importing it, but not actually using any of the features.
from discord.ext import commands
import discord
bot = commands.Bot(command_prefix = "n!") #Initialize bot with prefix
#bot.command(pass_context=True)
async def check(ctx):
await bot.say("Nations Bot is online and well!")
#bot.command(pass_context=True)
async def negotiate(ctx, member: discord.Member):
voice_channel = bot.get_channel('channel_id')
author = ctx.message.author
await bot.move_member(author, voice_channel)
await bot.move_member(member, voice_channel)
bot.run('TOKEN')
Here we use a converter to accept a Member as input. Then we resolve the author of the message from the invocation context and move both Members to the voice channel.