Skip to main content

NoneBot2 米游社大别野 Bot 适配器。MiHoYo Villa Bot adapter for nonebot2.

Project description

nonebot-adapter-villa

NoneBot-Adapter-Villa

✨ 大别野 协议适配 ✨

license version python pypi download wakatime ruff

安装

nb create 创建项目时选择 Villa 适配器

或在现有 NoneBot2 项目目录下使用脚手架安装:

nb adapter install nonebot-adapter-villa

配置

修改 NoneBot 配置文件 .env 或者 .env.*

配置 Bot 帐号列表,每个 bot 有 3 个必填配置,可前往「大别野开放平台」申请,取得以下配置:

  • bot_id: 机器人 id,以bot_开头
  • bot_secret: 机器人密钥
  • pub_key: 加密和验证所需的 pub_key (请使用开放平台中的复制按钮而不是手动复制)
  • test_villa_id: Bot 未上线时填写调试别野的 id,已上线可不填或填 0

此外,还要根据连接方式填写额外配置:

  • connection_type: 连接方式,填写 webhookwebsocket,默认为 webhook

Webhook 连接

  • callback_url: http 回调地址 endpoint,例如开放平台中回调地址是http://域名/your/callback/url,那么配置里的 callback_url 填写 /your/callback/url
  • verify_event:是否对回调事件签名进行验证,默认为 True

使用 webhook 方式连接时,驱动器需要 ReverseDriverForwardDriver,参考 driver 配置项。

webhook 配置完整示例:

DRIVER=~fastapi+~httpx
VILLA_BOTS='
[
  {
    "bot_id": "bot_123456789",
    "bot_secret": "abc123def456",
    "pub_key": "-----BEGIN PUBLIC KEY-----\nyour_pub_key\n-----END PUBLIC KEY-----\n",
    "connection_type": "webhook",
    "callback_url": "/your/callback/url",
    "verify_event": true
  }
]
'

Websocket 连接 (官方测试中)

使用 websocket 方式连接时,驱动器需要 ForwardDriver,参考 driver 配置项。

websocket 配置完整示例:

DRIVER=~httpx+~websockets
VILLA_BOTS='
[
  {
    "bot_id": "bot_123456789",
    "bot_secret": "abc123def456",
    "pub_key": "-----BEGIN PUBLIC KEY-----\nyour_pub_key\n-----END PUBLIC KEY-----\n",
    "connection_type": "websocket",
    "test_villa_id": 0
  }
]
'

已支持消息段

  • MessageSegment.text: 纯文本
    • 米游社自带表情也是用text来发送,以[表情名]格式,例如:MessageSegment.text("[爱心]")
    • 支持样式,,可叠加:
      • bold: 加粗
      • italic: 斜体
      • underline: 下划线
      • strikethrough: 删除线
    • 例如:MessageSegment.text("加粗", blod=True) + MessageSegment.text("斜体", italic=True)
  • MessageSegment.mention_robot: @机器人
  • MessageSegment.mention_user: @用户
    • user_namevilla_id 必须给出其中之一,给 villa_id 时,调用 api 来获取用户名
  • MessageSegment.mention_all: @全体成员
  • MessageSegment.room_link: #房间跳转链接
  • MessageSegment.link: 超链接
    • 使用 link 的话链接能够点击进行跳转,使用 text 的话不能点击
    • 字段 show_text 是指链接显示的文字,但若指定了该字段,Web 端大别野会无法正常跳转
    • 字段 requires_bot_access_token 为 True 时,跳转链接会带上含有用户信息的 token
  • MessageSegment.quote: 引用(回复)消息
    • 不能单独使用,要与其他消息段一起使用
  • MessageSegment.image: URL 图片
    • 图片 url 需为米哈游官方图床 url
    • 非官方图床 url 可以通过 Bot.transfer_image 接口转换为官方图床 url
    • 本地图片可以通过 Bot.upload_image 接口来上传图片,使用返回结果的 url 来发送
    • 一条消息只能发送一张图片,多张图片拼接时,只会发送最后一张
    • 与其他消息段拼接时,将无法在 web 端显示出来
  • MessageSegment.post: 米游社帖子
    • 只能单独发送,与其他消息段拼接时将会被忽略
  • MessageSegment.preview_link: 预览链接(卡片)
    • 该消息段未在官方文档公开
    • 无法在 web 端显示出来
  • MessageSegment.badge: 消息徽标(消息下方的可链接跳转的下标)
    • 该消息段未在官方文档公开
    • 不能单独使用,要与其他消息段一起使用
    • 无法在 web 端显示出来
  • 消息组件,有两种构造方式:
    • MessageSegment.components:传入若干个 component,适配器会自动根据组件显示的文本长度来计算组件面板布局(推荐)
    • MessageSegment.panel:传入一个组件模板 ID 或自己构造好的自定义组件面板布局 Panel 对象

以下是一个简单的插件示例,展示各种消息段:

from nonebot import on_command
from nonebot.params import CommandArg
from nonebot.adapters.villa import MessageSegment, SendMessageEvent, Message

