系统通知

除消息通道外,SDK 还提供系统通知这种通道用于消息之外的通知分发。目前有两种类型:内置系统通知和自定义系统通知。现在主要包括群变动的相关通知,例如入群申请,入群邀请等,如果第三方应用还托管了好友关系,好友的添加、删除也是这个类型的通知。系统通知由 SDK 负责接收和存储,并提供较简单的未读数管理。发送自定义系统通知可以设置推送相关的参数。

注意:这里的入群申请、入群邀请的通知要区别于群操作的结果通知,比如创建群,解散群、踢人、拉人等群操作的通知。群操作的通知是通过IM消息通道来下发的(详见群通知事件

SysMessage参数说明

类型 参数 说明
NIMResCode kNIMSysMsgKeyLocalRescode 通知错误码 详见 NIMResCode
NIMMessageFeature kNIMSysMsgKeyLocalFeature 通知属性,区分离线,多端同步,漫游通知等等,详见NIMMessageFeature
int kNIMSysMsgKeyLocalUnreadCount 总计的通知未读数
string kNIMSysMsgKeyLocalContent 通知内容,无格式json字符串,字段定义详见NIMSysMessageContent

NIMSysMessageContent参数说明

类型 参数 说明
int64_t kNIMSysMsgKeyTime 通知时间戳(毫秒),选填
int kNIMSysMsgKeyType 通知的类型,如申请入群、邀请入群、添加好友等等,详见NIMSysMsgType
string kNIMSysMsgKeyToAccount 接收者id,如果是个人,则是对方用户id,如果是群,则是群id,必填
string kNIMSysMsgKeyFromAccount 发送者id,选填,如发送自定义通知消息时,可选填
string kNIMSysMsgKeyMsg 通知附言,按需填写
string kNIMSysMsgKeyAttach 附件,按需填写,类似于普通IM消息的附件内容,查看发送消息
int64_t kNIMSysMsgKeyMsgId 服务器消息id(自定义通知消息,必须填0),发送方不需要填写
int kNIMSysMsgKeyLocalStatus 本地定义的系统消息状态,见NIMSysMsgStatus,发送方不需要填写
string kNIMSysMsgKeyLocalClientMsgId 通知ID(客户端)
-- 消息设置 以下字段是消息内的设置字段,也属于通知内容一部分
int kNIMSysMsgKeyCustomSaveFlag (选填)自定义通知消息是否存离线:0-只发给在线用户,1-可发给离线用户
string kNIMSysMsgKeyCustomApnsText (选填)自定义通知消息推送文本,不填则不推送
int kNIMSysMsgKeyPushEnable (可选)是否需要推送, 0:不需要,1:需要,默认填1,配合kNIMSysMsgKeyCustomApnsText使用
int kNIMSysMsgKeyPushNeedBadge (可选)推送是否要做消息计数(角标), 0:不需要,1:需要,默认填1,配合kNIMSysMsgKeyCustomApnsText使用
int kNIMSysMsgKeyPushNeedPrefix (可选)推送是否需要推送昵称,0:不需要,1:需要,默认填0,配合kNIMSysMsgKeyPushEnable使用
string kNIMSysMsgKeyPushPayload (可选)第三方自定义的推送负载内容,必须为可以解析为json的非格式化的字符串,长度2048
bool kNIMSysMsgKeyAntiSpamEnable 是否需要过易盾反垃圾,默认false
string kNIMSysMsgKeyAntiSpamContent (可选)开发者自定义的反垃圾字段,长度限制:5000字符,配合kNIMSysMsgKeyAntiSpamEnable使用

NIMSysMessageContent解析示例:

//假设message是消息内容的json对象
void ParseSysMessageContent(Json::Value message)
{
    if (message.isObject())
    {
       int64_t timetag = message[kNIMSysMsgKeyTime].asUInt64();
       NIMSysMsgType type = (NIMSysMsgType)message[kNIMSysMsgKeyType].asUInt();
       char* receiver_accid = message[kNIMSysMsgKeyToAccount].asString();
       char* sender_accid = message[kNIMSysMsgKeyFromAccount].asString();
       char* content = message[kNIMSysMsgKeyMsg].asString();
       char* attach = message[kNIMSysMsgKeyAttach].asString();
       int64_t id = message[kNIMSysMsgKeyMsgId].asUInt64();
       NIMSysMsgStatus status = (NIMSysMsgStatus)message[kNIMSysMsgKeyLocalStatus].asUInt();

       //解析消息设置
       int push_need_badge = (BoolStatus)message[kNIMSysMsgKeyPushNeedBadge].asInt() == 1 ? BS_TRUE : BS_FALSE;
       int need_push = (BoolStatus)message[kNIMSysMsgKeyPushEnable].asInt() == 1 ? BS_TRUE : BS_FALSE;
       int push_need_prefix = (BoolStatus)message[kNIMSysMsgKeyPushNeedPrefix].asInt() == 1 ? BS_TRUE : BS_FALSE;
       int need_offline = (BoolStatus)message[kNIMSysMsgKeyCustomSaveFlag].asInt() == 1 ? BS_TRUE : BS_FALSE;
       char* push_payload = message[kNIMSysMsgKeyPushPayload].asString();
       char* push_content = message[kNIMSysMsgKeyCustomApnsText].asString();
       int anti_spam_enable = message[kNIMSysMsgKeyAntiSpamEnable].asInt() == 1 ? BS_TRUE : BS_FALSE;
       char* anti_spam_content = message[kNIMSysMsgKeyAntiSpamContent].asString();
       ...
    }
}

NIMSysMsgType通知类型说明

枚举 说明
kNIMSysMsgTypeTeamApply 0 申请入群
kNIMSysMsgTypeTeamReject 1 拒绝申请入群
kNIMSysMsgTypeTeamInvite 2 邀请入群
kNIMSysMsgTypeTeamInviteReject 3 拒绝邀请入群
kNIMSysMsgTypeFriendAdd 5 加好友
kNIMSysMsgTypeFriendDel 6 删除好友
kNIMSysMsgTypeCustomP2PMsg 100 点对点透传消息
kNIMSysMsgTypeCustomTeamMsg 101 群透传消息
kNIMSysMsgTypeUnknown 1000 未知类型,作为默认

推送、反垃圾等等消息设置类似IM的消息设置

接收系统通知

注册/注销系统消息接收事件。需要在登录之前先注册。为了保证整个程序逻辑的一致性,APP 需要针对不同类型的系统通知进行相应的操作。

void nim_sysmsg_reg_sysmsg_cb(const char *json_extension, nim_sysmsg_receive_cb_func cb, const void *user_data);
参数 说明
cb 通知回调
json_extension 扩展字段,预留
user_data APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理
//收到系统通知回调
void my_nim_sysmsg_receive_cb_func(const char *content, const char *json_extension, const void *user_data)
{
    //content解析为SysMessage
    Json::Value values;
    Json::Reader reader;
    if (reader.parse(content, values) && values.isObject())
    {
        NIMResCode rescode_ = (NIMResCode)values[kNIMSysMsgKeyLocalRescode].asUInt();
        NIMMessageFeature feature_ = (NIMMessageFeature)values[kNIMSysMsgKeyLocalFeature].asUInt();
        int total_unread_count_ = values[kNIMSysMsgKeyLocalUnreadCount].asUInt();

        //解析通知内容为NIMSysMessageContent定义内容
        Json::Value message = values[kNIMSysMsgKeyLocalContent];
        ParseSysMessageContent(message);
    }
}
//监听事件
nim_sysmsg_reg_sysmsg_cb(0,my_nim_sysmsg_receive_cb_func,0);

//取消监听
nim_sysmsg_reg_sysmsg_cb(0,0,0);

发送自定义系统通知

除了内置系统通知外,SDK 也额外提供了自定义系统给开发者,方便开发者进行业务逻辑的通知。这个通知既可以由客户端发起也可以由开发者服务器发起。

客户端发起的自定义通知,该类型通知格式由开发者自定义(kNIMSysMsgKeyAttach ),SDK 仅负责发送、接收,支持在线或离线发送,且支持点对点通知和群通知,不做任何解析,也不会存储,因此也不会在聊天记录中体现,可以使用的场景例如发送正在输入的状态等。

此外,自定义系统通知内容(SysMessage)还提供了属性设置如下:

注意:SDK 并不负责自定义通知的持久化,APP 需要根据自己的业务逻辑按需进行解析和持久化的工作。

void nim_sysmsg_send_custom_notification(const char *json_msg, const char *json_extension);
参数 说明
json_msg 消息内容,详见SysMessage
json_extension 扩展字段,预留
//以测试账号test1为例;
Json::FastWriter fw;

//创建通知内容
Json::Value message;
message[kNIMSysMsgKeyToAccount] = "test1";
message[kNIMSysMsgKeyType] = type;
message[kNIMSysMsgKeyLocalClientMsgId] = "消息唯一uuid";//开发者生成
values[kNIMSysMsgKeyTime] = 1520423612222;//当前时间UNIX时间戳 13位(毫秒)

//消息设置,按需
message[kNIMSysMsgKeyPushNeedBadge] = 1;
message[kNIMSysMsgKeyPushEnable] = 1;
message[kNIMSysMsgKeyPushNeedPrefix] = 1;
message[kNIMSysMsgKeyCustomSaveFlag] = 1;
message[kNIMSysMsgKeyCustomApnsText] = "这是一条推送通知消息";//推送消息的内容
message[kNIMSysMsgKeyAntiSpamEnable] = 1;
message[kNIMSysMsgKeyAntiSpamContent] = "{\"type\":0,\"data\":\"sss\"}";//参考IM 反垃圾设置

//可以创建附件内容
Json::Value attchment;
attchment["content"] = "这是attachment内容";
attchment["id"] = 2;
message[kNIMSysMsgKeyAttach] = fw.write(attchment);

//可以添加推送负载信息
Json::Value payload;
payload["Content"] = "这是推送负载信息";
message[kNIMSysMsgKeyPushPayload] = fw.write(payload);

char* msg = fw.write(message);

....

//发送消息
nim_sysmsg_send_custom_notification(msg,0);

发送自定义系统通知结果

发送自定义通知消息结果通知。

void nim_sysmsg_reg_custom_notification_ack_cb(const char *json_extension, nim_custom_sysmsg_ack_cb_func cb, const void *user_data);
参数 说明
cb 通知回调
json_extension 扩展字段,预留
user_data APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理
void my_nim_custom_sysmsg_ack_cb_func(const char *result, const void *user_data)
{
    //解析result
    Json::Value values;
    Json::Reader reader;
    if (reader.parse(result, values) && values.isObject())
    {
        NIMResCode rescode = (NIMResCode)values[kNIMSendAckKeyRescode].asUInt();
        char* msg_id = values[kNIMSendAckKeyMsgId].asString();
        char* talk_id = values[kNIMSendAckKeyTalkId].asString();
        int64_t msg_timetag = values[kNIMSendAckKeyTimetag].asInt64();
        ...
    }
    ...
}
//监听事件
nim_sysmsg_reg_custom_notification_ack_cb(0,my_nim_custom_sysmsg_ack_cb_func,0);

//取消监听
nim_sysmsg_reg_custom_notification_ack_cb(0,0,0);

通知消息管理

SDK提供接口查询历史消息,查询消息未读数、设置已读、删除通知等功能支持

查询系统通知

查询本地系统消息(按时间逆序起查,逆序排列)。

nim_sysmsg_query_cb_func参数说明

类型 参数 说明
int count 消息总数
int unread_count 未读通知消息总数
string result 通知消息集合,详见SysMessage)
user_data APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理
//查询结果回调
void nim_sysmsg_query_msg_async(int limit_count, int64_t last_time, const char *json_extension, nim_sysmsg_query_cb_func cb, const void *user_data);
参数 说明
limit_count 一次查询数量,建议20
last_time 上次查询最后一条消息的时间戳(按时间逆序起查,即最小的时间戳),起始查询填0
cb 操作结果回调
json_extension 扩展字段,预留
user_data APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理
void my_nim_sysmsg_query_cb_func(int count, const char *result, const char *json_extension, const void *user_data)
{
    //解析result
    Json::Value values;
    Json::Reader reader;
    if (reader.parse(sysmsgs_json, values) && values.isObject())
    {
        uint unread = values[kNIMSysMsglogQueryKeyUnreadCount].asUInt();
        Json::Value content = values[kNIMSysMsglogQueryKeyContent];
        int len = content.size();
        for (int i = 0; i < len; i++)
        {
            //解析为NIMSysMessageContent所定义的数据
            Json::Value message = content[i];
            ParseSysMessageContent(message);
            ...
        }
        ...
    }
}
//起始查询
nim_sysmsg_query_msg_async(20,0,0,my_nim_sysmsg_query_cb_func,0);

