# Notification APIs

本组API用于发送通知、修改和查询通知状态。

# 发送通知

# 功能介绍

发送通知又两种方式:

# 准备工作

发送通知的应用申请以及授权范围申请见概述中的准备工作,另外由于第一种方式发送通知接口所需的访问令牌采用资源拥有者密码凭据许可方式获取,因此您还必须拥有一个jAccount账号及其密码,对于第二种方式无须账号。

  • 对于发送邮件通知,该账号应为邮件的发件人jAccount账号,并已开通邮件服务,用未开通邮件服务的账号调用API会成功,但邮件不会发送成功。
  • 对于发送短信通知,该账号应为能够登录sms.sjtu.edu.cn的前缀为sms_的jAccount账号。如果您想用其他账号发送短信,需要发送邮件到gwang@sjtu.edu.cn申请,并写明发送短信的应用appId,我们会和该应用的申请单位核实后进行配置。
  • 对于交我办通知,如果您的应用是首次发送交我办消息,请发送邮件到xiejing0217@sjtu.edu.cn申请发送权限。在交我办中查看消息的界面里消息会按照应用分类,缺省应用名称即为分类名,如果您想使用一个不同于应用名称的分类名,也可发邮件到xiejing0217@sjtu.edu.cn申请更换一个合适的分类名。
  • 对于微信模板通知,准备工作较为复杂,请参见附录

# 请求参数

请求发送通知时请设置Content-Type请求头为application/json,并在请求体中放一个通知对象,格式如下

# Notification 通知 Structure

