跳转至

格式化、颜色和 CDN URL

三个小模块负责构建 Discord 会渲染的文本和 URL:bostie.fmt 用于 Markdown、提及和时间戳,bostie.color 用于颜色,bostie.cdn 用于图片 URL。

from datetime import UTC, datetime, timedelta

import bostie
from bostie import AllowedMentions, Context, Embed, EmbedMedia, User, cdn, color, fmt

bot = bostie.Bot()


@bot.user_command("Profile card")
async def profile_card(ctx: Context, user: User) -> None:
    created = user.created_at
    banner = None
    if user.banner is not None:
        banner = EmbedMedia(url=cdn.user_banner(user.id, user.banner, size=1024))
    embed = Embed(
        title=fmt.escape_markdown(user.display_name),
        description=f"Joined Discord {fmt.timestamp(created, 'R')}",
        color=color.hsv(user.id % 360 / 360, 0.6, 0.9),
        thumbnail=EmbedMedia(url=cdn.display_avatar(user, size=256)),
        image=banner,
    )
    await ctx.respond(embeds=[embed], ephemeral=True)


@bot.command
async def remind(ctx: Context, text: str, minutes: int = 10) -> None:
    """Show a reminder time in everyone's own time zone."""
    due = datetime.now(UTC) + timedelta(minutes=minutes)
    safe = fmt.escape_mentions(text)
    await ctx.respond(
        f"{fmt.user(ctx.user.id)}: {safe} at {fmt.timestamp(due, 't')}",
        allowed_mentions=AllowedMentions(users=(ctx.user.id,)),
    )
函数 返回 Discord 显示为
fmt.user(user_id) <@id> 该用户,并通知对方
fmt.role(role_id) <@&id> 该身份组,并通知其成员
fmt.channel(channel_id) <#id> 指向该频道的链接
fmt.command(name, command_id) </name:id> 一个可点击的命令;name 可以包含命令组和子命令
fmt.emoji(name, emoji_id, animated=False) <:name:id> 一个自定义表情符号
fmt.game_profile(game_id) <@$id> 一个游戏资料
fmt.timestamp(when, style=None) <t:seconds:style> 按每位读者自己的时区和语言显示的时间
fmt.guild_navigation(kind, role_id=None) <id:kind> 指向服务器某个标签页的链接:"customize"、"browse"、"guide" 或 "linked-roles";只有 "linked-roles" 接受身份组
fmt.store(application_id, sku_id=None) 一个商店 URL 应用的商店页面或某个 SKU,显示为一张卡片

fmt.timestamp 接受 datetime 或 Unix 秒数。它的样式与 Discord 一致:"t" 16:20,"T" 16:20:30,"d" 20/04/2021,"D" April 20, 2021,"f" April 20, 2021 at 16:20(未指定样式时 Discord 的默认样式),"F" 在此基础上加上星期,"s" 20/04/2021, 16:20,"S" 再加上秒,"R" 为相对时间,例如“in 5 minutes”。模型上的 user.mention、role.mention 和 channel.mention 与这些提及函数给出的文本相同,bot.command_mention 会替你查找命令的 ID(注册命令)。

来自用户的文本

  • fmt.escape_markdown(text) 让 Markdown 按输入的原样显示,同时保持链接可用。
  • fmt.remove_markdown(text) 去除 Markdown。
  • fmt.escape_mentions(text) 通过插入零宽空格,破坏 @everyone、@here 以及用户和身份组的提及,使其无法发出通知。
  • fmt.mentioned_users(text)、fmt.mentioned_roles(text) 和 fmt.mentioned_channels(text) 返回文本中提及的 ID。

转义只是一层防护;无论文本写了什么,最终由 allowed_mentions 决定哪些提及能发出通知。

颜色

bostie.color 以 int 形式提供 Discord 的品牌色:BLURPLE、GREEN、YELLOW、FUCHSIA 和 RED。color.rgb(red, green, blue) 接受三个 0 到 255 的值,color.hsv(hue, saturation, value) 接受三个 0 到 1 的值,color.parse("#5865F2") 读取六位十六进制数字,可以带 #、0x 前缀,也可以都不带。嵌入内容的 color、容器的 accent_color 以及身份组都接受这些值。

CDN URL

bostie.cdn 用于构建 Discord 所存储图片的 URL。每个函数都接受模型中的 ID 和图片哈希,以及 size(16 到 4096 之间的 2 的幂)和 format("png"、"jpg"、"jpeg"、"webp"(默认)或 "gif" 之一)。哈希以 a_ 开头的动态图片在 WebP 或 GIF 格式下仍保持动态;对静态图片使用 "gif",或使用不在列表中的尺寸,会引发 ValueError。await bot.http.read(url) 可以下载图片,REST 指南中有说明。

函数 图片
display_avatar(user) 用户的头像,没有头像时为默认头像
user_avatar(user_id, avatar)、default_avatar(user_id) 用户自己的头像或默认头像
user_banner(user_id, banner)、avatar_decoration(asset) 用户的横幅和头像装饰
member_avatar(guild_id, user_id, avatar)、member_banner(...) 成员在服务器中专用的头像和横幅
guild_icon、guild_splash、guild_discovery_splash、guild_banner 服务器的各种图片,由 guild_id 和哈希构建
guild_tag_badge(guild_id, badge) 服务器标签的徽章
role_icon(role_id, icon) 身份组的图标
emoji(emoji_id, animated=False) 自定义表情符号
sticker(sticker_id, format_type) 贴纸,按其格式类型为 PNG、Lottie JSON 或 GIF
sticker_pack_banner(banner_asset_id) 贴纸包的横幅
scheduled_event_cover(event_id, image) 服务器活动的封面
application_icon、application_cover、application_asset、store_page_asset 应用的图标、封面、Rich Presence 素材和商店图片
team_icon(team_id, icon) 团队的图标
soundboard_sound(sound_id) 音效板音效的音频