Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Jul 24, 2023
1 parent 9e46219 commit 81a9d50
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 33 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
"build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vitepress build ."
},
"devDependencies": {
"@koishijs/components": "^1.3.1",
"@koishijs/core": "^4.13.8",
"@koishijs/components": "^1.3.2",
"@koishijs/core": "^4.13.9",
"@koishijs/market": "^4.1.2",
"@koishijs/registry": "^6.0.2",
"@koishijs/vitepress": "^2.2.1",
"@types/node": "^20.4.2",
"@types/spark-md5": "^3.0.2",
"cross-env": "^7.0.3",
"element-plus": "2.3.8",
"koishi": "^4.13.8",
"koishi": "^4.13.9",
"marked-vue": "^1.2.3",
"typescript": "^5.1.6",
"vitepress": "1.0.0-alpha.73",
Expand Down
2 changes: 1 addition & 1 deletion zh-CN/api/message/elements.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,5 +282,5 @@ hello<message/>world
| `nickname` || ~ || ~ | ~ |
| `avatar` || ~ | ~ | ~ | ~ |

- [1]: 基于 Webhook 功能,目前暂未支持
- [1]: 基于 webhook 功能,目前暂未支持
- [2]: 仅限 forward 和 quote 消息
57 changes: 41 additions & 16 deletions zh-CN/guide/adapter/bot.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,13 @@ class ReplBot extends Bot {
(bot as DiscordBot).internal.getGuild(guildId)
```

另一种方法是在有 `Session` 对象的环境中,直接通过 `session[platform]` 就可以访问到对应适配器的内部接口。这种方式的好处是无需类型断言
另一种方法是在有 `Session` 对象的环境中,直接通过 `session[platform]` 就可以访问到对应适配器的内部接口。这种方式不仅无需类型断言,并且能够直接访问到会话的原始数据

```ts
session.discord.getGuild(guildId)

session.discord.t // 原始事件名称
session.discord.d // 原始事件数据
```

你甚至还可以用这种方式对多种适配器提供定制化的支持:
Expand Down Expand Up @@ -108,7 +111,7 @@ class DiscordBot extends Bot {

## 实现内部接口

不同平台由于 API 的差异性,`Internal` 类的实现方式也会有所不同。对于简单的平台,你完全可以手动实现每一个内部接口;但如果平台本身就有上百个 API,手写每一个内部接口显然既费时又啰嗦。因此,Koishi 提供了一些技巧以简化你的适配工作。我们这里仍然以 Discord 为例。
不同的平台由于其 API 的差异性,`Internal` 类的实现方式也会有所不同。对于简单的平台,你完全可以手动实现每一个内部接口 (甚至可以不实现 `Internal` 类,就像 REPL 适配器那样);但如果平台本身就有上百个 API,手写每一个内部接口显然既费时又啰嗦。因此,Koishi 提供了一些技巧以简化你的适配工作。我们这里仍然以 Discord 为例。

### 使用 HTTP 服务

Expand Down Expand Up @@ -151,22 +154,18 @@ class DiscordBot extends Bot {
class Internal {
constructor(private http: Quester) {}

static createMethod(path: string, method: Quester.Method) {
return async function (this: Internal, ...args: any[]) {
// 将参数填入路径中
const url = path.replace(/\{([^}]+)\}/g, () => {
if (!args.length) throw new TypeError('missing arguments')
return args.shift()
})
return this.http(method, url)
}
}

static define(path: string, methods: Partial<Record<Quester.Method, string | string[]>>) {
for (const key in methods) {
const method = key as Quester.Method
for (const name of makeArray(methods[method])) {
this.prototype[name] = this.createMethod(path, method)
this.prototype[name] = async function (this: Internal, ...args: any[]) {
// 将参数填入路径中
const url = path.replace(/\{([^}]+)\}/g, () => {
if (!args.length) throw new TypeError('missing arguments')
return args.shift()
})
return this.http(method, url)
}
}
}
}
Expand All @@ -185,8 +184,11 @@ Internal.define('/guilds/{guild.id}', {
Internal.define('/users/@me/guilds', {
GET: 'getCurrentUserGuilds',
})
```

// 通过类型合并的方式,将这些方法添加到 Internal 类型上
最后别忘了通过类型合并的方式,将这些方法添加到 `Internal` 类型上:

```ts
interface Internal {
getGuild(guildId: string): Promise<Discord.Guild>
modifyGuild(guildId: string, data: Discord.PartialGuild): Promise<Discord.Guild>
Expand All @@ -195,4 +197,27 @@ interface Internal {
}
```

上面的代码还没有考虑请求体和异常处理等问题,如果想要深入了解,可以阅读 Discord 适配器的 [源码](https://github.com/satorijs/satori/blob/master/adapters/discord/src/types/internal.ts)。事实上,Discord 的接口在平台中也算是比较复杂的。有了这些技巧的加持,相信其他平台的适配器你一定也能手到擒来。
上面的代码还没有考虑请求体和异常处理等问题,如果想要深入了解,可以阅读 Discord 适配器的 [源码](https://github.com/satorijs/satori/blob/master/adapters/discord/src/types/internal.ts)。事实上,Discord 的接口已经是比较复杂的了。相信有了这些技巧的加持,其他平台的适配器你一定也能手到擒来。

### 注入会话属性

在本节的最后,我们还有一点伏笔没有回收。我们还需要在 `Session` 对象中注入 `discord` 属性,以便插件能够访问到内部接口:

```ts
declare module 'koishi' {
interface Session {
discord?: Internal & Payload
}
}
```

这里的 `Internal` 对应着内部接口,而 `Payload` 则对应着原始事件数据。当构造会话对象时 (将在下一节具体介绍),我们需要将这些数据注入到 `Session` 对象中:

```ts
// 平台注入的属性不建议设置为 enumerable
Object.defineProperty(session, 'discord', {
// 将 Internal 作为原型,将 Payload 作为实例属性
value: Object.assign(Object.create(internal), payload),
writable: true,
})
```
4 changes: 0 additions & 4 deletions zh-CN/guide/adapter/index.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
# 基本示例

::: tip
本章将介绍如何开发适配器。如果你没有适配聊天平台的需求,可以直接跳过本章。
:::

::: tip
在学习本章之前,建议先完整阅读 [入门 > 跨平台](../../manual/usage/platform.md)
:::
Expand Down
2 changes: 1 addition & 1 deletion zh-CN/guide/basic/command.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# 指令开发

::: tip
在学习本节之前,建议先阅读 [入门 > 指令系统](../../manual/usage/command.md)
在学习本节之前,建议先完整阅读 [入门 > 指令系统](../../manual/usage/command.md)
:::

正如我们在入门篇中介绍的那样,一个 Koishi 机器人的绝大部分功能都是通过指令提供给用户的。Koishi 的指令系统能够高效地处理大量消息的并发调用,同时还提供了快捷方式、调用前缀、权限管理、速率限制、本地化等大量功能。因此,只需掌握指令开发并编写少量代码就可以轻松应对各类用户需求。
Expand Down
4 changes: 0 additions & 4 deletions zh-CN/guide/console/index.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
# 扩展控制台

::: tip
本章将介绍如何开发控制台插件。如果你没有扩展控制台的需求,可以直接跳过本章。
:::

::: tip
在学习本章之前,建议先完整阅读 [入门 > 认识控制台](../../manual/console/index.md)
:::
Expand Down
2 changes: 1 addition & 1 deletion zh-CN/guide/i18n/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
:::

::: tip
在学习本章之前,建议先阅读 [入门 > 国际化](../../manual/usage/i18n.md)
在学习本章之前,建议先完整阅读 [入门 > 国际化](../../manual/usage/i18n.md)
:::

如果你在运营一个大型社区,那么你可能会遇到这种场景:群组内设立了许多不同语言的频道,每个频道分别供不同地区的用户进行交流。在这种情况下,最合适的做法是让你的机器人在不同的频道下使用不同的语言进行回复。本质上,这不会改变机器人的运行逻辑,因此最好的做法是将涉及的每一段文本都抽离出来,通过统一的方式进行管理,并在发送前进行本地化渲染。
Expand Down
2 changes: 1 addition & 1 deletion zh-CN/guide/plugin/filter.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# 过滤器

::: tip
在学习本节之前,建议先阅读 [入门 > 过滤器](../../manual/usage/filter.md)
在学习本节之前,建议先完整阅读 [入门 > 过滤器](../../manual/usage/filter.md)
:::

默认情况下,一个会话事件、中间件或者指令都对所有的会话生效。但如果我们希望这些功能只对部分群聊或者用户生效,我们就需要用到 **过滤器**
Expand Down
2 changes: 1 addition & 1 deletion zh-CN/guide/plugin/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# 认识插件

::: tip
在学习本章之前,建议先阅读 [入门 > 安装和配置插件](../../manual/console/market.md)
在学习本章之前,建议先完整阅读 [入门 > 安装和配置插件](../../manual/console/market.md)
:::

模块化是 Koishi 的核心特性。借助插件系统,Koishi 得以将各种功能解耦出来,并以模块的形式分发。在「开发上手」中我们已经体验了基础的插件开发范例。本章将介绍更多的模块化编写方式,并介绍一些场景下的最佳实践。
Expand Down
2 changes: 1 addition & 1 deletion zh-CN/manual/recipe/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Koishi 应用默认情况下只能在本机访问。而对于某些需求,你可能希望在公网上访问到 Koishi 的控制台或其他网络服务:

- 让更多人访问到你的 Koishi 控制台
- 使用作为 Webhook 服务端的插件 (例如 [github](https://github.koishi.chat))
- 使用作为 webhook 服务端的插件 (例如 [github](https://github.koishi.chat))

本节教程将指导你完成 Koishi 应用的公网部署。

Expand Down

0 comments on commit 81a9d50

Please sign in to comment.