第三方应用集成禅道客户端进行消息通知 分享链接

最后编辑:王林 于 2021-11-02 13:51:30

禅道开源版11.0版本集成了禅道客户端功能。

禅道里的消息通知可以发送到禅道客户端, 同时增加了消息通知接口。

与禅道集成的第三方应用,也可以通过该消息通知接口,将第三方应用的消息发送到禅道客户端里。

本文将详细介绍第三方应用如何集成禅道客户端进行消息通知。

一、设置应用集成 

第三方应用要与禅道做集成,具体请参考: http://www.zentao.net/book/zentaopmshelp/integration-287.html

二、签名机制

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

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

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

  • $moduleName :要调用的 API 所属模块名称(通常为 “im”),必须提供;

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

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

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

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

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


/x.php?m=im&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=im&f=getChatUsers&code=myAppCode') + '3cd0914d656e90ab181f1d52ff352cfe');
// 这样 $token 的计算值为 'f5633c34c0c551a16c1d63bceb38d6a8'

下面将详细说明第三方应用在完成和禅道的集成后如何通过禅道客户端进行消息通知。

三、通过禅道客户端进行消息通知

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

im/getChatGroups

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

  • 请求方式:GET;
  • 模块名称:im;
  • 方法名称:getChatGroups;
  • 参数:无;
  • 返回值:JSON 对象,该对象属性定义如下:
属性名称 类型 说明
result 字符串 如果为'success'则操作成功,如果为其他值则表示操作失败
message 字符串 如果操作失败,则使用此属性返回失败原因提示文本
data 对象 该对象定义了系统中的讨论组清单,对象属性名为讨论组的全局唯一 标识字符串(GID),属性对应的值为讨论组名称

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

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

正常情况下返回值如下:

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

im/getChatUsers

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

  • 请求方式:GET;

  • 模块名称:im;

  • 方法名称:getChatUsers;

  • 参数:

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

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

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

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

正常情况下返回值如下:

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

im/sendNotification

此接口用于向通知中心(小喧喧)推送通知消息。

  • 请求方式:POST;
  • 模块名称:im;
  • 方法名称:sendNotification;
  • 参数:无;
  • 返回值:JSON 对象,该对象属性定义如下:
属性名称 类型 说明
result 字符串 如果为'success'则操作成功,如果为其他值则表示操作失败
message 字符串 如果操作失败,则使用此属性返回失败原因提示文本

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

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

属性名称 类型 可选性 说明
users 数组 特定条件必须 使用一个用户 ID 数组指定通知发送给哪些用户,例如[1, 4],也可以指定一个用户账号组成的数组,例如['admin', 'zhangsan', 'lisi']
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/x.php?m=im&f=sendNotification&code=myAppCode&token=f5633c34c0c551a16c1d63bceb38d6a8

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

const notifycationData = {
    users: [1, 3],
    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 postUrl = 'https://myxxb.com/x.php?m=im&f=sendNotification&code=myAppCode&token=f5633c34c0c551a16c1d63bceb38d6a8';
fetch(postUrl, {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify(data)
}).then(r => {
    return r.json();
}).then(response => {
    if (response && response.result === 'success') {
        console.log('操作成功');
    }
}); 

正常情况下返回值如下:

{ "result": "success" }

im/sendChatMessage

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

  • 请求方式:POST;
  • 模块名称:im;
  • 方法名称:sendChatMessage;
  • 参数:无;
  • 返回值:JSON 对象,该对象属性定义如下:
属性名称 类型 说明
result 字符串 如果为'success'则操作成功,如果为其他值则表示操作失败
message 字符串 如果操作失败,则使用此属性返回失败原因提示文本

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

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

属性名称 类型 可选性 说明
gid 字符串 特定条件必须 为讨论组的全局唯一字符串,指定通知发送到的讨论组,当向讨论组发送通知时必须(即receiver为'group')
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/x.php?m=im&f=sendChatMessage&code=myAppCode&token=f5633c34c0c551a16c1d63bceb38d6a8

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

const notifycationData = {
    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 postUrl = 'https://myxxb.com/x.php?m=im&f=sendChatMessage&code=myAppCode&token=f5633c34c0c551a16c1d63bceb38d6a8';
fetch(postUrl, {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify(data)
}).then(r => {
    return r.json();
}).then(response => {
    if (response && response.result === 'success') {
        console.log('操作成功');
    }
}); 

正常情况下返回值如下:

{ "result": "success" }
先知 25203