应用集成 API

喧喧从 2.4 版本新增了应用集成 API,第三方应用可以方便的调用 API 来进行向喧喧讨论组发送通知等操作。

设置应用集成

要调用应用集成 API,首先要进行设置,设置步骤如下:

  1. 创建应用:如果还没有添加过应用则需要先创建一个应用,方法是打开后端管理界面(xxb),进入“应用→添加应用”页面:

  2. 开启应用集成:在应用管理列表进入集成设置页面,启用集成功能,并获取生成的密匙:


注意:创建应用时,请使用一个不会与其他应用产生冲突的应用代号,并且应用代号必须要为英文、数字或下划线的组合形式。应用代号在调用 API 时会用到。

注意:应用密匙在调用 API 时会用到,应该妥善保管应用集成时的密匙。

API 格式和签名机制

API 格式

第三方应用在请求喧喧数据时所调用的 API 的请求地址格式为:

/api.php?m=$moduleName&f=$methodName$params&code=$code&token=$token

以上请求地址格式中的变量定义如下:

  • $moduleName :要调用的 API 所属模块名称,必须提供;

  • $methodName :要调用的 API 所属模块内的方法名称,如果缺省则为 index

  • $params :要调用的 API 方法参数,如果没有参数可以留空,如果所调用的 API 方法有参数则将参数名和参数值通过通用网址查询字符串的形式插入到 $params 所在位置,例如 gid=XXX

  • $code :应用代号,必须提供;

  • $token :调用 API 时的数字签名。

例如获取讨论组 gid 为 64da14c3-c07a-45af-9c61-4e638de4af26 中的用户数据请求地址为:

/api.php?m=chat&f=getChatUsers&code=myAppCode&token=f5633c34c0c551a16c1d63bceb38d6a8

签名算法

API 请求地址中的数字签名 $token 应该在每次调用时根据应用集成密匙生成,具体算法为:

$token = md5(md5($query) + $key)

以上公式包含的变量定义如下:

  • $query :请求地址中查询字符串(? 之后的部分)不包含 &token=$token 的部分;

  • $key :应用密匙。

例如:

// 查询参数
var $query = 'm=chat&f=getChatUsers&code=myAppCode';

// 应用密匙
var $key   = '3cd0914d656e90ab181f1d52ff352cfe';

// 计算签名字符串
var $token = md5(md5('m=chat&f=getChatUsers&code=myAppCode') + '3cd0914d656e90ab181f1d52ff352cfe');

// 这样 $token 的计算值为 'f5633c34c0c551a16c1d63bceb38d6a8'

API 定义

下面列出目前第三方应用可以使用的 API。

chat/getChatGroups

此接口用于获取系统中的讨论组列表。

  • 请求方式:GET

  • 模块名称:chat

  • 方法名称:getChatGroups

  • 参数:无;

  • 返回值:JSON 对象,该对象属性定义如下:

属性名称 类型 说明
result 字符串 如果为 ‘success’ 则操作成功,如果为其他值则表示操作失败
message 字符串 如果操作失败,则使用此属性返回失败原因提示文本
data 对象 该对象定义了系统中的讨论组清单,对象属性名为讨论组的全局唯一 标识字符串(GID),属性对应的值为讨论组名称

下面为一个示例请求地址:

https://myxxb.com/api.php?m=chat&f=getChatGroups&code=myAppCode&token=f5633c34c0c551a16c1d63bceb38d6a8

正常情况下返回值如下:

{
    "result": "success",
    "data": {
        "30683aea-7a1f-4ec8-a6d6-834e0310fd7d": "第四期项目讨论",
        "81c6ba89-00ab-4431-8e47-063556ae4886": "研发部",
        "64da14c3-c07a-45af-9c61-4e638de4af26": "公司总群"
    }
}

chat/getChatUsers

此接口用于获取指定讨论组中的成员信息或者获取系统中全部成员信息。

  • 请求方式:GET

  • 模块名称:chat

  • 方法名称:getChatUsers

  • 参数:

    • gid :设置为要获取用户成员信息的讨论组的全局唯一 标识字符串(GID),如果留空,则请求会返回系统所有成员信息。

  • 返回值:JSON 对象,该对象属性定义如下:

属性名称 类型 说明
result 字符串 如果为 ‘success’ 则操作成功,如果为其他值则表示操作失败
message 字符串 如果操作失败,则使用此属性返回失败原因提示文本
data 对象 该对象定义了成员清单,对象属性名为成员 ID,属性对应的值为成员显示名称