matcher = on_command("test")


@matcher.handle()
async def _(event: SendMessageEvent, args: Message = CommandArg()):
    arg = args.extract_plain_text().strip()
    if arg == "纯文本":
        msg = MessageSegment.text(text="这是一段纯文本")
    elif arg == "艾特bot":
        msg = MessageSegment.mention_robot(
            bot_id=event.robot.template.id, bot_name=event.robot.template.name
        )
    elif arg == "艾特我":
        msg = MessageSegment.mention_user(
            user_id=event.from_user_id, villa_id=event.villa_id
        )
    elif arg == "艾特全体":
        msg = MessageSegment.mention_all()
    elif arg == "房间链接":
        msg = MessageSegment.room_link(villa_id=event.villa_id, room_id=event.room_id)
    elif arg == "超链接":
        msg = MessageSegment.link(
            url="https://www.baidu.com", show_text="百度", requires_bot_access_token=False
        )
    elif arg == "引用消息":
        msg = MessageSegment.quote(event.msg_uid, event.send_at) + MessageSegment.text(
            text="引用原消息"
        )
    elif arg == "图片":
        msg = MessageSegment.image(
            url="https://www.miyoushe.com/_nuxt/img/miHoYo_Game.2457753.png"
        )
    elif arg == "帖子":
        msg = MessageSegment.post(
            post_id="https://www.miyoushe.com/ys/article/40391314"
        )
    elif arg == "预览链接":
        msg = MessageSegment.preview_link(
            icon_url="https://www.bilibili.com/favicon.ico",
            image_url="https://i2.hdslb.com/bfs/archive/21b82856df6b8a2ae759dddac66e2c79d41fe6bc.jpg@672w_378h_1c_!web-home-common-cover.avif",
            is_internal_link=False,
            title="崩坏3第一偶像爱酱",
            content="「海的女儿」——《崩坏3》S级律者角色「死生之律者」宣传PV",
            url="https://www.bilibili.com/video/BV1Mh4y1M79t?spm_id_from=333.1007.tianma.2-2-5.click",
            source_name="哔哩哔哩",
        )
    elif arg == "徽标消息":
        msg = MessageSegment.badge(
            icon_url="https://upload-bbs.mihoyo.com/vila_bot/bbs_origin_badge.png",
            text="徽标",
            url="https://mihoyo.com",
        ) + MessageSegment.text(text="带有徽标的消息")
    else:
        return

    await matcher.finish(msg)

使用命令@bot /test 纯文本时,bot会回复这是一段纯文本

关于消息组件的详细介绍:

from nonebot.adapters.villa.message import MessageSegment
from nonebot.adapters.villa.models import CallbackButton, InputButton, LinkButton, Panel

# 目前有三种按钮组件,每个组件都必须有 id 和 text 字段
# id字段用于标识组件,必须是唯一的,text字段用于显示组件的文本
# need_callback字段如果设为True,表示点击按钮后会触发ClickMsgComponentEvent事件回调
# extra字段用于开发者自定义,可以在事件回调中获取到

# 文本按钮
# 用户点击后,会将按钮的 input 字段内容填充到用户的输入框中
input_button = InputButton(
    id="1",
    text="文本按钮",
    input="/文本",
)

# 回调按钮
# need_callback恒为True,点击按钮后会触发ClickMsgComponentEvent事件回调
callback_button = CallbackButton(
    id="2",
    text="回调按钮",
)

# 链接按钮
# 用户点击后,会跳转到按钮的 link 字段所指定的链接
# need_token字段为True时,会在链接中附带token参数,用于验证用户身份
link_button = LinkButton(
    id="3",
    text="链接按钮",
    link="https://www.baidu.com",
    need_token=True,
)

# 构造消息段
com_msg = MessageSegment.components(
    input_button,
    callback_button,
    link_button,
)

# 适配器会自动根据每个组件的text字段的长度,自动调整按钮的排版
# 如果需要自定义排版,可以使用MessageSegment.panel方法
# 自己构造好Panel对象,传入
panel = Panel(mid_component_group_list=[[input_button, callback_button], [link_button]])
com_msg = MessageSegment.panel(panel)

# 如果有预先设置好的消息组件模板 ID,可以直接使用
template_id = 123456
com_msg = MessageSegment.panel(template_id)
# 模板通过 Bot.create_component_template 接口来创建

# 如果有多个 MessageSegment.panel 相加,则只会发送最后一个

交流、建议和反馈

如遇问题请提出 issue ,感谢支持!

欢迎来开发者的大别野「尘世闲游」(ID: wgiJNaU)进行交流~

相关项目

  • NoneBot2: 非常好用的 Python 跨平台机器人框架!
  • villa-py: 大别野 Bot Python SDK(暂时停更)。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nonebot_adapter_villa-1.4.2.tar.gz (37.4 kB view hashes)

Uploaded Source

Built Distribution

nonebot_adapter_villa-1.4.2-py3-none-any.whl (38.9 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page