//假设起始查询的最后一条消息时间戳是 '1520423612222'
nim_sysmsg_query_msg_async(20,1520423612222,0,my_nim_sysmsg_query_cb_func,0);

查询未读消息数

void nim_sysmsg_query_unread_count(const char *json_extension, nim_sysmsg_res_cb_func cb, const void *user_data);
参数 说明
cb 操作结果回调
json_extension 扩展字段,预留
user_data APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理
void my_nim_sysmsg_res_cb_func(int res_code, int unread_count, const char *json_extension, const void *user_data)
{
    ...
}
//查询未读通知数
nim_sysmsg_query_unread_count(0,my_nim_sysmsg_res_cb_func,0);

设置消息状态

可以将消息状态设置为通过,拒绝,已读,已失效等状态。

NIMSysMsgStatus枚举说明

枚举 说明
kNIMSysMsgStatusNone 0 默认,未读
kNIMSysMsgStatusPass 1 收到消息,通过
kNIMSysMsgStatusDecline 2 收到消息,拒绝
kNIMSysMsgStatusRead 3 收到消息,已读
kNIMSysMsgStatusDeleted 4 已删
kNIMSysMsgStatusInvalid 5 已失效
void nim_sysmsg_set_status_async(int64_t msg_id, enum NIMSysMsgStatus status, const char *json_extension, nim_sysmsg_res_ex_cb_func cb, const void *user_data);
参数 说明
msg_id 消息id
status 消息状态,详见NIMSysMsgStatus
cb 操作结果回调
json_extension 扩展字段,预留
user_data APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理
void my_nim_sysmsg_res_ex_cb_func(int res_code, int64_t msg_id, int unread_count, const char *json_extension, const void *user_data)
{
    if (res_code == 200)//成功
    {
        ...
    }
}
//设置消息状态
int64_t msgId = "213213111";
nim_sysmsg_set_status_async(msgId,kNIMSysMsgStatusPass,0,my_nim_sysmsg_res_ex_cb_func,0);

