How to save information in text document - discord.py

I am new to making discord bots, i was wondering how to save the information in a text document.
I found the code online and it works fine, i just want to know if its possible to save the output to a text document.
import discord
import os
import sys
intents = discord.Intents.default()
intents.presences = True
intents.members = True
client = discord.Client(intents=intents)
#client.event
async def on_ready():
for guild in client.guilds:
for member in guild.members:
print(member)

You can use a build-in python module called logging
here is an example
import discord
import os
import sys
import logging
intents = discord.Intents.default()
intents.presences = True
intents.members = True
client = discord.Client(intents=intents)
# ----------------------- the logger -----------------------
logging.basicConfig(filename='log.txt', filemode='a', format='%(asctime)s %(msecs)d- %(process)d -%(levelname)s - %(message)s', datefmt='%d-%b-%y %H:%M:%S %p', level=logging.INFO)
#client.event
async def on_ready():
for guild in client.guilds:
for member in guild.members:
print(member)
it will save every output with INFO level into a file called log.txt
all logging level listed here

Related

TypeError: event() missing 2 required positional arguments: 'self' and 'coro'

This is my code so far. I don't under stand what is wrong with it..
import os
import discord
client = discord.Client
#client.event
async def on_ready(): <--- This part errors
print('Bot is Online')
client.run(os.environ['token'])
Your problem is that you forgot the brackets when defining your Client. Also intents is a required argument now, so you need to set those as well.
import discord
intents = discord.Intents.default()
client = discord.Client(intents=intents)
Quickstart docs: https://discordpy.readthedocs.io/en/latest/quickstart.html

How to make bot reply to a mention discord.py

