Chain对象

# 简介

Chain 对象是构建你的消息体的类。任何有关发送消息的函数,消息接受的参数类型均为 Chain
相信在之前的章节里,你已经见过它了。Chain 对象提供丰富的消息构建方式,可以让你发送多彩的文字图片,甚至是html模板。
这是最简单的一条文本消息:

Chain(data).text('你好,世界')

# 实例化参数

任何时候,Chain 对象都需要传入 Message 对象 以实例化。

参数名 类型 释义 默认值
data Message Message 对象
at Bool 是否 @ 用户 True
quote Bool 是否回复用户(引用消息) False

提示

在之前和以后的章节里,为了达到更好的演示效果,对话示例图内的消息回复均会设置 quote=True, at=False

# Chain 构建消息的方法

Chain 对象支持链式语法,用于构建复杂的消息结构。以下方法均返回 Chain 对象自身。

方法名 参数 释义 异步
at user,enter 添加 @ 一个用户
text text,enter,auto_convert 添加一段文字
text_image text,images,width,height 添加一张文字图片
image target 添加一张图片
voice target 添加一条语音
html path,data,is_template,render_time 使用 html 页面生成一张图片

# Chain.at

添加 @ 一个用户

参数名 类型 释义 默认值
user Int @ 的用户QQ号,默认为 Message 对象的用户
enter Bool 是否 @ 用户后换行 False
Chain(data).at(12345678).text('你好,世界')

Chain 对象在实例化的时候,默认会在消息体头部添加 @用户

# Chain.text

添加一段文字

参数名 类型 释义 默认值
text String 内容文本
enter Bool 本段落是否换行 False
auto_convert Bool 是否超出字数后转换为图片 True
Chain(data).text('你好,世界')

当文字数量超过一定长度时(默认配置为 100),会自动将本段落转换为图片发送,设置 auto_convert=False 可关闭自动转换。

插入表情

在文本内使用 [face:ID] 模板可以插入 QQ 表情。

Chain(data).text('你好,世界 [face:21]')

# Chain.text_image

添加一张文字图片

参数名 类型 释义 默认值
text String 内容文本
images List[ImageElem] 插入图片 None
width Int 图片宽度 None
height Int 图片高度 None
Chain(data).text_image('你好,世界')

此方法可以将文字转换为图片发送,使用调色模板可以进行文字调色,亦可插入图片渲染。

# 调色模板

