I'm working on a Discord bot using Discord.pythat processes image attachments in messages. The bot is supposed to read the attachments and recognize text from them using pytesseract. However, my logs show that all attachments are empty even though there are image files attached to messages.
Here's the relevant part of my code:
import discord
import cv2
import numpy as np
from PIL import Image
import pytesseract
from discord.ext import commands
import aiohttp
import logging
logging.basicConfig(level=logging.DEBUG)
intents = discord.Intents.default()
intents.messages = True
bot = commands.Bot(command_prefix="!", intents=intents)
def find_apple_and_crop(image_bytes, template_image_path):
input_image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
template_image = cv2.imread(template_image_path, cv2.IMREAD_GRAYSCALE)
gray_input_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)
result = cv2.matchTemplate(gray_input_image, template_image, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
top_left = max_loc
height, width = template_image.shape
bottom_right = (top_left[0] + width, top_left[1] + height)
cropped_image = input_image[top_left[1]:bottom_right[1], top_left[0]:bottom_right[0]]
cropped_image_pil = Image.fromarray(cv2.cvtColor(cropped_image, cv2.COLOR_BGR2RGB))
text = pytesseract.image_to_string(cropped_image_pil, lang='eng')
return text
@bot.event
async def on_message(message):
if message.author == bot.user:
return
logging.debug(f'Message ID: {message.id} Content: {message.content}')
logging.debug(f'Embeds: {message.embeds}')
logging.debug(f'Attachments: {message.attachments}')
logging.debug(f'Content: {message.content}')
if message.attachments:
for attachment in message.attachments:
if attachment.filename.endswith(('.png', '.jpg', '.jpeg', '.gif')):
template_image_path = 'apple_template.png'
image_bytes = await attachment.read()
recognized_text = find_apple_and_crop(image_bytes, template_image_path)
await message.channel.send(f'Recognized text: {recognized_text}')
await bot.process_commands(message)
async def fetch_attachments(channel_id, limit=20):
channel = bot.get_channel(channel_id)
if not channel:
print(f"Channel with ID {channel_id} not found.")
return
async for message in channel.history(limit=limit):
logging.debug(f'Message ID: {message.id} Content: {message.content}')
logging.debug(f'Embeds: {message.embeds}')
logging.debug(f'Attachments: {message.attachments}')
for attachment in message.attachments:
if attachment.filename.endswith(('.png', '.jpg', '.jpeg', '.gif')):
async with aiohttp.ClientSession() as session:
async with session.get(attachment.url) as resp:
if resp.status == 200:
image_bytes = await resp.read()
template_image_path = 'apple_template.png'
recognized_text = find_apple_and_crop(image_bytes, template_image_path)
await channel.send(f'Recognized text: {recognized_text}')
@bot.event
async def on_ready():
print(f'Logged in as {bot.user}')
channel_id = 1207841341149683764
bot.loop.create_task(fetch_attachments(channel_id, limit=20))
bot.run('YOUR_DISCORD_BOT_TOKEN'
Can anyone help me understand why this is happening and how to fix it?
I also checked to see if images were attached elsewhere, and I created a code that retrieves all messages from the channel as soon as it connects to check for them.
I'm working on a Discord bot using Discord.pythat processes image attachments in messages. The bot is supposed to read the attachments and recognize text from them using pytesseract. However, my logs show that all attachments are empty even though there are image files attached to messages.
Here's the relevant part of my code:
import discord
import cv2
import numpy as np
from PIL import Image
import pytesseract
from discord.ext import commands
import aiohttp
import logging
logging.basicConfig(level=logging.DEBUG)
intents = discord.Intents.default()
intents.messages = True
bot = commands.Bot(command_prefix="!", intents=intents)
def find_apple_and_crop(image_bytes, template_image_path):
input_image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
template_image = cv2.imread(template_image_path, cv2.IMREAD_GRAYSCALE)
gray_input_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)
result = cv2.matchTemplate(gray_input_image, template_image, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
top_left = max_loc
height, width = template_image.shape
bottom_right = (top_left[0] + width, top_left[1] + height)
cropped_image = input_image[top_left[1]:bottom_right[1], top_left[0]:bottom_right[0]]
cropped_image_pil = Image.fromarray(cv2.cvtColor(cropped_image, cv2.COLOR_BGR2RGB))
text = pytesseract.image_to_string(cropped_image_pil, lang='eng')
return text
@bot.event
async def on_message(message):
if message.author == bot.user:
return
logging.debug(f'Message ID: {message.id} Content: {message.content}')
logging.debug(f'Embeds: {message.embeds}')
logging.debug(f'Attachments: {message.attachments}')
logging.debug(f'Content: {message.content}')
if message.attachments:
for attachment in message.attachments:
if attachment.filename.endswith(('.png', '.jpg', '.jpeg', '.gif')):
template_image_path = 'apple_template.png'
image_bytes = await attachment.read()
recognized_text = find_apple_and_crop(image_bytes, template_image_path)
await message.channel.send(f'Recognized text: {recognized_text}')
await bot.process_commands(message)
async def fetch_attachments(channel_id, limit=20):
channel = bot.get_channel(channel_id)
if not channel:
print(f"Channel with ID {channel_id} not found.")
return
async for message in channel.history(limit=limit):
logging.debug(f'Message ID: {message.id} Content: {message.content}')
logging.debug(f'Embeds: {message.embeds}')
logging.debug(f'Attachments: {message.attachments}')
for attachment in message.attachments:
if attachment.filename.endswith(('.png', '.jpg', '.jpeg', '.gif')):
async with aiohttp.ClientSession() as session:
async with session.get(attachment.url) as resp:
if resp.status == 200:
image_bytes = await resp.read()
template_image_path = 'apple_template.png'
recognized_text = find_apple_and_crop(image_bytes, template_image_path)
await channel.send(f'Recognized text: {recognized_text}')
@bot.event
async def on_ready():
print(f'Logged in as {bot.user}')
channel_id = 1207841341149683764
bot.loop.create_task(fetch_attachments(channel_id, limit=20))
bot.run('YOUR_DISCORD_BOT_TOKEN'
Can anyone help me understand why this is happening and how to fix it?
I also checked to see if images were attached elsewhere, and I created a code that retrieves all messages from the channel as soon as it connects to check for them.
You need the message_content
intent to receive attachments, as the discord.py docs for Message.attachments
state:
attachments
A list of attachments given to a message. If
Intents.message_content
is not enabled this will always be an empty list unless the bot is mentioned or the message is a direct message.
intents = discord.Intents.default()
intents.message_content = True
You also need to turn on the "Message Content Intent" in the Discord Developer Portal for your app.