I'm making a discord bot and a problem that has come up for me is that the bot won't reply to the user, here is the code
#Code Imports
import discord
import random
from discord import message
from discord import channel
from discord.embeds import Embed
from discord.ext import commands
from discord.ext.commands.bot import Bot
from discord.message import Message
from apikeys import *
from discord import guild
from discord import emoji
from discord import *
from discord import ContentFilter
from discord import channel
from discord import client
#intents
intents=discord.Intents.default()
intents.members=True
#prefix
client=commands.Bot(command_prefix='!',intents=intents)
#Start
#client.event
async def on_ready():
for emoji in client.emojis:
print("Name:", emoji.name + ",", "ID:", emoji.id)
print('Bot is Online {0.user}'.format(client))
print("--------------------------------------------------------------------------------------------------------------------------------------------------------")
client.remove_command('help')
#Commands
#client.command()
async def work(ctx):
await ctx.send('use !war to get up the war menu')
emojigood = '\N{THUMBS UP SIGN}'
emojibad="\N{THUMBS DOWN SIGN}"
#client.command()
async def help(ctx):
embed=discord.Embed(title='Help', description='!war is currently under testing please do not complain about it', color=0x00000)
await ctx.send(embed=embed)
#client.command()
async def war(ctx):
embed = discord.Embed(title='War', description='You are starting a war, do you want to continue?', color=0x00000)
msg = await ctx.send(embed=embed)
await msg.add_reaction(emojigood)
await msg.add_reaction(emojibad)
def check(r, user):
return (r.emoji == emojigood or r.emoji == emojibad) and r.message == msg
#Checks whether the message is the same, and the emoji is one of the accepted ones, and returns either True or False
r, user = await client.wait_for('reaction_add',timeout=10 ,check=check)
#this is equivalent to a event listener within your command, it will stop there until a reaction that meets the requirements has been found
#(This won't block other commands and functions)
if r.emoji == emojigood:
embed = discord.Embed(title='War', description='Please now choose a country', color=0x00000)
await ctx.send(embed=embed)
prefix = "!" #insert your prefix
async def on_message(message):
if message.author == client.user:
return
if message.content == f'{prefix}war': #dont need to use this string, just illustrating the point
await message.channel.send("What country do you want to start a war with?")
def check(msg):
return msg.author == message.author and len(msg.role_mentions) > 0
msg = await client.wait_for('message', check=check)
role = msg.role_mentions[0]
channel = client.get_channel(849230881994047508)
await channel.send(f"{role.mention} {message.author} has declared war on you.")
client.run(token)
What's meant to happen:
Bot: Which role would you like to start a war with
User:#something
Bot:Send information to UN, 'War on #something'
I don't know how to make it see the role mention
You have a couple of issues, the way to make the code you're using function decently is to replace message.content with message.clean_content, however, 1. That will react to any message starting with # or a mention, which is probably not what you want, and 2. any message not beginning with the mention wouldn't work.
You say in your description that you're looking for role mentions, which is a different attribute, and you're looking to send a message, and wait for a response, so here's a piece of sample code that would solve those issues, assuming I'm interpreting your question correctly:
def check(msg):
return msg.author == message.author and len(msg.role_mentions) > 0
msg = await client.wait_for('message', check=check)
role = msg.role_mentions[0]
channel = client.get_channel(ID of the channel)
await channel.send(f"{role.mention} {message.author} has declared war on you."
If I misinterpreted any of what you wanted or you're not sure how some of it works, shoot me a comment and I'll do my best to explain!
Docs reference for slightly more complex objects used:
role_mentions,
wait_for(),

Can I make a bot to scrape a Discord server once it''s logged in?

Below is the beginning of a script to scrape a discord server with a bot.
How do I edit it to scrape from every channel in the server once I've logged in with the bot? (Perhaps by editing on_ready() instead of on_message()?)
Essentially, I want to scrape a channel without entering "_scan" into it. I would hard code the number of messages to scrape.
I give full credit for this to https://levelup.gitconnected.com/how-to-gather-message-data-using-a-discord-bot-from-scratch-with-python-2fe239da3bcd, and more thoroughly, https://github.com/ThiagoFPMR/Scraper-Bot/blob/main/bot.py.
import os
import discord
import logging
import pandas as pd
logging.basicConfig(level=logging.INFO)
client = discord.Client()
guild = discord.Guild
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
await client.change_presence(activity=discord.Game('_scan help'))
#client.event
async def on_message(message):
if message.author == client.user:
return
elif message.content.startswith('_'):
cmd = message.content.split()[0].replace("_","")
if len(message.content.split()) > 1:
parameters = message.content.split()[1:]
# Bot Commands
if cmd == 'scan':
data = pd.DataFrame(columns=['content', 'time', 'author'])
# Acquiring the channel via the bot command
if len(message.channel_mentions) > 0:
channel = message.channel_mentions[0]
else:
channel = message.channel
...

Discord.py Bot is not online, but still works

i have a problem with my discord bot, whenever i run the code below using apraw to get the titles of the recent submissions on a subreddit the bot doesn't appear online anymore but still returns the titles in CMD :
Bot is not online when i execute this but still asks for subreddit name & prints the titles of the new posts of the subreddit in CMD:
import asyncio
import apraw
from discord.ext import commands
bot = commands.Bot(command_prefix = '?')
#bot.event
async def on_ready():
print('Bot is ready')
await bot.change_presence(status=discord.Status.online, activity=discord.Game('?'))
#bot.command()
async def online (ctx):
await ctx.send('Bot is online !')
reddit = apraw.Reddit(client_id = "CLIENT_ID",
client_secret = "CLIENT_SECRET",
password = "PASSWORD",
user_agent = "pythonpraw",
username = "LittleBigOwl")
#bot.event
async def scan_posts():
xsub = str(input('Enter subreddit name : '))
subreddit = await reddit.subreddit(xsub)
async for submission in subreddit.new.stream():
print(submission.title)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(scan_posts())
bot.run('TOKEN')
But is online when i execute this but obviously doesn't ask for sub name... :
import asyncio
import apraw
from discord.ext import commands
bot = commands.Bot(command_prefix = '?')
#bot.event
async def on_ready():
print('Bot is ready')
await bot.change_presence(status=discord.Status.online, activity=discord.Game('?'))
#bot.command()
async def online (ctx):
await ctx.send('Bot is online !')
bot.run('TOKEN')
So reddit is the problem here. But what exaclty do i ahve to change in order to make my bot apear online whilst still being able to retreive the titles of new submissions on a given subreddit? The code doesn't return any error:/
the #bot.event that you put above async def scan_posts(): should be changed to #bot.command(). It triggers by itself because you have this in your code:
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(scan_posts())
this is what causes the scan_posts to run automatically. You should remove this as you want scan_posts to be a bot command and not something that happens automatically. The bot also doesn't come online because of this code. What this does is check if this file has been run and then runs scan_posts. The rest of the code won't be triggered.
Also, you shouldn't change presence in on_ready as Discord has a high chance to completely disconnect you during the on_ready event and there is nothing you can do to prevent it. Instead you can use the activity and status kwargs in commands.Bot like:
bot = commands.Bot(command_prefix = '?', status=discord.Status.online, activity=discord.Game('?'))

discord.py how to use client.login instead of client.run

I have searching the web for 2 hours on how to this i eventually just gave up.
so basically im trying to make a discord bot (i know how to make one) but im trying to use client.login / client.connect instead of client.run i just want an example of a discord bot that can sign into any account with the token and do something. And i know your gonna ask "Where is the code?" well i don't have the code im just looking for an example not a fix.
but if you must see
#!/usr/bin/env python3
import requests
import discord
import asyncio
token = open("token.txt", "r").read() # I've opted to just save my token to a text file.
#User = discord.User()
client = discord.Client()
##client.event
async def on_ready():
print("on ready executed")
for guild in client.guilds:
for memberd in guild.members:
str = memberd.id
user = client.get_user(str)
await user.send('test')
print(memberd)
client.login(token)
#client.run(token)
As far as i know if you want to use client.login you do
import discord
client = discord.Client()
#client.event()
async def on_ready():
print("Bot is online")
client.login()
Note that client is old and it is better to use cogs and use commands.Bot()
eg.
import discord
from discord.ext import commands
from discord.ext.commands import Bot, Context
client = Bot(command_prefix=".")
#client.event()
async def on_ready()
print("[Status] Ready")
#client.command()
async def ping(ctx:Context):
ctx.send("pong")
client.run("Token")
But if you still want to use the old discord you could use it

Resources