在文本内使用 [cl 文字内容@#颜色代码 cle] 格式的模板,即可将指定文字内容改变颜色。

简单尝试一下,再继续运用前一节示例一的内容,让 世界 两个字变为红色






 

from core import bot, Message, Chain


@bot.on_group_message(keywords='你好')
async def _(data: Message):
    return Chain(data).text_image('你好,[cl 世界@#ff0000 cle]')
1
2
3
4
5
6

你可以收到如下的回复

hello_world_5

text_image 无法插入表情

如果 Chain.text 的文本内使用了调色模板,将会强制转换为图片。同时 [face:ID] 模板也会失效。

# 渲染图片

在 images 参数内传入一个包含 ImageElem 对象的列表,即可在文字图片内渲染图片。

ImageElem

参数名 类型 释义 默认值
path String 图片路径
size Int 图片大小
pos (Int, Int) 图片渲染位置 (x, y)

简单尝试一下,发送一张 你好,世界 的文字图片,并在里面插入一张图片。
值得注意的是,因为 你好,世界 文字只有一行,所以需要指定一下图片高度。否则插入的图片可能会显示不全。
你可以一次插入很多张图片,所以任何时候,都请把握好你的文字图片宽高与插入的图片的大小、坐标之间的影响。


 





 


 
 

from core import bot, Message, Chain
from core.builtin.imageCreator import ImageElem


@bot.on_group_message(keywords='你好')
async def _(data: Message):

    image = ImageElem(path='resource/images/face/face1.png', size=80, pos=(0, 20))

    return Chain(data).text_image('你好,世界',
                                  images=[image],
                                  height=100)
1
2
3
4
5
6
7
8
9
10
11
12

你可以收到如下的回复

hello_world_6

# Chain.image

添加一张图片

参数名 类型 释义 默认值
target String, Bytes 图片文件路径或图片 bytes
Chain(data).image(target)

图片路径示例






 

from core import bot, Message, Chain


@bot.on_group_message(keywords='你好')
async def _(data: Message):
    return Chain(data).image('resource/images/face/face1.png')
1
2
3
4
5
6

你可以收到如下的回复

hello_world_7

Chain.image 也可以传入图片的 bytes 对象。
实时生成的图片或网络图片可以直接把 bytes 结果传入 Chain.image 以节省 IO 消耗。


 





 



from core import bot, Message, Chain
from core.network.download import download_async


@bot.on_group_message(keywords='你好')
async def _(data: Message):

    web_image = await download_async('https://....')

    return Chain(data).image(web_image)
1
2
3
4
5
6
7
8
9
10

# Chain.voice

添加一条语音

参数名 类型 释义 默认值
target String 语音 wav 文件路径
Chain(data).voice(target)

注意

仅支持 wav 格式的语音文件






 

from core import bot, Message, Chain


@bot.on_group_message(keywords='你好')
async def _(data: Message):
    return Chain(data, at=False).voice('resource/voice/阿米娅/阿米娅_问候.wav')
1
2
3
4
5
6
hello_world_8

# Chain.html

使用 html 页面生成一张图片

参数名 类型 释义 默认值
path String 模板文件路径或网站URL
data Dict, List 模板文件数据
is_template Bool 是否为模板文件 True
render_time Int 渲染时间(毫秒) 200
Chain(data).html('template.html', {...})

# 创建html模板文件

html模板文件存放在 template 目录下,参数 path 默认以该文件夹作为根目录。
template 目录内创建一个 hello.html



 

.
└── template
    └── hello.html
1
2
3

编写如下标准模板内容

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!-- 引入字体样式 -->
    <link type="text/css" rel="styleSheet" href="../font.css"/>
    <title>template</title>
</head>
<body>
<div id="template">

</div>
</body>
<!-- 引入 vue.js -->
<script src="../vue.min.js"></script>
<script>
    const template = new Vue({
        el: '#template',
        methods: {
            init(data) {
                this.$set(this, 'data', data)
            }
        },
        data() {
            return {
                data: {}
            }
        },
        mounted() {
            // 暴露 init 方法供核心调用
            window.init = this.init
        }
    })
</script>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# Vue.js

模板文件建议使用 Vue.js (opens new window) (以下简称 vue) 编写,vue 将有效提高模板渲染速度以及代码可读性,以下文档将使用 vue 进行讲解,并默认你熟悉使用 vue 开发

编写模板,在模板内加入渲染代码

<!-- hello.html -->
<div id="template">
    <div>你好,{{ data.username }}</div>
</div>
1
2
3
4

将需要渲染的数据传入模板









 

from core import bot, Message, Chain


@bot.on_group_message(keywords='你好')
async def _(data: Message):
    init_data = {
        'username': data.nickname
    }
    return Chain(data).html('hello.html', init_data)
1
2
3
4
5
6
7
8
9

即可在触发会话时,渲染 hello.html 制作图片发送回复。

关于

html 制图旨在不使用 PIL 也能制作出美观的图片,但不希望你滥用。在仅渲染文字和少量图案时,PIL 的效率会比 html 快得多。

# 通过网站URL制图

支持直接使用网站URL生成图片

注意

在页面加载完毕后,默认预留200ms的渲染时间。如果页面有部分元素是异步渲染的,将有可能不显示在图片内。可通过参数 render_time 设置需要的时间。






 

from core import bot, Message, Chain


@bot.on_group_message(keywords='百度')
async def _(data: Message):
    return Chain(data).html('https://www.baidu.com/', is_template=False, render_time=1000)
1
2
3
4
5
6

# 消息链

Chain 对象支持链式语法,你只需要按顺序以链式使用上述方法,即可拼接出内容丰富的消息。

Chain(data).text(...).image(...).text(...).voice(...).html(...)

其中,voice 方法并不参与构建消息体,因为 QQ 无法在发送的文字消息中间镶嵌语音,语音将会单独发送。

# 自定义的消息对象

Chain 对象所接受的参数 data 是函数接收的 Message 对象,实例化一个自定义的 Message 对象可以让消息发送到预期的位置。messageChain 模块提供了工具函数实现这一效果。

custom_chain

custom_chain 函数返回 Chain 对象。你可以按照 Chain 对象的操作方式对 custom_chain 的返回值做操作。

参数名 类型 释义 默认值
user_id Int 模拟的用户 QQ 号
group_id Int 模拟的群号
msg_type String 消息类型 group

注意

以下的示例将展示使用 custom_chain 实现跨群发送消息的效果,仅用于演示。实际情况请谨慎使用。


 




 

from core import bot, Message, Chain
from core.builtin.messageChain import custom_chain


@bot.on_group_message(keywords='你好')
async def _(data: Message):
    return custom_chain(user_id=目标用户, group_id=目标群号).text('你好,世界')
1
2
3
4
5
6
7

# 向管理员们发送消息

上下文管理函数 send_to_admin

向所有配置中授权的管理员发送私聊消息,该操作不限定使用的位置,可以在任何地方使用。

 



 


from core import websocket


async def _():
    async with websocket.send_to_admin() as chain:
        chain.text(...)
1
2
3
4
5
6

# 结语

完成这一节,你已经完全了解 AmiyaBot 开发功能时的主要内容了。AmiyaBot 内置了很多工具函数,但即使没有它们,依然不影响你独立完成功能开发。
工具函数以及其他细节的介绍可以返回文档首页查看索引。

上次更新: 12/14/2022, 12:49:25 PM