下面为获取 GID 为 '30683aea-7a1f-4ec8-a6d6-834e0310fd7d' 的讨论组成员信息的示例请求地址:

https://myxxb.com/api.php?m=chat&f=getChatUsers&gid=30683aea-7a1f-4ec8-a6d6-834e0310fd7d&code=myAppCode&token=f5633c34c0c551a16c1d63bceb38d6a8

正常情况下返回值如下:

{
    "result": "success",
    "data": {
        "1": "管理员",
        "3": "张三",
        "4": "李四"
    }
}

notifyMSG

此接口用于向指定的讨论组推送通知消息。

  • 请求方式:POST

  • 模块名称:chat

  • 方法名称:notifyMSG

  • 参数:无;

  • 返回值:JSON 对象,该对象属性定义如下:

属性名称 类型 说明
result 字符串 如果为 ‘success’ 则操作成功,如果为其他值则表示操作失败
message 字符串 如果操作失败,则使用此属性返回失败原因提示文本

将要推送的通知消息对象转换为 JSON 字符串形式,然后使用 data 域通过 POST 请求发送到服务器。

一个通知消息对象拥有如下属性:

属性名称 类型 可选性 说明
receiver 字符串 必须 值为 'users' 或者 'group' ,如果为 'users' 则将消息通知发送给用户,用户会在通知中心(小喧喧)中接收到通知,如果是 'group' 则是向讨论组里发通知
gid 字符串 特定条件必须 为讨论组的全局唯一字符串,指定通知发送到的讨论组,当向讨论组发送通知时必须(即 receiver'group'
userList 数组 特定条件必须 使用一个用户 ID 数组指定通知发送给哪些用户,当向用户发送通知时必须(即 receiver'users'
title 字符串 必须 通知消息的标题
subtitle 字符串 可选 通知消息的副标题
content 字符串 可选 通知消息的内容文本
contentType 字符串 必须 可选值包括:'plain' 表示纯文本,'text' 表示 Markdown 格式的文本
url 字符串 可选 该通知消息所指向的网页链接
actions 对象数组 可选 使用 操作对象数组表示该通知支持的操作
sender 对象 可选 通知的 发送方信息对象

通知的 操作对象包含如下属性:

属性名称 类型 可选性 说明
label 字符串 必须 操作按钮上显示的文本
icon 字符串 可选 操作按钮上显示的图标
url 字符串 必须 点击此操作按钮时要打开的页面链接
type 字符串 可选 操作按钮类型,影响操作按钮外观,可选值包括 'primary''success''danger''warning''info''important''special'

发送方信息对象包容如下属性:

属性名称 类型 可选性 说明
id 字符串或数字 必须 标识发送方唯一身份的字符串或数字
name 字符串 可选 发送方在界面上显示的名称
avatar 字符串 必须 发送方头像图片链接地址

下面为一个发送通知消息的示例 POST 请求地址:

https://myxxb.com/api.php?m=chat&f=notifyMSG&code=myAppCode&token=f5633c34c0c551a16c1d63bceb38d6a8

下面为使用 JavaScript Fetch API 发起请求示例代码:

const notifycationData = {
    receiver: 'group',
    gid: 'f3de9ff9-dcb4-49de-915b-377ee9143418',
    title: '测试通知消息',
    subTitle: '测试通知消息副标题',
    content: '**测试消息**内容',
    contentType: 'text',
    url: 'http://xuan.im',
    actions: [
        {
            type: 'danger',
            label: '更新日志',
            url: 'https://xuan.im/page/changelogs.html'
        }, {
            type: 'normal',
            label: '下载地址',
            url: 'http://xuan.im/page/download.html'
        }
    ],
    sender: {
        avatar: 'https://avatars2.githubusercontent.com/u/472425?s=460&v=4',
        name: 'Catouse',
        id: 'catouse'
    }
};

const formData = new FormData();
formData.append('data', JSON.stringify(data));

const postUrl = 'https://myxxb.com/api.php?m=chat&f=notifyMSG&code=myAppCode&token=f5633c34c0c551a16c1d63bceb38d6a8';

fetch(postUrl, {
    method: 'POST',
    body: formData
}).then(r => {
    return r.json();
}).then(response => {
    if (response && response.result === 'success') {
        console.log('操作成功');
    }
});

正常情况下返回值如下:

{
    "result": "success"
}