Aeria
GitHub
改 · 3.7

写插件

最后核对 2026-10-08对应提交 79735c5依据 plugins.py · plugin_discord.py · plugin.py · PluginSettings.tsx · PLUGIN_PERMISSIONS.md

插件是跑在 Aeria 同一个进程里的 Python 代码,通过宿主给的接口做事:收命令、发消息、存自己的数据、在后台跑任务。这一篇从零写一个能用的小插件,后面几篇逐项细讲。

本页 7 节
  1. 要写的东西
  2. 例子:每天早上在一个频道里说句早安
  3. 装上、确认、启用
  4. 接下来
  5. 内置插件
  6. 对应的代码
  7. 没做到的

要写的东西

一个插件是一个目录,放在插件目录里(默认 data/plugins/<插件编号>/),里面两样:

例子:每天早上在一个频道里说句早安

data/plugins/morning-note/plugin.json:

{
  "id": "morning-note",
  "name": "早安",
  "version": "1.0.0",
  "description": "每天早上在指定频道发一句早安",
  "entrypoint": "plugin.py",
  "permissions": ["discord.channel.send", "webui.plugin_panel"]
}

data/plugins/morning-note/plugin.py:

import asyncio
from datetime import datetime


class MorningNote:
    async def setup(self, context):
        self.context = context
        # 托管的后台任务:崩了宿主按退避重启,停用、重载时一起停
        context.spawn("morning", self._loop)

    async def teardown(self):
        return None

    def panel_schema(self):
        # 网页后台「插件中心 → 设置」里画成一张表单
        return {"sections": [{"title": "发到哪", "fields": [
            {"path": "channel_id", "type": "string", "label": "频道编号"},
        ]}]}

    async def _loop(self):
        await self.context.discord.wait_until_ready()
        last_day = None
        while True:
            now = datetime.now()
            channel_id = self.context.config().get("channel_id")
            if channel_id and now.hour == 8 and now.date() != last_day:
                await self.context.discord.send_channel(int(channel_id), content="早安")
                last_day = now.date()
            await asyncio.sleep(60)


plugin = MorningNote()

装上、确认、启用

  1. 把这个目录放进插件目录,重启运行时。
  2. 网页后台「插件中心」里找到它,点「确认能力」:列出来的就是 permissions 里写的那几项。
  3. 点「设置」,填频道编号,保存;然后「启用」。

接下来

内置插件

随 Aeria 一起发的插件不用联网下载,在插件中心里直接装。现在有一个:「对话指令」。它本身不干活,加载着就表示「人格可以把对话里冲着它的请求交给模型判断是不是指令」;不装,人格只聊天。服务器管理、放歌这些自然语言的请求都要它在。

新装默认不装,要用就在插件中心装上。

对应的代码

没做到的