按消息类型批量设置消息状态

void nim_sysmsg_set_logs_status_by_type_async(enum NIMSysMsgType type, enum NIMSysMsgStatus status, const char *json_extension, nim_sysmsg_res_cb_func cb, const void *user_data);
参数 说明
type 消息类型,详见NIMSysMsgType
status 消息状态,详见NIMSysMsgStatus
cb 操作结果回调
json_extension 扩展字段,预留
user_data APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理
void my_nim_sysmsg_res_cb_func(int res_code, int unread_count, const char *json_extension, const void *user_data)
{
    if (res_code == 200)//成功
    {
        ...
    }
}
//按类型设置消息状态
nnim_sysmsg_set_logs_status_by_type_async(kNIMSysMsgTypeTeamApply, kNIMSysMsgStatusPass, 0,my_nim_sysmsg_res_cb_func,0);

设置全部消息已读

void nim_sysmsg_read_all_async(const char *json_extension, nim_sysmsg_res_cb_func cb, const void *user_data);
参数 说明
cb 操作结果回调
json_extension 扩展字段,预留
user_data APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理
void my_nim_sysmsg_res_cb_func(int res_code, int unread_count, const char *json_extension, const void *user_data)
{
    ...
}
//设置全部消息已读
nim_sysmsg_read_all_async(0,my_nim_sysmsg_res_cb_func,0);

