You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在discord.py中将用户提及转换为服务器昵称?

解决Discord消息中用户提及ID转服务器昵称的问题

我为Discord服务器做了一个自定义推特推送功能,目前功能正常,但有个问题:用户消息里提及他人时,文本会以<@1234...>的ID格式显示,我想把它替换成被提及用户的服务器昵称。下面是我写在cog里的代码:

import discord
from discord.ext import commands
from PIL import Image, ImageDraw, ImageFont, ImageOps
import aiohttp
import textwrap
from textwrap import wrap
import datetime
from datetime import datetime, timedelta
import asyncio
import json
import pytz

...

@commands.Cog.listener()
async def on_message(self, message):
    nickname = message.author.nick
    if nickname is None: 
      nickname = message.author.name 
    if message.author.bot:
      return
    elif message.channel.id == 1065325485506170891:
      await message.delete()
      avatar_url = str(message.author.avatar.url)
      async with self.session.get(avatar_url) as resp:
        avatar_data = await resp.read()
      with open("pfp.png", "wb") as f:
        f.write(avatar_data)
      pfp = Image.open("pfp.png").convert("RGBA")
      size = (75, 75)
      mask = Image.new("L", size, 0)
      draw = ImageDraw.Draw(mask)
      draw.ellipse((0, 0) + size, fill=255)
      pfp = ImageOps.fit(pfp, mask.size, centering=(0.5,0.5))
      pfp.putalpha(mask)
      pfp = pfp.resize(size, Image.LANCZOS)
      img = Image.open('Tweet_Template.png') 
      draw = ImageDraw.Draw(img)
      img.paste(pfp, (15, 70), pfp)
      font2 = ImageFont.truetype('cogs/Cantarell-Regular.ttf', 20)
      font5 = ImageFont.truetype('cogs/Cantarell-Bold.ttf', 20)
      draw = ImageDraw.Draw(img)
      message_tweet = str(message.content)
      if message.attachments:
        wrapped = textwrap.wrap(message_tweet, width=40)
      else:
        wrapped = textwrap.wrap(message_tweet, width= 60)
      wrapped_message = '\n'.join(wrapped)
      draw.text((90, 140), wrapped_message, box_width=50, fill='black',font=font2)
      draw.text((111, 111), message.author.name, fill='gray', font=font2)
      draw.text((95, 85), nickname, fill='black', font=font5)
      timezone = pytz.timezone('America/New_York')
      timestamp = datetime.now()
      est = str(timestamp.astimezone(timezone).strftime("%I:%M:%S %p EST • %B %d"))
      draw.text((20, 230), est, fill='gray', font=font2)
      if message.attachments:
        attachment = message.attachments[0]
        url = attachment.url
        async with self.session.get(url) as resp:
          attachment_data = await resp.read()
        with open("attachment.png", "wb") as f:
          f.write(attachment_data)     
        attachment = Image.open("attachment.png")
        attachment = attachment.resize((200, 175), Image.LANCZOS)
        img.paste(attachment, (400, 75), attachment)
      img.save('Tweet.png')
      react_here = await message.channel.send(file=discord.File('Tweet.png'))
      await react_here.add_reaction("❤️")
      await react_here.add_reaction("↪️")

...

我尝试过使用member.guild.name属性,但不确定该放在哪里才能生效,也试过使用.replace方法,但都没有成功。


解决方案

核心逻辑是遍历消息中的被提及成员对象,将ID格式的提及字符串替换为对应的服务器昵称,具体修改如下:

1. 添加提及替换代码

在获取message_tweet = str(message.content)之后,插入以下代码:

message_tweet = str(message.content)
# 遍历所有被提及的成员,替换ID格式为昵称
for member in message.mentions:
    # 优先用服务器昵称,没有则用用户名
    mention_name = member.nick if member.nick else member.name
    # 处理两种提及格式:普通提及<@ID> 和 带昵称的提及<@!ID>
    message_tweet = message_tweet.replace(f'<@{member.id}>', mention_name)
    message_tweet = message_tweet.replace(f'<@!{member.id}>', mention_name)

2. 修改后的完整代码片段

...
draw = ImageDraw.Draw(img)
message_tweet = str(message.content)
# 新增:替换用户提及为服务器昵称
for member in message.mentions:
    mention_name = member.nick if member.nick else member.name
    message_tweet = message_tweet.replace(f'<@{member.id}>', mention_name)
    message_tweet = message_tweet.replace(f'<@!{member.id}>', mention_name)
if message.attachments:
    wrapped = textwrap.wrap(message_tweet, width=40)
else:
    wrapped = textwrap.wrap(message_tweet, width= 60)
wrapped_message = '\n'.join(wrapped)
draw.text((90, 140), wrapped_message, box_width=50, fill='black',font=font2)
...

说明

  • message.mentions会返回消息中所有被@的成员对象,直接从对象中获取nick(服务器昵称)或name(账号用户名)即可
  • Discord有两种提及格式:普通提及是<@用户ID>,针对设置了服务器昵称的用户会显示为<@!用户ID>,所以两种格式都需要替换

内容的提问来源于stack exchange,提问作者Ethan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 05:07:45