{
    "id":{guid},                       // 通知id,发送时可不填,返回数据中可通过该字段获取发送通知的唯一id
    "name":{string},                   // 标题
    "content":{string},                // 正文
    "html":{string},                   // html格式正文
    "abstract":{string},               // 正文摘要,发送短信通知时该摘要内容优先于content的内容
    "app": {notification.App},         // 交我办消息内容对象,数据结构见下
    "phones":[{string}],               // 发送到的手机号列表,上限100个
    "emails":[{string}],               // 发送到的邮箱列表,上限100个
    "accounts":[{string}],             // 发送到的jAccount账号列表,上限100个
    "users":[{notification.User}],     // 发送到的用户列表,上限100个,数据结构见下
    "channels":[{string}]              // 发送渠道,支持的渠道列表见下
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 发送通知时的Notification参数详细说明

参数 类型 描述
id guid 通知id,选填
name string 标题,字符数不能超过500,发送邮件时必填,发送app(app_sms)消息时为手机通知栏消息标题非必填,不填时会依次尝试使用app对象里的title,abstract,不允许这三项都同时为空;当发送app(app_sms)消息时app字段不传,就会将name用于组装app对象,此时name将会作为app.abstract处理,需要小于100字符
content string 正文,纯文本格式。
1. 发送邮件时和html字段选填其一
2. 发送短信时和abstract字段选填其一
3. 发送微信模板通知时必填
4. 发送app(app_sms)消息时为手机通知栏消息内容,和abstract字段选填其一
5. app_sms渠道content会被作为短信内容,优先级高于abstract,字数不能超过2048
6. app(app_sms)渠道发送消息时,当app字段为空时,content字段会用于组装app字段的content内容,此时外层这个content字段最大长度为1000
html string 正文,html格式,发送邮件时和content选填其一,html内容优先于content内容,即有html内容时以html格式发送。
app App app渠道附加信息,发送app消息时也非必填,如果不填会用name,content组装一个缺省的app信息,此时name和content字段的验证规则详见app对象的验证规则
abstract string 正文摘要,选填。
1. 发送sms通知时该字段内容优先于content内容,即该字段有内容以该字段为发送短信内容,没有则以content为发送短信内容,sms渠道该字段字符数不能超过2048
2. app和app_sms渠道该字段在content无内容时会被当做content使用
3. app_sms渠道如果交我办消息发送失败,则会以content或abstract内容发送短信,但是此渠道下content字段优先级高于abstract字段,这和sms渠道不同
phones [string] 手机号,上限100个,使用sms渠道时必填。
注意:使用app_sms渠道时必填且phones和accounts须一一对应(数量和顺序要一致)
emails [string] email,上限100个,使用email渠道时必填
accounts [string] jAccount账号,上限100个,使用app渠道时必填。
注意:使用app_sms渠道时必填且phones和accounts须一一对应(数量和顺序要一致)
app_sms渠道如果提供的accounts中某项为空字串,会取phones中对应项发送短信
users [User] 收信人列表,上限100个,仅应用于外部ChannelAPI以及微信模版通知,如果使用微信模板通知或者ChannelApi时,users必填
channels [string] 发送渠道,必填,目前支持email,sms,app,app_sms,wechat_template,可以同时填几个渠道表示这条通知同时几个渠道都发送

# App 交我办消息 Structure

{
    "displayStyle": {string},           // 消息展示格式。basic|fee|operation|news|todo选填,缺省basic
    "title": {string},                  // 消息详情标题 小于100字符 basic,fee,operation格式支持选填,news格式不支持title
    "abstract": {string},               // 消息强调显示标题 小于100字符 basic,fee,operation格式支持必填,news格式不支持
    "pictureUrl": {string},             // 图片url,只有news支持且必填
    "pushUrl": {string},                // 手机通知栏点击跳转链接,选填,不填时采用urls中第一个链接;如果没有urls则直接定位到消息中心页面
    "content":[{                        // 消息详情,basic,fee,operation格式支持选填,最多5组
        "name":{string},                // 详情标签显示文字,必填
        "value":{string}                // 该标签对应的内容,必填
    }],	         
    "urls":[{                           // 详情页面url对象。basic,fee,operation,news都支持
        "url":{string},	                // 链接url,必填,最大长度1024
        "urlName":{String},             // 链接文字,选填,缺省为"查看详情",最大长度20
        "urlType":{String}              // urlType为类型cordova|web|button选填,缺省web
    }],
    "expireTime":{long}                 // 消息有效期(秒),不填或者0代表长期有效
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 发送通知时的App参数详细说明

参数 类型 描述
displayStyle string 消息展示格式,可以是basic|fee|operation|news|todo 选填,缺省basic
其中todo类型较为特殊,只推送手机通知栏消息,用户点击后会跳转交我办的待办事项且交我办消息里不保留该消息
title string 消息详情标题 小于100字符 basic,fee,operation格式支持选填,news格式不支持title
abstract string 消息强调显示标题 小于100字符 basic,fee,operation支持必填,news格式不支持。在app对象不提供情况下,会将消息对象的name字段放到abstract上,提供app对象时以app中的abstract为准。
pictureUrl string 图片url,basic,fee,operation/不支持,news支持必填
urls object 详情页面url对象,四种格式都支持对象中url是详情页面url必填,urlName为链接文字选填,缺省为"查看详情",urlType为类型cordova|web|button 选填,缺省web
content [{name,value}] 消息详情,basic,fee,operation格式支持选填,name为标签文字必填;value为该标签下的内容必填。在app对象不提供情况下,会将消息对象的content字段构造一个{name:'内容',value:content}对象放到content数组中作为唯一值,app对象有时以app对象中的content为准。注意:content数组长度最大限制为5。 注意app.content内容json序列化后最大长度为1000。
总结app消息内容的大小可以大致认为当app参数不提供时,Notification参数上的content最多1000字符,当提供了app参数时,app参数上的content加起来最多1000字符。

# 交我办消息效果图示


发送的数据
{
    "name":"场馆预约",
    "content":"您已成功预订场馆",   
    "app":{
            "abstract":"场馆预约成功",
            "content":[{
                    "name":"内容",
                    "value":"场地XXX,费用YYY"
                },{
                    "name":"时间",
                    "value":"2021-01-01 20:00"
                }]
    },
    "accounts":["tester"],
    "phones":["13908888888"],
    "channels":["app_sms"]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
示例 手机消息推送栏内容

提示

发送app_sms渠道时,以上content信息:“您已成功预订场馆”也将会是短信内容


示例 basic类型消息内容
示例 fee类型消息使用title字段
示例 operation类型消息在urls中定义urlType为button的按钮链接
示例 news类型消息

# User 用户 Structure

{                     
    "id":{guid},                // 用户唯一id
    "name":{string},            // 姓名
    "account":{string},         // 账号 
    "email":{string},           // 邮箱
    "phone":{string}            // 手机号  
}
1
2
3
4
5
6
7

# 支持的发送渠道列表 Data

渠道代码 描述
email 邮件
sms 短信
app 交我办消息
app_sms 交我办消息(交我办消息发送失败时会用短信发送)
wechat_template 微信模版通知,该渠道开通步骤见附录
外部channel名称 用于外部ChannelAPI发送通知,channel名称由各ChannelAPI自行指定,目前尚未有任何外部渠道

为什么交我办消息会发送失败?

发送交我办消息时,以下原因会导致发送失败

  1. 用户没安装交我办
  2. 用户在系统中关闭了交我办的通知功能
  3. 用户交我办上登录了其他账号

app_sms渠道会先尝试发送交我办通知,如果发送失败会发送短信通知。

# 响应参数

所有API的响应参数都具有相同的通用结构,本文档只描述通用结构中entities数组返回的数据对象。

发送成功后会将发送的通知对象返回,其中的id会填写此次发送通知的标识id,可以用于以后的查询

{
    "errno":{number},           // 错误号,0表示成功
    "error":{string},           // 错误信息,在错误号不为0时可查看详细错误原因
    "total":0,                  // 固定为0 ,无意义
    "entities":[notification]   // 通知的请求对象,其中id会被替换成通知服务记录的唯一id
}
1
2
3
4
5
6

# 请求示例


示例 发送邮件(普通格式)
PUT /v1/notification?access_token=token HTTP/1.1
Host: api.sjtu.edu.cn
Content-Type: application/json

{
    "name":"测试邮件标题",
    "content":"测试邮件正文内容",
    "emails":["service@sjtu.edu.cn"],
    "channels":["email"]
}
1
2
3
4
5
6
7
8
9
10
示例 发送邮件(HTML格式)
PUT /v1/notification?access_token=token HTTP/1.1
Host: api.sjtu.edu.cn
Content-Type: application/json

{
    "name":"测试邮件标题",
    "html":"<html><body>邮件内容</body></html>",
    "emails":["service@sjtu.edu.cn"],
    "channels":["email"]
}
1
2
3
4
5
6
7
8
9
10
示例 发送短信
PUT /v1/notification?access_token=token HTTP/1.1
Host: api.sjtu.edu.cn
Content-Type: application/json

{
    "abstract":"测试短信通知",
    "phones":["13908888888"],
    "channels":["sms"]
}
1
2
3
4
5
6
7
8
9
示例 同时发送邮件和短信
PUT /v1/notification?access_token=token HTTP/1.1
Host: api.sjtu.edu.cn
Content-Type: application/json

{
        "name":"邮件标题",
        "content":"邮件正文,可能很长",
        "abstract":"短信内容,简短一些",
        "emails":["service@sjtu.edu.cn"],
        "phones":["13908888888"],
        "channels":["email","sms"]
}
1
2
3
4
5
6
7
8
9
10
11
12
示例 发送交我办消息
PUT /v1/notification?access_token=token HTTP/1.1
Host: api.sjtu.edu.cn
Content-Type: application/json

{
    "name":"交我办消息",
    "content":"消息正文",
    "accounts":["testprofile"],
    "channels":["app"]
}
1
2
3
4
5
6
7
8
9
10
示例 发送交我办消息(失败后发短信)
PUT /v1/notification?access_token=token HTTP/1.1
Host: api.sjtu.edu.cn
Content-Type: application/json

{
    "name":"交我办消息",
    "content":"消息正文",
    "accounts":["testprofile"],
    "phones":["13908888888"],
    "channels":["app_sms"]
}
1
2
3
4
5
6
7
8
9
10
11

# 响应示例


示例 典型的成功发送响应
HTTP/1.1 200 
Content-Type: application/json;charset=UTF-8

{
    "errno":0,
    "error":"success",
    "total":0,
    "entities":[{
        "id":"B4C6AFCD-2A83-4646-A410-E47E41A03EC7",
        "name":"邮件标题",
        "content":"邮件正文",
        "emails":["service@sjtu.edu.cn"],
        "channels":["email"]
    }]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 获取通知状态

# 功能介绍

应用发送通知后如果想查询通知的状态可调用此接口,请注意此接口要求以客户端凭据授予方式获取scope为notifications的令牌
请求的通知id可以有多个(最多100个),该id即发送通知时返回的结果中的通知id。

# 请求参数

  • notificationId 查询的通知id

# 响应参数

所有API的响应参数都具有相同的通用结构,本文档只描述通用结构中entities数组返回的数据对象。

查询成功后返回请求参数通知id指定的通知任务

  • 通知任务 Structure
{
    "id":{guid},                   // 通知id   
    "tasks":[{                     // 发送任务列表
        "taskId":{guid},           // 发送任务id
        "channel":{string},        // 发送渠道,如果渠道是app_sms,这里填的是实际发送的渠道。根据不同的发送渠道,选填以下phone,email,account字段
        "phone":{string},          // 接收人手机号(可选)             
        "email":{string},          // 接收人email(可选)
        "account":{string},        // 接收人账号(可选)  
        "sendingStatus":{string},  // 发送状态 pending|sent|retrying|fail(待发送|已发送|重试中|失败)
        "readingStatus":{string},  // 阅读状态 read|unread|unknown(已读|未读|未知) 注意仅交我办消息会设置已读状态,其余类型均为未知
        "sendtime":{number},       // 发送时间(unix时间戳,但注意单位毫秒) 
        "readtime":{number}        // 用户读取消息的时间(unix时间戳,但注意单位毫秒)  注意仅交我办消息会设置读取时间
    }]                          
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 请求示例

GET /notification/status?id=4e4503f9-8d28-11eb-95bb-fa163ee22824&access_token=token HTTP/1.1
Host: api.sjtu.edu.cn
1
2

# 响应示例


示例 查询通知状态的返回
HTTP/1.1 200 
Content-Type: application/json;charset=UTF-8

{
    "errno":0,
    "error":"success",
    "total":1,
    "entities":[{
        "id":"4e4503f9-8d28-11eb-95bb-fa163ee22824",
        "tasks":[{
            "taskId":"51593388-8d28-11eb-95bb-fa163ee22824",
            "channel":"email",
            "email":"tester@sjtu.edu.cn",
            "sendingStatus":"sent",
            "readingStatus":"unknown",
            "sendtime": 1649226161000,
        }]
    }]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 标记通知状态

# 功能介绍

通知渠道根据请求参数中的通知任务id,标记通知状态,一次请求最多标记100个。注意此接口要求以客户端凭据授予方式获取scope为modify_notification的令牌。请注意此api由负责发送的终端应用(发送渠道)调用。

# 请求参数

请求参数为需要标记的任务列表,以json格式放于请求体内,格式如下:

{
    "tasks":[{                     // 标记的任务列表
        "taskId":{guid},           // 发送任务id
        "account":{string},        // 发送的账号,可选填
        "read":{boolean},          // 是否已读,必填
        "readtime":{number}        // 用户读取时间(unix时间戳,但注意单位毫秒),可选填 
    }]     
}
1
2
3
4
5
6
7
8

# 响应参数

所有API的响应参数都具有相同的通用结构,本文档只描述通用结构中entities数组返回的数据对象。

返回的结果结构同获取通知状态接口,数据为请求标记状态的通知

# 请求示例


示例 将通知标记为已读
POST /notification/status?access_token=token HTTP/1.1
Content-Type: application/json

{
    "tasks":[{
        "taskId":"51593388-8d28-11eb-95bb-fa163ee22824",
        "read":"true",
        "readtime":1649226165413
    }]
}
1
2
3
4
5
6
7
8
9
10

# 响应示例


示例 将通知标记为已读后的返回数据
HTTP/1.1 200 
Content-Type: application/json;charset=UTF-8

{
    "errno":0,
    "error":"success",
    "total":1,
    "entities":[{
        "id":"4e4503f9-8d28-11eb-95bb-fa163ee22824",
        "tasks":[{
            "taskId":"51593388-8d28-11eb-95bb-fa163ee22824",
            "channel":"email",
            "email":"tester@sjtu.edu.cn",
            "sendingStatus":"sent",
            "readingStatus":"read",
            "sendtime":1649226161000,
            "readtime":1649226165413
        }]
    }]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 常见问题

# 通知收不到的原因

这里的通知收不到指发送已经返回成功,但是过了段时间收不到通知的情况,正常情况下发送成功到收到通知不会超过1分钟。

  • 邮件通知收不到请检查
    • 发送者账号是否开通了邮件服务
    • 接收者邮箱是否正确
  • 短信通知收不到请检查
    • 发送者账号是否是前缀为sms_的jAccount账号,如果不是该类型账号是否发邮件到gwang@sjtu.edu.cn申请开通过
    • 接收者手机信号是否正常
    • 接收者手机号码是否正确
  • 交我办通知收不到请检查
    • 如果您的应用第一次发送交我办通知,请发送邮件到xiejing0217@sjtu.edu.cn申请发送权限
    • 接收者账号是否正常登录了交我办

如果以上情况都没有,请联系yech@sjtu.edu.cn

# 附录

# 申请开通微信模版通知的步骤说明

  • 首先,发送公众号必须是服务号才能发送微信模版通知,如果公众号还不是服务号必须申请认证。
  • 成为服务号后,在管理页面功能菜单项下点击添加功能插件按钮,进入页面后点击模版消息,申请开通模版消息功能。申请时会要求填写所属行业(可以有2个),每个行业都会有一些预设的模版供选择。
  • 模版消息功能开通后,就可以在功能->模版消息菜单中查看并选择需要的模版添加到可发送的模版列表中(添加后会在我的模版列表中出现),如果没有满足要求的模版,可以在模版库页面中点击“帮助我们完善模版库”链接,在这里自定义需要的模版,提交官方审核。
  • 发送微信消息时候需要提供接收用户的jaccount,需要用户关注交大网络信息中心公众号且绑定过jaccount才行,另外微信通过unionId的机制来关联不同微信公众号中用户的关系(详见https://mp.weixin.qq.com/wiki (opens new window) 中关于unionId的介绍),所以在服务号上需要绑定微信开放平台账号,这个最好需要服务号的管理员到网络信息中心来申请现场开通,远程开通稍复杂。同时管理员需要将公众号的AppId,AppSecret提供给网络信息中心。
  • 调用通知api另外需要申请一个具有发送通知权限的应用,以及一个专门用于发送通知的jaccount,关联后该公众号只能通过这个jaccount来发送通知。
  • 以上几项步骤都完成后就可以发送微信模版消息了。
  • 微信模版通知的数据中users必填,users中主要起作用的是account字段,这里填写用户的jaccount账号。通知的数据放在content中,格式参考微信官方文档 (opens new window)中https://api.weixin.qq.com/cgi-bin/message/template/send这个接口的post数据说明,其中touser字段不用给出,因为这个在users中已经给出了,template_id就是需要发送的模版id,在后台模版消息列表中可以看到。将接口需要post的数据json序列化后填到content字段即可,一段典型的模版通知数据如下:
示例 微信模板通知发送数据
{
    "content":"{\"template_id\":\"5p_kZYdONXSqJwbmSB6FOVXQUhZRUyWFVson1wL1D90\",\"data\":{\"remark\":{\"value\":\"如有疑问请致电\"},
                     \"keyword1\":{\"value\":\"书名\"},\"keyword2\":{\"value\":\"2018-4-1\"},\"first\":{\"value\":\"您在我馆借阅的图书即将到期,请准备归还\"}}}"
    "users“:[{                         
        "account":"sjtu_account_001"
    }],
    "channels":["wechat_template"]           
}
1
2
3
4
5
6
7
8