开启自定义消息通知
在接收Sugar BI 的定时推送和数据预警,除了邮箱、群机器人和 APP 通知外,还支持一种额外的自定义消息通知方式(部署的 Sugar BI 版本需要是 5.0.2 及以上),例如要把消息通过短信的方式发送给接收者,这种情况则可以使用这种方式进行消息通知。
环境变量配置
# 自定义通知方式的请求的目标 url
sugar_custom_notify_url=http(s)://******
# 自定义通知方式的名称
sugar_custom_notify_name=短信
# 自定义通知方式在定时推送和数据预警中启用,默认都启用
sugar_custom_notify_type=time,warning
# 自定义通知方式请求的目标 url 的密钥,加签认证(不需要验证则不填写)
sugar_custom_notify_secret=sugar_secret
# 将签名信息放在哪些位置,可以多选(请求头,url 参数,请求体) 默认 query
sugar_custom_notify_sign_position=headers,query,body
sugar_custom_notify_url
:填写的是要将消息推送到的 http(s) 地址
sugar_custom_notify_name
:是在定时推送和数据预警中的「通知方式」中要展示的名称,例如上述例子填写的是短信
,如果不填写则名称是自定义
。
sugar_custom_notify_type
:指的是在哪些功能中开启,time
指定时推送,warning
指数据预警。默认不填写的话是在两个功能中都开启,英文逗号(,)分割。
发送和返回的数据格式要求
我们会以 post 的方式向推送地址(sugar_custom_notify_url
)发送请求,post 的数据格式为 'Content-Type': 'application/json; charset=utf-8'
,数据内容如下:
{
"emails": ["string", "string"], // 接收人的邮箱列表
"text": {
"title": "string", // 标题 - string 类型
"content": "string" // 内容(数据预警包含)- string 类型
},
"type": "string", // 消息类型,time(定时推送);warning(数据预警)- string 类型
"redirectUrl": "string", // 报表或者大屏链接 - string 类型
"imageUrl": "string", // 图片的 url 地址(定时推送包含)- string 类型
"imageData": "string" // 图片的 base64 编码(定时推送包含)- string 类型
}
如果您需要通过短信来通知接收人,那么就可以使用 emails 的邮箱列表查找到接收人的手机号,调用短信平台从而发送短信,这部分逻辑需要您在推送地址中自己来实现。
返回参数:
{
"errcode": 0, // 非 0 表示发送错误 - number 类型
"errmsg": "ok" // 信息内容 - string 类型
}
安全设置-签名校验
sugar_custom_notify_secret
:是要进行签名计算的密钥,提升推送地址的安全性,如果填写的推送地址需要进行签名校验,则在此配置要验证的密钥,如不需要进行签名验证,则跳过可以跳过此部分
。
签名的计算方式:把 timestamp + "|" + secret
当做签名字符串,使用 HmacSHA256 算法计算签名,然后进行 Base64 encode。在推送地址中具体验证逻辑可参考下述的示例代码。
sugar_custom_notify_sign_position
:签名信息需要放在哪些位置,headers
指请求头中,query
指 url 参数中,body
指请求体中。如果不填写,则只在 url 参数(query)中添加,英文逗号(,)分割。下述的示例代码,签名信息都在 url 参数中。
参数 | 说明 |
---|---|
timestamp | 当前时间戳,单位是毫秒 |
sign | 计算后的签名 |
签名验证示例代码,(Node.js)
import crypto = require('crypto');
const secret = 'sugar_secret';
const timestamp = req.query.timestamp;
const nowTime = Date.now();
const oneHour = 3600 * 1000; // 设置请求的时间误差,这里以 1 小时为例,具体可自行调整
if (nowTime - timestamp > oneHour) {
return '请求的时间误差超过 1 小时';
}
const fromSign = req.query.sign;
const stringToSign = timestamp + '|' + secret;
// 计算出来的签名和传递过来的签名一致,说明请求正确,否则拒绝
const sign = crypto.createHmac('sha256', secret).update(stringToSign).digest().toString('base64');
if (sign !== fromSign) {
return '签名校验错误';
}
// do next ...
签名计算示例代码(Java)
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import java.net.URLEncoder;
public class SignExample {
public static void main(String[] args) throws Exception {
String secret = "sugar_secret";
Long timestamp = Long.parseLong(request.getParameter("timestamp"));
Long nowTime = System.currentTimeMillis();
Long oneHour = 3600 * 1000; // 设置请求的时间误差,这里以 1 小时为例,具体可自行调整
if(nowTime - timestamp > oneHour) {
return '请求的时间误差超过 1 小时';
}
String stringToSign = timestamp + "|" + secret;
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256");
mac.init(signingKey);
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)),"UTF-8");
String fromSign = new String(request.getParameter("sign"));
if(sing != fromSign) {
return '签名校验错误';
}
// do next ...
}
}
签名计算示例代码(Python)
# python 3.8
import time
import hmac
import hashlib
import base64
import requests
import urllib.parse
timestamp = requests.params.timestamp
nowTime = str(round(time.time() * 1000))
oneHour = 3600 * 1000
# 设置请求的时间误差,这里以 1 小时为例,具体可自行调整
if (nowTime - timestamp > oneHour) {
return '请求的时间误差超过 1 小时'
}
secret = 'sugar_secret'
secret_enc = secret.encode('utf-8')
string_to_sign = '{}|{}'.format(timestamp, secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
fromSign = requests.params.sign
if (fromSign != sign) {
return '签名校验错误'
}
# do next ...