• 欢迎来到小可 · Wiki,人人可编辑的,多平台聊天机器人“小可”的官方文档资源。
  • 小可很可爱,请给我们打钱
  • 原 MkDocs 已迁入本站。若发现 404 属正常现象,请点击左上角搜索您想要的模块。

新建模块指南:修订间差异

来自小可 · Wiki,人人可编辑的,QQ机器人“小可”的官方文档资源
→‎处理消息:​ fk
标签2017年版源代码编辑
无编辑摘要
 
(未显示3个用户的26个中间版本)
第1行: 第1行:
<del>不 吧不会吧,真的会有人来给屎山 写模块 吗(</del>
本文将 教你如何编 自定义 模块
 


== 说明 ==
== 说明 ==
 
 所有模块 储存在 <code>./modules/</code> 文件夹。如果你想编写新的模块,请在 新建一个文件夹。
  我们将 所有模块储存在 <code>modules</code>文件夹。如果你想编写新的模块,请在 里面 新建一个文件夹。


 文件夹的名字并不用于区分模块名,仅用于分类。
 文件夹的名字并不用于区分模块名,仅用于分类。


 机器人在加载的时候会遍历<code>modules</code>文件夹,并加载每个模块文件夹里的<code>__init__.py</code>,请将想要加入的模块定义编写在<code>__init__.py</code>中或确保其能够被引用。
 机器人在加载的时候会遍历 <code>./modules/</code> 文件夹,并加载每个模块文件夹里的 <code>__init__.py</code>,请将想要加入的模块定义编写在 <code>__init__.py</code> 中或确保其能够被引用。
 
当前可用的模块类型有<code>Command</code>(一般命令类型)、<code>Regex</code>(正则表达式类型)、<code>Schedule</code>(计划任务类型)、<code>StartUp</code>(自启类型)。
 


== 编写 ==
== 编写 ==
 我们假设你现在写好了具体的 业务 代码,现在你想把其做成一个可以给机器人使用的功能:
 我们假设你现在写好了具体的代码,现在你想把其做成一个可以给机器人使用的功能:


=== 定义模块 ===
=== 定义模块 ===
 编写模块之前,我们需要先定义一个模块类型。
  编写模块之前,我们需要先定义一个模块类型。


'''此定义方式目前仅支持<code>Command</code>和<code>Regex</code>模块,<code>Schedule</code>和<code>StartUp</code>请见下文的“旧版”'''
注:Regex同理。
==== Command ====
<syntaxhighlight lang="python3">
<syntaxhighlight lang="python3">
from core.component import on_command
from core.component import module


test = on_command(
test = module(
    bind_prefix='test', # 定义模块名
    bind_prefix='test1', # 定义模块名
    desc=' 啊吧啊吧啊吧', # 此模块的简介
    desc=' 这是一个简介', # 此模块的简介
    alias='m', # 此模块的别名 ,用法请见下文
    alias='t', # 此模块的别名
    developers=['OasisAkari', 'Dianliang233'], # 开发者的名字
    developers=['Example'], # 开发者的名字
    recommend_modules=['mcbv', 'mcdv']), # 推荐 打开 的其他模块,用于在 打开 此模块时进行一并提示
    recommend_modules=['test2', 'test3']), # 推荐 启用 的其他模块,用于在 启用 此模块时进行一并提示
    required_admin = False, # 将此模块标记为仅 群组 管理员可执行,覆盖下文所述的子命令设定,默认为False
    required_admin = False, # 将此模块标记为仅 对话 管理员可执行,覆盖下文所述的子命令设定,默认为False
    base = False, # 将此模块标记为基础模块,无需 打开 即可使用,默认为False
    base = False, # 将此模块标记为基础模块,无需 启用 即可使用,默认为False
    required_superuser = False # 将此模块标记为仅机器人超级管理员可使用,覆盖下文所述的子命令设定,默认为False
    required_superuser = False, # 将此模块标记为仅机器人超级管理员可使用,覆盖下文所述的子命令设定,默认为False
   support_languages=['zh_cn', 'zh_tw', 'en_us'] # 此模块支持的语言,未在列表内的语言在启用模块时会出现提醒
)
)
</syntaxhighlight>
</syntaxhighlight>
第41行: 第33行:
 现在你已经定义好了一个模块,现在你需要将你想要的东西绑定上去了。
 现在你已经定义好了一个模块,现在你需要将你想要的东西绑定上去了。


 在前文中,我们给<code>test</code>变量声明了定义,我们将围绕这个定义进行绑定子命令,为了使代码简洁,我们使用了装饰器:
 在前文中,我们给 <code>test</code> 变量声明了定义,我们将围绕这个定义进行绑定子命令,为了使代码简洁,我们使用了装饰器:


==== Command ====
==== Command (一般命令) ====
<syntaxhighlight lang="python3">
<syntaxhighlight lang="python3">
from core.elements import MessageSession
from core.builtins import Bot


@test.handle(help_doc='<args1>', # 设置此命令的语法,前缀匹配模块名,此处忽略。可 为list或tuple 来经手多条命令。可为空。
@test.command(help_doc='<args1>', # 设置此命令的语法,前缀匹配模块名,此处忽略。可 为 list 或 tuple  来经手多条命令。可为空。
        required_admin = False, # 将此命令标记为仅 群组 管理员可使用。
        required_admin = False, # 将此命令标记为仅 对话 管理员可使用。
        required_superuser = False, # 将此命令标记为进机器人超级管理员可使用。
        required_superuser = False, # 将此命令标记为进机器人超级管理员可使用。
        available_for = '*' # 控制此命令可被使用的消息来源,默认为 '*'(所有)
        available_for = '*' # 控制此命令可被使用的消息来源,默认为 '*'(所有)
        )
        )
async def _(msg: MessageSession):
async def _(msg: Bot.MessageSession):
    ...
    ...
</syntaxhighlight>
</syntaxhighlight>
  当help_doc 为空时,则代表此模块允许无需语法命令即可执行。如:使用~test命令(后面不带任何东西),即可触发装饰器下面的函数,否则会出现“语法错误”的提示。
  当 <code>help_doc</code>  为空时,则代表此模块允许无需语法命令即可执行。如:使用 <code>~test</code>  命令(后面不带任何东西),即可触发装饰器下面的函数,否则会出现“语法错误”的提示。


 与语法匹配的命令将会被切割存储 于msg.parsed_msg(dict类型)
 与语法匹配的命令将会被切割存储 于 <code>msg.parsed_msg</code> (dict 类型)


 如:{'<args1>': 'xxx'}
 如:<code>{'<args1>': 'xxx'}</code>


==== Regex ====
==== Regex (正则表达式) ====
<syntaxhighlight lang="python3">
<syntaxhighlight lang="python3">
from core.elements import MessageSession
from core.builtins import Bot


@test.handle(pattern=r'\[\[(.*?)]]', # 正则表达式语法
@test.regex(pattern=r'\[\[(.*?)]]', # 正则表达式语法
       mode='M', # 正则模式,设为'M'为匹配模式,'A'为匹配所有模式
       mode='M', # 正则模式,设为'M'为匹配模式,'A'为匹配所有模式
       flags=0, # 设置正则的flags,如Re.M|Re.I
       flags=0, # 设置正则的flags,如Re.M|Re.I
       show_typing=False #设置命令执行时是否展示输入提示(如戳一戳),默认为True
       show_typing=False #设置命令执行时是否展示输入提示(如戳一戳),默认为True
        )
        )
async def _(msg: MessageSession):
async def _(msg: Bot.MessageSession):
   ...
</syntaxhighlight>
 
与表达式匹配的命令结果将会存储于 <code>msg.matched_msg</code> 中。
 
当你输入的命令匹配 <code>help_doc</code> 内的语法时,机器人将会把消息传入装饰器下方的函数,然后你就可以进行发挥了。
 
==== Schedule(计划任务) ====
<syntaxhighlight lang="python3">
from core.builtins import Bot
from core.scheduler import CronTrigger
 
