跳到主要内容

机器人与Webhook

机器人:互联网的未来

机器人(Bot)是新一代的互联网应用(App),我们可以用熟悉的对话聊天方式与机器人交互,机器人的玩法随着技术的成熟愈发多样,如“修图”,“查询数据”,“客服(自动回复)”,“控制智能家电”,“AI 伴侣”,“收费”等,并且不同功能的机器人又能被总管机器人(例如 AgentGPT、Longchain 等)调用协同工作。VoceChat 的机器人与 Webhook 方便了机器人的开发与使用。下面是用户利用 VoceChat 开发的机器人例子:

背景移除GPT4

以上案例均来自SilenceChat, 官网:https://ai.silencetime.com/

什么是 VoceChat 机器人

VoceChat 机器人本质是一个可以让你可编程控制的 VoceChat 账号,创建成功后,借助API Key可以便捷地向 VoceChat 发消息(频道和私聊都可以)。

什么是 Webhook

Webhook 依附于机器人而存在,是一个用以接收 VoceChat 推送数据的 URL 地址,可以这么理解:机器人负责把消息传送到 VoceChat,Webhook 则负责传出 VoceChat 消息到指定自定义 API。

创建机器人

提示

机器人管理入口只有管理账号才能看到

设置 => 机器人&Webhook进入机器人管理页面,点击新增按钮,弹窗中设置机器人姓名与 Webhook(选填),即可完成机器人的创建。

创建机器人

提示

创建成功后,可以在列表修改机器人头像

初始化一个 API Key

提示

API Key 是机器人与 VoceChat 通信的凭证,请妥善保存,如有泄露或遗失,请及时删除,重新生成。

给 API Key 起个名称,用以区分其他 API Key: 创建api key 复制并妥善保存生成的 API Key: copy api key

API Key 的使用

提示

以下提到的所有 API 均可在已部署的 API 文档内找到,

有了 API Key,就可以通过自定义 API,借助机器人向 VoceChat 发消息了,目前开放了两个 API(均可在已部署的 API 文档内找到):

重要提示

调用机器人相关 API 时,均须设置 http header:x-api-key:API Key(此处请替换为自己的 API Key 值)

消息类型介绍

VoceChat 目前定义了三种消息类型:文本消息Markdown 消息文件消息。它们有各自的数据结构和注意点。

文本消息

  • http header: content-type: text/plain
  • body: 纯文本,例如:message

Markdown 消息

  • http header: content-type: text/markdown
  • body: Markdown 源码,例如:**bold**

文件消息(图片,音视频,文档等)

  • http header: content-type: vocechat/file

  • body:

    {
    "path": "string"
    }
提示

文件消息比较特殊,需要先调用上传文件的 API,使用上传成功拿到的资源 path 填充到 body 里,然后当做消息发出去,具体流程,请参阅常见问题:如何发送文件消息

向新用户发欢迎消息

新用户注册进入server后,bot设置的webhook(参考后文)会收到新消息“newuser”,你可以继而发送欢迎消息(参考后文)。

向特定用户发消息,对应私聊场景

API:/api/bot/send_to_user/{uid}uid为用户 ID

温馨提示

uid可以从对话的 URL 里获取,比如http://replace.your.domain/#/chat/dm/1,最后数字即为uid;或者在用户信息页面找到:
UID

HTTP 请求举例:向uid:1发送纯文本消息:hello,http 请求结构(此处只列举出关键描述):

POST https://replace.yours.domain/api/bot/send_to_user/1
content-type: text/plain
x-api-key: xxxxxxxxxxxx

hello

具体编程语言举例:

温馨提示

无论哪种编程语言,本质上都是为了构建上面举例的 HTTP 请求

//我们使用最常用的axios发请求,向uid为1的用户发送纯文本消息:hello
import axios from "axios";

axios
.post(`https://replace.your.domain/api/bot/send_to_user/1`, `hello`, {
headers: {
"content-type": "text/plain",
"x-api-key": "xxxxxxxxxxxx",
},
})
.then((resp) => {
console.log("发送成功,消息ID:", resp.data);
})
.catch((err) => {
console.error("发送失败:", err.message);
});

HTTP 请求举例:向uid:1发送 markdown 消息:加粗的hello,http 请求结构(此处只列举出关键描述):

POST /api/bot/send_to_user/1
content-type: text/markdown
x-api-key: xxxxxxxxxxxx

**hello**

具体编程语言举例:

//我们使用最常用的axios发请求,向uid为1的用户发送markdown消息:加粗的hello
import axios from "axios";

axios
.post(`https://replace.your.domain/api/bot/send_to_user/1`, `**hello**`, {
headers: {
"content-type": "text/markdown",
"x-api-key": "xxxxxxxxxxxx",
},
})
.then((resp) => {
console.log("发送成功,消息ID:", resp.data);
})
.catch((err) => {
console.error("发送失败:", err.message);
});
具体使用方式请参考自部署的 API 文档

向特定频道发消息,对应群聊场景

提示
重要提示

特定频道必须是该机器人所在的频道;

gid可以在 Channel URL 里获取,比如http://replace.your.domain/#/chat/channel/102,最后数字即为gid;或者在频道设置页找到:
GID

