discord.py - Sending virtual PDF file - python-3.x

Is there any way to upload a virtual PDF file onto Discord (I do not want files to be created on my computer). I already know I can send virtual txt files with io.StringIO like this:
import discord, asyncio
from discord.ext import commands
from io import StringIO
bot = commands.Bot()
#bot.command()
async def send(ctx, *, string):
await ctx.send(file=discord.File(
fp=StringIO("This is a test"),
filename="Test.txt"
)
But this doesn't work with PDF files. I tried using io.BytesIO instead but I got no result. Do anyone please know how to solve this problem?

Here's an example using FPDF:
import discord
from discord.ext import commands
from io import BytesIO
from fpdf import FPDF
bot = commands.Bot("!")
#bot.command()
async def pdf(ctx, *, text):
pdf = FPDF()
pdf.add_page()
pdf.set_font('Arial', 'B', 16)
pdf.cell(40, 10, text)
bstring = pdf.output(dest='S').encode('latin-1')
await ctx.send(file=discord.File(BytesIO(bstring), filename='pdf.pdf'))
bot.run("token")

Related

Send a screenshot to discord channels

I am writing a program that screenshots my computer screen and send it to my discord channel. This is done by a discord bot made by me. Below shows what I did:
First, define a function that does a screenshot:
import keyboard
import mouse
import os
def screenshot():
keyboard.press('win + shift + s')
time.sleep(1.5)
mouse.press('left')
mouse.drag(0, 0, 1600, 850, duration=0.2)
mouse.release('left')
filename = f"Screenshot_{time.strftime('%Y%m%d')}_{time.strftime('%I%M%S')}.png"
os.chdir('Path_of_screenshot_saves_here') # I have tested it, the path is correct
time.sleep(1)
with open(filename, 'r') as f:
return f
Then, the code of the discord bot:
import discord
import keyboard
import time
import os
import mouse
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)
#client.event
async def on_ready():
print(f'Logged in as {client.user}')
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('$ss'): # sends a screenshot when it receives a message starts with '$ss'
await message.channel.send(screenshot())
client.run('my_bot_token_here')
The bot does send something to the channel. However, instead of sending out a png file, it sends something like this:
<io.TextIOWrapper name='Screenshot_20230219_030537.png' mode='r' encoding='cp1252'>
What have I done wrong? Are there any ways to solve this? Thanks for any help in advance.

Getting python file outside of folder

I'm try to import my main python file but it's not working.
import discord
from discord.ext import commands
from ..bot import bot
class help(commands.Cog):
def __init__(self, client):
self.client = client
#commands.command(name="help", aliases=["Help"])
async def help(self,context, message = None):
embed = discord.Embed(title="Help command")
cmds = ""
if message == None:
bot.listcom(cmds)
embed.add_field(name="Commands", value=cmds)
if not message == None:
pass
await context.send(embed=embed)
def setup(client):
client.add_cog(help(client))
Terminal Output:
ImportError: attempted relative import with no known parent package
I tried using import ..bot but it gave a syntax error and when I tried using just import bot it said it didn't exist. Can somebody help me?
https://stackoverflow.com/a/24868877/16237426
found that..
in your case that should work:
import sys, os
sys.path.append(os.path.abspath(os.path.join('..')))
from bot import bot

(Discord.py) Read in a image from the attachment url and display it

I was able to get the URL from the attachment and send back the image to the discord server, but when it came to displaying the image through the Pycharm IDE, I was not able to do so.
I tried using matplotlib and skimage to display the image but to no avail.
import os
import discord
from discord.ext import commands
import requests
from discord import Embed
import matplotlib.pyplot as plt
from skimage import io
client = commands.Bot(command_prefix = '.')
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('$hello'):
await message.channel.send('Hello')
if message.attachments[0].url.endswith('png') or message.attachments[0].url.endswith('jpg') or message.attachments[0].url.endswith('jpeg'):
await message.channel.send('This is a picture') #check if the attachment is a image
url = message.attachments[0].url # get the url to the attached image
e = discord.Embed()
e.set_image(url=message.attachments[0].url)
await message.channel.send(embed=e) # embed the image and send it back to the discord channel
#try to display the image
image = io.imread(url)
plt.imshow(image)
plt.show()
Re-Upload Image
We can directly use requests to load the url.
import requests
from matplotlib.pyplot import imshow
import numpy as np
from PIL import Image
url = "https://i.stack.imgur.com/5yS9j.jpg"
im = Image.open(requests.get(url, stream=True).raw)
imshow(np.asarray(im))
References:
Stack question