@test.schedule(trigger=CronTrigger.from_crontab('30 8 * * MON') # 触发此装饰器的条件)
async def _():
    ...
    ...
</syntaxhighlight>
</syntaxhighlight>


  与表达式匹配 命令结果 将会 存储于msg.matched_msg中。
==== FetchTarget ====
<syntaxhighlight lang="python3">
from core.builtins import Bot
...
await Bot.FetchTarget.post_message('test', '啊吧啊吧') # 向所有已开启 test 模块的用户推送消息。
sender = 'QQ|123456' # QQ号为123456 好友
fetch = Bot.FetchTarget.fetch_target(sender) # 获取信息
if fetch: #如获取到
   await fetch.sendMessage('xxx') # 发送消息
</syntaxhighlight>
 
主要用于从数据库中获取用户推送内容。
 
=== 通用装饰器 ===
 
假设你已经会使用了以上装饰器,而你又特别懒,则你可以使用通用装饰器来代替以上三种装饰器,此装饰器 将会 自动识别条件并归类函数。
 
<syntaxhighlight lang="python3">
from core.builtins import Bot
 
@test.handle('<args1>')
async def _(msg: Bot.MessageSession):
   ...
 
 
@test.handle(re.complie('(.*)'))
async def _(msg: Bot.MessageSession):
   ...
 


当你输入的命令匹配help_doc内的语法时,机器人将会把消息传入装饰器下方的函数,然后你就可以进行发挥了。
@test.handle(CronTrigger.from_crontab('30 8 * * MON'))
async def _():
   ...
</syntaxhighlight>


=== 处理消息 ===
=== 处理消息 ===
 我们在装饰器下方的函数定义了一 个msg 参数,发送消息将围绕它进行。
 我们在装饰器下方的函数定义了一 个 msg  参数,发送消息将围绕它进行。
 我们在此处仅展示基础方法,具体可用的操作请借 助ide 查看。
 我们在此处仅展示基础方法,具体可用的操作请借 助 IDE  查看。
<syntaxhighlight lang="python3">
<syntaxhighlight lang="python3">
...
...
send = await msg.sendMessage('你好') # 向发送对象发送一条消息
send = await msg.sendMessage('你好 ') # 向发送对象发送一条消息
send.delete() # 将这条消息删除
send.delete() # 将这条消息删除
...
...
confirm = await msg.waitConfirm(' 真的要这么做 吗?') # 在发送此消息后将暂停执行,等待用户的下一条消息
confirm = await msg.waitConfirm(' 你确定 吗?') # 在发送此消息后将暂停执行,等待用户的下一条消息
if confirm: # 用户发送了确认的词语
if confirm: # 用户发送了确认的词语
    ...
    ...


</syntaxhighlight>
</syntaxhighlight>
 发送的消息可以 为str 或装有消息组件 的list ,如:<code><nowiki>[Plain('今日 份的LittleC'), Image('https://github.com/komeiji-satori/Dress/raw/master/XxLittleCxX/0x01.jpg')]</nowiki></code> (被打
 发送的消息可以 为字符串 或装有消息组件 的列表 ,如:<code><nowiki>[Plain('今日 图片:'), Image('https://example.com/test.jpg')]</nowiki></code>


=== 消息来源 ===
=== 消息来源 ===
 目前可用的有<code>QQ|Group</code>(QQ群) <code>QQ</code>(QQ好友) <code>QQ|Guild</code>(QQ频道) <code>Discord|Channel</code>(Discord频道) <code>Discord|DM|Channel</code>(Discord私聊频道) <code>Telegram|private</code>(Telegram私聊) <code>Telegram|group</code>(Telegram群组) <code>Telegram|supergroup</code>(Telegram supergroup(?) <code>Telegram|channel</code>(Telegram频道) <code>TEST|Console</code> 控制台
 目前可用的 消息来源(对话) 以下几种:
* QQ
** <code>QQ|Group</code>(QQ
** <code>QQ</code>(QQ 好友)
** <code>QQ|Guild</code>(QQ 频道)
* Discord
** <code>Discord|Channel</code>(Discord 频道)
** <code>Discord|DM|Channel</code>(Discord 私聊频道)
* Telegram
** <code>Telegram|Private</code>(Telegram 私聊)
** <code>Telegram|Group</code>(Telegram 群组)
**<code>Telegram|Supergroup</code>(Telegram 超级群组
** <code>Telegram|Channel</code>(Telegram 频道)
* KOOK
** <code>KOOK|Group</code>(KOOK  频道)
* Matrix
** <code>Matrix|Room</code> (Matrix 聊天室)
* [[ 控制台]]
** <code>TEST|Console</code>


=== 消息组件 ===
=== 消息组件 ===
 目前可用的有<code>Plain</code>(文本)、<code>Image</code>(图片)、<code>Voice</code>(语音)
 目前 主要 可用的有<code>Plain</code>(文本)、<code>Image</code>(图片)、<code>Voice</code>(语音)


=== 别名 ===
=== 别名 ===
第103行: 第158行:
 当为<code>str</code>、<code>List[str]</code>、<code>Tuple[str]</code>时,别名将会指向模块名。
 当为<code>str</code>、<code>List[str]</code>、<code>Tuple[str]</code>时,别名将会指向模块名。


 如上文,<code>alias='m'</code>,则使用<code>~m xxx<code> = </code>~test xxx</code>
 如上文,<code>alias='t'</code>,则使用<code>~t xxx</code> = <code>~test1 xxx</code>
 
当为dict时则可自定义别名映射到的东西,如<code>{'enable': 'module enable'}</code>,则~enable xxx = ~module enable xxx
 
=== 旧版声明 ===
我们在旧版命令未引入“handle”特性,使得一个装饰器只能对应一个模块,不存在绑定子命令的特性。
 
此处介绍是由于时间关系,<code>Schedule</code>(计划任务类型)、<code>StartUp</code>(自启类型)尚未支持新版。
 
==== Schedule ====
<syntaxhighlight lang="python3">
from core.component import on_schedule
from core.elements import CronTrigger
 
@on_schedule(
     bind_prefix='test', # 定义模块名
     trigger=CronTrigger.from_crontab('30 8 * * MON'), # 触发器
     desc='啊吧啊吧', # 模块简介
     alias=None, # 命令别名
     recommend_modules=None, # 推荐打开模块
     developers=None, # 开发者列表
     required_superuser=False, # 是否需要超级管理员才能打开
)
async def weekly_rss(bot: FetchTarget):
   ...
 
</syntaxhighlight>


当为 dict 时则可自定义别名映射的命令,如<code>{'enable': 'module enable'}</code>,则<code>~enable xxx</code> = <code>~module enable xxx</code>


===== FetchTarget =====
=== 多语言 ===
  主要用于从数据库 获取用户推送内容
  我们加入了多语言支持,所有的多语言文件在模块文件夹下的 <code>locales</code> 文件夹,其 <code>zh_cn.json</code>、<code>en_us.json</code> 等 json 文件分别存储不同语言的键名


<syntaxhighlight lang="python3">
  目前官方存储库的大部分公 命令的多语言由机器人维护,新模块仅需在文件夹下存储<code>zh_cn.json</code> 即可
await bot.post_message('test', '啊吧啊吧') # 向所有已 <code>test</code> 模块的用户推送消息
sender = 'QQ|123456' # QQ号为123456的好友
fetch = bot.fetch_target(sender) # 获取信息
if fetch: #如获取到
   await fetch.sendMessage('xxx') # 发送消息
</syntaxhighlight>


在代码中可通过<code>MessageSession.locale.t("键名")</code>调用多语言。命令帮助则是<code>{键名}</code>,如<code>test <arg1> <nowiki>{{help.test}}</nowiki></code>


[[Category:开发]]
[[Category:开发]]
{{#dpl:category=开发|mode=userformat|format=,²{#related:%PAGE%}²,,|ordermethod=lastedit}}
{{#dpl:category=开发|mode=userformat|format=,²{#related:%PAGE%}²,,|ordermethod=lastedit}}

2024年4月25日 (四) 08:41的最新版本

本文将会教你如何编写自定义模块。

说明

所有模块都储存在 ./modules/ 文件夹。如果你想编写新的模块,请在此新建一个文件夹。

文件夹的名字并不用于区分模块名,仅用于分类。

机器人在加载的时候会遍历 ./modules/ 文件夹,并加载每个模块文件夹里的 __init__.py,请将想要加入的模块定义编写在 __init__.py 中或确保其能够被引用。

编写

我们假设你现在写好了具体的代码,现在你想把其做成一个可以给机器人使用的功能:

定义模块

在编写模块之前,我们需要先定义一个模块类型。

from core.component import module

test = module(
    bind_prefix='test1', # 定义模块名
    desc='这是一个简介', # 此模块的简介
    alias='t', # 此模块的别名
    developers=['Example'], # 开发者的名字
    recommend_modules=['test2', 'test3']), # 推荐启用的其他模块,用于在启用此模块时进行一并提示
    required_admin = False, # 将此模块标记为仅对话管理员可执行,覆盖下文所述的子命令设定,默认为False
    base = False, # 将此模块标记为基础模块,无需启用即可使用,默认为False
    required_superuser = False, # 将此模块标记为仅机器人超级管理员可使用,覆盖下文所述的子命令设定,默认为False
    support_languages=['zh_cn', 'zh_tw', 'en_us'] # 此模块支持的语言,未在列表内的语言在启用模块时会出现提醒
)

绑定模块

现在你已经定义好了一个模块,现在你需要将你想要的东西绑定上去了。

在前文中,我们给 test 变量声明了定义,我们将围绕这个定义进行绑定子命令,为了使代码简洁,我们使用了装饰器:

Command(一般命令)

from core.builtins import Bot

@test.command(help_doc='<args1>', # 设置此命令的语法,前缀匹配模块名,此处忽略。可为 list 或 tuple 来经手多条命令。可为空。
             required_admin = False, # 将此命令标记为仅对话管理员可使用。
             required_superuser = False, # 将此命令标记为进机器人超级管理员可使用。
             available_for = '*' # 控制此命令可被使用的消息来源,默认为 '*'(所有)
             )
async def _(msg: Bot.MessageSession):
    ...

help_doc 为空时,则代表此模块允许无需语法命令即可执行。如:使用 ~test 命令(后面不带任何东西),即可触发装饰器下面的函数,否则会出现“语法错误”的提示。

与语法匹配的命令将会被切割存储于 msg.parsed_msg(dict 类型)

如:{'<args1>': 'xxx'}

Regex(正则表达式)

from core.builtins import Bot

@test.regex(pattern=r'\[\[(.*?)]]', # 正则表达式语法
            mode='M', # 正则模式,设为'M'为匹配模式,'A'为匹配所有模式
            flags=0, # 设置正则的flags,如Re.M|Re.I
            show_typing=False #设置命令执行时是否展示输入提示(如戳一戳),默认为True
             )
async def _(msg: Bot.MessageSession):
    ...

与表达式匹配的命令结果将会存储于 msg.matched_msg 中。

当你输入的命令匹配 help_doc 内的语法时,机器人将会把消息传入装饰器下方的函数,然后你就可以进行发挥了。

Schedule(计划任务)

from core.builtins import Bot
from core.scheduler import CronTrigger

@test.schedule(trigger=CronTrigger.from_crontab('30 8 * * MON') # 触发此装饰器的条件)
async def _():
    ...

FetchTarget

from core.builtins import Bot
...
await Bot.FetchTarget.post_message('test', '啊吧啊吧') # 向所有已开启 test 模块的用户推送消息。
sender = 'QQ|123456' # QQ号为123456的好友
fetch = Bot.FetchTarget.fetch_target(sender) # 获取信息
if fetch: #如获取到
    await fetch.sendMessage('xxx') # 发送消息

主要用于从数据库中获取用户推送内容。

通用装饰器

假设你已经会使用了以上装饰器,而你又特别懒,则你可以使用通用装饰器来代替以上三种装饰器,此装饰器将会自动识别条件并归类函数。

from core.builtins import Bot

@test.handle('<args1>')
async def _(msg: Bot.MessageSession):
    ...


@test.handle(re.complie('(.*)'))
async def _(msg: Bot.MessageSession):
    ...


@test.handle(CronTrigger.from_crontab('30 8 * * MON'))
async def _():
    ...

处理消息

我们在装饰器下方的函数定义了一个 msg 参数,发送消息将围绕它进行。 我们在此处仅展示基础方法,具体可用的操作请借助 IDE 查看。

...
send = await msg.sendMessage('你好。') # 向发送对象发送一条消息
send.delete() # 将这条消息删除
...
confirm = await msg.waitConfirm('你确定吗?') # 在发送此消息后将暂停执行,等待用户的下一条消息
if confirm: # 用户发送了确认的词语
    ...

发送的消息可以为字符串或装有消息组件的列表,如:[Plain('今日图片:'), Image('https://example.com/test.jpg')]

消息来源

目前可用的消息来源(对话)有以下几种:

  • QQ
    • QQ|Group(QQ 群聊)
    • QQ(QQ 好友)
    • QQ|Guild(QQ 频道)
  • Discord
    • Discord|Channel(Discord 频道)
    • Discord|DM|Channel(Discord 私聊频道)
  • Telegram
    • Telegram|Private(Telegram 私聊)
    • Telegram|Group(Telegram 群组)
    • Telegram|Supergroup(Telegram 超级群组)
    • Telegram|Channel(Telegram 频道)
  • KOOK
    • KOOK|Group(KOOK 频道)
  • Matrix
    • Matrix|Room(Matrix 聊天室)
  • 控制台
    • TEST|Console

消息组件

目前主要可用的有Plain(文本)、Image(图片)、Voice(语音)

别名

主要用于快捷触发命令,或是兼容老的命令语法。 当为strList[str]Tuple[str]时,别名将会指向模块名。

如上文,alias='t',则使用~t xxx = ~test1 xxx

当为 dict 时则可自定义别名映射的命令,如{'enable': 'module enable'},则~enable xxx = ~module enable xxx

多语言

我们加入了多语言支持,所有的多语言文件在模块文件夹下的 locales 文件夹,其中 zh_cn.jsonen_us.json 等 json 文件分别存储不同语言的键名。

目前官方存储库的大部分公开命令的多语言由机器人维护,新模块仅需在文件夹下存储zh_cn.json即可。

在代码中可通过MessageSession.locale.t("键名")调用多语言。命令帮助则是{键名},如test <arg1> {{help.test}}

Cookie帮助我们提供我们的服务。通过使用我们的服务,您同意我们使用cookie。