Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 months ago.
Improve this question
I'm looking to make a program that DM's my friend every day at a certain time. Is this possible? Everything I've found online is through a bot, but I just want to DM him directly through his UserID
Is it possible?
Yes, what a suprize.
Steps
You have to do this 4 easy steps (I use discord.py):
Create a cog
Create a loop
Check if one day is over (let's say you want to DM at 10am)
Send a DM
Start the loop
Step 1
First we create a cog. A cog is just a way to manage your commands, listeners etc. It's a good practice for this. Read more about here: https://discordpy.readthedocs.io/en/latest/ext/commands/cogs.html?highlight=cog
from discord.ext import commands
class DMFriend(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
async def setup(bot):
await bot.add_cog(DMFriend(bot))
Step 2
To do this, we use tasks.loop. Let's say, we want to check every 10 minutes if it's 10am.
from discord.ext import commands, tasks
class DMFriend(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
#tasks.loop(minutes=10)
async def dm_friend(self):
async def setup(bot):
await bot.add_cog(DMFriend(bot))
Step 3
We use the variable message_sent as a flag, that the DM doesn't get send every time it goes through. Also I do now == 10, because now should have at least one time the value 10 because it goes through (ideally) 6 times an hour.
import datetime
from discord.ext import commands, tasks
class DMFriend(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
self.message_sent = False
#tasks.loop(minutes=10)
async def dm_friend(self):
now = datetime.datetime.utcnow().hour
if now == 10 and not self.message_sent:
self.message_sent = True
else:
self.message_sent = False
async def setup(bot):
await bot.add_cog(DMFriend(bot))
Step 4
Now we need to send the DM. For that we use bot.get_user() and send()
import datetime
from discord.ext import commands, tasks
class DMFriend(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
self.message_sent = False
self.user = self.bot.get_user(USER_ID)
#tasks.loop(minutes=10)
async def dm_friend(self):
now = datetime.datetime.utcnow().hour
if now == 10 and not self.message_sent:
await self.user.send("Your DM")
self.message_sent = True
else:
self.message_sent = False
async def setup(bot):
await bot.add_cog(DMFriend(bot))
Step 5
Now we just have to start the loop. For that we create a command.
import datetime
from discord.ext import commands, tasks
class DMFriend(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
self.message_sent = False
self.user = self.bot.get_user(USER_ID)
#tasks.loop(minutes=10)
async def dm_friend(self):
now = datetime.datetime.utcnow().hour
if now == 10 and not self.message_sent:
await self.user.send("Your DM")
self.message_sent = True
else:
self.message_sent = False
#commands.command()
async def start(self, ctx: commands.Context):
self.dm_friend.start()
async def setup(bot):
await bot.add_cog(DMFriend(bot))
That's it!
Note: This is just an easy go-through. When the bot disconnects (crash, server restart) you'll have to start it again. Also you shouldn't mass DM users, it's against the Discord ToS.
Related
So, I'm new to python and even more to coding bots on discord. At the moment I'm using discord.py and red-bot (https://docs.discord.red/en/stable/index.html).
At the moment I'm trying to make the bot listen to a new message and print something in response to it, but I just can't figure it out. Since I'm using red-bot I didn't go through the steps of using client = discord.Client() and setting a token on the code itself so using #client.event() doesn't seem to work, nor #bot.event(), and I can't really find any other way to make the bot listen for an on_message() event.
Edit with part of my code:
import discord
from discord.ext import commands
from redbot.core import commands
class MyCog(commands.Cog):
client = discord.Client()
def __init__(self, bot):
self.bot = bot
#bot.event()
async def on_message(self, message):
if 'test' in message.content:
await self.send_message(message.channel, 'it works!')
Console returns that bot in #bot.event() is not defined.
Also a separate initialization file, it's done this way to follow Red's guide of how to make a cog.
from .remind import MyCog
def setup(bot):
bot.add_cog(MyCog(bot))
Here is an example of a cog that replies to a specific word mentioned. It also has a cooldown to prevent the bot spamming which I find absolutely neccesary to include.
from curses.panel import bottom_panel
import discord
from discord.ext import commands
class brilliant(commands.Cog):
def __init__(self, bot):
self.bot = bot
self._cd = commands.CooldownMapping.from_cooldown(1, 60.0, commands.BucketType.member) # Change accordingly
# rate, per, BucketType
def ratelimit_check(self, message):
"""Returns the ratelimit left"""
bucket = self._cd.get_bucket(message)
return bucket.update_rate_limit()
#commands.Cog.listener()
async def on_message(self, message):
if message.author == self.bot.user:
return
msg = message.content.lower()
brilliant = ['brilliant', 'Brilliant', 'brilliant!', 'Brilliant!']
if any(word in msg for word in brilliant):
retry_after = self.ratelimit_check(message)
if retry_after is None:
await message.channel.send("Brilliant!")
await self.bot.process_commands(message)
else:
return
async def setup(bot):
await bot.add_cog(brilliant(bot))
If you want it in the main file, you can put something a lot simpler:
brilliant = ['brilliant', 'Brilliant', 'brilliant!', 'Brilliant!']
#bot.event
async def on_message(message):
if message.author == bot.user:
return
msg = message.content.lower()
if any(word in msg for word in brilliant):
await message.channel.send("Brilliant!")
await bot.process_commands(message)
Hope it helps.
I need to log many events on my Discord server and i am trying add logging feature to my bot. But it looks like this:
#bot.event
async def on_message_delete(m):
created_at = m.created_at.strftime('%d-%m-%Y %H:%M:%S')
log_content = f'{m.author} deleted message.\n[{created_at}] "{m.content}"'
await Logging().write_log(1, log_content)
#bot.event
async def on_message_edit(m_before, m_after):
created_at = m_after.created_at.strftime('%d-%m-%Y %H:%M:%S')
edited_at = m_after.edited_at.strftime('%d-%m-%Y %H:%M:%S')
log_content = f'{m_after.author} edited message.\n[{created_at}] "{m_before.content}"\n[{edited_at}] "{m_after.content}"'
await Logging().write_log(1, log_content)
#bot.event
async def on_raw_reaction_add(payload):
channel = bot.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
created_at = message.created_at.strftime('%d-%m-%Y %H:%M:%S')
log_content = f'{payload.member} addded reaction {payload.emoji} to message from {message.author}.\n[{created_at}] "{message.content}"'
await Logging().write_log(2, log_content)
#bot.event
async def on_raw_reaction_remove(payload):
channel = bot.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
created_at = message.created_at.strftime('%d-%m-%Y %H:%M:%S')
log_content = f'{payload.member} removed reaction {payload.emoji} from message by {message.author}.\n[{created_at}] "{message.content}"'
await Logging().write_log(2, log_content)
# and more
How can I put this to another file? Or something like that
What you are looking for is dpy's Cogs
There comes a point in your bot’s development when you want to organize a collection of commands, listeners, and some state into one class. Cogs allow you to do just that.
A quick example here would be :
class Logging(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.Cog.listener()
async def on_member_join(self, member):
# Do your logging stuff here
...
More details on adding and removing Cogs have been detailed in the documentation which you can read here
NOTE: In some versions of dpy add_cog, setup are coroutine functions and needs to be awaited. Be sure to crosscheck your version :D
I am trying to get export my troll commands in a discord bot i run to a new file, using cogs and extensions. However, the commands do not register, and I'm not sure why. I'll send the code here. (just ignore the weird function launch, it makes more sense when you look at the bot entirely but its spread thought 2k lines. )
#bot.py
import os
import sys
import time
import datetime
import discord
from discord.ext.commands import Bot
from discord import Intents
import assets
import role_counter
from discord.ext import commands
import discord.ext.commands
from dotenv import load_dotenv
import git_push
import merit_config
import trolls
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
TOKEN_TEST = os.getenv('DISCORD_TOKEN_TEST')
GUILD = os.getenv('DISCORD_GUILD')
cogs = ['cogs.trolls']
def startup(START):
global LAUNCH
global bot
if START == TOKEN:
intents = Intents.all()
bot = commands.Bot(intents=intents, command_prefix='.')
bot.remove_command('help')
LAUNCH = TOKEN
startup(TOKEN)
initial_extensions = ['cogs.trolls']
if __name__ == '__main__':
for extension in initial_extensions:
bot.load_extension(extension)
def main():
while True:
bot.run(LAUNCH)
#trolls.py
import assets
from discord.ext import commands
class troll_commands(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.command()
async def troll(self, ctx):
if ctx.channel.id == '936902313589764146' or '939028644175699968':
await ctx.send(f"```{assets.troll_command()}```")
await self.bot.process_commands()
def setup(bot):
bot.add_cog(troll_commands(bot))
I've mirrored every example i can find, it just isn't working and idk why. If I'm missing some code to reporodce please just tell me, ill edit this post.
It depends on the version you're currently using but as you're having issues, you need to clarify what sort of error you're getting.
If you're using V2 then you do need to use async for the majority of your code now, here's a migration guide if you would like to take a look: https://discordpy.readthedocs.io/en/stable/migrating.html.
The main areas that you need to fix are:
if __name__ == '__main__':
for extension in initial_extensions:
bot.load_extension(extension) # you need to await this
def main(): # you aren't ever calling main
while True:
bot.run(LAUNCH)
and
def setup(bot): # needs to be async
bot.add_cog(troll_commands(bot)) # needs to be awaited
There are some other things you should reconsider like global vars but this should work for now.
You have to use async and await to be able to add a cog.
You have to async and await the extension loading and running the bot
await bot.load_extension(extension)
async def setup(bot):
await bot.add_cog(Command(bot))
When I tried adding a Cog for my bot it gives me a TypeError
module() takes at most 2 arguments (3 given)
class Commands(commands.cog):
def __init__(self, client):
self.client = client
self.song_queue = {}
self.setup()
def setup(self):
for guild in self.client.guilds():
self.song_queue[guild.id] = []
I also set it up using
async def setup():
client.add_cog(Commands(client))
client.loop.create_task(setup())
guilds is a list, you can't call it, and self.client.guilds will always be empty, you'll need to find another way to have a setup function when the bot is "ready" –
Taku
I have a webhook cog for a discord bot I'm making. I want to make the embarrass command (in the webhook cog) trigger a webhook to be created with a user's name and pfp, which is working just fine. however, I also want this command to be able to be set onto a specific user, and that is where the problem arises. When I try to add a member parameter into the embarrass function, so it looks like: async def embarrass(self, ctx, member: discord.Member
it doesn't work. every time I execute the command after that I get a "command embarrass not found" error. this holds true regardless of if I pass through the paramter, and if I add member: discord.Member = None to it to make it not required; nothing I've done works. I would greatly appreciate any help on this topic.
Here is my main.py:
import random
import asyncio
import aiohttp
import json
import keep_alive
from discord import Game
from discord.ext.commands import Bot
import datetime
import re
import time
from subprocess import call
import discord
from discord.ext import commands
from discord.utils import get
import text
import os
TOKEN = os.environ['token']
bot = commands.Bot(command_prefix=".")
startup_extensions = ["Cog.Cog_Template", "Cog.webhooks"]
#bot.event
async def on_ready():
# On read, after startup
print(f"Connecting...\nConnected {bot.user}\n") # Send message on connected
if __name__ == "__main__": # When script is loaded, this will run
for extension in startup_extensions:
try:
bot.load_extension(extension) # Loads cogs successfully
except Exception as e:
exc = '{}: {}'.format(type(e).__name__, e)
print('Failed to load extension {}\n{}'.format(extension, exc))
keep_alive.keep_alive()
bot.run(TOKEN)
And here is my cog file (its called webhook.py and its in a folder called Cog:
from discord import Webhook, RequestsWebhookAdapter
from discord.ext import commands
import random
embarrasslist = ["I use and throughly like airpods","I respond with \"^\" to everything because I'm too dumb to have an original thought of my own","The only time I ever go outside is for school","I made a discord server where exactly 3 people joined, and they were were my alt accounts.","I get legitimately scared when I play five nights at freddy's","I play PC Games with a steam controller","I unironically use 69 in my usernames","I cried myself to sleep when I found out that my favourite chair had a dent in it","My parent's gave me a PS Move instead of a Wii for christmas","I unironically watch Ali-A","I spam .embarrass because I am very narcissistic and want to see my face on a bot", "I couldn't teach my son how to ride a bike cause I can't ride one myself","I own a sonic pillow and I kiss it every night before I go to sleep","I set my favorite 3ds game to system settings because I thought I was being clever","I set my favorite 3ds game to system settings because I can't buy any more games","Paul Blart: Maul Cop is my favorite movie","I thought shrek 3 wasn't bad","I have a gameinformer subscription","It took me a full day to beat the first level of super mario bros","My favorite emote is :joy:","I spent 2 hours learning how to make a new folder on my computer","I torrented fortnite"]
class WebHooks(commands.Cog, name="WebHooks"):
global embarrasslist
def __init__(self, bot):
self.bot = bot
#commands.command(name="embarrass")
async def embarrass(self, ctx, member: discord.Member = None):
"""Send a message as a webhook"""
if member != None:
user = member
elif member = None:
user = ctx.message.author
embarrassnumber = random.randint(0,21)
embarrassment = embarrasslist[embarrassnumber]
looking_webhooks = await ctx.channel.webhooks()
if looking_webhooks:
for webhook in looking_webhooks:
if webhook.name == "NexInfinite-GitHub":
await send_webhook(webhook, embarrassment, ctx, user)
return
else:
pass
webhook = await ctx.channel.create_webhook(name="NexInfinite-GitHub")
await send_webhook(webhook, embarrassment, ctx, user)
return
#commands.command(name="embaras", aliases = ["embarras","embarass"])
async def embarras(self, ctx):
"""Send a message as a webhook"""
cantspell = "I don't know how to spell *embarrass* properly"
looking_webhooks = await ctx.channel.webhooks()
if looking_webhooks:
for webhook in looking_webhooks:
if webhook.name == "NexInfinite-GitHub":
await send_webhook(webhook, cantspell, ctx)
return
else:
pass
webhook = await ctx.channel.create_webhook(name="NexInfinite-GitHub")
await send_webhook(webhook, cantspell, ctx)
return
def setup(bot):
bot.add_cog(WebHooks(bot))
async def send_webhook(webhook, message, ctx, uservar):
webhook_id = webhook.id
webhook_token = webhook.token
webhook = Webhook.partial(int(webhook_id),
f"{webhook_token}",
adapter=RequestsWebhookAdapter())
webhook.send(f'{message}', username=f"{ctx.uservar.display_name}",
avatar_url=ctx.uservar.avatar_url) # Sends the message as the author
I am running this on repl.it so thats why I import keep_alive, and I have another cog that I added with other commands but that doesn’t seem to be the issue either. I can add it if you request it however.
Thanks for the help!
I forgot to import discord at the top, so I couldn't successfully use discord.Member. Importing discord solved this issue.