删除单条通知消息

void nim_sysmsg_delete_async(int64_t msg_id, const char *json_extension, nim_sysmsg_res_ex_cb_func cb, const void *user_data);
参数 说明
msg_id 消息id
cb 操作结果回调
json_extension 扩展字段,预留
user_data APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理
void my_nim_sysmsg_res_ex_cb_func(int res_code, int64_t msg_id, int unread_count, const char *json_extension, const void *user_data)
{
    if (res_code == 200)//成功
    {
        ...
    }
}
//删除消息
int64_t msgId = 213213111;
nim_sysmsg_delete_async(msgid,0, my_nim_sysmsg_res_ex_cb_func,0);

按消息类型批量删除消息

void nim_sysmsg_delete_logs_by_type_async(enum NIMSysMsgType type, const char *json_extension, nim_sysmsg_res_cb_func cb, const void *user_data);
参数 说明
type 消息类型,详见NIMSysMsgType
cb 操作结果回调
json_extension 扩展字段,预留
user_data APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理
void my_nim_sysmsg_res_cb_func(int res_code, int unread_count, const char *json_extension, const void *user_data)
{
    ...
}
//删除kNIMSysMsgTypeTeamApply类型的所有消息
nim_sysmsg_delete_logs_by_type_async(kNIMSysMsgTypeTeamApply,0, my_nim_sysmsg_res_cb_func,0);