How to import functions from different file and use in discord.py

A straight Forward question - How to import a function from a different file and use that in discord.py cuz i tried that and failed for example there is file a and b which looks like
a.py:
async def joke(ctx):
joke = 'Your mama so fat boy'
await ctx.send(joke)
and i want to use the joke function from file a to file b and the code i write was:
from a import joke
from discord.ext import commands
#some discord code
TOKEN = 'My_Secret_Token'
GUILD = 'My_Guild'
client = commands.Bot(command_prefix='!')
#client.command(name='joke', help='This will return a joke')
joke()
client.run(TOKEN)
And the line joke() is returning me error
File "main.py", line 31
joke()
^
SyntaxError: invalid syntax
And i am here confused that why it is returning me error and how can i pass the argument ctx. So please come up with a solution for me.
Edit: After debugging and scratching my head for hours i came up with a solution which is also not working that i modified my b.py a little bit :
from a import joke
from discord.ext import commands
#some discord code
TOKEN = 'My_Secret_Token'
GUILD = 'My_Guild'
client = commands.Bot(command_prefix='!')
#client.command(name='joke', help='This will return a joke')
async def my_function(ctx):
joke(ctx)
client.run(TOKEN)
You can use cogs for this. Docs: https://discordpy.readthedocs.io/en/latest/ext/commands/cogs.html
Here is an Example:
Your main.py
import discord
from discord.ext import commands
import os
client = commands.Bot(command_prefix='!')
for file in os.listdir("cogs"):
if file.endswith(".py"):
name = file[:-3]
client.load_extension(f"cogs.{name}")
client.run(TOKEN)
Make a secound /cogs/joke.py
import discord
from discord.ext import commands
import random
class joke(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.command()
async def joke(self, ctx):
jokes = [
'Your mama so fat boy',
'joke2',
'joke3',
'joke4',
'joke5'
]
answer = random.choice(jokes)
await ctx.send(answer)
def setup(bot):
bot.add_cog(joke(bot))

Custom Search Command Discord.py

I'm attempting to make a Custom Search command using the Custom Search API.
Naturally I have no idea how to implement it. I'm hoping someone can take a look at what I have and help me figure out how to make it work in this style?
import discord
from discord.ext import commands
import discord.utils
import time
import os
import dotenv
from dotenv import load_dotenv
load_dotenv()
SEARCH = os.getenv("CUSTOM_SEARCH_API_KEY")
class Util(commands.Cog):
def __init__(self, client):
self.client = client
#commands.command(name="Search", aliases=["search"])
#commands.has_permissions(embed_links=True, add_reactions=True)
async def _search(self, ctx, *, message):
if not ctx.author.Bot:
guild = ctx.guild
msg = ctx.message
cli = self.client.user
gold = discord.Color.dark_gold()
embed = discord.Embed(color=gold, name=f"{image.name}", description=f"{image.desc}", timestamp=msg.created_at)
embed.set_image(url=f"{image.url}")
embed.set_thumbnail(url=cli.avatar_url)
embed.set_footer(text=guild.name, icon_url=guild.icon_url)
await ctx.send(embed=embed)
return
def setup(client):
client.add_cog(Util(client))
I'm using dotenv to store my API key
Basically, I'm wanting it to be a somewhat detailed command.
If searching for posts it will find the exact post. and if searching for images it will go by tag and find a random image matching the selected tag(s).
I would like for it to respond via rich embed if possible.
I'm fully aware my above code won't work at all. I simply put it there as a base for part of the embed that I want to try to implement.
Some help would be much appreciated.
I'm using discord.py rewrite and I have my commands set up through cogs.
This is my bot.py file that contains the handler for my cogs.
import discord
from discord.ext import commands
import os
import json
import dotenv
from dotenv import load_dotenv
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
PREFIX = os.getenv("COMMAND_PREFIX")
client = commands.Bot(command_prefix=PREFIX)
client.remove_command('help')
for filename in os.listdir("./cogs"):
if filename.endswith(".py"):
client.load_extension(f"cogs.{filename[:-3]}")
client.run(TOKEN)

Resources