API:/api/bot/send_to_group/{gid}gid为频道 ID,使用方式和私聊场景大同小异,只是在 API PATH 上有区别,其他一样。

回复特定消息

API:/api/bot/reply/{mid}mid为被回复的消息 ID,使用方式和私聊场景大同小异,只是在 API PATH 上有区别,其他一样。

其他相关 API

  • /api/bot:获取与机器人相关的所有频道列表
  • /api/bot/file/prepare:上传文件前的准备 API,其返回值在后续调用上传 API 的时候会用到
  • /api/bot/file/upload:上传文件 API,用于后续发送文件类消息
  • /api/bot/user/{uid}:获取具体的用户信息
  • /api/bot/user/{uid}:获取具体的用户信息
  • /api/bot/group/{gid}:获取具体的频道信息
提示

机器人文件上传相关 API 的使用,请参考FAQ

设置 Webhook

重要提示

Webhook 地址会预校验:HTTP GET请求响应状态码200则通过校验。后续 VoceChat 会以HTTP POST方式向该地址推送聊天数据,注意:推送接收到,请务必给出HTTP STATUS 200的响应,否则会当做推送失败处理,会重复推送。

set webhook

Webhook 推送的数据类型

VoceChat 会实时向已设置的 Webhook 推送所有该机器人相关的消息数据,包括不限于:

  • 新消息
  • 编辑消息
  • 删除消息
  • 回复消息

下面分别举例:

新消息

有新消息时,会推送此数据:

{
"created_at": 1672048481664, //消息创建的时间戳
"detail": {
"content": "hello this is my message to you", //消息内容
"content_type": "text/plain", //消息类型,text/plain:纯文本消息,text/markdown:markdown消息,vocechat/file:文件类消息
"expires_in": null, //消息过期时长,如果有大于0数字,说明该消息是个限时消息
"properties": null, //一些有关消息的元数据,比如at信息,文件消息的具体类型信息,如果是个图片消息,还会有一些宽高,图片名称等元信息
"type": "normal" //消息类型,normal代表是新消息
},
"from_uid": 7910, //来自于谁
"mid": 2978, //消息ID
"target": { "gid": 2 } //发送给谁,gid代表是发送给频道,uid代表是发送给个人,此时的数据结构举例:{"uid":1}
}

文件消息

消息类型 text/plaintext/markdown同归属于文本消息,数据结构比较简单明了,无需赘述。在此特别说明下vocechat/file文件消息:

{
"created_at": 1672048481664,
"detail": {
"content": "2023/1/26/cbb7ba67-10d8-4aad-b7c3-b8a7b3ecfc15", //资源的file_path
"content_type": "vocechat/file", //消息类型,text/plain:纯文本消息,text/markdown:markdown消息,vocechat/file:文件类消息
"expires_in": null,
"properties": {
"content_type": "image/png",
"height": 332,
"width": 445,
"name": "xxx.png",
"size": 234235
}, //有关该文件的元信息
"type": "normal"
},
"from_uid": 7910,
"mid": 2978,
"target": { "gid": 2 }
}
  • 此时content字段值,是指资源的file_path,需做一次转换,才能拿到完整的资源地址,转换规则:{PROTOCOL}://{SERVER_HOST}/api/resource/file?file_path={encodeURI(content)}
    • PROTOCOL:http 或者 https,根据自己部署实例的实际情况而定
    • SERVER_HOST即自己部署实例的主机名(如有特殊端口号,比如3000,不要忘记加上)
    • file_path参数需要做一次 URI 转义
  • properties有具体的文件类型信息,以及其它一些元信息,比如文件名,文件大小,如果是个图片消息,还会有一些宽高等
提示

以下的数据结构和上面的大同小异,只注释关键区别部分

编辑消息

消息被编辑时,会推送此数据:

{
"created_at": 1672060767247,
"detail": {
"detail": {
"content": "hello I'm editing this message lol",
"content_type": "text/plain",
"properties": null,
"type": "edit" //二级消息类型,edit代表是编辑消息
},
"mid": 2890,
"type": "reaction" //一级消息类型,reaction代表是针对消息的响应
},
"from_uid": 722,
"mid": 2979,
"target": { "uid": 13466 }
}

删除消息

消息被删除时,会推送此数据:

{
"created_at": 1672060943856,
"detail": {
"detail": {
"type": "delete" //二级消息类型,delete代表是删除消息
},
"mid": 2889, //被删除的消息ID
"type": "reaction"
},
"from_uid": 722,
"mid": 2980,
"target": { "uid": 13466 }
}

回复消息

消息被回复时,会推送此数据:

{
"created_at": 1672061091917,
"detail": {
"content": "I want to reply to a message",
"content_type": "text/plain",
"mid": 2858, //被回复的消息ID
"properties": { "mentions": [] },
"type": "reply" //二级消息类型,reply代表是回复消息
},
"from_uid": 722,
"mid": 2981,
"target": { "uid": 13466 }
}

自定义机器人的消息加密

secret 的set和get接口为可选项,不设置即明文传输。 set secret,需要自定义一个16字节长度的字符串,后端将自动aes加密。webhook收到消息后,需要aes解密,然后 pkcs7 unpad,即可得到得到原始的json。